流式事件
stream: true 时三种协议的 SSE 事件格式、HopBase 插入的保活注释,以及流中错误的下发方式。
请求体传 "stream": true 后,创建对话补全、创建响应与创建消息改为返回 text/event-stream(SSE)。事件格式沿用各协议官方定义,官方 SDK 的流式接口可以直接使用;HopBase 只在其中插入保活注释,不改动事件内容。
/v1/chat/completionsPOST/v1/responsesPOST/v1/messages保活注释
流式期间 HopBase 约每 10 秒在两个事件之间写入一行 SSE 注释,避免长推理时连接被中间代理判为空闲而断开:
: hopbase-keepalive以冒号开头的行是 SSE 规范里的注释,官方 SDK 与标准 SSE 解析器都会忽略;自己按行解析时,请跳过以 : 开头的行,不要当作 JSON 解析。模型长时间没有任何输出时(约 90~150 秒,因模型而异),网关判定卡住并重试或报错,详见并发、超时与计费。
Chat Completions
每个事件一行 data:,内容是 chat.completion.chunk 对象,文字在 choices[0].delta.content;最后以 data: [DONE] 结束。
data: {"id":"chatcmpl-EXAMPLE","object":"chat.completion.chunk","model":"gpt-5.6-sol","choices":[{"index":0,"delta":{"role":"assistant","content":"我是"},"finish_reason":null}]}
data: {"id":"chatcmpl-EXAMPLE","object":"chat.completion.chunk","model":"gpt-5.6-sol","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"id":"chatcmpl-EXAMPLE","object":"chat.completion.chunk","model":"gpt-5.6-sol","choices":[],"usage":{"prompt_tokens":14,"completion_tokens":52,"total_tokens":66}}
data: [DONE]| 字段 | 说明 |
|---|---|
choices[].delta.content | 本段文字 |
choices[].delta.tool_calls | 工具调用参数分段下发,按 index 拼接 function.arguments |
choices[].finish_reason | 最后一段非空:stop / length / tool_calls |
usage | 只有请求传了 stream_options.include_usage: true 才下发,在最后一个 choices 为空的事件里;不传不影响计费 |
Responses
每个事件由 event: 行和 data: 行组成,data 里的 type 与事件名相同。
event: response.created
data: {"type":"response.created","response":{"id":"resp_EXAMPLE","status":"in_progress"}}
event: response.output_text.delta
data: {"type":"response.output_text.delta","item_id":"msg_EXAMPLE","output_index":0,"content_index":0,"delta":"我是"}
event: response.completed
data: {"type":"response.completed","response":{"id":"resp_EXAMPLE","status":"completed","usage":{"input_tokens":14,"output_tokens":58,"total_tokens":72}}}| 事件 | 说明 |
|---|---|
response.created | 响应开始 |
response.output_text.delta | 一段输出文字,在 delta |
response.output_text.done | 一段内容结束,text 为完整文字 |
response.completed | 成功结束,response.usage 为用量 |
response.failed | 中途失败,原因在 response.error.code:rate_limit_exceeded / server_error / invalid_prompt |
Anthropic Messages
事件顺序:message_start → 每个内容块 content_block_start / content_block_delta / content_block_stop → message_delta(带 stop_reason 与输出用量)→ message_stop。
event: message_start
data: {"type":"message_start","message":{"id":"msg_EXAMPLE","role":"assistant","model":"claude-sonnet-5","content":[],"usage":{"input_tokens":9,"output_tokens":1}}}
event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"你好!"}}
event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":14}}
event: message_stop
data: {"type":"message_stop"}流中错误
流一旦开始输出,HTTP 状态码就已是 200,之后的错误通过事件下发,不会再改状态码:
Chat Completions data: {"error": {…}} (不带 event: 行)
Responses event: response.failed
Anthropic event: errorClaude 流在中途断开时,HopBase 会补发一条 Anthropic 错误事件后结束:
event: error
data: {"type":"error","error":{"type":"api_error","message":"Response stream interrupted, please retry"}}客户端要在读流的循环里处理错误事件。已收到的片段无法续传,需要整条请求重新发起;中断前已产出的部分按量计费。重试策略见错误码与重试。