快速结论:该报错出现在使用 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字段。
解决步骤
- 先确认问题来自
_format_messages的字段裁剪,而不是 agent 或提示词逻辑:用debug=True观察请求历史,或直接打印将要回传的消息结构,核对server_tool_use/web_search_tool_result上是否缺少caller。 - 临时变通(可优先尝试):继承
ChatAnthropic,覆写_get_request_payload,从输入消息中把caller拷贝回匹配的server_tool_use和对应*_tool_result块上。注意两处都要处理,且默认{"type": "direct"}的 caller 建议跳过不转发。 - 替换 agent 构建中的
ChatAnthropic(...)为上述子类实例,其余调用保持不变。 - 若希望从根源修复,可关注上游 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 的录制磁带),结论以实际请求为准。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。

![[Bug] test_detect_file_encodings fails on Windows: cannot reopen an open NamedTemporaryFile](https://www.chat-gpts.plus/wp-content/uploads/2026/11/39891-fc38f0ab-768x403.jpg)
