
普通 tool use 的执行路径很直白模型生成工具名和参数程序执行工具把结果放回对话模型继续判断。tool_choice、Pydantic 和 structured JSON 改善了参数约束与返回格式没有改变这条路径。tool_use/中值得单独分析的两组 notebook 改了路径本身。Programmatic Tool Calling 让工具结果先进入程序Tool Search 则让工具定义按需进入上下文。前者控制模型看到哪些结果后者控制模型看到哪些能力。普通调用把工具结果变成了模型输入programmatic_tool_calling_ptc.ipynb先用传统方式处理一个差旅审计任务找出工程团队成员读取每个人第三季度的费用明细汇总已批准的差旅支出再检查超预算人员是否有自定义额度。传统循环需要模型先取员工列表再取八个人的费用阅读每条费用的金额、商户、收据地址、审批链等字段算出总额后继续查询预算。数据库本来已经返回结构化数据系统却把全部原始记录变成 token让模型承担过滤、求和和连接。这次运行用了 4 次 Claude API 调用和 110,473 个 token耗时 35.38 秒。问题不在工具调用次数而在所有中间数据都必须经过模型上下文模型选择工具 → 工具返回大量记录 → 记录进入模型上下文 → 模型决定循环、过滤和下一次调用工具接上模型以后外部数据并没有绕开模型反而可能成为上下文里最大的部分。PTC 把确定性工作移进代码PTC 给工具增加allowed_callers允许 code execution 环境调用它们。模型先生成一段 Python由 Python 在容器内循环调用工具、过滤已批准记录、按类别求和并挑出超预算员工。只有处理结果返回模型收据地址和无关元数据留在容器里。同一个任务的 PTC 运行使用 15,919 个 token比传统版本少 85.6%API 调用仍是 4 次时间从 35.38 秒变为 34.88 秒只少 1.4%。这组结果明确显示上下文用量下降却不足以说明执行明显提速。若工具本身耗时占主导少传 token 不会显著缩短总时间。PTC 也不是把 Agent 改成固定脚本。模型仍决定要查什么并现场写出执行计划变化发生在循环内部传统方式每批结果 → 模型 → 下一次工具调用 PTC 每批结果 → Python 过滤和聚合 → 精简结果 → 模型它适合批量读取、连接、排序、去重、统计以及“先算出 A再只对满足 A 的对象查询 B”这种依赖。模型负责把任务编成小程序解释器负责可靠地运行循环和算术。相应的风险也换了位置。允许代码批量调用工具会扩大一次错误计划的影响范围。notebook 因此要求工具显式声明可被 code execution 调用并提醒只开放适合重复执行的工具。只读查询和计算容易控制发邮件、退款、删数据之类有外部副作用的操作不能因为能写进循环就批量开放。PTC 还要处理容器状态和过期示例把container_id带到下一轮因为后续代码依赖前一轮容器中的状态容器失效后这种连续性也会消失。验证问题随之出现。传统轨迹虽然昂贵但每次工具结果都在模型消息中PTC 把大量中间状态留在容器里。如果只记录最终答案便很难知道模型生成的代码有没有漏记录、用错过滤条件或吞掉异常。节省上下文不能等于删除审计轨迹。生产实现至少要单独保存生成代码、实际调用清单、关键中间计数和异常而不是把它们全部塞回模型。Prime Agent 的 RLM 可以看作 PTC 思想的一种更完整实现把 PTC 的“模型写代码组织工具”扩展成了长期运行的 Agent 工作台 模型主要看到一个ipython工具。模型写 Python再由 Python 调用 skill、MCP、shell 和子 Agent。大量数据留在运行时中处理只把摘要和结论返回模型。PTC是 API 提供的单轮执行机制代码调用显式授权的工具。Prime Agent自己实现了持久 IPython kernel、host bridge、状态恢复和子 Agent范围更大也能跨轮保存变量。Tool Search 让能力列表也按需加载当工具从十几个增长到几百个另一个输入开始膨胀工具 schema。每个工具的名称、说明、参数和约束都会放入请求。模型还没处理用户问题就先收到一份越来越长的 API 目录。tool_search_with_embeddings.ipynb把工具定义当作检索对象。系统预先将工具名、描述和 schema 编成向量运行时模型先调用唯一可见的tool_search程序对查询做 embedding按余弦相似度返回 top-ktool_reference被命中的完整定义才在那个位置进入上下文。示例只有 8 个工具但机制针对更大的库。查询“check the weather”时前三名依次是get_weather、get_forecast和get_air_quality查询“stock market data”时前三名是get_stock_price、get_market_news和calculate_compound_interest。第三名已经说明语义检索并不理解任务只是在描述空间里找近邻。Tool Search 增加了一道新的失败条件。以前工具选错至少所有工具都在模型眼前现在检索器若漏掉正确工具模型甚至不知道它存在。系统的能力上限由两部分共同决定能否召回正确工具 × 模型能否在召回集合中正确使用它因此评测不能只看最终任务成功率还要单独测工具召回率尤其要覆盖别名、缩写、跨语言描述和需要多工具组合的请求。top-k 太小会漏工具太大又把 schema 开销带回来。embedding 只按语义相关性排序也不会自动考虑权限、成本、延迟、地区和可靠性这些条件必须进入过滤或重排。动态加载还会碰到 prompt cachetool_search_alternate_approaches.ipynb给出一个不需要 embedding 的版本system prompt 只列工具名模型调用describe_tool(name)取得完整定义。它适合工具名清晰、模型容易从目录中直接选中的场景也暴露了动态工具与 prompt cache 的关系。如果每发现一个工具就把它普通地追加到tools列表后续请求的前缀随之变化原来的 prompt cache 会失效。示例把新工具标记为defer_loadingTrue同时在 tool result 中返回tool_referenceAPI 从这个位置把完整定义加载进上下文而不是改动开头的 prompt。这不是一个 API 小技巧。工具发现改变了上下文的结构系统既要让新能力在当前回合可用又要避免每次发现都重建此前相同的长前缀。Tool Search 解决的是工具可见性defer_loading解决的是可见性变化后怎样保持缓存稳定。两种发现方式的适用边界也不同。describe_tool不会检索错但前提是模型已经知道正确工具名embedding 允许自然语言发现却可能召回错误。工具库规模大、命名不稳定时需要语义或混合检索目录短而清楚时直接列名更容易调试。控制进入模型的边界PTC 与 Tool Search 看起来一个管执行、一个管发现处理的却是同一个成本来源模型上下文被当成了所有信息的默认中转站。PTC 让原始工具结果停在代码环境只把筛选和聚合后的内容交给模型。Tool Search 让大部分工具定义留在目录只把当前任务需要的 schema 交给模型。二者都没有减少系统拥有的信息只缩小了模型每一轮必须阅读的信息。缩小以后可靠性检查必须移到边界上。对 PTC要验证程序实际调用和聚合了什么对 Tool Search要验证正确工具有没有被召回。只检查最终文本是否流畅会同时漏掉两类静默错误程序少算了一部分数据或者检索阶段从未给模型正确工具。