Cách LLM truyền trực tuyến phản hồi

Ngày xuất bản: 21 tháng 1 năm 2025

Câu trả lời của LLM được truyền trực tuyến bao gồm dữ liệu được phát ra liên tục và tăng dần. Dữ liệu truyền trực tuyến trông khác nhau giữa máy chủ và ứng dụng khách.

Từ máy chủ

Để hiểu rõ câu trả lời truyền trực tuyến trông như thế nào, tôi đã yêu cầu Gemini kể cho tôi một câu chuyện cười dài bằng công cụ dòng lệnh curl. Hãy xem xét lệnh gọi sau đây đến Gemini API. Nếu bạn dùng thử, hãy nhớ thay thế {GOOGLE_API_KEY} trong URL bằng khoá Gemini API của bạn.

$ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent?alt=sse&key={GOOGLE_API_KEY}" \
      -H 'Content-Type: application/json' \
      --no-buffer \
      -d '{ "contents":[{"parts":[{"text": "Tell me a long T-rex joke, please."}]}]}'

Yêu cầu này ghi lại đầu ra sau đây (đã rút gọn) ở định dạng luồng sự kiện. Mỗi dòng bắt đầu bằng data:, sau đó là tải trọng thông báo. Định dạng cụ thể không thực sự quan trọng, điều quan trọng là các đoạn văn bản.

//
data: {"candidates":[{"content": {"parts": [{"text": "A T-Rex"}],"role": "model"},
  "finishReason": "STOP","index": 0,"safetyRatings": [{"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT","probability": "NEGLIGIBLE"},{"category": "HARM_CATEGORY_HATE_SPEECH","probability": "NEGLIGIBLE"},{"category": "HARM_CATEGORY_HARASSMENT","probability": "NEGLIGIBLE"},{"category": "HARM_CATEGORY_DANGEROUS_CONTENT","probability": "NEGLIGIBLE"}]}],
  "usageMetadata": {"promptTokenCount": 11,"candidatesTokenCount": 4,"totalTokenCount": 15}}

data: {"candidates": [{"content": {"parts": [{ "text": " walks into a bar and orders a drink. As he sits there, he notices a" }], "role": "model"},
  "finishReason": "STOP","index": 0,"safetyRatings": [{"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT","probability": "NEGLIGIBLE"},{"category": "HARM_CATEGORY_HATE_SPEECH","probability": "NEGLIGIBLE"},{"category": "HARM_CATEGORY_HARASSMENT","probability": "NEGLIGIBLE"},{"category": "HARM_CATEGORY_DANGEROUS_CONTENT","probability": "NEGLIGIBLE"}]}],
  "usageMetadata": {"promptTokenCount": 11,"candidatesTokenCount": 21,"totalTokenCount": 32}}
Sau khi thực thi lệnh, các khối kết quả sẽ truyền trực tuyến.

Tải trọng đầu tiên là JSON. Hãy xem kỹ hơn candidates[0].content.parts[0].text được đánh dấu:

{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "A T-Rex"
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0,
      "safetyRatings": [
        {
          "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
          "probability": "NEGLIGIBLE"
        },
        {
          "category": "HARM_CATEGORY_HATE_SPEECH",
          "probability": "NEGLIGIBLE"
        },
        {
          "category": "HARM_CATEGORY_HARASSMENT",
          "probability": "NEGLIGIBLE"
        },
        {
          "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
          "probability": "NEGLIGIBLE"
        }
      ]
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 11,
    "candidatesTokenCount": 4,
    "totalTokenCount": 15
  }
}

Mục nhập text đầu tiên đó là phần bắt đầu của câu trả lời do Gemini tạo. Khi bạn trích xuất thêm các mục text, phản hồi sẽ được phân tách bằng dòng mới.

Đoạn mã sau đây cho thấy nhiều mục text, cho thấy phản hồi cuối cùng từ mô hình.

"A T-Rex"

" was walking through the prehistoric jungle when he came across a group of Triceratops. "

"\n\n\"Hey, Triceratops!\" the T-Rex roared. \"What are"

" you guys doing?\"\n\nThe Triceratops, a bit nervous, mumbled,
\"Just... just hanging out, you know? Relaxing.\"\n\n\"Well, you"

" guys look pretty relaxed,\" the T-Rex said, eyeing them with a sly grin.
\"Maybe you could give me a hand with something.\"\n\n\"A hand?\""

...

Nhưng điều gì sẽ xảy ra nếu thay vì yêu cầu mô hình đưa ra những câu chuyện cười về khủng long bạo chúa, bạn yêu cầu mô hình đưa ra một thứ gì đó phức tạp hơn một chút. Ví dụ: yêu cầu Gemini đưa ra một hàm JavaScript để xác định xem một số là chẵn hay lẻ. Các khối text: trông hơi khác một chút.

Giờ đây, đầu ra chứa định dạng Markdown, bắt đầu bằng khối mã JavaScript. Mẫu sau đây có các bước tiền xử lý giống như trước đây.

"```javascript\nfunction"

" isEven(number) {\n  // Check if the number is an integer.\n"

"  if (Number.isInteger(number)) {\n  // Use the modulo operator"

" (%) to check if the remainder after dividing by 2 is 0.\n  return number % 2 === 0; \n  } else {\n  "
"// Return false if the number is not an integer.\n    return false;\n }\n}\n\n// Example usage:\nconsole.log(isEven("

"4)); // Output: true\nconsole.log(isEven(7)); // Output: false\nconsole.log(isEven(3.5)); // Output: false\n```\n\n**Explanation:**\n\n1. **`isEven("

"number)` function:**\n   - Takes a single argument `number` representing the number to be checked.\n   - Checks if the `number` is an integer using `Number.isInteger()`.\n   - If it's an"

...

Để vấn đề trở nên khó khăn hơn, một số mục được đánh dấu bắt đầu ở một đoạn và kết thúc ở một đoạn khác. Một số mã đánh dấu được lồng vào nhau. Trong ví dụ sau, hàm được đánh dấu sẽ được chia thành 2 dòng: **isEven(number) function:**. Kết hợp lại, kết quả là **isEven("number) function:**. Điều này có nghĩa là nếu muốn xuất Markdown được định dạng, bạn không thể chỉ xử lý từng khối riêng lẻ bằng một trình phân tích cú pháp Markdown.

Từ khách hàng

Nếu bạn chạy các mô hình như Gemma trên máy khách bằng một khung như MediaPipe LLM, dữ liệu truyền phát trực tiếp sẽ được truyền qua một hàm gọi lại.

Ví dụ:

llmInference.generateResponse(
  inputPrompt,
  (chunk, done) => {
     console.log(chunk);
});

Với Prompt API, bạn sẽ nhận được dữ liệu truyền trực tuyến dưới dạng các khối bằng cách lặp lại trên một ReadableStream.

const languageModel = await LanguageModel.create();
const stream = languageModel.promptStreaming(inputPrompt);
for await (const chunk of stream) {
  console.log(chunk);
}

Các bước tiếp theo

Bạn có thắc mắc về cách kết xuất dữ liệu truyền trực tuyến một cách hiệu quả và an toàn không? Đọc các phương pháp hay nhất để hiển thị câu trả lời của LLM.