ChatAnthropic streaming drops thinking field from empty thinking blocks (signature_delta-only), replay fails with 400 thinking.thinking: Fie

当 Anthropic 流式返回一个 空 thinking 块 (仅有 signature_delta,无 thinking_delta)时,ChatAnthropic 流处理会丢失 thinking 字段,回放该消息到下一轮请求时 API 返回 400 thinking.thinking: Fie

快速结论:当 Anthropic 流式返回一个 空 thinking 块(仅有 signature_delta,无 thinking_delta)时,ChatAnthropic 流处理会丢失 thinking 字段,回放该消息到下一轮请求时 API 返回 400 thinking.thinking: Field required。优先检查 langchain-anthropic 包版本,并应用对 _make_message_chunk_from_anthropic_eventsignature_delta 分支的修复。

适用环境:LangChain 的 langchain-anthropic 集成,使用 Claude 模型(如 claude-opus-4-6)且启用 adaptive thinking 时触发。

最快修复方案:libs/partners/anthropic/langchain_anthropic/chat_models.py 中,找到 _make_message_chunk_from_anthropic_event 函数里处理 signature_delta 的分支,添加一行 content_block.setdefault("thinking", "")。如下所示(已验证可直接应用):

elif event.delta.type in {"thinking_delta", "signature_delta"}:
    content_block = event.delta.model_dump()
    content_block["index"] = event.index
    content_block["type"] = "thinking"
    if event.delta.type == "signature_delta":
        content_block.setdefault("thinking", "")   # 修复:确保空块有 thinking 字段
    message_chunk = AIMessageChunk(content=[content_block])

注意事项:该修复仅针对 signature_delta-only 的空 thinking 块场景;对于正常含 thinking_delta 的块,空字符串在 chunk 合并时会被文本覆盖,行为不变。直接修改源代码后需重新测试相关单元测试。

问题场景

用户在使用 LangChain 的 ChatAnthropic 模型(例如 claude-opus-4-6)进行流式推理时,若 Anthropic API 返回一个 thinking 文本为空 的 thinking 块(常出现在 tool result 之后的 assistant turn),流式事件序列为:content_block_startthinking="")随后仅接收到 signature_delta 事件,没有任何 thinking_delta。此时流式聚合出的消息块缺少 thinking 键,当后续对话回放该消息时,Anthropic API 拒绝请求并抛出 400 错误。

报错原文

anthropic.BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'messages.1.content.0.thinking.thinking: Field required'}, 'request_id': 'req_011Ccew3oAKvavEEJnTroFjZ'}

原因分析

问题由 _make_message_chunk_from_anthropic_event 函数中两个行为共同导致:

  • content_block_start 事件对于 thinking 类型块被直接丢弃(不会产生 chunk),因此空块的起始信息(包含 thinking="")丢失。
  • signature_delta 分支在构建内容块时使用 event.delta.model_dump(),该字典只包含 signature 字段,不含 thinking

对于正常含 thinking_delta 的块,thinking 字段由 thinking_delta 提供;但对于空 thinking 块,没有 thinking_delta,聚合出的消息块只有 {"type": "thinking", "signature": ..., "index": 0},缺少必需的 thinking 字段。回放该消息到下一轮请求时,API 校验失败。

环境排查

  • langchain-anthropic 包版本:建议升级至包含该修复的最新版本;若无法升级,需人工应用代码补丁。
  • Python 版本:无特定限制,但建议 >= 3.9。
  • Anthropic API 模型:使用 adaptive thinking 的 Claude 模型(如 claude-opus-4-6claude-sonnet-4-6 等)更容易复现。
  • 流式使用方式:在 agent 循环中,助手先返回工具调用结果,随后获得空 thinking 块时触发。

解决步骤

  1. 打开 libs/partners/anthropic/langchain_anthropic/chat_models.py 文件,定位到 _make_message_chunk_from_anthropic_event</code

    参考来源

    langchain-ai/langchain #38639

    GamsGo AI

    AI 工具推荐

    想把多个 AI 模型放在一个入口?

    GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

    了解 GamsGo AI

    推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

    这个方案解决了吗?

celebrityanime
celebrityanime
文章: 15898

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注