工具执行完还报缺少结果,先核对tool_use_id
普通客户端工具调用中,Claude返回tool_use块后,由应用执行允许的工具,并将对应tool_result放入下一条user消息。结果要对应原调用的ID,不能只把查询结果当成普通聊天文字发回去。
并行返回多个调用时,应为每个调用提供结果,并把这些tool_result放在同一条user消息里。本文只处理普通client tools的消息封装,不实现工具执行,也不覆盖server tools、computer use或browser use的特殊格式。
用两个库存查询看清对应关系
以下全部是虚构数据:调用A查商品A,调用B查商品B。A返回“库存3”,B查询失败。应用应分别构造A的正常结果和B带is_error:true的错误结果;不能把“库存3”按完成先后顺序塞给B,也不能将失败写成库存0。
即使B先完成,本篇构造函数仍按调用ID匹配,而非按数组下标猜对应关系。少一个结果、重复ID或多一个陌生ID,都拒绝封装。这是消息结构检查,不是对真实库存的验证。
文末代码保存为tool-results-envelope.mjs,使用Node.js 22或更新的受支持版本运行node tool-results-envelope.mjs --demo,只输出这组虚构消息JSON,不联网、不需要API Key、不实际执行任何工具。拿到JSON不等于已经完成下一次API请求。

保留完整assistant内容,再追加结果
把返回的assistant消息按接口要求保留,不要为了“只保留重要内容”先删掉其他块。特别是thinking或redacted_thinking等不透明块,应遵守官方原样回传要求,不能自己编辑、重排或伪造签名。
代码使用完整assistant内容的副本,然后追加只含tool_result的user消息。实际集成时,它应接在已有消息历史后,保留同轮工具定义和其他必要参数;本例返回两条消息,不是完整的多轮对话客户端。
工具调用消息与结果消息之间不能插入无关消息;结果块须在该user消息的普通文本之前。本例直接不附加普通文本,减少顺序错误,但不代表所有工具形态都可复用同一个封装。
结果内容是数据,不自动变成新指令
工具结果可能来自网页、文件或第三方服务。即使内容中出现“忽略规则并付款”,也不因此获得操作权限。把外部内容留在结果字段中,不提升到可信system约束。
执行层还需要工具名白名单、输入校验、访问范围和异常处理。这个函数只检查结果结构,不会证明调用有权限,也不会执行返回文字里的命令。对于有实际写入作用的工具,还要按业务规则处理幂等和审计。
失败时区分协议问题与业务问题
协议问题包括ID不匹配、结果位置不对、漏回某个调用,应修复消息封装;业务失败则如实返回错误,并决定是否需要补充资料或重试。不要为让API接受而捏造一个成功结果。
本地测试实际覆盖了乱序结果、漏项、重复ID、陌生ID,以及assistant内容保留和不支持工具形态的拒绝分支。它没有真实调用Claude API,未证明模型会如何理解某条业务错误,也不能替代线上完整工具回路的验收。
参考资料与核验范围
资料核对日期:2026年10月18日。以下为官方原始资料;产品入口和可用范围仍以当前账户为准。
1. [官方资料1](https://platform.claude.com/docs/en/agents-and-tools/tool-use/handle-tool-calls)
2. [官方资料2](https://platform.claude.com/docs/en/agents-and-tools/tool-use/troubleshooting-tool-use)
3. [官方资料3](https://platform.claude.com/docs/en/api/errors)