这篇把 Agent 从概念热词还原成可拆解、可评测的系统工程问题。

最值得拿走的是两条主线:能力由环境与工具清单决定,成败由规划与反思决定。文中对「计划先验证再执行」「写操作必须设定自动化级别」「始终打印每次工具调用与参数」等做法的强调,直指 Agent 项目最常见的误用——把 Agent 当成一次性提示词,而不是带监督回路的系统;此外对多 Agent 的界定(多组件即多 Agent)也常被夸大化理解。

相比站内偏概念与岗位视角的内容,这篇补上了 Agent 架构与评测指标的底层框架:计划生成的粒度选择、控制流支持、工具消融实验都可直接搬进评审清单。它写于 2025 年初,正是多 Agent 框架与 MCP 生态爆发前夜,中文读者读它能分清哪些是新噱头、哪些是自强化学习时代就没变过的底层问题;落地国内项目时还需叠加数据合规与人工审批环节。

读完立即为你手头的 Agent 项目列一张失败模式清单:无效工具、参数错误、目标偏离、超时,各配一个检测指标。

—— FDEChina编辑部 · 架构师视角

智能体(agent)被许多人视为人工智能的终极目标。Stuart Russell 与 Peter Norvig 的经典教材《人工智能:现代方法》(Artificial Intelligence: A Modern Approach,Prentice Hall,1995)就把 AI 研究这一领域定义为「对理性智能体的研究与设计」。

基础模型(foundation model)前所未有的能力,为过去难以想象的智能体式应用打开了大门。这些新能力终于让开发自主、智能的 Agent 成为可能——它们可以充当我们的助手、同事与教练。它们可以帮我们搭建网站、收集数据、规划旅行、做市场调研、管理客户账户、自动化数据录入、帮我们准备面试、替我们面试候选人、谈判交易,等等。可能性似乎无穷无尽,而这些 Agent 的潜在经济价值同样巨大。

本文先给出 Agent 的整体概览,随后讨论决定 Agent 能力的两个关键方面:工具与规划。Agent 有了新的运作方式,也就有了新的失败方式。本文最后将讨论如何通过评测(evaluation)捕捉这些失败。

本文改编自《AI Engineering》(2025)一书的 Agents 章节,为使其独立成篇做了少量修改。

几点说明:

  • 由 AI 驱动的 Agent 是一个新兴领域,在定义、开发与评测方面尚无成熟的理论框架。本文尽力基于现有文献构建一个框架,但它会随领域的发展而演进。与书的其他章节相比,这一章更具实验性。我从早期审阅者那里得到了许多有益的反馈,也希望从这篇博文的读者那里继续获得反馈。
  • 就在本书出版前夕,Anthropic 发布了一篇关于构建有效 Agent 的博文 Building effective agents(2024 年 12 月)。我很高兴看到 Anthropic 的博文与我的 Agent 章节在概念上一致,只是术语略有差异。不过,Anthropic 的文章聚焦于孤立的模式,而本文解释的是这些事物为什么以及如何这样运作。此外,本文在规划、工具选择与失败模式上着墨更多。
  • 本文包含大量背景信息。如果觉得某些部分过于细节,直接跳过也完全没问题!

Agent 概览

「Agent」一词被用在许多不同的工程语境中,包括但不限于软件智能体(software agent)、智能体(intelligent agent)、用户代理(user agent)、对话式智能体(conversational agent)和强化学习智能体(reinforcement learning agent)。那么,Agent 到底是什么?

Agent 是任何能够感知其环境并作用于该环境的东西。《人工智能:现代方法》(1995)将 Agent 定义为:任何可以被视为通过传感器(sensor)感知环境、并通过执行器(actuator)作用于环境的东西。

这意味着,Agent 的特征由它所处的环境和它所能执行的动作集合来刻画。

Agent 能在其中运作的环境由它的用例决定。如果一个 Agent 是为玩游戏而开发的(例如 Minecraft、围棋、Dota),那这个游戏就是它的环境。如果你想让 Agent 从互联网上抓取文档,环境就是互联网。自动驾驶汽车 Agent 的环境则是道路系统及其周边区域。

AI Agent 能执行的动作集合,会因它能访问的工具而得到扩展。你日常使用的许多生成式 AI 应用其实都是能使用工具的 Agent,尽管工具可能很简单。ChatGPT 就是一个 Agent:它能搜索网页、执行 Python 代码、生成图像。RAG 系统也是 Agent——文本检索器、图像检索器和 SQL 执行器就是它们的工具。

Agent 的环境与它的工具集之间存在强依赖关系。环境决定了 Agent 潜在能用的工具有哪些:例如,如果环境是一盘国际象棋,Agent 唯一可能的动作就是合法的棋步。反过来,Agent 的工具清单也限制了它能运作的环境:例如,如果一台机器人的唯一动作是游泳,那它就只能待在水域环境里。

图 6-8 展示了 SWE-agent(Yang et al., 2024)的可视化,这是一个构建在 GPT-4 之上的 Agent。它的环境是带有终端和文件系统的计算机,它的动作集合包括浏览仓库、搜索文件、查看文件和编辑代码行。

图 6-8:SWE-agent 是一个编码 Agent,其环境是计算机,其动作包括导航、搜索、查看文件和编辑。

AI Agent 的使命是完成任务,任务通常由用户给出。在 AI Agent 中,AI 是大脑:它处理任务、规划一串动作来达成任务,并判断任务是否已经完成。

回到上文的 Kitty Vogue 例子中那个处理表格数据的 RAG 系统。这是一个简单的 Agent,有三个动作:

  • 生成回复(response generation);
  • 生成 SQL 查询(SQL query generation);
  • 执行 SQL 查询(SQL query execution)。

给定查询「预测 Fruity Fedora 未来三个月的销售收入」,Agent 可能会执行如下动作序列:

  • 推理如何完成这个任务。它可能判断:要预测未来销量,首先需要过去五年的销售数据。Agent 的推理可以以中间回复的形式呈现。
  • 调用 SQL 查询生成,生成查询以获取过去五年的销售数据。
  • 调用 SQL 查询执行,执行这条查询。
  • 对工具输出(SQL 查询执行的输出)进行推理,看它们如何帮助销量预测。它可能判断这些数据不足以做出可靠的预测,也许是因为存在缺失值。于是它决定还需要过去营销活动的信息。
  • 调用 SQL 查询生成,生成获取过去营销活动的查询。
  • 调用 SQL 查询执行。
  • 推理认为这些新信息足以帮助预测未来销量,然后生成预测。
  • 推理判断任务已成功完成。

与非 Agent 用例相比,Agent 通常需要更强大的模型,原因有二:

  • 错误叠加:Agent 通常需要执行多个步骤才能完成一个任务,整体准确率随步数增加而下降。如果模型每步的准确率是 95%,10 步之后准确率会降到 60%,100 步之后只剩 0.6%。
  • 风险更高:有了工具,Agent 能执行影响更大的任务,但任何一次失败都可能带来更严重的后果。

需要很多步骤的任务可能既耗时又费钱。一个常见的抱怨是:Agent 只擅长烧你的 API 额度。然而,如果 Agent 能做到自主运行,它们可以节省人的时间,让这些成本物有所值。

给定一个环境,Agent 在其中的成功取决于它能访问的工具,以及它的 AI 规划器(planner)的强弱。我们先来看看模型可以使用的不同种类的工具,接着再分析 AI 的规划能力。

工具

一个系统并不需要访问外部工具才能成为 Agent。然而,没有外部工具,Agent 的能力会很有限。单独来看,一个模型通常只能执行一种动作——LLM 能生成文本,图像生成器能生成图像。外部工具能让 Agent 的能力大幅提升。

工具既帮助 Agent 感知环境,也帮助它作用于环境。让 Agent 感知环境的动作是只读动作(read-only actions),让 Agent 作用于环境的动作是写动作(write actions)。

Agent 能访问的工具集合就是它的工具清单(tool inventory)。由于工具清单决定了 Agent 能做什么,认真考虑给 Agent 什么工具、给多少工具就非常重要。工具越多,Agent 的能力越强。但工具越多,理解并用好它们也越难。要找到合适的工具集合,实验必不可少,后文「工具选择」一节会展开讨论。

取决于 Agent 所处的环境,可能的工具非常多。以下是你可能要考虑的三类工具:知识增强(即上下文构建)、能力扩展,以及让 Agent 得以作用于其环境的工具。

知识增强

我希望到目前为止,这本书已经让你相信了相关上下文对模型回复质量的重要性。有一类重要的工具能帮助增强 Agent 的知识。其中一些已经讨论过:文本检索器、图像检索器和 SQL 执行器。其他潜在的工具还包括内部人员搜索、返回不同产品库存状态的库存 API、Slack 检索、邮件读取器等。

许多这类工具用你所在组织的私有流程和信息来增强模型。不过,工具也可以让模型访问公开信息,尤其是来自互联网的信息。

网页浏览是 ChatGPT 最早、也最受期待的能力之一。网页浏览能防止模型「过时」。当模型训练所用的数据变得陈旧时,模型就过时了。如果模型的训练数据截止到上周,它就无法回答需要本周信息的问题,除非这些信息被放进上下文。没有网页浏览,模型就无法告诉你天气、新闻、即将举行的活动、股价、航班状态等信息。

我用「网页浏览」作为一个统称,涵盖所有访问互联网的工具,包括网页浏览器和各种 API,例如搜索 API、新闻 API、GitHub API 或社交媒体 API。

网页浏览让你的 Agent 能参考最新信息,生成更好的回复、减少幻觉(hallucination),但它也可能把你的 Agent 暴露给互联网上的污秽角落。挑选互联网 API 时务必谨慎。

能力扩展

你还可以考虑用来解决 AI 模型固有局限的工具。它们是提升模型性能的简单办法。例如,AI 模型不擅长数学是出了名的。如果你问模型 199,999 除以 292 等于多少,模型很可能会答错。但如果模型能用计算器,这个计算就轻而易举。与其试图训练模型精通算术,不如直接给模型一个工具,这在资源上划算得多。

其他能显著提升模型能力的简单工具还包括:日历、时区转换器、单位转换器(例如磅转千克),以及能在模型不擅长的语言之间互译的翻译器。

更复杂但强大的工具是代码解释器(code interpreter)。与其训练模型理解代码,不如给它一个代码解释器去执行一段代码、返回结果,或分析代码失败的原因。这个能力让你的 Agent 可以充当编码助手、数据分析师,甚至研究助理——能写代码跑实验并报告结果。不过,自动执行代码有代码注入攻击的风险,第 5 章「防御性提示工程」一节讨论过这一点。妥当的安全措施对保护你和你的用户至关重要。

工具可以把纯文本模型或纯图像模型变成多模态模型。例如,一个只能生成文本的模型可以把文生图模型当作工具,从而既能生成文本也能生成图像。给定一个文本请求,Agent 的 AI 规划器会决定调用文本生成、图像生成,还是两者都调用。ChatGPT 之所以既能生成文本又能生成图像,就是这个原理——它用 DALL-E 作为自己的图像生成器。

Agent 还可以用代码解释器生成图表,用 LaTeX 编译器渲染数学公式,或用浏览器把 HTML 代码渲染成网页。

类似地,一个只能处理文本输入的模型可以用图像描述(image captioning)工具处理图像,用转录工具处理音频,用 OCR(光学字符识别)工具读取 PDF。

与只靠提示工程甚至微调(finetuning)相比,工具使用能显著提升模型性能。Chameleon(Lu et al., 2023)显示,一个由 GPT-4 驱动、配备了 13 个工具的 Agent,在多个基准上能胜过单独的 GPT-4。这个 Agent 使用的工具包括知识检索、查询生成器、图像描述器、文本检测器和 Bing 搜索。

在 ScienceQA(一个科学问答基准)上,Chameleon 把已发表的最好少样本(few-shot)结果提升了 11.37%。在 TabMWP(表格数学应用题,Lu et al., 2022)这个涉及表格数学题的基准上,Chameleon 把准确率提升了 17%。

写动作

到目前为止,我们讨论的都是让模型从数据源读取信息的只读动作。但工具也可以执行写动作,对数据源做出更改。SQL 执行器可以检索数据表(读),也可以修改或删除表(写)。邮件 API 可以读邮件,也可以回复邮件。银行 API 可以查询你的当前余额,也可以发起转账。

写动作让系统能做更多事。它们可以让你把整个客户触达流程自动化:调研潜在客户、找到他们的联系方式、起草邮件、发送第一封邮件、阅读回复、跟进、提取订单、把新订单更新到数据库,等等。

然而,让 AI 有能力自动改变我们的生活,这个前景令人不安。正如你不该把删除生产数据库的权限交给实习生,你也不该允许一个不可靠的 AI 发起银行转账。对系统能力及其安全措施的信任至关重要。你需要确保系统受到保护,免受那些试图操纵它执行有害动作的恶意行为者的侵害。

专栏:Agent 与安全

每当我向一群人谈论自主 AI Agent 时,总会有人提到自动驾驶汽车。「如果有人黑进车来绑架你怎么办?」自动驾驶汽车的例子因为其物理性而显得格外触动神经,但 AI 系统即使不在物理世界中存在,也能造成伤害。它可以操纵股市、窃取版权、侵犯隐私、强化偏见、传播错误信息和宣传,等等,第 5 章「防御性提示工程」一节讨论过这些。

这些都是合理的担忧,任何想利用 AI 的组织都需要认真对待安全与安保问题。但这并不意味着 AI 系统永远不该获得在真实世界中行动的能力。如果我们能信任一台机器把我们送入太空,我希望有一天,安全措施会足以让我们信任自主的 AI 系统。再说,人类也会犯错。就我个人而言,比起随便一个陌生人,我更愿意搭一辆自动驾驶汽车。

正如合适的工具能让人类的生产力大幅提升——你能想象没有 Excel 怎么做生意、没有起重机怎么盖摩天大楼吗?——工具也让模型能完成多得多的任务。许多模型提供商已经为其模型支持工具使用,这个功能通常被称为函数调用(function calling)。往后,我预计带丰富工具集的函数调用会成为大多数模型的标配。

规划

基础模型 Agent 的核心,是那个负责解决用户所给任务的模型。一个任务由它的目标和约束定义。例如,一个任务是:在 5,000 美元预算内规划一趟从旧金山到印度的两周旅行。目标是两周旅行,约束是预算。

复杂任务需要规划。规划过程的产出是一份计划(plan),即概述完成任务所需步骤的路线图。有效的规划通常要求模型理解任务、考虑达成任务的多种方案,并选择最有希望的那一个。

只要你参加过任何规划会议,你就知道规划有多难。作为一个重要的计算问题,规划已被充分研究,要完整覆盖它需要好几卷书。这里我只能讲点皮毛。

规划概览

给定一个任务,解决它的方式有很多种,但并非所有方式都会通向成功。而在正确的解法中,有些比另一些更高效。考虑查询「有多少没有收入的公司融到了至少 10 亿美元?」,以及两个示例解法:

  • 找出所有没有收入的公司,然后按融资额过滤。
  • 找出所有融到至少 10 亿美元的公司,然后按收入过滤。

第二种更高效。没有收入的公司远多于融到 10 亿美元的公司。只看这两个选项,一个智能的 Agent 应该选择方案 2。

你可以在同一个提示里把规划与执行耦合在一起。例如,你给模型一个提示,让它逐步思考(比如用思维链提示),然后在同一个提示里执行这些步骤。但如果模型给出一个 1,000 步、根本完不成目标的计划怎么办?没有监督的话,Agent 可能把这 1,000 步跑上几个小时,在 API 调用上浪费时间和金钱,你才发现它根本在原地打转。

为了避免徒劳的执行,规划应当与执行解耦。你先让 Agent 生成一份计划,只有当这份计划通过验证之后才执行它。计划可以用启发式规则来验证。例如,一个简单的启发式是排除含无效动作的计划:如果生成的计划需要 Google 搜索,而 Agent 无法访问 Google 搜索,这个计划就是无效的。另一个简单的启发式是排除所有超过 X 步的计划。

计划也可以用 AI 评委(AI judge)来验证。你可以让模型评估这份计划是否合理,或者该如何改进。

如果生成的计划被评价为不好,你可以让规划器再生成一份。如果生成的计划好,就执行它。

如果计划中包含外部工具,就会触发函数调用。执行这份计划得到的输出随后也需要再次评估。注意,生成的计划不必是覆盖整个任务的端到端计划,它也可以是针对某个子任务的小计划。整个过程如图 6-9 所示。

图 6-9:将规划与执行解耦,只执行通过验证的计划。

你的系统现在有了三个组件:一个生成计划,一个验证计划,另一个执行计划。如果你把每个组件都视为一个 Agent,这就可以算作一个多智能体系统(multi-agent system)。由于大多数智能体工作流的复杂度都足以涉及多个组件,大多数 Agent 都是多 Agent 的。

为了给这个过程提速,你可以不按顺序生成计划,而是并行生成几份计划,让评估器挑出最有希望的那一份。这是又一种延迟-成本权衡,因为同时生成多份计划会产生额外成本。

规划需要理解任务背后的意图:用户想用这个查询做什么?意图分类器(intent classifier)常被用来帮助 Agent 规划。如第 5 章「把复杂任务拆成更简单的子任务」一节所示,意图分类既可以用另一个提示完成,也可以用为此专门训练的分类模型完成。意图分类机制可以视为你的多智能体系统中的又一个 Agent。

知道意图能帮 Agent 选对工具。例如在客服场景中,如果查询与账单有关,Agent 可能需要一个工具来检索用户最近的付款记录;但如果查询是关于如何重置密码,Agent 可能需要访问文档检索。

提示:有些查询可能超出 Agent 的能力范围。意图分类器应该能把请求归类为 IRRELEVANT(不相关),让 Agent 得以礼貌地拒绝这些请求,而不是浪费算力去琢磨出不存在的解法。

到目前为止,我们都假设 Agent 自动化全部三个阶段:生成计划、验证计划和执行计划。现实中,人可以介入任何阶段来辅助流程并降低风险。

  • 人类专家可以提供计划、验证计划,或执行计划的一部分。例如,对于 Agent 难以生成完整计划的复杂任务,人类专家可以给出一个高层计划,让 Agent 在此基础上展开。
  • 如果计划涉及高风险操作,比如更新数据库或合并代码变更,系统可以在执行前请求人类明确批准,或把这些操作交由人类执行。要做到这一点,你需要清楚地定义 Agent 对每种动作所拥有的自动化级别。

总结一下,解决一个任务通常涉及以下流程。注意,反思(reflection)对 Agent 并非强制,但它会显著提升 Agent 的表现。

  • 计划生成:想出完成任务的计划。计划是一串可管理的动作,所以这个过程也叫任务分解(task decomposition)。
  • 反思与纠错:评估生成的计划。如果计划不好,生成新的。
  • 执行:执行计划中列出的动作。这通常涉及调用具体的函数。
  • 反思与纠错:收到动作结果后,评估这些结果,判断目标是否已经达成。识别并纠正错误。如果目标未完成,生成新的计划。

你在本书中已经见过一些计划生成和反思的技术。当你让模型「一步一步思考」时,你是在让它分解任务;当你让模型「验证你的答案是否正确」时,你是在让它反思。

基础模型作为规划器

一个悬而未决的问题是:基础模型的规划能力到底如何。许多研究者认为,基础模型——至少那些构建在自回归(autoregressive)语言模型之上的模型——不会规划。Meta 首席 AI 科学家 Yann LeCun 曾明确表示,自回归 LLM 不会规划(2023)。

自回归 LLM 不能规划(也不能真正推理)。——Yann LeCun,2023 年 9 月

尽管有大量传闻证据表明 LLM 是糟糕的规划者,但目前还不清楚:这是因为我们不知道如何正确使用 LLM,还是因为 LLM 从根本上就不能规划。

规划在本质上是搜索问题。你在通往目标的不同路径之间搜索,预测每条路径的结果(奖励),并选出结果最有希望的路径。而且很多时候,你可能发现根本不存在能带你到达目标的路径。

搜索常常需要回溯(backtracking)。例如,想象你处在某一步,有两个可能的动作:A 和 B。执行动作 A 之后,你进入了一个不太有希望的状态,于是你需要回溯到之前的状态去执行动作 B。

有人认为,自回归模型只能向前生成动作,无法回溯去生成替代动作,因此得出结论:自回归模型不能规划。但这不一定成立。在执行了含动作 A 的路径之后,如果模型判断这条路径说不通,它可以改用动作 B 来修订路径,这实际上就是回溯。模型也总可以推倒重来,另选一条路径。

LLM 规划能力差,也可能是因为没有被给予规划所需的工具。要规划,不仅要知道有哪些可用动作,还要知道每个动作的潜在结果。举个简单的例子:假设你想爬上一座山。你的候选动作是右转、左转、掉头或直行。然而,如果右转会让你坠下悬崖,你可能就不会考虑这个动作。用技术语言说,一个动作把你从一个状态带到另一个状态,必须知道结果状态才能决定是否采取某个动作。

这意味着,只提示模型生成一串动作——比如流行的思维链(chain-of-thought)提示技术所做的那样——是不够的。论文《Reasoning with Language Model is Planning with World Model》(Hao et al., 2023)认为,LLM 由于包含如此多的关于世界的信息,有能力预测每个动作的结果;这种 LLM 可以把结果预测纳入进来,生成连贯的计划。

即使 AI 不能规划,它仍然可以成为规划器的一部分。用搜索工具和状态跟踪系统来增强 LLM,或许能帮助它规划。

专栏:基础模型(FM)规划器与强化学习(RL)规划器

智能体是强化学习(reinforcement learning,RL)的核心概念。维基百科把 RL 定义为一个研究「智能体应当如何在动态环境中采取动作以最大化累积奖励」的领域。

RL Agent 和基础模型(foundation model,FM)Agent 在很多方面相似:它们都由环境和可能的动作来刻画。主要区别在于规划器的工作方式。

  • 在 RL Agent 中,规划器由 RL 算法训练。训练这个 RL 规划器可能需要大量时间和资源。
  • 在 FM Agent 中,模型就是规划器。这个模型可以通过提示或微调来提升规划能力,通常所需的时间和资源更少。

不过,没有什么能阻止 FM Agent 引入 RL 算法来提升性能。我猜测,长期来看 FM Agent 和 RL Agent 会走向融合。

计划生成

把模型变成计划生成器最简单的方式是提示工程。想象你要创建一个 Agent,帮助顾客了解 Kitty Vogue 的产品。你给这个 Agent 接入三个外部工具:按价格检索产品、检索热销产品、检索产品信息。下面是一个用于计划生成的提示示例。这个提示仅作说明之用,生产环境的提示通常复杂得多。

SYSTEM PROMPT:Propose a plan to solve the task. You have access to 5 actions:* get_today_date()* fetch_top_products(start_date, end_date, num_products)* fetch_product_info(product_name)* generate_query(task_history, tool_output)* generate_response(query)The plan must be a sequence of valid actions.ExamplesTask: "Tell me about Fruity Fedora"Plan: [fetch_product_info, generate_query, generate_response]Task: "What was the best selling product last week?"Plan: [fetch_top_products, generate_query, generate_response]Task: {USER INPUT}Plan:

关于这个例子有两点值得注意:

  • 这里使用的计划格式——一个函数列表、参数由 Agent 自行推断——只是组织 Agent 控制流的诸多方式之一。
  • generate_query 函数接收任务的当前历史和最近的工具输出,生成一个查询,交给回复生成器。每一步的工具输出都会被加入任务历史。

给定用户输入「上周卖得最好的产品价格是多少」,生成的计划可能是这样:

  • get_time()
  • fetch_top_products()
  • fetch_product_info()
  • generate_query()
  • generate_response()

你可能会问:「那每个函数需要的参数怎么办?」确切的参数很难提前预测,因为它们往往取自之前的工具输出。如果第一步 get_time() 输出「2030-09-13」,Agent 就能推理出下一步应该带着如下参数调用:

fetch_top_products(    start_date="2030-09-07",    end_date="2030-09-13",    num_products=1)

通常,信息不足以确定函数的确切参数值。例如,如果用户问「最畅销产品的平均价格是多少?」,以下问题的答案并不明确:

  • 用户想看多少个最畅销产品?
  • 用户想要的是上周、上个月还是有史以来的最畅销产品?

这意味着模型经常不得不靠猜,而猜就可能错。

因为动作序列和相关参数都由 AI 模型生成,它们都可能被幻觉出来。幻觉可能导致模型调用一个无效函数,或调用有效函数但参数错误。一般用于提升模型性能的技术,都可以用来提升模型的规划能力。

让 Agent 更擅长规划的几个技巧:

  • 写更好的系统提示,配更多示例。
  • 给工具及其参数写更好的描述,让模型更理解它们。
  • 重写函数本身,让它们更简单,比如把一个复杂函数重构为两个更简单的函数。
  • 使用更强的模型。一般来说,更强的模型更擅长规划。
  • 为计划生成微调模型。

函数调用

许多模型提供商为它们的模型提供工具使用功能,实际上把模型变成了 Agent。工具就是一个函数,因此调用工具常被称为函数调用(function calling)。不同模型 API 的工作方式不同,但总体上函数调用是这样工作的:

  • 创建工具清单。声明所有你可能希望模型使用的工具。每个工具由它的执行入口(例如函数名)、参数和文档(例如这个函数做什么、需要什么参数)来描述。
  • 指定 Agent 在某次查询中可以使用哪些工具。因为不同的查询可能需要不同的工具,许多 API 允许你为每次查询指定一个已声明工具的列表。有些 API 还允许你通过以下设置进一步控制工具使用:
    • required:模型必须至少使用一个工具。
    • none:模型不应使用任何工具。
    • auto:模型自行决定使用哪些工具。

函数调用如图 6-10 所示。这里用伪代码书写,以便能代表多种 API。要使用某个具体的 API,请参考其文档。

图 6-10:一个模型使用两个简单工具的示例。

给定一个查询,如图 6-10 那样定义的 Agent 会自动生成要使用哪些工具及其参数。有些函数调用 API 会保证只生成有效的函数,但无法保证参数值正确。

例如,给定用户查询「40 磅是多少千克?」,Agent 可能判断它需要 lbs_to_kg_tool 这个工具,参数值为 40。Agent 的回复可能是这样:

response = ModelResponse(    finish_reason='tool_calls',    message=chat.Message(        content=None,        role='assistant',        tool_calls=[            ToolCall(                function=Function(                    arguments='{"lbs":40}',                    name='lbs_to_kg'),                type='function')        ]))

从这个回复中,你可以调用函数 lbs_to_kg(lbs=40),并用它的输出来生成给用户的回复。

提示:与 Agent 打交道时,始终让系统报告每次函数调用所使用的参数值。检查这些值,确保它们正确。

规划粒度

计划是概述完成任务所需步骤的路线图。路线图可以有不同粒度。做一年的规划,按季度的计划比按月的计划层级更高,按月的又比按周的计划层级更高。

规划与执行之间存在权衡。详细的计划更难生成,但更容易执行;高层级的计划更容易生成,但更难执行。绕开这个权衡的一个办法是分层规划:先用一个规划器生成高层级计划(例如按季度的计划),然后对每个季度,用相同或不同的规划器生成按月的计划。

到目前为止,所有生成计划的例子都使用确切的函数名,这非常细粒度。这种做法的问题在于,Agent 的工具清单会随时间变化。例如,获取当前日期的函数 get_time() 可能改名为 get_current_time()。工具一变,你就得更新提示和所有示例。使用确切函数名还让规划器难以跨用例复用,因为不同用例的工具 API 各不相同。

如果你之前为了让模型基于旧工具清单生成计划而微调过它,你就得在新工具清单上重新微调。

为了避免这个问题,计划也可以用更自然的语言来生成,它比领域特定的函数名层级更高。例如,给定查询「上周卖得最好的产品价格是多少」,可以指示 Agent 输出这样的计划:

  • 获取当前日期
  • 检索上周最畅销的产品
  • 检索产品信息
  • 生成查询
  • 生成回复

使用更自然的语言,能让你的计划生成器对工具 API 的变化更稳健。如果你的模型主要在自然语言上训练,它很可能更擅长理解和生成自然语言形式的计划,也更不容易产生幻觉。

这种做法的缺点是,你需要一个翻译器,把每个自然语言动作翻译成可执行的命令。Chameleon(Lu et al., 2023)把这个翻译器称为程序生成器(program generator)。不过,翻译比规划简单得多,可以用更弱的模型完成,幻觉风险也更低。

复杂计划

到目前为止的计划示例都是顺序的:计划中的下一个动作总在上一个动作完成后执行。动作可以被执行的顺序称为控制流(control flow)。顺序形式只是控制流的一种。其他类型的控制流还包括并行、if 语句和 for 循环。下面对每种控制流做个概览,顺序流用于对比:

  • 顺序:任务 A 完成后执行任务 B,可能因为任务 B 依赖任务 A。例如,SQL 查询必须先从自然语言输入翻译出来,然后才能执行。
  • 并行:同时执行任务 A 和任务 B。例如,给定查询「帮我找 100 美元以下的最畅销产品」,Agent 可以先检索前 100 个最畅销产品,然后并行检索其中每个产品的价格。
  • if 语句:根据上一步的输出,决定执行任务 B 还是任务 C。例如,Agent 先查看 NVIDIA 的财报,然后根据财报决定卖出还是买入 NVIDIA 股票。Anthropic 的文章把这种模式称为「路由(routing)」。
  • for 循环:重复执行任务 A,直到满足特定条件。例如,不断生成随机数,直到生成一个质数。

这些控制流如图 6-11 所示。

图 6-11:计划可以按不同顺序执行的示例。

在传统软件工程中,控制流的条件是精确的。而在 AI 驱动的 Agent 中,控制流由 AI 模型决定。带非顺序控制流的计划,无论生成还是翻译成可执行命令,都更加困难。

提示:评测一个 Agent 框架时,检查它支持哪些控制流。例如,如果系统需要浏览十个网站,它能同时进行吗?并行执行可以显著降低用户感知的延迟。

反思与纠错

再好的计划也需要不断评估和调整,才能最大化成功的机会。虽然反思对 Agent 的运行并非严格必需,但它对 Agent 取得成功是必需的。

任务过程中有很多环节可以引入反思:

  • 收到用户查询后,评估请求是否可行。
  • 初始计划生成后,评估计划是否合理。
  • 每个执行步骤之后,评估是否走在正确的轨道上。
  • 整个计划执行完毕后,判断任务是否已完成。

反思和纠错是两个相伴而行的不同机制。反思产生洞见,帮助发现需要纠正的错误。

反思可以由同一个 Agent 用自我批评(self-critique)提示完成,也可以由一个独立组件完成,例如专门的打分器(scorer):一个为每个输出结果给出具体分数的模型。

自 ReAct(Yao et al., 2022)首次提出以来,推理与动作交替进行已成为 Agent 的常见模式。Yao 等人用「推理」一词同时涵盖规划和反思。在每一步,Agent 被要求解释它的思考(规划)、执行动作,然后分析观察结果(反思),直到 Agent 认为任务完成为止。通常会用示例提示 Agent 按如下格式生成输出:

Thought 1: ...Act 1: ...Observation 1: ...... [continue until reflection determines that the task is finished] ...Thought N: ...Act N: Finish [Response to query]

图 6-12 展示了一个遵循 ReAct 框架的 Agent 回答 HotpotQA(Yang et al., 2018,一个多跳问答基准)问题的例子。

图 6-12:一个 ReAct Agent 的实际运行。

你可以在多 Agent 设置中实现反思:一个 Agent 负责规划和执行动作,另一个 Agent 在每一步(或若干步)之后评估结果。

如果 Agent 的回复没能完成任务,你可以提示 Agent 反思为什么失败、如何改进。基于这个建议,Agent 生成新的计划。这让 Agent 能从自己的错误中学习。

例如,给定一个代码生成任务,评估器可能评出生成的代码有三分之一的测试用例没通过。Agent 随后反思失败的原因是没把所有数字都为负的数组考虑进来。于是 Actor 生成新代码,把全负数组考虑在内。

这就是 Reflexion(Shinn et al., 2023)采用的方法。在这个框架里,反思被拆成两个模块:评估输出的评估器(evaluator),以及分析哪里出了问题的自我反思模块。图 6-13 展示了 Reflexion Agent 工作的例子。作者用「轨迹(trajectory)」一词指代计划。在每一步,经过评估和自我反思之后,Agent 提出一条新轨迹。

图 6-13:Reflexion Agent 工作方式的示例。

与计划生成相比,反思相对容易实现,而且能带来出人意料的好性能提升。这种方法的缺点是延迟和成本。思考、观察,有时还有动作,可能消耗大量 token,推高成本和用户感知延迟,对中间步骤很多的任务尤其如此。为了让 Agent 服从输出格式,ReAct 和 Reflexion 的作者都在提示里放了大量示例。这增加了输入 token 的计算成本,也挤占了留给其他信息的上下文空间。

工具选择

因为工具往往在任务成败中扮演关键角色,工具选择需要仔细考量。给你的 Agent 什么工具,取决于环境和任务,也取决于驱动 Agent 的那个 AI 模型。

没有万无一失的指南告诉你如何选出最佳工具集。Agent 文献中的工具清单五花八门。例如:

  • Toolformer(Schick et al., 2023)微调 GPT-J 学习了 5 个工具。
  • Chameleon(Lu et al., 2023)使用 13 个工具。
  • Gorilla(Patil et al., 2023)尝试提示 Agent 在 1,645 个 API 中选出正确的 API 调用。

工具越多,Agent 的能力越强。但工具越多,用好它们就越难。这和人一样:掌握一大堆工具更难。增加工具也意味着增加工具描述,可能超出模型上下文的容纳范围。

与构建 AI 应用时的许多其他决策一样,工具选择需要实验和分析。以下几件事可以帮你做决策:

  • 比较 Agent 在不同工具集下的表现。
  • 做消融实验(ablation study),看看从清单中移除某个工具后,Agent 的性能会下降多少。如果一个工具移除后性能不降,就移除它。
  • 找出 Agent 经常出错的工具。如果一个工具对 Agent 来说实在太难用——比如大量的提示工程甚至微调都教不会模型——就换掉这个工具。
  • 画出工具调用的分布,看哪些工具用得最多、哪些用得最少。图 6-14 展示了 Chameleon(Lu et al., 2023)中 GPT-4 与 ChatGPT 工具使用模式的差异。

图 6-14:不同模型和任务表现出不同的工具使用模式。

Chameleon(Lu et al., 2023)的实验还说明了两点:

  • 不同任务需要不同工具。ScienceQA(科学问答任务)比 TabMWP(表格数学题求解任务)更依赖知识检索类工具。
  • 不同模型有不同的工具偏好。例如,GPT-4 似乎比 ChatGPT 使用更广的工具集;ChatGPT 似乎偏爱图像描述,而 GPT-4 似乎偏爱知识检索。

提示:评测 Agent 框架时,评估它支持哪些规划器和工具。不同框架可能聚焦不同类别的工具。例如,AutoGPT 聚焦社交媒体 API(Reddit、X 和 Wikipedia),而 Composio 聚焦企业级 API(Google Apps、GitHub 和 Slack)。

  • 你的需求很可能随时间变化,因此要评估扩展 Agent、接入新工具有多容易。

作为人类,我们生产力提升不只因为使用手头的工具,还因为用简单的工具造出越来越强大的工具。那么,AI 能否用它的初始工具创造出新工具?

Chameleon(Lu et al., 2023)提出研究工具转移(tool transition):用过工具 X 之后,Agent 有多大概率调用工具 Y?图 6-15 展示了一个工具转移的例子。如果两个工具经常一起使用,可以把它们合并成一个更大的工具。如果 Agent 知晓这一信息,它自己就可以组合初始工具,持续构建更复杂的工具。

图 6-15:Chameleon(Lu et al., 2023)的一棵工具转移树。

Voyager(Wang et al., 2023)提出了技能管理器(skill manager),用来追踪 Agent 获得的新技能(工具),以便日后复用。每个技能是一段程序。当技能管理器判断一个新创建的技能有用(例如它成功帮 Agent 完成了一个任务),就把它加入技能库(skill library,概念上类似工具清单)。这个技能之后可以被检索出来,用于其他任务。

在本节前文我们提到,Agent 在某个环境中的成功取决于它的工具清单和规划能力。任何一方面的失败都会导致 Agent 失败。下一节讨论 Agent 的各种失败模式以及如何评测它们。

Agent 的失败模式与评测

评测就是为了发现失败。Agent 执行的任务越复杂,可能的失败点就越多。除了第 3、4 章讨论的所有 AI 应用共有的失败模式之外,Agent 还有由规划、工具执行和效率引起的独有失败。有些失败比其他失败更容易捕捉。

要评测一个 Agent,先识别它的失败模式,再测量每种失败模式发生的频率。

规划失败

规划很难,失败的方式也很多。最常见的规划失败模式是工具使用失败。Agent 生成的计划可能包含以下一种或多种错误:

  • 无效工具:例如,它生成了一个包含 bing_search 的计划,但工具清单里并没有这个工具。
  • 有效工具、无效参数:例如,它调用 lbs_to_kg 时传了两个参数,但这个函数只需要一个参数 lbs。
  • 有效工具、错误的参数值:例如,它调用 lbs_to_kg 时传了一个参数 lbs,但把值设成了 100,而实际应该是 120。

另一种规划失败模式是目标失败:Agent 没能达成目标。这可能是因为计划没有解决任务,或者解决了任务却没有遵守约束。举例说明:假设你让模型规划一趟预算 5,000 美元、从旧金山到印度的两周旅行。Agent 可能规划了一趟从旧金山到越南的旅行,或者给你规划了一趟从旧金山到印度的两周旅行,但花费远超预算。

一个常被 Agent 评测忽视的约束是时间。很多情况下,Agent 花多少时间不那么要紧,因为你可以把任务交给 Agent,等它做完再来查看。但在很多情况下,Agent 随着时间推移价值下降。例如,你让 Agent 准备一份资助申请书,而它在资助截止日期之后才完成,那这个 Agent 就帮不上什么忙了。

一种有趣的规划失败由反思中的错误引起:Agent 确信自己完成了任务,而实际上并没有。例如,你让 Agent 把 50 个人分配到 30 间酒店客房。Agent 可能只分配了 40 个人,却坚称任务已经完成。

要评测 Agent 的规划失败,一个办法是创建一个规划数据集,其中每个样本是一个二元组(任务,工具清单)。对每个任务,让 Agent 生成 K 份计划,然后计算以下指标:

  • 所有生成的计划中,有多少是有效的?
  • 对一个给定任务,Agent 要生成多少份计划才能得到一份有效计划?
  • 所有工具调用中,有多少是有效的?
  • 调用无效工具的频率是多少?
  • 用无效参数调用有效工具的频率是多少?
  • 用错误的参数值调用有效工具的频率是多少?

分析 Agent 的输出,寻找规律。Agent 在哪类任务上失败更多?你有相应的假设吗?模型经常在哪些工具上犯错?有些工具可能对 Agent 更难用。你可以通过更好的提示、更多的示例或微调,来提升 Agent 使用困难工具的能力。如果这些都不奏效,可以考虑把这个工具换成更好用的。

工具失败

工具失败发生在工具用对了、但工具输出错了的情况。一种失败模式是工具直接给出错误的输出。例如,图像描述器返回了错误的描述,或者 SQL 查询生成器返回了错误的 SQL 查询。

如果 Agent 只生成高层计划,并且有一个翻译模块负责把每个计划动作翻译成可执行命令,那么翻译错误也会导致失败。

工具失败依赖于具体工具。每个工具都需要独立测试。始终打印出每一次工具调用及其输出,以便检查和评估。如果你有翻译器,为它创建基准来评测。

检测「缺失工具」型的失败,需要理解哪些工具本应被使用。如果你的 Agent 经常在某个特定领域失败,这可能是因为它缺少这个领域的工具。与人类领域专家合作,观察他们会使用什么工具。

效率

一个 Agent 可能生成了有效计划、用对了工具、完成了任务,但效率低下。以下是评估 Agent 效率时值得跟踪的几项指标:

  • Agent 完成一个任务平均需要多少步?
  • Agent 完成一个任务平均花多少钱?
  • 每个动作通常花多长时间?有没有特别耗时或昂贵的动作?

你可以把这些指标与你的基线对比,基线可以是另一个 Agent,也可以是人类操作员。比较 AI Agent 与人类 Agent 时要记住:人类和 AI 的运作模式非常不同,对人类高效的事情对 AI 可能低效,反之亦然。例如,访问 100 个网页,对一次只能看一个页面的人类 Agent 来说很低效,但对能同时访问所有网页的 AI Agent 来说轻而易举。

结语

归根结底,Agent 的概念相当简单。Agent 由它运作的环境和它能访问的工具集合来定义。在 AI 驱动的 Agent 中,AI 模型是大脑,它利用工具和来自环境的反馈,来规划如何最好地完成任务。工具的接入让模型能力大幅提升,所以智能体模式(agentic pattern)是不可避免的。

虽然「Agent」听起来很新颖,但它建立在 LLM 早期就开始使用的许多概念之上,包括自我批评、思维链和结构化输出。

本文从概念层面讲了 Agent 如何工作以及 Agent 的各个组成部分。在未来的文章中,我会讨论如何评测 Agent 框架。

智能体模式经常要处理超出模型上下文上限的信息。一个能补充模型上下文来处理信息的记忆系统,可以显著增强 Agent 的能力。由于本文已经很长,我会在以后的博客文章中探讨记忆系统如何工作。

延伸阅读:Agent 相关的更多主题资料见 Agent 主题页;Agent 项目的整体交付节奏可参考 FDE 项目生命周期FDE 能力模型;AI 编码与工程实践的延伸内容见 AI Coding 主题页

本文由 FDEChina 团队翻译自原文,转载已注明出处;如需引用请以原文为准。