流式响应
Halro 的流式是标准 SSE,直接透传上游的事件形状。三个可流式的端点各有自己的事件集合,不通用。
一旦有字节出去,就不会再换 Provider
Section titled “一旦有字节出去,就不会再换 Provider”这是流式下最该先知道的一条:Halro 的重试与 Provider 回退是有界的,而且只在客户端还没看到任何响应字节时才可能发生。第一个事件发出之后,即使上游中途失败,网关也不会静默切到另一个 Provider 重来 —— 你会看到一个中断的流,而不是一段拼接自两个模型的输出。
对你的代码意味着:流中断要由你的应用决定怎么办(重发整个请求、还是把已收到的部分交给用户),网关不会替你做这个决定。重发前请读重试、超时与幂等。
Chat Completions
Section titled “Chat Completions”事件:chat.completion.chunk、[DONE]、error。
curl -N https://halro.example.com/v1/chat/completions \ -H "Authorization: Bearer $HALRO_GATEWAY_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "chat", "max_tokens": 256, "stream": true, "messages": [{"role": "user", "content": "你好"}] }'import osfrom openai import OpenAI
client = OpenAI(base_url="https://halro.example.com/v1", api_key=os.environ["HALRO_GATEWAY_KEY"], timeout=60.0, max_retries=0)with client.chat.completions.stream( model="chat", max_tokens=256, messages=[{"role": "user", "content": "你好"}],) as stream: for event in stream: if event.type == "content.delta": print(event.delta, end="", flush=True)Responses
Section titled “Responses”事件序列更细,共 11 种:response.created、response.in_progress、response.output_item.added、response.content_part.added、response.output_text.delta、response.output_text.done、response.content_part.done、response.output_item.done、response.completed、response.incomplete、error。
只消费文本增量的话,关注 response.output_text.delta 即可;但必须同时处理 response.incomplete 与 error —— 前者表示流正常结束但输出未完成(例如撞到 max_output_tokens),语义与 response.completed 完全不同。
Anthropic Messages
Section titled “Anthropic Messages”事件:message_start、content_block_start、content_block_delta、content_block_stop、message_delta、message_stop、ping、error。
ping 是保活事件,没有内容,直接跳过。用量信息在 message_delta 里。
不支持流式的端点
Section titled “不支持流式的端点”/v1/embeddings 与 /v1/messages/count_tokens 没有流式。后者的 stream 字段会被明确拒绝,不是被忽略。