流式行为
当客户端向 ProxAI 请求流式响应时,ProxAI 会保留上游 Server-Sent Events (SSE) 字节流,同时观察协议事件。从使用者视角看,三件事最重要:流最终会结束、错误以可读形态到达、卡住的 tool call 不会让客户端永远等待。
健康的流是什么样
Section titled “健康的流是什么样”每个 provider 协议都有自己的 terminal event。只有收到预期的 terminal event,ProxAI 才认为这条流完整。这实现了 行为契约 C19。
OpenAI Responses
Section titled “OpenAI Responses”- 1
response.created流开始。
- 2
response.output_item.added新的 output item 开始(message、reasoning、function_call 等)。
- 3
response.output_text.delta / response.function_call_arguments.delta文本或工具调用参数增量 bytes。
- 4
response.output_item.doneoutput item 完成。
- 5
response.completedterminal event,流完整结束。
OpenAI Chat Completions
Section titled “OpenAI Chat Completions”- 1
chat.completion.chunkcontent、tool calls 和 finish_reason 的增量 chunk。
- 2
[DONE]终止 sentinel;没有它的 EOF 会被视为不完整。
Anthropic Messages
Section titled “Anthropic Messages”- 1
message_start流开始。
- 2
content_block_start / content_block_delta / content_block_stop一个 content block(text、thinking、tool_use 等)按增量产生。
- 3
message_delta携带 stop_reason、stop_sequence、usage 等 message-level delta。
- 4
message_stopterminal event,流完整结束。
卡住的工具调用
Section titled “卡住的工具调用”如果上游开始流式发送 function/tool arguments 但一直没有完成,ProxAI 可以用协议形态的错误关闭流,而不是让客户端一直挂起。它由以下配置控制:
[tool_calls]timeout_secs = 120这是语义超时,不是整条请求的总时长上限。它只在工具调用参数流已经开始后才生效。这实现了 行为契约 C20。
工具调用时流卡住
可能原因
- 上游开始发送 tool arguments,但没有发送匹配的 done event。
- 原始 HTTP stream 还开着,但 provider 语义层已经 stalled。
下一步检查
- 调低或调整 `[tool_calls].timeout_secs`。
- 针对单次请求开启 `upstream_response` capture。
- 查看诊断中的 recent SSE tail。
流关闭但没有最终答案
可能原因
- 缺少 `[DONE]`、`response.completed` 或 `message_stop` 等 terminal event。
- 上游连接在协议状态完成前关闭。
下一步检查
- 查看 stream outcome 日志。
- 对照该协议预期的 terminal event。
- 捕获 upstream response bytes。
Unicode 文本看起来损坏
可能原因
- 把不完整的 byte chunk 当成完整 UTF-8 文本解释。
- 某个工具把原始 bytes 当字符串切片。
下一步检查
- 只在完整 SSE event data 上解码。
- 保持 byte-oriented scanning。
- 避免对任意 chunk 做字符串切片。