全书目录

第一编 概念层

第 3 章 为什么 Agent 不是“会调用工具的聊天机器人”

8 分钟 3,357 字 第 4 / 161 个阅读单元

这是大模型时代最常见、也最具有误导性的误解之一。

很多系统一旦接上 function calling、搜索、数据库、浏览器、shell 或者某个业务 API,就会立刻被包装成 Agent。 于是大家很容易形成一个过于粗糙的定义:

text
Agent = 聊天机器人 + 工具调用

这个定义之所以危险,不是因为它完全错了,而是因为它只看到了最表层的一层。

工具调用当然重要。 没有动作能力,系统很难从“回答问题”走向“推进任务”。 但工具调用本身,只能说明系统多了一只手,不能说明它已经有了完整的任务中枢。

如果要把这件事说得更准确一点,可以先下一个判断:

text
工具调用只是 Agent 的动作接口,
不是 Agent 的系统定义。

这句话背后的原因很简单。

一个真正的 Agent,不只是“能不能调工具”,而是至少还要同时解决下面这些问题:

  • 当前目标到底是什么
  • 当前状态处于任务的哪一阶段
  • 现在是否应该调用工具
  • 应该选哪个工具
  • 参数应该怎么构造
  • 返回结果是否可信
  • 结果会怎样改变当前状态
  • 下一步该继续、回退、换路还是停下
  • 什么时候应该请求用户确认
  • 什么时候应该移交给人类或别的 Agent

只要少掉其中几层,系统就可能退化成“会调函数的聊天界面”。

所以,真正需要区分的是两种完全不同的工具使用方式。

第一种,是回答增强型工具使用。 工具的作用是帮助系统更好地回答当前这一轮。

第二种,是任务推进型工具使用。 工具的作用是改变外部世界、获得新观察、更新内部状态,并推动任务进入下一阶段。

前者更接近工具增强聊天机器人。 后者才更接近 Agent。

OpenAI 的工具与 Agents SDK 文档其实已经把这个区别隐含得很清楚。 它们谈工具时,从来不是只谈“调用某个函数”,而是把 tools 放进 agent loop 里,与 sessions、handoffs、guardrails、tracing 一起出现。

这说明在官方运行时视角里,工具并不是一个孤立能力,而是闭环中的一个动作节点:

  • 模型判断当前是否需要动作
  • 选择并发起 tool call
  • 外部系统执行动作
  • 结果回流到上下文
  • Agent 依据结果继续决策
  • 直到完成、暂停、移交或中止

如果没有这个循环,工具调用大概率就只是“回答时顺手查点东西”。

Anthropic 对工具的讨论也很有代表性。 它一方面强调 tool use 的价值,另一方面又专门写了“如何为 agents 写工具”。 这件事本身就说明:工具是否存在不是关键,关键是工具是否真的可被 Agent 当作稳定动作接口来理解和使用。

Anthropic 在工具设计里强调:

  • 工具名称是否清晰
  • 描述是否足够让模型理解何时调用
  • 参数模式是否自然
  • 返回值是否可供后续决策继续消费

如果工具只是能调,但不好理解、不好组合、不好承接下一步,它对 Agent 的价值会非常有限。

这背后的逻辑非常重要:

text
工具不是“外挂能力”,而是 Agent 的动作语言。

动作语言设计得差,Agent 就算模型再强,也容易做出奇怪决策。

研究界的几条主线,也都在证明“工具调用不等于 Agent”。

Toolformer 讨论的不是“模型终于会调 API”这么浅的一层,而是四个更本质的问题:

  • 什么时候需要调用工具
  • 应该调用什么工具
  • 参数如何构造
  • 返回结果如何纳入后续推理

也就是说,真正困难的地方从来都不是“有没有工具”,而是“如何把工具调用嵌入决策过程”。

ReAct 更进一步。 它把 reasoning 和 acting 交替起来,说明动作不是回答的附属操作,而是思考过程的一部分。 Agent 并不是先把所有东西想完,再偶尔调用一个工具; 很多时候,恰恰是因为先去行动、先去观察,后续推理才会改变。

Reflexion 又补上了另一面。 即便工具调用成功,也不代表任务成功。 真正的 Agent 还需要根据结果反思:刚才那一步有没有把任务推向目标,接下来是否该调整策略。

再往后看工具使用 benchmark,这个区别会更明显。

GorillaAPIBankToolBench 这类工作,主要验证的是:

  • 模型能否选对 API
  • 参数能否填对
  • 工具说明能否被理解

这些能力当然是 Agent 的基础,但它们只覆盖了“动作接口正确性”。 它们还没有覆盖完整任务里更难的部分:

  • 目标分解是否正确
  • 多次工具调用顺序是否合理
  • 长链路状态是否一致
  • 工具失败后是否会改路
  • 什么时候该停
  • 是否真的完成了用户要的事

换句话说,tool-use benchmark 能证明模型“会用手”,却还不能证明系统“会做事”。

这也是为什么很多系统在 demo 里看起来很强:

  • 能查网页
  • 能读数据库
  • 能调代码解释器
  • 能调用业务 API

但一旦任务链路拉长,就会迅速出现问题:

  • 忘记已经查过什么
  • 选错下一步工具
  • 把局部结果当最终结果
  • 连续调用很多工具却没有真正推进任务
  • 明明失败了却错误宣布完成

这些失败都不是“工具缺失”导致的,而是因为系统没有建立完整的目标-状态-决策-反馈结构。

所以,把 Agent 理解成“会调用工具的聊天机器人”,最大的错误在于它把动作能力误当成了控制能力。

一个更准确的说法应该是:

text
聊天机器人把工具当作回答增强,
Agent 把工具当作任务推进中的可编排动作。

这里“可编排”三个字很关键。

因为真正的 Agent 要编排的,从来不只是“下一个调用什么工具”,而是:

  • 哪个子目标先做
  • 哪一步需要新观察
  • 哪一步需要持久化状态
  • 哪一步需要等待外部结果
  • 哪一步需要人工确认
  • 哪一步应该终止,而不是继续盲目调用

LangGraph 一类状态图框架之所以强调 state、interrupts、persistence,并不是因为这些词好听,而是因为只靠 tool calling 根本不足以支撑真实任务。 Microsoft Foundry、AutoGen 和 Google ADK 也都把 tools 放在更大的 runtime 里理解: 真正的 Agent 还需要 session、memory、event loop、workflow/state、orchestration。 这说明工业界早就默认:工具只是部件,不是定义。

看 benchmark,会更容易明白这一点。

如果“会调用工具”就足够了,那么真实环境 benchmark 不应该那么难。 但不管是 WebArenaOSWorld,还是更偏工程的软件任务 benchmark,问题都在说明:

  • 有动作接口,不等于有稳定策略
  • 有多个工具,不等于有完整执行过程
  • 有几次成功调用,不等于最终任务能收口

举两个简单对比。

第一个,是信息查询任务。

如果用户说:

“帮我查一下今天上海天气。”

系统只需要:

  • 识别天气意图
  • 调用天气工具
  • 返回结果

这当然可以很好用,但它本质上仍然更像工具增强问答。

第二个,是家庭出行规划。

如果用户说:

“帮我结合天气、孩子年龄、家庭预算和周边活动,安排今天下午的家庭出游方案,如果室外不合适就给室内备选。”

这时系统就不再是一次调用天气工具那么简单了。 它需要:

  • 拆解目标
  • 识别隐含约束
  • 查询多种信息源
  • 比较不同候选方案
  • 根据天气或库存变化动态改路
  • 必要时继续追问用户
  • 最后把多个观察收束成一份可执行建议

这里当然也要调用工具,但工具已经不是“功能点”,而是整条任务链中的动作部件。

再看编码任务,差别会更明显。

一个普通聊天系统可以:

  • 读取文件
  • 搜索代码
  • 回答“这个函数在做什么”

但一个真正的编码 Agent 通常要形成循环:

  • 先理解需求
  • 再定位相关文件
  • 修改代码
  • 运行测试或静态检查
  • 根据日志继续修正
  • 必要时重新搜索上下文
  • 最后确认结果是否满足任务

这里 shell、编辑器、测试命令当然都属于工具。 但真正决定系统水平的,不是“有没有这些工具”,而是“能不能把这些工具组织成一条有目标感的执行轨迹”。

因此,本章想留下的判断标准应该是:

text
会调用工具,只能证明系统有动作能力;
只有当系统能围绕目标持续组织工具、状态、反馈与停止条件时,
它才真正进入 Agent 形态。

这也是为什么成熟 Agent 设计里,tools 很少单独出现,而总是和这些概念一起出现:

  • goal
  • state
  • memory
  • loop
  • handoff
  • guardrail
  • tracing
  • evaluation

因为只谈 tools,不谈这些结构,最后往往会把 Agent 做成一个“动作很多、任务很碎、看起来很忙但收不了口”的系统。

下一章我们要继续把这个系统拆成最小闭环,看看 Agent 最基础、最不可再省的五个环节到底是什么。