以前人给 AI 造工具,现在 AI 自己造工具

从声明式工具调用到程序化工具调用(PTC),AI Agent 的工具范式正在发生根本性转变

目录:

做 AI Agent 开发这一年多来,我经历了一个认知上的转变:以前的默认思路是"我要给 AI 准备好一切工具,让它去调用";而现在,越来越多的场景让我意识到——AI 为了完成任务,会自己造工具。这不是一个隐喻,而是一个正在发生的技术事实。

旧范式:人类是工具制造者

传统的 AI Agent 架构中,人类的角色很明确——工具制造者

你定义工具的名称、描述、参数 Schema,然后把它交给模型。模型在推理过程中,判断需要使用哪个工具,生成对应的 JSON 参数,系统执行后将结果返回给模型的上下文窗口。模型再基于这个结果继续推理。

人类定义工具 → 模型选择工具 → 生成参数(JSON) → 执行 → 结果回到上下文 → 模型继续推理
                                                    每次都要经过模型

这个模式在过去两年里运转得不错。MCP 服务器、Function Calling、Tool Use——整个生态都围绕这个范式构建。人类负责"想好 AI 需要什么工具",然后把工具打磨好,AI 负责"正确地调用它们"。

这里有一个隐含的假设:人类能够预见 AI 需要的所有工具

旧范式的瓶颈

但当 Agent 的任务变得复杂时,这个假设就开始崩塌了。

组合爆炸问题

假设你给了 AI 三个工具:网页搜索、文件读取、数据分析。一个简单的研究任务可能需要:搜索 → 读取结果 → 再搜索 → 交叉比对 → 分析 → 再搜索验证。每一步的结果都要回到模型的上下文窗口,模型要对每一步都做一次完整的推理。

搜索(query1) → [结果回到上下文] → 推理 → 搜索(query2) → [结果回到上下文] → 推理
→ 读取(url1) → [结果回到上下文] → 推理 → 分析(data) → [结果回到上下文] → 推理...

六次工具调用就是六次往返。每次往返都有成本:

  • 延迟:每次都要等模型生成下一步
  • Token 膨胀:中间结果全部序列化进上下文,即使下一步只需要其中五行数据,也可能把几千行塞进去
  • 推理浪费:模型需要在每一步都重新理解整个上下文

工具粒度的两难

工具设计者面临一个永恒的困境:

  • 工具太粗粒度(一个工具做很多事)→ 参数复杂,模型调用准确率下降
  • 工具太细粒度(每个工具只做一件小事)→ 需要大量往返,延迟和 Token 成本飙升

上一篇文章中,我主张工具应该足够简单。但简单带来的副作用是:完成一个复杂任务需要调用更多次工具,每次都要经过模型的上下文窗口。

新范式:AI 自己造工具

Anthropic 最近在 Claude Opus/Sonnet 4.6 中推出的**程序化工具调用(Programmatic Tool Calling, PTC)**正式打破了旧范式。

PTC 的核心思想出人意料地简单:Claude 不再逐个调用工具,而是编写代码来编排工具调用

人类定义基础工具 → 模型编写编排代码 → 代码在容器中执行,直接调用工具
                                    中间结果回到代码(不是模型上下文)
                                    代码继续处理(筛选、聚合、循环...)
                                    只有最终结果回到模型上下文

关键区别在于:中间结果不再回到模型的上下文窗口,而是回到正在运行的代码。模型写的代码决定了如何处理这些中间结果——筛选、聚合、交叉引用、循环——所有这些编排逻辑都由代码完成,而不是由模型逐步推理。

一个具体的例子

假设要完成一个深度搜索任务:“找出最近三个月关于 PTC 的所有技术博客,对比它们的观点”。

旧范式(每次都往返模型):

模型  web_search("PTC technical blog")  返回50条结果到上下文
模型推理:我需要过滤和深入阅读...
模型  web_search("programmatic tool calling 2026")  返回50条结果到上下文
模型推理:让我筛选相关的...
模型  fetch_url(url1)  全文返回到上下文
模型  fetch_url(url2)  全文返回到上下文
...10+次往返,上下文急剧膨胀)

新范式(PTC):

# 模型生成这段编排代码,在容器中执行
results = await web_search("PTC programmatic tool calling")
filtered = [r for r in results if r.date > "2025-12" and r.relevance > 0.7]

summaries = []
for item in filtered[:5]:
    content = await fetch_url(item.url)
    # 代码在容器中直接处理,不回到模型上下文
    key_points = extract_key_arguments(content)
    summaries.append({"title": item.title, "points": key_points})

# 只有最终的结构化摘要回到模型
return {"total_found": len(results), "analyzed": summaries}

50 条原始搜索结果、多篇全文内容——这些中间数据全部在代码中处理完毕,只有最终的精炼摘要才进入模型的上下文。

效果

Anthropic 公布的数据很有说服力:在 BrowseComp 和 DeepsearchQA 基准测试上,PTC 让准确率平均提高了 11%,同时输入 Token 数量减少了 24%。采用 PTC 的 Opus 4.6 在 LMArena 的 Search Arena 中排名第一。

更少的 Token、更高的准确率——这不是一个取舍,而是一个帕累托改进。

这意味着什么

PTC 不只是一个性能优化技巧。它代表了 AI 与工具关系的范式转变:

1. 从"使用工具"到"编排工具"

以前 AI 是一个逐步执行的操作员:给我一个工具,我调用一次,等结果,再想下一步。现在 AI 更像一个程序员:给我一组基础能力,我写代码把它们组合成新的工具。

这和人类工具使用的演化路径惊人地相似:

  • 石器时代:使用现成的工具
  • 青铜时代:组合材料制造新工具
  • 工业时代:用工具制造工具(机床)
  • 信息时代:用代码编排工具(自动化)

AI 正在从"石器时代"跨入"信息时代"。

2. 工具设计的重心转移

以前设计工具时,你要考虑的是:“这个工具能不能让 AI 一次调用就完成任务?”

现在的问题变成了:“这个工具能不能作为一个基础构建块,让 AI 灵活组合?”

这两种设计哲学导向完全不同的工具形态:

旧思路新思路
设计目标工具自身功能完备工具可被代码组合
参数尽量覆盖所有场景保持原子操作
返回值面向人类理解面向程序处理
粒度越精确越好越基础越好

3. 控制性没有丧失

有人会担心:让 AI 自己写代码编排工具调用,不会失控吗?

PTC 的巧妙之处在于:工具的实现仍然在你的控制之下。当代码中调用 await web_search(query) 时,容器会暂停,这个调用会作为一个标准的工具使用事件穿过沙盒边界——经过你的工具处理器、MCP 服务器或任何你设置的中间层。你可以检查、拒绝、记录、排队等待人工批准。

换句话说:AI 获得了编排的自由,但每一步执行仍然在人类的监管之下

┌─────────────────────────────────┐
  AI 生成的编排代码(沙盒内)      
                                 
  result = await tool(params)    │──→ 穿过沙盒边界
                                         
    结果回到代码                       工具处理器(你的代码)
                                     - 权限检查 
  final = process(result)            - 日志记录 
  return final ──→ 回到模型上下文      - 速率限制 
└─────────────────────────────────┘    - 人工审批 

和 Claude Code 的关联

如果你用过 Claude Code,你会发现这种"AI 自己造工具"的理念已经在实践中体现了。

Claude Code 的核心就是一个跑在循环里的 bash 工具。但它不仅仅用 bash——它把特定行动提升为专门的工具(比如 AskUserQuestionEditRead),以获得更好的用户体验、护栏和可观测性。

PTC 是这个思路的进一步延伸:不是给 AI 更多的工具,而是给 AI 用代码组合现有工具的能力。AI 从"工具使用者"进化成了"工具编排者"——甚至可以说是"工具制造者"。

对 Agent 开发者的启示

如果你正在构建 AI Agent,PTC 带来的范式转变值得认真思考:

1. 给 AI 提供基础构建块,而不是完整方案

把工具设计成可以被程序化组合的原子操作。与其提供一个"深度搜索"工具,不如提供 web_searchfetch_urlextract_text 这样的基础能力,让 AI 用代码把它们编排成深度搜索。

2. 关注工具的可组合性

工具的返回值应该是结构化的、可被代码处理的。面向人类的自然语言描述很好,但面向程序的结构化数据更重要。

3. 控制点设在工具层,而不是编排层

不要试图控制 AI 的编排逻辑,而是在每个工具的执行层面设置护栏。这样 AI 可以自由组合,但每一步操作都在你的掌控之中。

结论

回看 AI Agent 工具使用的演进路径:

手动定义 → 声明式调用 → 程序化编排 → AI 自造工具

我们正处在从"声明式调用"向"程序化编排"过渡的阶段。PTC 是一个标志性的节点——它表明,AI 不再满足于被动地使用人类预定义好的工具,而是开始主动地用代码来创造新的工具组合。

这并不意味着人类工具设计者的角色变得不重要了。恰恰相反,设计好的基础工具变得更加关键——因为它们是 AI 造新工具的原材料。就像编程语言的标准库一样,基础越扎实,上层的创造力就越强。

以前是人给 AI 准备工具来感知环境和行动。现在 AI 为了完成任务会自己造工具。这不是 AI 的"叛逆",而是工具使用能力的自然演进——从使用工具到制造工具,这本就是智能的标志。


See also