Передайте stream: true — и ответ пойдёт по частям, как только модель начнёт его писать. Первый токен приходит за доли секунды вместо целого ответа за несколько секунд.
stream = client.chat.completions.create(
model="google/gemini-3-flash",
messages=[{"role": "user", "content": "Расскажи о Марсе"}],
stream=True,
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="", flush=True)Ответ приходит как text/event-stream. Каждая строка данных — объект того же вида, что и обычный ответ, но с полем delta вместо message. Поток закрывается строкой data: [DONE].
data: {"choices":[{"delta":{"role":"assistant","content":""}}]}
data: {"choices":[{"delta":{"content":"Марс"}}]}
data: {"choices":[{"delta":{"content":" — четвёртая"}}]}
data: {"choices":[{"delta":{},"finish_reason":"stop"}],
"usage":{"prompt_tokens":14,"completion_tokens":96,"total_tokens":110}}
data: [DONE]Блок usage приходит в последнем содержательном чанке, вместе с finish_reason. Считать токены по числу дельт нельзя: в одной дельте может быть и один символ, и целое слово — это зависит от площадки.
finish_reason: "error", повтор остаётся на вашей стороне.proxy_buffering off.delta.tool_calls[i].function.arguments до конца потока. Разбирать JSON по дороге бесполезно — до конца он невалиден.