Streaming
Como uma completion em streaming chega ao fio, o que transporta o último frame, e o que acontece quando um cliente se desconecta.
O transporte
Defina stream: true e a resposta é text/event-stream: um objeto JSON por linha data:, cada um seguido de uma linha vazia. O buffering está desativado para que um proxy não retenha frames.
HTTP/1.1 200 OK
content-type: text/event-stream; charset=utf-8
cache-control: no-cache, no-transform
connection: keep-alive
Os frames
O primeiro frame transporta o papel de assistant, depois um frame por delta, depois um frame com finish_reason e o bloco de encaminhamento, depois exatamente um terminador. Um cliente que siga o formato lê o terminador e para; não deve tratar um terminador em falta como uma resposta completa.
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Hallo"},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"llmeu":{…}}
data: [DONE]
O bloco de encaminhamento viaja com o último frame
O frame final transporta o mesmo objeto llmeu que a resposta sem streaming devolve: trace_id, model_used, model_version, provider, endpoint_id, inference_region, sovereignty_class, policy_id, retention e a estimativa de custo. Em modo streaming, a utilização só é conhecida no fim, e é por isso que o bloco viaja com o último frame em vez do primeiro.
Desconexão do cliente
Fechar a ligação interrompe o trabalho e escreve o trace com o que foi realmente produzido. Um pedido cancelado continua a ser uma chamada que aconteceu, por isso aparece na utilização; não é registado como uma completion concluída.
O que não pode ser transmitido em streaming
Embeddings e a API da plataforma são respostas JSON únicas. stream: true numa rota sem streaming é um erro de validação, não um fallback silencioso para um frame.