Yayınlanma tarihi: 21 Ocak 2025
Yayınlanan LLM yanıtı, artımlı ve sürekli olarak verilen verilerden oluşur. Yayın verileri, sunucu ve istemcide farklı görünür.
Sunucudan
Yayınlanan yanıtın nasıl göründüğünü anlamak için Gemini'a curl
komut satırı aracını kullanarak uzun bir şaka anlatmasını istedim. Gemini API'ye yapılan aşağıdaki çağrıyı inceleyin. Bu özelliği denerseniz URL'deki
{GOOGLE_API_KEY}
kısmını Gemini API anahtarınızla değiştirmeyi unutmayı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."}]}]}'
Bu istek, aşağıdaki (kısaltılmış) çıkışı etkinlik akışı biçiminde kaydeder.
Her satır, data:
ile başlar ve ardından mesaj yükü gelir. Somut biçim aslında önemli değildir, önemli olan metin parçalarıdır.
//
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}}
İlk yük JSON biçimindedir. Vurgulanan bölümleri daha yakından inceleyin
candidates[0].content.parts[0].text
:
{
"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
}
}
İlk text
girişi, Gemini'ın yanıtının başlangıcıdır. Daha fazla text
giriş ayıklarken yanıt yeni satırla ayrılır.
Aşağıdaki snippet'te, modelin nihai yanıtını gösteren birden fazla text
girişi yer almaktadır.
"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?\""
...
Ancak modele T-Rex şakaları yerine biraz daha karmaşık bir şey sorarsanız ne olur? Örneğin, Gemini'dan bir sayının çift mi yoksa tek mi olduğunu belirleyecek bir JavaScript işlevi oluşturmasını isteyin. text:
parçaları biraz farklı görünüyor.
Çıkış artık Markdown biçiminde ve JavaScript kod bloğuyla başlıyor. Aşağıdaki örnek, öncekiyle aynı işleme öncesi adımlarını içerir.
"```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"
...
İşleri daha da zorlaştıran bir durum ise işaretlenmiş öğelerin bir bölümle başlayıp başka bir bölümle bitmesidir. Bazı işaretlemeler iç içe yerleştirilmiş. Aşağıdaki örnekte, vurgulanan işlev iki satır arasında bölünmüştür:
**isEven(
ve number) function:**
. İkisinin toplamı **isEven("number) function:**
. Bu nedenle, biçimlendirilmiş Markdown çıktısı almak istiyorsanız her parçayı Markdown ayrıştırıcıyla ayrı ayrı işleyemezsiniz.
Müşteriden
Gemma gibi modelleri MediaPipe LLM gibi bir çerçeveyle istemcide çalıştırıyorsanız akış verileri bir geri çağırma işlevi aracılığıyla gelir.
Örneğin:
llmInference.generateResponse(
inputPrompt,
(chunk, done) => {
console.log(chunk);
});
Prompt API ile ReadableStream
üzerinde yineleme yaparak akış verilerini parçalar halinde alırsınız.
const languageModel = await LanguageModel.create();
const stream = languageModel.promptStreaming(inputPrompt);
for await (const chunk of stream) {
console.log(chunk);
}
Sonraki adımlar
Yayınlanan verileri nasıl performanslı ve güvenli bir şekilde oluşturacağınızı mı merak ediyorsunuz? LLM yanıtlarını oluşturmayla ilgili en iyi uygulamalarımızı inceleyin.