Agentic run with dynamic filtering (web_search_20260209 inside code_execution) rejected with “code_execution tool use … without a correspo

该报错出现在使用 langchain-anthropic 的 ChatAnthropic 搭配 Anthropic 服务端工具 web_search_20260209 时:动态搜索运行在 code_execution 内部,嵌套的 server_tool_use / *_tool_result 块带

快速结论:该报错出现在使用 langchain-anthropic 的 ChatAnthropic 搭配 Anthropic 服务端工具 web_search_20260209 时:动态搜索运行在 code_execution 内部,嵌套的 server_tool_use / *_tool_result 块带有 caller 字段,但 _format_messages 在回传历史时丢弃了它,导致 API 认为 code_execution 调用没有对应结果而返回 400。优先排查回传请求中是否保留了 caller。

适用环境:Issue 中已确认可复现于 langchain-anthropic 1.4.6 和 1.7.7,涉及包 langchain、langchain-anthropic、langchain-core;使用 create_agent 构建 agent,模型侧为 Anthropic(示例代码中为 claude-sonnet-5,以实际配置为准)。Python、CUDA、显卡、操作系统版本 Issue 未给出,不作推测。

最快修复方案:暂无确认的一步修复方案。Issue 中给出了可优先尝试的临时变通:通过继承 ChatAnthropic 并覆写 _get_request_payload,从输入消息中把 caller 重新拷贝到对应的块上。

注意事项:变通方案属于推测性临时手段,Issue 作者未在官方代码上验证合并。修复时必须同时保留 server_tool_use 和 web_search_tool_result(以及其他 *_tool_result)两类块上的 caller:只恢复 server_tool_use 会触发另一条 400(unexpected tool_use_id)。另外,默认的 {"type": "direct"} caller 建议不转发,否则会改变所有现存的 web search / web fetch / code execution 对话请求,并可能破坏录制的 VCR 磁带。

问题场景

用户用 create_agent 构建 agent,工具中包含 Anthropic 内置的 web_search_20260209(由 ChatAnthropic 原样透传给 API)。当模型启用动态过滤、把搜索嵌套在 code_execution 内执行时,后续请求被 API 以 400 拒绝。该问题具有间歇性:只有当模型在单次 code_execution 中执行不止一次搜索时才会出现。另有一点:当 Claude 在同一个响应里既调用客户端工具、又发起搜索时,该响应会以 stop_reason: "tool_use" 结束并留下未完成的 code_execution server_tool_use,下一轮才携带嵌套的 server_tool_use / web_search_tool_result 块,再下一轮请求即触发 400。

报错原文

Agentic run with dynamic filtering (web_search_20260209 inside code_execution) rejected with "code_execution tool use ... without a corresponding code_execution_tool_result block"

messages.1: `code_execution` tool use with id `srvtoolu_…` was found without a corresponding `code_execution_tool_result` block

仅恢复 server_tool_use 上的 caller 时,API 返回的是另一条错误:

unexpected `tool_use_id` found in `web_search_tool_result` blocks: srvtoolu_…. Each `web_search_tool_result` block must have a corresponding `server_tool_use` block before it.

原因分析

最可能的原因是 ChatAnthropic 存储的 AIMessage 本身保留了每个块上的 caller,但 _format_messages 在组装回传请求时改用了白名单式拷贝:

  • server_tool_use 分支只拷贝 type、id、input、name、server_name、cache_control;
  • *_tool_result 分支(web_search_tool_result、code_execution_tool_result 等)只拷贝 type、content、tool_use_id、is_error、cache_control、retrieved_at;
  • 客户端 tool_use 分支则显式拷贝了 caller,所以不受影响。

结果是嵌套搜索在回传历史中变成了顶层调用,code_execution 调用看起来没有结果,API 因而报 400。用原始 SDK 重放失败 payload 可验证:按 _format_messages 当前构建方式发送 → 400;仅恢复 server_tool_use 的 caller → 另一条 400;同时恢复 server_tool_use 和 web_search_tool_result 的 caller → 被接受。container id 不是必要条件,同样历史无论带不带 container 都被接受。

环境排查

  • 确认 langchain-anthropic 版本(Issue 中可复现的是 1.4.6 与 1.7.7),并确认 langchain、langchain-core 版本。
  • 确认使用的工具定义是否为 {"type": "web_search_20260209", "name": "web_search"},是否启用了动态过滤。
  • 确认触发场景是否包含:在同一个响应里既调用客户端工具又发起搜索,或单次 code_execution 内有多次搜索。
  • 排查时应把回传的请求 payload 与原响应对照,检查 server_tool_use 与 web_search_tool_result 块上是否还保留 caller 字段。

解决步骤

  1. 先确认问题来自 _format_messages 的字段裁剪,而不是 agent 或提示词逻辑:用 debug=True 观察请求历史,或直接打印将要回传的消息结构,核对 server_tool_use / web_search_tool_result 上是否缺少 caller。
  2. 临时变通(可优先尝试):继承 ChatAnthropic,覆写 _get_request_payload,从输入消息中把 caller 拷贝回匹配的 server_tool_use 和对应 *_tool_result 块上。注意两处都要处理,且默认 {"type": "direct"} 的 caller 建议跳过不转发。
  3. 替换 agent 构建中的 ChatAnthropic(...) 为上述子类实例,其余调用保持不变。
  4. 若希望从根源修复,可关注上游 PR:Issue 中作者已准备好同时覆盖两处、并带单元测试的修复,等待维护者分配 issue 后提交。

验证方法

重新运行同样的 agent 查询,确保触发多步搜索或“客户端工具 + 搜索”的组合场景。若不再返回 code_execution without a corresponding code_execution_tool_result block 或 unexpected tool_use_id 的 400,并且最终助手回答正常输出,即说明 caller 已被正确回传。注意该修复尚未在真实 API 上验证过嵌套动态搜索场景(Issue 中暂无可覆盖 web_search_20260209 的录制磁带),结论以实际请求为准。

参考来源

langchain-ai/langchain #40868

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 33094

发表回复

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