DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

ChatOpenAI 流里缺少 ID

ChatOpenAI 普通流式聚合缺少 response_metadata id,非流式却有。核对 1.7.1 的顶层 chunk ID 转换,在正确响应层保留真实标识。

ChatOpenAI 非流式调用的 response_metadata['id'] 有 chatcmpl 响应 ID,切换普通 Chat Completions 流式输出后,聚合结果里却没有这个字段。内容正常、token usage 也可能正常,仍不能据此认为供应商响应标识已被保存。

这一条件有 langchain-openai 1.6.6、1.7.0 的反馈,已核对的正式 1.7.1 中,普通流式 chunk 转换器仍没有把顶层响应 id 带入 generation metadata。本文针对这条路径,不把所有兼容端点或 Responses API 都算成相同问题。

顶层响应 ID 没进入转换结果

Chat Completions 流的 id 位于每个 chunk 顶层,同一次 completion 的分块共享这个值。它不在普通 choices[0].delta 里。

转换器从 delta 构造消息,另行保存结束原因、模型名和 usage;顶层 id 没有进入这一份结果。即使应用把所有 AIMessageChunk 都相加,也无法从已经丢失的字段中恢复它。

非流式 _create_chat_result 会保存响应字典里的 id,因而出现调用方式不同、相同字段是否存在也不同的现象。先对照原始响应、封装层转换结果与最终存储,不只查最终聚合代码。

按需要选择取 ID 的路径

业务可以等待完整结果时,应核对实例与绑定参数,让调用确实走非流式 Chat Completions 路径,再从返回消息的 response_metadata 读取供应商 id。不能只把方法名改成 invoke,却仍保留会触发流式处理的实例配置。

必须流式展示时,响应 ID 应在原始响应进入这条转换器之前,沿已有 SDK 或网关记录路径保存,再与本次应用请求关联。已转换的 token 回调没有这个字段,就不能从回答正文猜出一个值,也不能把 LangChain 的另一个消息 id 字段直接当作供应商响应 id。

记录时核对同一次 completion 的 id 一致,保留缺失状态和实际端点信息;不要把上一次请求的值填进当前记录。usage-only chunk 的 choices 可以为空,也应纳入检查。只检查含正文的一个 chunk,可能漏掉实际封装层的其他分支。

不要为了得到一个字段,擅自给普通聊天加上结构化输出或切换 Responses API。这会改变输出协议、解析与历史约定,并非审计字段的等价补救。HTTP 请求追踪标识也有自己的用途,不应混记为 completion 标识。

内容相同不等于记录完整

获准的受控验收应覆盖 invoke、ainvoke、stream 与 astream,以及多个内容片段、usage-only 片段和兼容端点不提供 id 的情形。检查最终记录的响应 ID、内容、结束状态与 usage 分别正确;没有供应商值时保留为空,不能生成一个看似正确的 chatcmpl 字符串。

流被中断时也不能只因已经取得 id 就认定回答完整。标识证明的是关联对象,不证明所有内容都收到、生成正常结束或工具调用已通过校验。

已经完成的流式请求没有保存原始 id 时,不应为补字段盲目重发同一请求。第二次生成是新的响应,可能有新的内容、费用或副作用;旧记录应明确保留这一缺口,后续请求再沿正确路径采集。