智能体 Agents
许多人认为,智能体(intelligent agents)是 AI 研究的终极目标。Stuart Russell 和 Peter Norvig 的经典著作《Artificial Intelligence: A Modern Approach》(Prentice Hall,1995)将 AI 研究领域定义为"对理性智能体的研究与设计"。
基础模型展现出前所未有的能力,为过去难以想象的智能体应用打开了大门。这些新能力让我们终于有可能开发出自主的智能体,让它们充当我们的助手、同事和教练,帮我们搭建网站、收集数据、规划行程、做市场调研、管理客户账户、自动化录入数据、准备面试、面试候选人、谈判交易等等。应用场景似乎无穷无尽,而这些智能体的潜在经济价值也极为可观。
本节首先概述智能体,然后介绍决定其能力的两个关键方面:工具与规划。智能体带来了全新的运作方式,也伴随着全新的失败模式。本节最后会讨论如何评估智能体以捕捉这些失败。
本文改编自《AI Engineering》(2025)一书的 Agents 章节,并做了少量编辑使其成为一篇独立的文章。
说明:
- AI 驱动的智能体是一个新兴领域,目前尚无成熟的理论框架来定义、开发和评估它们。本节是基于现有文献尽力搭建的一个框架,随着领域发展它也会持续演进。与本书其他部分相比,本节的探索性更强。我从早期审稿人那里收到了宝贵的反馈,也希望能从本博客文章的读者那里获得更多反馈。
- 就在本书出版前夕,Anthropic 发表了一篇关于 Building effective agents 的博客文章(2024 年 12 月)。令我欣慰的是,Anthropic 的博客文章与我的智能体章节在概念上是一致的,尽管术语略有不同。不过,Anthropic 的文章侧重于孤立的模式,而我的文章则覆盖了背后的原理与运作机制,并且更深入地讨论了规划、工具选择和失败模式。
- 这篇帖子包含大量背景信息。如果觉得内容有点过于深入细节,可以直接跳读!
智能体概述
“agent”一词在许多不同的工程语境中都出现过,包括但不限于软件 agent、智能 agent、用户 agent、对话 agent 以及强化学习 agent。那么,agent 究竟是什么?
智能体是任何能够感知其所处环境并作用于该环境的事物。《人工智能:一种现代方法》(1995)将智能体定义为任何可以通过传感器感知环境,并通过执行器作用于环境的事物。
这意味着,智能体的特征由其所运行的环境和它能够执行的动作集合所决定。
智能体能够运行的环境由其用例决定。如果开发的智能体是用来玩游戏的(例如《Minecraft》、围棋、《Dota》),那么该游戏就是它的环境。如果你想让智能体从互联网上抓取文档,那么环境就是互联网。自动驾驶汽车智能体的环境则是道路系统及其周边区域。
AI 智能体能够执行的动作集合会因其可使用的工具而得到增强。你日常互动的许多生成式 AI 应用程序其实就是带有工具的智能体,尽管这些工具比较简单。ChatGPT 就是一个智能体,它能搜索网页、执行 Python 代码并生成图像。RAG 系统也是智能体——文本检索器、图像检索器和 SQL 执行器就是它们的工具。
智能体的环境与其工具集之间存在很强的依赖关系。环境决定了智能体潜在可用的工具。例如,如果环境是国际象棋游戏,那么智能体唯一可能的动作就是合法的走棋。然而,智能体的工具清单也会限制它能够运行的环境。例如,如果机器人的唯一动作是游泳,那它就只能局限于水域环境。
图 6-8 展示了对 SWE-agent(Yang 等人,2024)的可视化展示,这是一个基于 GPT-4 构建的智能体。它的环境是带有终端和文件系统的计算机。它的动作集合包括浏览代码仓库、搜索文件、查看文件和编辑代码行。
Figure 6-8. SWE-agent 是一个编码 agent,其运行环境是计算机,可执行的操作包括导航、搜索、查看文件和编辑AI agent 旨在完成用户提出的任务。在 AI agent 中,AI 充当大脑,负责处理任务、规划达成目标的动作序列,并判断任务是否已完成。
回到上面 Kitty Vogue 示例中那个基于表格数据的 RAG 系统。这是一个包含三个动作的简单 agent:
- 生成回答,
- 生成 SQL 查询,
- 执行 SQL 查询。
给定查询 "预测 Fruity Fedora 未来三个月的销售收入",agent 可能会按以下顺序执行动作:
- 推理如何完成该任务。它可能判断:要做销售预测,首先需要过去五年的销售数据。agent 的推理过程会以中间回复的形式呈现。
- 调用 SQL 查询生成,获取过去五年销售数据的查询语句。
- 调用 SQL 查询执行,运行该查询。
- 对工具输出(即 SQL 查询执行的结果)进行推理,判断其对销售预测的作用。它可能认为这些数据不足以做出可靠预测,例如因为存在缺失值,于是决定还需要过往营销活动的信息。
- 调用 SQL 查询生成,获取过往营销活动相关的查询语句。
- 调用 SQL 查询执行。
- 推理判断新获取的信息已足以支持销售预测,随即生成预测结果。
- 推理判断任务已成功完成。
相比非 agent 的应用场景,agent 通常需要更强大的模型,原因有两点:
- 错误累积:agent 通常需要多步协作才能完成任务,整体准确率会随着步骤数的增加而下降。如果模型每步准确率为 95%,那么经过 10 步后准确率会降至 60%,经过 100 步后仅剩 0.6%。
- 更高的风险:由于具备工具调用能力,agent 能完成影响力更大的任务,但任何失误都可能带来更严重的后果。
需要多步执行的任务往往既耗时间又花钱。常见的抱怨是:智能体唯一的本事就是疯狂消耗你的 API 额度。但是,如果智能体能够自主运行,它们可以节省人的时间,让这些成本花得值。
在给定环境下,智能体的成败取决于它能使用的工具以及AI 规划器的强弱。我们先来看看模型可以使用的各类工具,再分析 AI 的规划能力。
工具
一个系统即使不借助外部工具,也可以称为智能体。但没有外部工具的话,智能体的能力会非常有限。模型本身通常只能执行一种操作——大语言模型能生成文本,图像生成模型能生成图像。外部工具则能让智能体的能力大幅提升。
工具既帮助智能体感知环境,也帮助它对环境采取行动。让智能体感知环境的操作属于只读操作,而让它对环境采取行动的操作属于写入操作。
智能体能使用的工具集合就是它的工具清单。由于工具清单直接决定了智能体能做什么,因此认真思考该给它哪些工具、给多少工具非常重要。工具越多,智能体的能力越强;但工具越多,也越难被充分理解和有效利用。找到合适的工具组合需要不断试验,这一点会在后面的"工具选择"一节中详细讨论。
根据智能体所处的环境,可选的工具种类繁多。以下是你可以考虑的三类工具:知识增强(即上下文构建)、能力扩展,以及让智能体对环境采取行动的工具。
知识增强
希望本书到目前为止已经让你认识到:给模型提供恰当的上下文对其回答质量至关重要。有一类重要的工具专门用于扩充智能体的知识。其中一些已经在前面讨论过:文本检索器、图像检索器和 SQL 执行器。其他潜在的工具还包括内部人员搜索、返回各类产品状态的库存 API、Slack 检索、邮件读取器等等。
许多此类工具会用你们组织的私有流程和信息来增强模型。但工具也能让模型访问公开信息,尤其是来自互联网的内容。
网页浏览是 ChatGPT 最早集成、也最受期待的能力之一。网页浏览能避免模型过时——所谓过时,是指模型训练所用的数据已经不再新鲜。如果模型的训练数据截止于上周,那它就无法回答需要本周信息的问题,除非这些信息被放入上下文里。没有网页浏览,模型就没法告诉你天气、新闻、即将到来的活动、股价、航班状态等。
我把网页浏览当作一个统称,涵盖所有能访问互联网的工具,包括网页浏览器,以及搜索、新闻、GitHub、社交媒体等各类 API。
网页浏览能让你的智能体引用最新信息,从而生成更好的回答并减少幻觉,但同时也可能把它暴露在互联网的"下水道"里。选择互联网 API 时请务必谨慎。
能力扩展
你还可以考虑一些能弥补 AI 模型固有局限的工具,它们是提升模型表现的最简单方法。比如,AI 模型普遍不擅长数学。问它 199,999 除以 292 等于多少,大概率会算错。但只要给它一个计算器,这种运算就不在话下。与其费力训练模型的算术能力,不如直接给它一个工具,效率高得多。
其他能显著提升模型能力的简单工具还包括日历、时区转换器、单位转换器(比如磅转千克),以及能在模型不擅长的语言之间互译的翻译器。
更复杂但也更强大的工具是代码解释器。与其训练一个模型去理解代码,不如直接给它一个代码解释器,让它执行一段代码、返回结果或分析代码的失败原因。这个能力能让你的智能体充当编程助手、数据分析师,甚至能编写代码来运行实验并汇报结果的研究助手。不过,自动化执行代码会带来代码注入攻击的风险,这在第 5 章"防御性提示工程"一节中讨论过。为了保障你和用户的安全,必须采取妥善的安全措施。
工具可以把一个只能处理文本或只能处理图像的模型变成多模态模型。例如,一个只能生成文本的模型可以把文生图模型作为工具来用,从而同时生成文本和图像。面对一段文本请求,智能体的 AI 规划器会决定调用文本生成、图像生成,还是两者都调用。ChatGPT 能同时生成文本和图像,就是靠把 DALL-E 当作它的图像生成器。
智能体还可以用代码解释器来生成图表,用 LaTeX 编译器来渲染数学公式,或者用浏览器来把 HTML 代码渲染成网页。
同理,一个只能处理文本输入的模型,可以用图像描述工具来处理图像,用转录工具来处理音频,用 OCR(光学字符识别)工具来读取 PDF。
相较于单纯提示甚至微调,工具调用能显著提升模型的表现。Chameleon(Lu 等,2023)表明,一个由 GPT-4 驱动的智能体在配备了 13 种工具后,能在多个基准上超越单独的 GPT-4。该智能体使用的工具包括知识检索、查询生成器、图像描述器、文本检测器以及 Bing 搜索。
在科学问答基准 ScienceQA 上,Chameleon 把已发布的最佳少样本结果提升了 11.37%。在涉及表格数学问题的基准 TabMWP(Tabular Math Word Problems,Lu 等,2022)上,Chameleon 把准确率提升了 17%。
写入操作
到目前为止,我们讨论的都是只读操作——模型只能从数据源读取数据。但工具同样可以执行写操作,对数据源进行修改。SQL 执行器既能读取数据表(读),也能修改或删除数据表(写);邮件 API 既能读取邮件,也能回复邮件;银行 API 既能查询账户余额,也能发起转账。
写操作让系统能做更多事情。比如,它能帮你把整个客户开发流程自动化:调研潜在客户、查找联系方式、起草邮件、发送第一封信、阅读回复、跟进沟通、提取订单信息、更新数据库中的新订单,等等。
然而,让 AI 自动改变我们的生活,想想就让人害怕。就像不该把生产数据库的删除权限交给实习生一样,你也不该让一个不可靠的 AI 去发起转账。对系统能力和其安全措施的信任至关重要。你需要确保系统能够抵御那些企图操纵它执行有害操作的恶意行为者。
侧边栏:智能体与安全
每当我向一群人谈及自主 AI 智能体时,总会有人拿自动驾驶汽车来举例。"要是有人黑进汽车把你绑架了怎么办?"自动驾驶汽车的例子之所以让人觉得震撼,是因为它涉及物理世界。但即便没有物理实体的存在,AI 系统同样可以造成伤害——操纵股市、侵犯版权、侵犯隐私、强化偏见、传播虚假信息和宣传内容,等等,第 5 章"防御性提示工程"一节对此有详细讨论。
这些担忧都完全合理,任何想要利用 AI 的组织都必须认真对待安全和防护问题。但这并不意味着 AI 系统永远不该被赋予在真实世界中行动的能力。如果我们可以信任一台机器把我们送上太空,我也希望有一天,安全措施能够完善到让我们足以信任自主 AI 系统。而且,人同样会犯错。就个人而言,比起随便一个陌生人,我更愿意坐自动驾驶汽车。
正如合适的工具能让人类的生产力大幅提升——你能想象没有 Excel 怎么做生意,或者没有起重机怎么盖摩天大楼吗?——工具同样能让模型完成多得多的任务。许多模型提供商已经支持工具调用功能,通常称为 function calling。展望未来,我预计大多数模型都将普遍支持调用各种工具。
规划
基础模型智能体的核心,是负责解决用户任务的模型。任务由目标和约束条件共同定义。例如,有一项任务是规划从旧金山到印度的两周行程,预算 5,000 美元。目标是这两周的行程,约束条件则是预算。
复杂任务离不开规划。规划过程的产物是一份计划,即完成任务所需步骤的路线图。有效的规划通常要求模型理解任务、权衡不同方案,并选择最有前景的那一个。
参加过任何规划会议的人都知道,规划是件难事。作为一个重要的计算问题,规划已被广泛研究,相关内容足够写好几卷书。我在这里只能触及皮毛。
规划概述
对于一个任务,通常有多种解法,但并非所有解法都能成功。在正确解法之中,有些比其他更高效。以查询 "How many companies without revenue have raised at least $1 billion?" 为例,下面是两种解法:
- 先找出所有没有收入的公司,再按融资额筛选。
- 先找出所有融资额达到 10 亿美元的公司,再按收入筛选。
第二种方案更高效。没有收入的公司数量远远超过融资额达到 10 亿美元的公司。仅在这两种方案之间,理性的智能体就应当选择方案二。
你可以在同一个 prompt 里把规划和执行结合起来。比如,给模型一个 prompt,让它一步步思考(比如用思维链 prompt),然后在同一个 prompt 里执行这些步骤。但如果模型生成了一个一千步的计划却根本完不成目标呢?缺乏监督的情况下,智能体可能跑上几个小时,浪费大量时间和 API 调用费用,最后你才发现它哪儿也没去。
为了避免无效执行,规划应该与执行解耦。先让智能体生成一个计划,经过验证后再执行。计划可以用启发式方法来检验,比如一条简单规则:剔除包含无效动作的计划。如果生成的计划需要调用 Google 搜索,但智能体并没有 Google 搜索权限,那这个计划就是无效的。另一条简单规则是:剔除步骤超过 X 个的计划。
计划也可以用 AI 评判器来验证。你可以请一个模型评估这个计划是否合理,以及如何改进。
如果生成的计划被评为不合格,可以让规划器重新生成;如果合格,就执行它。
如果计划涉及外部工具,就会触发函数调用。执行计划的输出结果同样需要再次评估。注意,生成的计划不必是覆盖整个任务的端到端计划,也可以是针对某个子任务的小计划。整个流程如图 6-9 所示。
你的系统现在包含三个组件:一个负责生成计划,一个负责验证计划,另一个负责执行计划。如果把每个组件都看作一个智能体,这就可以算作一个多智能体系统。由于大多数智能体工作流都足够复杂、需要多个组件参与,因此大多数智能体本质上都是多智能体系统。
为了加快速度,可以不用串行生成计划,而是并行生成多个计划,让评估器从中挑选最有前途的一个。这又是一个延迟与成本之间的权衡——同时生成多个计划会带来额外开销。
规划需要理解任务背后的意图:用户提出这个查询是想做什么?通常会用一个意图分类器来帮助智能体做规划。如第 5 章中「将复杂任务拆分为更简单的子任务」一节所述,意图分类可以通过另一个提示词或专门训练的分类模型来实现。这个意图分类机制本身也可以看作你多智能体系统中的另一个智能体。
了解意图有助于智能体挑选合适的工具。以客服场景为例:如果是账单相关的问题,智能体可能需要调用工具来查询用户最近的支付记录;如果是问如何重置密码,那就需要去访问文档检索。
提示:
有些查询可能超出了智能体的处理范围。意图分类器应当能够把这类请求归为
IRRELEVANT(无关),让智能体礼貌地拒绝,而不是浪费算力去想一个根本行不通的方案。
到目前为止,我们一直假设智能体会自动完成全部三个阶段:生成计划、验证计划、执行计划。而在实际应用中,人可以在任意阶段参与进来,辅助流程并降低风险。
- 领域专家可以提供计划、审核计划,或者直接执行计划中的某些部分。比如面对智能体难以一次性生成完整方案的复杂任务时,专家可以先给出一个高层规划,再由智能体去细化和展开。
- 如果计划涉及高风险操作——比如更新数据库或合并代码改动——系统可以在执行前要求人工明确确认,或者直接交由人来执行这些操作。要做到这一点,你需要为每个动作明确规定智能体所能拥有的自动化权限等级。
总结一下,完成一项任务通常会经过以下流程。需要注意的是,反思并非智能体的必备环节,但加上它会显著提升智能体的表现。
- 生成计划:针对任务设计一个执行方案。计划本质上是一系列可执行的步骤,所以这个过程也叫任务分解。
- 反思与纠错:评估生成的计划,如果不够好,就重新生成一个。
- 执行:执行生成计划中列出的动作,通常涉及调用特定的函数。
- 反思与纠错:在收到动作执行结果后,评估这些结果并判断目标是否已达成,找出并修正错误。若目标未完成,则生成新的计划。
你在本书中已经接触过一些计划生成和反思的技巧。当你让模型"一步步思考"时,你是在让它分解任务;当你让模型"验证答案是否正确"时,你是在让它进行反思。
作为规划者的基础模型
一个悬而未决的问题是:基础模型的规划能力究竟有多强?许多研究者认为,基础模型——至少是那些基于自回归语言模型构建的——并不具备真正的规划能力。Meta 的首席 AI 科学家 Yann LeCun 明确指出,自回归 LLM 无法进行规划(2023 年)。
自回归 LLM 无法规划
— Yann LeCun (@ylecun) 2023 年 9 月 13 日
(也无法真正进行推理)。
"虽然我们自身有限的实验并未表明通过微调能在规划能力上带来显著提升,但或许在投入更多微调数据和精力后,经验性能确实有可能…… https://t.co/rHA5QHi90C
虽然有大量轶事证据表明 LLM 是糟糕的规划者,但目前尚不清楚这究竟是因为我们不知道如何正确使用 LLM,还是因为 LLM 在根本上就无法进行规划。
规划本质上是一个搜索问题。你在通往目标的不同路径中进行搜索,预测每条路径的结果(收益),然后选择最有希望达成结果的那条路径。通常,你也可能发现根本不存在能将你带向目标的路径。
搜索常常需要进行回溯。例如,假设你正处在某个步骤,此时有两个可选动作: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)规划器
智能体(agent)是强化学习中的核心概念,维基百科将其定义为一门"关注智能体如何在动态环境中采取动作以最大化累积奖励"的学科。
RL 智能体和 FM 智能体在很多方面相似,都用环境和可能的动作来刻画。两者的主要区别在于规划器的运作方式。
- 在强化学习(RL)智能体中,规划器由 RL 算法训练。训练这个 RL 规划器往往需要大量时间和资源。
- 在基础模型(FM)智能体中,模型本身就是规划器。可以通过提示工程或微调来提升其规划能力,通常所需的时间和资源也少得多。
不过,FM 智能体完全可以引入 RL 算法来提升性能。我猜测长远来看,FM 智能体和 RL 智能体会走向融合。
生成规划
把模型变成规划生成器,最简单的方法是提示工程。假设你想打造一个智能体,帮客户了解 Kitty Vogue 的产品。你给这个智能体开放三个外部工具:按价格检索商品、检索热销商品、获取商品详情。下面是一个用于生成规划的提示示例,仅作演示,实际生产中的提示通常会更复杂。
系统提示(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.
Examples
Task: "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:
关于这个示例有两点需要说明:
- 这里采用的规划格式——由智能体自行推断参数的函数列表——只是众多智能体控制流组织方式中的一种。
generate_query函数接收当前的任务历史和最近一次工具输出,用来生成查询语句,再送入响应生成器。每一步的工具输出都会被追加到任务历史中。
对于用户输入"What"s the price of the best-selling product last week"(上周最畅销商品的价格是多少),模型生成的规划大致如下:
get_time()fetch_top_products()fetch_product_info()generate_query()generate_response()
你可能会好奇:"每个函数需要哪些参数呢?" 准确预测参数很难,因为它们通常要从上一步工具的输出中提取。比如第一步 get_time() 返回 "2030-09-13",智能体就可以推断下一步该这样调用:
fetch_top_products(
start_date="2030-09-07",
end_date="2030-09-13",
num_products=1
)
很多时候信息不足以确定函数参数的具体值。比如用户问"畅销商品的平均价格是多少?",下面这些问题的答案都不明确:
- 用户想看多少件畅销商品?
- 用户想了解的是上周、上个月还是所有时间的畅销商品?
这意味着模型经常要靠猜,而猜很可能是错的。
由于动作序列和相关参数都由 AI 模型生成,它们都可能出现幻觉。幻觉会导致模型调用不存在的函数,或者虽然函数存在但参数错误。提升模型整体性能的方法也能用来增强其规划能力。
技巧:让智能体更擅长规划。
- 编写更好的系统提示,提供更多示例。
- 更清晰地描述工具及其参数,帮助模型更好地理解。
- 重写函数使其更简洁,例如把一个复杂的函数拆成两个简单的函数。
- 使用更强的模型——一般来说,更强的模型规划能力也更好。
- 针对规划任务微调模型。
函数调用
许多模型服务商为模型提供工具使用能力,相当于把模型变成了智能体。工具就是一个函数,因此调用工具通常被称为函数调用。不同模型的 API 有所差别,但函数调用大体遵循如下流程:
- 建立工具清单。 声明模型可能用到的所有工具,每个工具都包含执行入口(如函数名)、参数以及文档说明(如函数的功能和所需参数)。
- 为查询指定智能体可以使用的工具。
由于不同查询可能需要不同的工具,许多 API 允许你针对每次查询声明一份工具列表。部分 API 还提供以下设置来进一步控制工具使用:required:模型必须使用至少一个工具。none:模型不应使用任何工具。auto:由模型自行决定使用哪些工具。
函数调用如图 6-10 所示。这里用伪代码编写,以便兼容多种 API。如需对接具体 API,请参阅对应文档。
对于给定的查询,按照图 6-10 定义的智能体会自动生成要使用的工具及其参数。某些函数调用 API 会保证生成的函数是合法的,但无法保证参数值的正确性。
例如,对于用户查询「40 磅等于多少千克?」,智能体可能会决定调用工具 lbs_to_kg_tool,并将参数值设为 40。其响应可能如下所示:
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),并使用其输出生成对用户的回复。
提示:在使用智能体时,务必让系统在每次函数调用时汇报所使用的参数值,并人工检查这些值是否正确。
规划的粒度
规划是完成任务所需步骤的路线图。路线图可以有不同的粒度:规划一整年时,按季度划分的规划比按月划分的更粗略,而按月划分的又比按周划分的更粗略。
规划与执行之间存在权衡:详细的计划生成起来更难,但执行起来更容易;高层级的计划则反过来。为了绕过这一矛盾,可以采用分层规划的方式:先用规划器生成高层计划,例如季度计划;然后针对每个季度,再用相同或不同的规划器生成月度计划。
到目前为止,前面所有的计划示例都使用了精确的函数名,这种方式粒度很细。这种做法的问题在于,智能体的工具清单会随时间变化。比如,获取当前时间的函数 get_time() 可能会被改名为 get_current_time()。一旦工具发生变化,你就得更新提示词和所有示例。使用精确的函数名还会让同一个规划器难以复用到具有不同工具 API 的场景中。
如果你之前已经微调过一个模型,让它基于旧工具清单生成计划,那么在工具清单更新后,你就需要用新清单重新微调模型。
为了避免这个问题,生成计划时可以使用更贴近自然语言的表述,它比那些领域相关的函数名更抽象。例如,对于"上周最畅销产品的价格是多少"这个查询,可以指示智能体输出如下计划:
get current dateretrieve the best-selling product last weekretrieve product informationgenerate querygenerate response
使用更自然的语言能让计划生成器在工具 API 变化时保持鲁棒。如果你的模型主要是用自然语言训练的,那它通常更能理解和生成自然语言形式的计划,幻觉问题也更少。
这种做法的缺点在于,你需要一个翻译器,把每条自然语言动作翻译成可执行命令。Chameleon(Lu 等人,2023)把这种翻译器称为程序生成器。不过翻译本身比规划简单得多,可以用更弱的模型来完成,幻觉风险也更低。
复杂计划
前面示例中的计划都是顺序执行的:下一步动作总是在前一步完成后才执行。动作的执行顺序称为控制流,顺序执行只是其中一种。其它控制流还包括并行、if 语句和 for 循环。下面逐一介绍每种控制流(顺序执行也一并列出以便对比):
-
顺序执行
在任务 A 完成后执行任务 B,通常是因为 B 依赖于 A。例如,必须先把自然语言输入翻译成 SQL 查询,才能执行该查询。
-
并行执行
同时执行任务 A 和 B。例如,面对"找出 100 美元以下最畅销的产品"这样的查询,智能体可以先获取销量前 100 的产品,然后并行地获取每个产品的价格。
-
If 语句
根据上一步的输出决定执行任务 B 还是任务 C。例如,智能体先查看 NVIDIA 的财报,再据此决定是买入还是卖出 NVIDIA 股票。Anthropic 的文章把这种模式称为"路由(routing)"。
-
For 循环
重复执行任务 A,直到满足特定条件。例如,不断生成随机数,直到生成一个素数。
这些不同的控制流如图 6-11 所示。
在传统软件工程中,控制流的判断条件是精确的;而在 AI 驱动的智能体中,控制流由 AI 模型来决定。包含非顺序控制流的计划,无论生成还是转换成可执行命令,都更加困难。
提示:
评估智能体框架时,要看它支持哪些控制流。比如系统需要浏览十个网站,它能否并行处理?并行执行可以显著降低用户感知的延迟。
反思与错误修正
即便计划再周全,也需要持续评估和调整,才能最大化成功的概率。虽然反思(reflection)并不是智能体运作的必要条件,但却是它取得成功的必要条件。
在任务执行过程中,有许多环节都可以借助反思:
- 收到用户请求后,评估该请求是否可行。
- 生成初步计划后,评估计划是否合理。
- 每执行一步后,评估是否走在正确的轨道上。
- 整个计划执行完毕后,判断任务是否真正完成。
反思和纠错是两个相辅相成的机制。反思能产生洞察,帮助发现需要修正的错误。
反思可以让同一个智能体通过自我批评(self-critique)的提示来完成,也可以交由独立的组件来实现,例如一个专门的评分器——一种针对每个输出给出具体分数的模型。
由 ReAct(Yao 等人,2022)首次提出的"推理与行动交织"模式,已经成为智能体的常见范式。Yao 等人所说的"推理"涵盖了规划和反思两个层面。在每一步中,智能体先阐述自己的思路(规划),再执行动作,然后分析观察结果(反思),直到它认为任务已经完成。实际使用中,通常会通过示例提示智能体按以下格式输出:
Thought 1: …
Act 1: …
Observation 1: …
… [继续,直到反思判定任务完成] …
Thought N: …
Act N: Finish [对请求的回复]
图 6-12 展示了一个采用 ReAct 框架的智能体回答 HotpotQA(Yang 等人,2018,一个多跳问答基准)问题的示例。
你也可以在多智能体设置中实现反思:让一个智能体负责规划和行动,另一个智能体在每一步或若干步之后评估其结果。
如果智能体的回复未能完成任务,可以提示它反思失败的原因以及改进方法。基于这些建议,智能体会生成新的计划,从而从错误中学习。
比如,假设有一个代码生成任务,评估器可能会判断生成的代码在三分之一的测试用例上失败了。智能体随后反思,发现失败的原因是它没有考虑到所有元素都为负数的数组这种情况。actor 模块接着生成新代码,把全负数组的情况纳入考量。
这正是 Reflexion(Shinn 等人,2023)所采用的思路。在该框架中,反思被拆分成两个模块:一个评估结果好坏的评估器,以及一个分析失败原因的自反思模块。图 6-13 展示了 Reflexion 智能体的运行实例。作者用"trajectory"这个词来指代计划。每一步经过评估和自反思之后,智能体都会提出一条新的 trajectory。
和计划生成相比,反思实现起来相对简单,却能带来意想不到的性能提升。这种方式的不足之处在于延迟和成本。思考、观察,有时还有动作,生成起来会消耗大量 token,进而增加开销和用户感知的延迟,对于中间步骤繁多的任务尤其明显。为了引导智能体遵循预期格式,ReAct 和 Reflexion 的作者都在提示里塞了大量示例,这既提高了输入 token 的计算成本,也压缩了留给其他信息的上下文空间。
工具选择
工具往往是任务能否成功的关键,所以选择工具时需要仔细权衡。给智能体配备哪些工具,取决于环境和任务本身,也取决于驱动智能体的 AI 模型。
如何挑选最佳工具组合,并没有万无一失的指南。各种智能体文献中使用的工具清单差异很大,例如:
- Toolformer(Schick 等人,2023)微调了 GPT-J,让它学会使用 5 种工具。
- Chameleon(Lu 等人,2023)使用了 13 种工具。
- Gorilla(Patil 等人,2023)尝试让智能体在 1645 个 API 中挑选出正确的调用。
工具越多,智能体的能力就越强。但工具越多,高效使用它们的难度也越大——这和人类难以同时精通大量工具有点像。此外,添加工具意味着增加工具描述,而描述过长可能会超出模型的上下文窗口。
和构建 AI 应用时的许多其他决策一样,工具的选择也需要不断实验和分析。以下几点或许能帮你做决定:
- 对比智能体在使用不同工具集时的表现。
- 做消融实验,看看从工具列表中移除某个工具后,智能体的性能会下降多少。如果移除后性能没有下降,那就把它去掉。
- 找出智能体经常出错的工具。如果某个工具实在太难用——比如经过大量提示工程甚至微调,模型仍然学不会——那就换掉它。
- 统计工具调用的分布,看看哪些工具用得最多、哪些用得最少。图 6-14 展示了 Chameleon(Lu 等人,2023)中 GPT-4 和 ChatGPT 工具使用模式的差异。
Chameleon(Lu 等人,2023)的实验还揭示了两点:
- 不同任务需要不同的工具。例如,科学问答任务 ScienceQA 对知识检索工具的依赖远高于表格数学问题求解任务 TabMWP。
- 不同模型对工具有不同的偏好。比如 GPT-4 选择的工具范围似乎比 ChatGPT 更广;ChatGPT 偏好图像描述,而 GPT-4 更倾向于知识检索。
小贴士:
评估智能体框架时,要看看它支持哪些规划器和工具。不同框架侧重的工具类别可能不同。例如,AutoGPT 主要面向社交媒体类 API(Reddit、X、Wikipedia),而 Composio 则聚焦企业级 API(Google Apps、GitHub、Slack)。
由于需求很可能会随时间变化,也要评估智能体框架能否方便地扩展,以纳入新工具。
作为人类,我们之所以变得更高效,不仅是因为使用现有的工具,还因为不断用简单工具创造出更强大的工具。AI 能否用其初始工具创造出新工具?
Chameleon(Lu 等人,2023)提出了工具迁移的研究:在调用工具 X 之后,智能体调用工具 Y 的概率有多大?图 6-15 展示了一个工具迁移的例子。如果两个工具经常一起使用,它们就可以被组合成一个更大的工具。如果智能体能意识到这一点,它就可以自主地将初始工具不断组合,构建出更复杂的工具。
Voyager(Wang 等人,2023)提出了一个技能管理器,用于记录智能体获得的新技能(工具),以便后续复用。每个技能都是一个代码程序。当技能管理器判定一个新创建的技能有用时(例如它成功帮助智能体完成了任务),就将该技能添加到技能库中(类似于工具库存的概念)。这个技能之后可以被检索,用于完成其他任务。
在本节前面我们提到,智能体在环境中的成功取决于其工具库存和规划能力。这两方面任何一处失败都可能导致智能体任务失败。下一节将讨论智能体的不同失败模式以及如何评估它们。
智能体的失败模式与评估
评估的核心是发现失败。任务越复杂,潜在的失败点就越多。除了第 3 章和第 4 章讨论的所有 AI 应用共有的失败模式之外,智能体还会因规划、工具执行和效率问题而产生独有的失败。有些失败比其他更容易察觉。
评估智能体时,需要识别其失败模式,并衡量每种失败模式出现的频率。
规划失败
规划难度很高,可能以多种方式失败。最常见的规划失败模式是工具使用失败。智能体生成的规划可能包含以下一种或多种错误。
-
无效工具
比如,它生成的方案里调用了
bing_search,但这个工具根本不在工具列表中。 -
工具存在,但参数无效。
比如,调用
lbs_to_kg时传了两个参数,而该函数只需要一个参数lbs。 -
工具存在,参数也正确,但参数值有误
比如,调用
lbs_to_kg时只传了一个参数lbs,但把 lbs 的值写成了 100,而正确值应该是 120。
另一种规划失败模式是目标失败:智能体没能达成目标。可能是因为方案本身无法完成任务,也可能是在满足约束条件方面出了问题。举个例子,你让模型规划一趟从旧金山到印度、为期两周、预算 5000 美元的行程。它可能给你安排一趟去越南的行程,或者虽然安排了从旧金山到印度、为期两周的行程,但花费远超预算。
时间是一个在智能体评估中经常被忽略的常见约束。在很多场景下,智能体耗时长短并不重要——你把任务交给它,等它完成时再查看结果就行。但在另一些场景下,智能体的价值会随着时间推移而下降。比如,你让智能体准备一份基金申请书,结果它在截止日期之后才完成,那这个智能体就没多大用处了。
有一种比较有意思的规划失败模式是由反思错误导致的:智能体深信自己已经完成了任务,实际上并没有。比如,你让它把 50 个人分配到 30 间酒店房间,它可能只安排了 40 个人,却坚持认为任务已经完成。
要评估智能体的规划失败情况,一种做法是构建一个规划数据集,其中每个样本都是一个元组 (task, tool inventory)。针对每个任务,用智能体生成 K 个方案,然后计算以下指标:
- 生成的所有方案中,有多少是有效的?
- 对于某个任务,智能体平均需要生成多少个方案才能得到一个有效的?
- 所有工具调用中,有多少是有效的?
- 调用无效工具的频率是多少?
- 工具有效但参数无效的调用频率是多少?
- 工具有效但参数值错误的调用频率是多少?
工具调用失败
工具调用失败是指虽然选用了正确的工具,但工具的输出有误。一种失败模式是工具本身就给出了错误的结果。例如,图像描述工具返回了错误的描述,或者 SQL 查询生成器生成了错误的 SQL 语句。 如果 agent 只生成高层规划,再由单独的翻译模块把每个规划动作转成可执行命令,那么翻译环节出错也会导致失败。 工具调用失败因工具而异,每个工具都需要独立测试。务必打印出每次工具调用及其输出,方便排查和评估。如果使用了翻译模块,要建立基准来评估它的表现。 要发现"遗漏工具"类的失败,你需要清楚应该使用哪些工具。如果 agent 在某个领域频繁失败,很可能是因为缺少该领域的工具。可以与人类领域专家协作,观察他们会使用哪些工具。效率
agent 也许能用正确的工具生成可行的方案完成任务,但过程可能并不高效。以下是评估 agent 效率时可以关注的几项指标:- agent 平均需要多少步才能完成一个任务?
- agent 平均完成一个任务的成本是多少?
- 每个动作通常耗时多久?是否存在特别耗时或昂贵的动作?
结语
智能体的概念其实并不复杂。智能体由其所处的环境和可调用的工具集合共同定义。在 AI 驱动的智能体中,AI 模型充当大脑,利用工具和环境反馈来规划如何最佳地完成任务。工具的加持让模型能力大幅提升,因此智能体模式的出现是必然的。
虽然"智能体"听起来是个新概念,但它建立在 LLM 早期就广泛使用的诸多技术之上,包括自我反思、思维链和结构化输出等。
本文从概念层面介绍了智能体的工作原理及其各个组成部分。在未来的文章中,我将讨论如何评估智能体框架。
智能体模式常常需要处理超出模型上下文限制的信息。借助记忆系统来补足模型的上下文容量,可以显著增强智能体的能力。鉴于本文篇幅已较长,记忆系统的工作机制将在后续博文中详细探讨。