ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

孤儿 tool_call:对账补漏

孤儿 tool_call:对账补漏 「手写中文版 claude code」教学系列codeAgent 是我从零手写的 claude code 复刻——不套壳不翻译从界面到 Agent 主循环一行行实现注释全是中文大白话适合当 Agent 开发教材从头读到尾。上一课解决了合并着端回去这一课处理端回去之前的对账——压缩和裁剪会把「调用↔结果」拆散拆散了就是 400。仓库https://github.com/Harvil1/codeAgent什么叫孤儿 tool_call协议要求严格配对assistant 发出的每个工具调用tool_calls 里的 id后面必须跟着同 id 的工具结果反过来工具结果前面必须有发起它的调用。压缩、裁剪、恢复会话——任何从中间动消息的操作都可能把一对搭档切成两半正向孤儿调用了结果没了被裁掉反向孤儿结果还在发起它的调用被裁了两种都让 API 直接 400报错信息还不直说是配对问题。对账函数源码agent/context_compressor.pydef_fix_tool_call_pairs(messages:list)-list:修复压缩切坏了的「工具调用 ↔ 工具结果」配对。 处理两类问题 - 正向孤儿调用了但没结果在 assistant(tool_calls) 后面的结果序列末尾 补一条假结果内容注明「因压缩丢失」。⚠️ 位置必须紧贴结果序列末尾 **不能**补到整个消息列表最后——中间隔了别的消息照样违反「紧跟其后」 Anthropic 查得最严还是 400 - 反向孤儿有结果但前面没发起它的调用直接删掉 压缩边界或上游 bug 都可能造出这种孤儿 # 反向孤儿按「截至当前位置见过哪些 id」判断逐步累加# 用全量集合会漏判错序——结果 B 出现在发起 B 的调用之前也会放行# B 已在全量集合里导致 API 400。seen_so_farset()...这个函数在我项目里是压缩流水线的固定收尾动作——七层压缩不管哪层动了刀昨天第 3 篇的 compress_if_needed最后统一过一遍对账。紧急压缩第 2 篇的 reactive_compact砍完消息也调它。注释里藏的两个深坑坑一补假结果的位置。正向孤儿补结果直觉是补到消息列表末尾——错。协议要求结果紧跟assistant 的调用序列中间隔了别的消息照样 400。必须紧贴该轮结果序列的末尾补。坑二判断反向孤儿不能用全量集合。我一开始的写法是先收集全部 tool_call id 再查结果——会漏判结果出现在发起它的调用之前这种错序全量集合里已经有这个 id检查放行实际顺序是非法的。正确做法是逐步累加的seen_so_far走到哪查到哪错序当场现形。设计启示把它做成独立纯函数 流水线固定收尾而不是散在各处打补丁好处是任何新加的动消息操作未来的压缩层、会话编辑功能自动获得对账保护忘了调用手动刀的风险归零。小结动历史必产生孤儿配对孤儿必 400——对账是压缩的标配收尾补结果的位置要紧贴调用序列判孤儿要用增量集合防错序漏判收尾动作做成统一纯函数新操作自动继承保护下一篇数硬币别占收银台——asyncio 的 to_thread 与 contextvars 一坑两命。仓库在这注释全中文欢迎 Star ⭐https://github.com/Harvil1/codeAgent标签PythonasyncioAgent大模型API
返回列表