AI 代理 (AI Agents)

原文:https://huyenchip.com/2025/01/07/agents.html

2025年1月7日 • Chip Huyen

智能代理被许多人视为人工智能的最终目标。由 Stuart Russell 和 Peter Norvig 编写的经典书籍《人工智能:现代方法》(Prentice Hall, 1995)将人工智能研究领域定义为“理性代理的研究与设计”。

基础模型的前所未有的能力开启了以前难以想象的代理型应用的大门。这些新能力终于使我们能够开发出能够作为助手、同事和教练的自主智能代理。它们可以帮助我们创建网站、收集数据、规划旅行、进行市场研究、管理客户账户、自动化数据录入、为面试做好准备、面试候选人、谈判交易等等。这些可能性似乎无穷无尽,而这些代理的潜在经济价值也是巨大的。

本章节将从代理的概述开始,接着探讨决定代理能力的两个方面:工具和规划。由于代理的新操作模式,它们也具有新的失败模式。本章节的最后将讨论如何评估代理以捕捉这些失败。

本文章改编自《人工智能工程》(AI Engineering, 2025)中关于代理的章节,经过少量编辑以使其成为独立文章。


注意事项

  • 基于人工智能的代理是一个新兴领域,目前尚无公认的理论框架来定义、开发和评估它们。本章节尝试从现有文献中构建一个框架,但会随着领域的发展而演变。相较于本书的其他章节,本章节更具实验性。我从早期审阅者那里获得了宝贵的反馈,也希望从本博文的读者那里获得更多反馈。
  • 就在本书出版之前,Anthropic 于 2024 年 12 月发布了一篇关于《构建高效代理》的博客文章(中文翻譯)。我很高兴看到 Anthropic 的文章与我关于代理的章节在概念上是一致的,尽管术语略有不同。然而,Anthropic 的文章专注于孤立的模式,而我的文章则涵盖了事情的运作原理和方法。我还更关注规划、工具选择和失败模式。
  • 本文章包含大量背景信息。如果某些部分显得过于细节化,请随意跳过!

代理概述

“代理”一词已在许多不同的工程领域中使用,包括但不限于软件代理、智能代理、用户代理、对话代理和强化学习代理。那么,究竟什么是代理呢?

代理是任何能够感知其环境并对其环境采取行动的事物。《人工智能:现代方法》(1995)将代理定义为“任何可以通过传感器感知其环境并通过执行器对该环境采取行动的事物”。

这意味着代理的特征由其所运行的环境以及它能够执行的动作集合所决定。

代理的环境由其用途定义。如果开发一个代理来玩游戏(例如《Minecraft》、《围棋》、《Dota》),那么该游戏就是代理的环境。如果您希望一个代理从互联网上抓取文档,那么该环境就是互联网。而自动驾驶汽车代理的环境则是道路系统及其附近区域。

代理可以执行的动作集合由其能访问的工具增强。许多日常交互的基于生成式 AI 的应用实际上是具有工具访问权限的代理,尽管这些工具可能很简单。例如,ChatGPT 是一个代理,它可以搜索网页、执行 Python 代码并生成图像。RAG(检索增强生成)系统也是代理——文本检索器、图像检索器和 SQL 执行器是它们的工具。

代理的环境和工具集合之间存在很强的依赖关系。环境决定了代理可能使用哪些工具。例如,如果环境是国际象棋游戏,那么代理的可能动作仅限于有效的国际象棋移动。然而,代理的工具库存限制了它可以操作的环境。例如,如果一个机器人的唯一动作是游泳,那么它会被限制在水环境中。


图 6-8 展示了一个基于 GPT-4 构建的代理 SWE-agent 的可视化。其环境是计算机的终端和文件系统。它的动作集合包括导航代码库、搜索文件、查看文件以及编辑代码行。


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


AI 代理的任务

AI 代理旨在完成通常由用户提供的任务。在 AI 代理中,AI 是处理任务的大脑,负责规划完成任务所需的动作序列,并确定任务是否已完成。

让我们回到上文提到的通过表格数据的 RAG 系统 Kitty Vogue 的例子。这是一个具有三种动作的简单代理:

  1. 响应生成;
  2. SQL 查询生成;
  3. SQL 查询执行。

假设查询是“预测 Fruity Fedora 在未来三个月的销售收入”。代理可能执行以下动作序列:

  1. 推理如何完成此任务。它可能决定,为了预测未来的销售,它首先需要过去五年的销售数据。代理的推理可以通过中间响应显示出来。
  2. 调用 SQL 查询生成动作,生成获取过去五年销售数据的查询。
  3. 调用 SQL 查询执行动作,执行此查询。
  4. 根据工具输出(SQL 查询执行的结果)进行推理,并判断这些数据是否足以进行销售预测。它可能决定这些数据不足以做出可靠的预测,可能因为数据中有缺失值。然后,它决定还需要过去的营销活动信息。
  5. 调用 SQL 查询生成动作,生成获取过去营销活动信息的查询。
  6. 调用 SQL 查询执行动作。
  7. 推理这些新信息是否足以进行预测。如果足够,它生成预测结果。
  8. 推理任务已成功完成。

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

  1. 复合错误:代理通常需要执行多个步骤来完成任务,当步骤数量增加时,总体准确性会下降。例如,如果模型每步的准确率为 95%,经过 10 步后,准确性会降至 60%;经过 100 步后,准确性仅为 0.6%。
  2. 更高的风险:由于代理可以访问工具,它们能够执行更有影响力的任务,但任何失败都可能导致更严重的后果。

代理在复杂任务中可能耗费大量时间和金钱。常见的抱怨是代理只会浪费 API 额度。然而,如果代理能够实现自主性,它们可以节省人类时间,从而使其成本变得值得。

考虑到一个环境,代理在其中的成功取决于可访问的工具以及其 AI 规划器的强大程度。接下来,我们将探讨模型可以使用的不同类型的工具,并分析 AI 的规划能力。


工具 (Tools)

一个系统不需要访问外部工具也可以是代理。然而,如果没有外部工具,代理的能力会受到限制。单靠模型本身通常只能执行一种动作——例如,LLM(大型语言模型)可以生成文本,而图像生成模型可以生成图像。外部工具能够让代理的能力大幅提升。

工具帮助代理既能感知环境,也能作用于环境。允许代理感知环境的动作是只读动作,而允许代理对环境采取行动的动作是写入动作

代理可以访问的工具集合称为其工具库存(tool inventory)。由于工具库存决定了代理可以做什么,因此需要仔细考虑给代理提供哪些工具以及提供多少工具。更多的工具可以赋予代理更多的能力。然而,工具越多,就越难理解并有效利用它们。实验是找到合适工具集合的必要方法,这将在后续的“工具选择”部分中讨论。

根据代理的环境,有多种可能的工具。以下是你可能需要考虑的三类工具:

  1. 知识增强(knowledge augmentation,即上下文构建);
  2. 能力扩展(capability extension
  3. 让代理能够对环境采取行动的工具(tools that let your agent act upon its environment

知识增强

希望通过本书,你已经认识到上下文对于模型响应质量的重要性。一类重要的工具是那些能够增强代理知识的工具。其中一些工具之前已经讨论过,例如文本检索器、图像检索器和 SQL 执行器。其他潜在工具包括:内部人员搜索、返回不同产品状态的库存 API、Slack 内容检索、电子邮件阅读器等。

许多此类工具通过整合组织的私有流程和信息增强模型。然而,工具也可以让模型访问公共信息,尤其是来自互联网的信息。

网页浏览是最早被整合进 ChatGPT 的功能之一,也是最受期待的能力之一。网页浏览可以防止模型“过时”。当模型的训练数据落后于当前信息时,模型就会变得过时。如果模型的训练数据截止于上周,它将无法回答需要本周信息的问题,除非这些信息通过上下文提供。如果没有网页浏览功能,模型将无法告诉你天气、新闻、即将发生的事件、股票价格或航班状态等信息。

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

尽管网页浏览可以让代理参考最新信息、生成更好的响应并减少幻觉(hallucination),它也可能让代理暴露在互联网上的“污秽之地”。因此,选择互联网 API 时需谨慎。


能力扩展

你可能还需要考虑一些工具,以弥补 AI 模型的固有局限性。使用这些工具是提升模型性能的简单方法。例如,AI 模型以数学能力差而臭名昭著。如果你问模型“199,999 除以 292 等于多少?”,很可能它会答错。然而,如果模型有一个计算器,这种计算将变得微不足道。与其试图训练模型擅长算术,不如直接给模型提供一个工具,这更高效。

其他简单但能显著增强模型能力的工具包括:日历、时区转换器、单位转换器(例如从磅到千克)、以及翻译工具(用于处理模型不擅长的语言)。

更复杂但更强大的工具是代码解释器。与其训练模型理解代码,不如直接让它访问一个代码解释器。代码解释器可以执行代码片段、返回结果或分析代码失败的原因。这种能力使得代理可以充当编码助手、数据分析师,甚至是研究助手,能够编写代码来运行实验并报告结果。然而,自动代码执行会带来代码注入攻击的风险(在第 5 章“防御性 Prompt 工程”部分讨论过)。采取适当的安全措施对于保护你自己和用户至关重要。

工具还能将一个仅支持文本或图像的模型转变为多模态模型。例如,一个只能生成文本的模型可以利用一个文本到图像的模型作为工具,从而生成文本和图像。代理的 AI 规划器根据请求决定调用文本生成、图像生成或两者。这就是 ChatGPT 能够生成文本和图像的工作原理——它使用 DALL-E 作为图像生成器。

代理还可以使用代码解释器生成图表和图形,使用 LaTeX 编译器呈现数学公式,或使用浏览器将 HTML 代码渲染为网页。同样,仅能处理文本输入的模型可以使用图像描述工具处理图像,使用转录工具处理音频,或者使用 OCR(光学字符识别)工具读取 PDF 文件。

与单纯的 Prompt 或微调相比,工具的使用可以显著提升模型性能。例如,Chameleon(Lu 等,2023 年)表明,增强了 13 种工具的 GPT-4 代理在多个基准测试中表现优于单独的 GPT-4。这个代理使用的工具包括知识检索、查询生成器、图像描述器、文本检测器和 Bing 搜索。

在 ScienceQA(一个科学问答基准测试)上,Chameleon 将最佳的少样本结果提高了 11.37%。在 TabMWP(一个表格数学问题基准测试)上,Chameleon 将准确率提高了 17%。


写入动作

到目前为止,我们讨论的都是允许模型从数据源读取的只读动作。但工具还可以执行写入动作,对数据源进行更改。例如,SQL 执行器可以检索数据表(读取)并更改或删除表(写入)。电子邮件 API 可以读取电子邮件,也可以回复电子邮件。银行 API 可以检索当前余额,也可以发起银行转账。

写入动作让系统能够做更多事情。例如,它可以让你自动化整个客户外联工作流:研究潜在客户、找到他们的联系方式、撰写电子邮件、发送首封邮件、阅读回复、跟进、提取订单、将新订单更新到数据库等。

然而,赋予 AI 自动改变我们生活的能力是令人恐惧的。就像你不会允许实习生删除生产数据库一样,你也不应该允许不可靠的 AI 发起银行转账。信任系统的能力及其安全措施至关重要。你需要确保系统受到保护,免受试图操纵它以执行有害操作的恶意行为者的攻击。

代理与安全性

每当我向一群人谈论自主 AI 代理时,总会有人提到自动驾驶汽车。“如果有人入侵汽车并绑架你怎么办?”虽然自动驾驶汽车的例子因为其物理性而显得更令人感同身受,但 AI 系统即使没有物理存在,也可能造成伤害。它可以操纵股市、窃取版权、侵犯隐私、强化偏见、传播虚假信息和宣传等,在第 5 章“防御性 Prompt 工程”部分中已经讨论过。

这些担忧都很合理,任何希望利用 AI 的组织都需要认真对待安全性。然而,这并不意味着 AI 系统永远不应该被赋予现实世界中的行动能力。如果我们可以信任机器将我们送上太空,我希望有一天,我们的安全措施将足够完善,使我们能够信任自主 AI 系统。此外,人类也会犯错。就我个人而言,我更愿意相信一辆自动驾驶汽车,而不是一个陌生人来搭载我。


正如工具可以让人类极大地提高效率——你能想象没有 Excel 的商业运作,或没有起重机的摩天大楼建设吗?——工具也能让模型完成更多任务。

许多模型提供商已经支持工具调用功能,这通常被称为“函数调用”(Function Calling)。展望未来,支持一组广泛工具的函数调用功能很可能会成为大多数模型的常见特性。


规划 (Planning)

在基础模型代理中,核心是负责解决用户任务的模型。一个任务由目标和约束定义。例如,一个任务可能是“安排从旧金山到印度的两周旅行,预算为 5,000 美元”。目标是两周的旅行,约束是预算。

复杂任务需要规划。规划过程的输出是一个计划,即完成任务所需步骤的路线图。有效的规划通常要求模型理解任务、考虑完成任务的不同选项,并选择最有前景的方案。

如果你曾参加过任何规划会议,你就知道规划是困难的。作为一个重要的计算问题,规划已经被深入研究,可能需要几卷书籍来覆盖所有内容。在这里,我只能简单探讨这一主题。


规划概述

面对一个任务,有许多可能的解决方法,但并非所有方法都能成功。此外,在正确的解决方案中,有些解决方案比其他的更高效。例如,考虑以下查询:“有多少家没有收入的公司筹集了至少 10 亿美元?”以下是两种可能的解决方案:

  1. 找出所有没有收入的公司,然后筛选出筹集了至少 10 亿美元的公司;
  2. 找出所有筹集了至少 10 亿美元的公司,然后筛选出没有收入的公司。

第二种方法更高效。没有收入的公司数量远远多于筹集了 10 亿美元的公司。在这两种方法中,一个智能代理应该选择第二种方法。


你可以在同一个 Prompt 中结合规划与执行。例如,你给模型一个 Prompt,让它逐步思考(类似链式思考提示 Chain-of-Thought Prompt),然后在一个 Prompt 中执行所有步骤。但如果模型提出了一个 1,000 步的计划,最终却无法完成目标怎么办?如果没有监督,代理可能会运行这些步骤好几个小时,浪费时间和金钱(例如 API 调用费用),直到你意识到它毫无进展。

为了避免无意义的执行,应该将规划与执行分离。你可以让代理首先生成一个计划,并且仅在该计划被验证后才执行。计划可以通过启发式算法进行验证。例如,一个简单的启发式方法是排除包含无效动作的计划。如果生成的计划需要 Google 搜索,但代理没有访问 Google 搜索的权限,那么这个计划就是无效的。另一个简单的启发式方法是排除所有超过 X 步的计划。

计划还可以通过 AI 评审员进行验证。你可以让模型评估计划是否合理,或者如何改进计划。

如果生成的计划被评估为不佳,你可以要求规划器生成另一个计划。如果计划被评估为良好,那么就执行计划。

如果计划涉及外部工具,将调用函数(Function Calling)。执行计划的输出也需要被再次评估。需要注意的是,生成的计划不必是整个任务的端到端计划。它可以是某个子任务的小计划。整个过程如图 6-9 所示。

图 6-9:将规划与执行分离,仅执行已验证的计划


你的系统现在包含三个组件:一个用于生成计划,一个用于验证计划,另一个用于执行计划。如果将每个组件视为一个代理,这可以被视为一个多代理系统。由于大多数代理工作流都足够复杂,需要多个组件,因此大多数代理实际上是多代理系统。

为了加快流程,你可以同时生成多个计划,并让评估器选择最有前景的那个计划。这是另一种延迟与成本的权衡,因为同时生成多个计划会增加额外的成本。


规划需要理解任务意图

规划的核心是理解任务背后的意图:用户希望通过这个查询实现什么?意图分类器(Intent Classifier)通常用于帮助代理进行规划。正如第 5 章“将复杂任务分解为简单子任务”部分所示,意图分类可以通过另一个 Prompt 或专门为此任务训练的分类模型完成。在你的多代理系统中,意图分类机制本身可以被视为另一个代理。

了解意图可以帮助代理选择正确的工具。例如,在客户支持任务中,如果查询是关于账单的,代理可能需要访问一个工具以检索用户的最近付款记录。但如果查询是关于如何重置密码的,代理可能需要访问文档检索工具。

小提示:某些查询可能超出代理的能力范围。意图分类器应该能够将这些请求分类为“无关”(IRRELEVANT),这样代理可以礼貌地拒绝,而不是浪费计算资源试图提供不可能的解决方案。

到目前为止,我们假设代理自动化了规划、验证和执行这三个阶段。实际上,人类可以在任意阶段参与,以帮助流程并降低风险。

  • 人类参与规划:对于代理无法生成完整计划的复杂任务,人类专家可以提供高层计划,供代理扩展。
  • 人类验证计划:如果计划涉及高风险操作,例如更新数据库或合并代码更改,系统可以要求明确的人类批准,或将操作交由人类执行。
  • 定义自动化级别:为了实现这一点,你需要清楚地定义代理对每个动作的自动化级别。

任务解决过程总结

解决一个任务通常包括以下流程:

  1. 计划生成:为完成任务生成一个计划。计划是可管理动作的序列,因此这一过程也被称为任务分解(Task Decomposition)。
  2. 反思与错误修正:评估生成的计划。如果计划不佳,则生成一个新计划。
  3. 执行:按照生成的计划采取行动。这通常涉及调用特定函数。
  4. 反思与错误修正:在收到执行结果后,评估这些结果并确定目标是否已完成。识别并纠正错误。如果目标尚未完成,则生成一个新计划。

你已经在本书中看到了一些生成计划和思考的技巧。当你要求一个模型 "一步一步地思考 "时,你就是在要求它分解任务。当你要求一个模型 "验证你的答案是否正确 "时,你就是在要求它进行反思。


基础模型作为规划器 (Foundation Models as Planners)

一个开放的问题是,基础模型在规划方面的表现如何。许多研究人员认为,至少基于自回归语言模型的基础模型并不擅长规划。例如,Meta 的首席 AI 科学家 Yann LeCun 在 2023 年明确表示,自回归 LLM 无法进行规划

尽管有许多关于 LLM 规划能力较差的轶事证据,但目前尚不清楚这是因为我们尚未找到正确使用 LLM 的方法,还是因为 LLM 本质上无法进行规划。

从本质上来说,规划是一个搜索问题。你需要在通往目标的不同路径中进行搜索,预测每条路径的结果(奖励),并选择最有前景的路径。有时你可能会发现没有任何路径能够到达目标。

搜索通常需要回溯(backtracking。例如,假设你处在一个步骤中,有两个可能的动作:A 和 B。如果采取动作 A 后进入了一个不理想的状态,你需要回溯到之前的状态并选择动作 B。

一些人认为,自回归模型只能生成前向动作(forward actions,而无法回溯以生成替代动作。因此,他们得出结论,自回归模型无法进行规划。然而,这并不完全正确。在执行了包含动作 A 的路径后,如果模型确定这条路径不合理,它可以通过修改路径来选择动作 B,从而实现某种形式的“回溯”。此外,模型还可以完全重新开始规划并选择另一条路径。

也有可能是因为我们没有给 LLM 提供足够的工具支持,导致其规划能力较弱。要进行规划,不仅需要了解可用的动作,还需要知道每个动作的潜在结果。例如,假设你想爬上一座山。可能的动作包括向右转、向左转、掉头或向前走。然而,如果向右转会导致你掉下悬崖,你可能就不会选择这个动作。在技术术语中,一个动作会将你从一个状态带到另一个状态,因此了解动作的结果状态是决定是否采取该动作的必要条件。

这意味着,仅仅提示模型生成一系列动作(如流行的链式思维提示技术 Chain-of-Thought Prompting 所做的那样)是不够的。论文《Reasoning with Language Model is Planning with World Model》(Hao 等,2023 年)认为,LLM 包含了大量关于世界的信息,因此能够预测每个动作的结果。这样的 LLM 可以通过整合结果预测来生成一致的计划。

即使 AI 不能独立完成规划,它仍然可以成为规划的一部分。我们可以通过为 LLM 添加搜索工具和状态跟踪系统来增强其规划能力。


基础模型(FM)与强化学习(RL)规划器的比较

代理是强化学习(Reinforcement Learning, RL)的核心概念之一。根据维基百科,RL 被定义为“研究智能代理如何在动态环境中采取行动以最大化累积奖励的领域”。

RL 代理和 FM 代理在许多方面是相似的:它们都由其环境和可能的动作定义。然而,它们的规划器工作方式不同:

  1. RL 代理

    • 规划器由 RL 算法训练而成。
    • 训练这个 RL 规划器可能需要大量时间和资源。
  2. FM 代理

    • 模型本身就是规划器。
    • 模型可以通过提示或微调来提高其规划能力,通常需要更少的时间和资源。

尽管如此,没有什么能够阻止 FM 代理通过整合 RL 算法来提高性能。我猜测,从长远来看,FM 代理和 RL 代理可能会融合。


计划生成 (Plan Generation)

最简单的将模型转变为计划生成器的方法是通过提示工程(Prompt Engineering)。假设你希望创建一个代理,帮助客户了解 Kitty Vogue 的产品。你为这个代理提供了三个外部工具:按价格检索产品、检索热门产品,以及检索产品信息。以下是一个用于生成计划的提示示例(仅供说明,实际生产环境中的提示可能更复杂):

系统提示

提出解决任务的计划。你可以使用以下 5 个动作:

  • 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)

计划必须是有效动作的序列。

示例
任务:“告诉我关于 Fruity Fedora 的信息”
计划:[fetch_product_info, generate_query, generate_response]

任务:“上周最畅销的产品是什么?”
计划:[fetch_top_products, generate_query, generate_response]

任务:{用户输入}
计划:

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

  • 这里使用的计划格式——由代理推断出参数的函数列表——只是结构化代理控制流的众多方法之一。
  • 生成查询(generate_query)函数利用任务当前的历史记录和最新的工具输出来生成一个查询,并输入到响应生成器中。每一步的工具输出都会添加到任务的历史记录中。

生成的计划可能如下所示(用户输入为“上周最畅销的产品的价格是多少?”):

1. get_time()
2. fetch_top_products()
3. fetch_product_info()
4. generate_query()
5. generate_response()

你可能会问:“这些函数所需的参数呢?”确切的参数通常很难预先确定,因为它们往往需要从之前的工具输出中提取。例如,如果第一步 get_time() 输出“2030-09-13”,代理可以推断下一步的参数如下:

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

然而,某些情况下,获取函数参数的完整信息可能会不足。例如,用户的问题是“畅销产品的平均价格是多少?”,那么以下问题可能尚未明确:

  1. 用户希望查看多少个畅销产品?
  2. 用户是想查看上周、上月还是所有时间的畅销产品?

这意味着模型经常需要做出猜测,而这些猜测可能是错误的。

由于动作序列和相关参数均由 AI 模型生成,因此可能会出现幻觉(hallucination)。幻觉可能导致模型调用无效的函数,或者使用错误的参数调用有效的函数。

提高代理规划能力的技巧

为了让代理更擅长规划,可以尝试以下方法:

  1. 改进系统提示:通过提供更多高质量的示例来优化提示设计。
  2. 提供更好的工具描述:清楚地描述工具的功能及其参数,这样模型可以更好地理解如何使用它们。
  3. 简化函数设计:将复杂的函数拆分为更简单的小函数,例如将一个复杂的函数分解为两个功能更明确的子函数。
  4. 使用更强大的模型:通常,性能更强的模型在规划方面表现得更好。
  5. 微调模型以生成计划:通过专门的训练数据微调模型,使其更擅长生成计划。

函数调用 (Function Calling)

许多模型提供商已经支持通过函数调用(function calling)来使用工具,实际上将模型转变成了代理。工具本质上是一种函数,因此调用工具可以被视为函数调用。不同的模型 API 工作方式有所不同,但函数调用通常遵循以下步骤:

  1. 创建工具库存(tool inventory):声明所有可能让模型使用的工具。每个工具都需要描述其执行入口(例如函数名称)、参数以及文档(例如函数的功能及其所需的参数)。
  2. 指定工具的使用范围:为每个查询指定代理可以使用的工具列表。
    • 有些 API 提供了进一步控制工具使用的选项:
      • 必需(required):模型必须至少使用一个工具。
      • 禁止(none):模型不应使用任何工具。
      • 自动(auto):模型自行决定是否使用工具。

以下是一个函数调用的示例。为更具普遍性,此示例用伪代码表示,可适用于多个 API。若需使用特定 API,请参考相关文档。

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

给定查询后,如图 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) 并使用其输出为用户生成最终响应。

提示:始终检查参数值

在处理代理时,要求系统报告每次函数调用所使用的参数值。检查这些参数值以确保它们是正确的。


规划粒度 (Planning Granularity)

一个计划是完成任务所需步骤的路线图,而路线图可以具有不同的粒度(granularity)。例如,要规划一年的工作,按季度制定计划属于更高层级的规划,而按月或按周制定计划则属于较低层级的规划。

规划与执行的权衡
  • 详细计划:更难生成,但执行起来更容易。
  • 高层计划:更容易生成,但执行起来更复杂。

为了解决这一权衡,可以采用分层规划的方法。首先使用一个规划器生成高层计划(例如按季度规划)。然后,对于每个季度,使用相同或不同的规划器生成更具体的计划(例如按月规划)。

自然语言与函数名称的规划

目前的示例中,生成的计划使用了具体的函数名称,这种方式非常细粒度。然而,代理的工具库存可能会随着时间发生变化。例如,获取当前日期的函数 get_time() 可能会被重命名为 get_current_time()。当工具发生变化时,需要更新提示和所有示例。此外,使用具体函数名称还会让规划器在不同的应用场景中难以复用。

为避免这一问题,计划也可以以更自然的语言生成,这种方式比使用领域特定的函数名称更高层。例如,针对查询“上周最畅销产品的价格是多少”,代理可以生成如下计划:

1. get current date 获取当前日期
2. retrieve the best-selling product last week 检索上周的畅销产品
3. retrieve product information 检索产品信息
4. generate query 生成查询
5. generate response 生成响应

使用自然语言生成计划可以让规划器对工具 API 的变化更具鲁棒性。如果模型主要接受自然语言训练,它通常更擅长生成自然语言计划,并且不容易出现幻觉问题。

自然语言计划的缺点是,需要一个翻译器将每个自然语言动作翻译为可执行的命令(函数调用)。Chameleon(Lu 等,2023 年)将这种翻译器称为“程序生成器”(program generator)。不过,翻译任务比规划任务简单得多,通常可以由性能较弱的模型完成,且幻觉风险较低。


复杂计划 (Complex Plans)

迄今为止的计划示例都是按顺序执行的:计划中的下一个操作总是在前一个操作完成后执行。执行操作的顺序称为控制流。顺序形式只是控制流的一种。其他类型的控制流包括并行、if 语句和 for 循环。下面的列表提供了每种控制流的概述,包括顺序控制流,以供比较:

  • 顺序(Sequential)

在任务A完成后执行任务B,可能是因为任务B依赖于任务A。例如,SQL 查询只有在从自然语言输入翻译后才能执行。

  • 并行(Parallel)

同时执行任务 A 和任务 B。例如,给定查询 "为我查找 100 美元以下最畅销的产品",代理可能首先检索前 100 种最畅销的产品,然后检索每种产品的价格。

  • 如果语句(If statement)

根据上一步的输出执行任务 B 或任务 C。例如,代理首先检查英伟达公司的收益报告。根据这份报告,它可以决定卖出或买入英伟达股票。Anthropic 的文章称这种模式为 "路由"。

  • 循环

重复执行任务 A,直到满足特定条件。例如,不断生成随机数,直到出现质数。

图 6-11 展示了不同计划执行顺序的示例,包括顺序执行、并行执行、条件语句和循环语句

在传统软件工程中,控制流程的条件是精确的。而在基于 AI 的代理中,控制流程由 AI 模型决定。非顺序控制流程的计划比顺序计划更难生成,也更难翻译为可执行的命令。

在评估代理框架时,检查其支持哪些控制流程。例如,如果系统需要浏览 10 个网站,它是否可以同时进行?并行执行可以显著减少用户感知的延迟。


反思与错误修正 (Reflection and Error Correction)

即使是最好的计划,也需要不断调整和评估,以最大化成功的可能性。尽管反思不是代理运行的必要条件,但它是代理成功的关键。

反思可以在任务过程中的多个阶段进行:

  1. 接收用户查询后:评估请求是否可行。
  2. 生成初始计划后:评估计划是否合理。
  3. 每一步执行后:评估是否在正确的轨道上。
  4. 完成整个计划后:判断任务是否完成。

反思与错误修正密切相关。反思能够生成洞察,帮助发现需要修正的错误。

反思可以通过同一个代理实现,使用自我批评提示(self-critique prompts)。也可以通过一个独立的组件来完成,例如一个专门的评分器(scorer),输出每个结果的具体分数。

ReAct(Yao 等,2022 年)首次提出的“推理与行动交替进行”模式已经成为代理的常见模式。Yao 等人将“推理”定义为包括规划和反思。在每一步中,代理被要求解释其思路(规划),采取行动,然后分析观察结果(反思),直到代理认为任务完成。代理通常通过示例提示,生成以下格式的输出:

思考 1: …  
行动 1: …  
观察 1: …  

[重复上述步骤,直到反思认为任务完成]  

思考 N: …  
行动 N: 完成 [对查询的响应]  

下图是图6-12,展示了一个遵循 ReAct 框架的代理如何回答来自 HotpotQA(Yang 等,2018 年)的多跳问题回答基准测试中的问题。


多代理反思实现

你可以在多代理设置中实现反思:一个代理负责规划和采取行动,另一个代理负责在每个步骤或若干步骤后评估结果。

如果代理的响应未能完成任务,可以提示代理反思为何失败以及如何改进。根据反思建议,代理生成一个新计划。这种方式让代理可以从错误中学习。

例如,对于代码生成任务,一个评估器可能会发现生成的代码未能通过三分之一的测试用例。代理随后反思失败的原因,例如它可能没有考虑到数组中所有数字均为负数的情况。随后,代理生成新的代码,考虑到所有为负数的数组。

这是 Reflexion(Shinn 等,2023 年)采用的方法。在该框架中,反思分为两个模块:一个评估器,用于评估结果;另一个自我反思模块,用于分析问题出在哪里。图 6-13 展示了 Reflexion 代理的操作示例。作者使用“轨迹”(trajectory)一词来指代计划。在每一步之后,经过评估和自我反思,代理会提出一个新的轨迹。

与计划生成相比,反思相对容易实现,并能带来显著的性能提升。这种方法的缺点主要在于延迟和成本。生成每一步的思考、观察和行动可能会消耗大量的 token,从而增加成本和用户感知的延迟,尤其是对于包含许多中间步骤的任务。为了引导代理遵循特定格式,ReAct 和 Reflexion 的作者在提示中使用了大量的示例。这增加了输入 token 的计算成本,同时减少了可以容纳其他信息的上下文空间。


工具选择 (Tool Selection)

由于工具在任务的成功中经常扮演关键角色,选择工具需要仔细考虑。代理的工具选择不仅取决于环境和任务,还取决于支持代理的 AI 模型。

工具选择的挑战

没有一种万无一失的方法可以选择最适合的工具集合。当前关于代理的文献包含了各种工具库存的案例。例如:

  • Toolformer(Schick 等,2023 年)微调了 GPT-J 来学习使用 5 种工具。
  • Chameleon(Lu 等,2023 年)使用了 13 种工具。
  • Gorilla(Patil 等,2023 年)尝试提示代理从 1,645 个 API 调用中选择正确的 API。

更多工具可以赋予代理更强的能力。然而,工具越多,代理高效使用它们的难度就越高。这种情况类似于人类使用工具:掌握一大堆工具比掌握少量工具更难。此外,添加更多工具也意味着工具描述会变长,可能无法完全适应模型的上下文窗口。


选择工具的实验方法

像构建 AI 应用中的许多决策一样,工具选择需要通过实验和分析找到最佳选择。以下是一些方法可以帮助你做出决定:

  1. 比较不同工具集合的效果:测试代理在不同工具组合下的表现。
  2. 进行消融研究:观察移除某个工具后,代理性能的下降程度。如果移除某个工具不会导致性能下降,可以考虑将其从库存中删除。
  3. 分析错误频发的工具:查找代理经常出错的工具。如果某个工具对代理来说太难使用(即使经过大量提示优化或微调仍无法正确使用),考虑更换为更简单的工具。
  4. 绘制工具调用分布:查看哪些工具使用频率较高,哪些工具使用频率较低。图 6-14 展示了 GPT-4 和 ChatGPT 在 Chameleon(Lu 等,2023 年)实验中的工具使用模式差异。


工具使用模式的差异

实验表明,不同任务需要的工具不同,不同模型对工具的偏好也不同。例如:

  • ScienceQA(科学问答任务)更依赖于知识检索工具。
  • TabMWP(表格数学问题任务)则对数学相关工具的依赖更强。
  • GPT-4 使用的工具集合更广,而 ChatGPT 更倾向于图像描述工具,而 GPT-4 更倾向于知识检索工具。
提示:评估工具支持

在评估代理框架时,检查其支持的规划器和工具种类。不同框架可能专注于不同类别的工具。例如,AutoGPT 主要支持社交媒体 API(如 Reddit、X 和 Wikipedia),而 Composio 则专注于企业 API(如 Google Apps、GitHub 和 Slack)。

随着需求的变化,你可能需要添加新工具,因此评估代理扩展工具的难易程度至关重要。

正如人类不仅通过使用工具变得高效,还通过从简单工具中创造出更强大的工具,AI 也有可能从其初始工具中创造新工具。例如:

  • 工具迁移(Tool Transition):Chameleon(Lu 等,2023 年)提出了研究工具迁移的概念。例如,工具 X 之后调用工具 Y 的可能性有多大?图 6-15 展示了工具迁移树。如果两个工具经常一起使用,它们可以被组合成一个更大的工具。如果代理能够意识到这些信息,它本身就能将初始工具组合起来,持续构建更复杂的工具。

  • 技能管理器(Skill Manager)Voyager(Wang 等,2023 年)提出了技能管理器的概念,用于跟踪代理新获得的技能(即工具),以便后续重用。每项技能都是一个代码程序。当技能管理器确定某项新技能有用时(例如,它成功帮助代理完成了一项任务),就将其添加到技能库中(类似于工具库存)。这些技能可以在其他任务中被调用使用。

正如前文所述,代理在环境中的成功取决于其工具库存和规划能力。两者中任一方面的缺陷都会导致代理失败。下一节将讨论代理的失败模式以及如何评估代理的性能。


代理的失败模式 (Failure Modes of Agents)

代理的强大能力开启了许多以前难以实现的可能性,但这些能力也带来了新的失败模式。这些失败模式可能导致性能下降、用户体验不佳,甚至带来安全风险。因此,理解这些失败模式并设计适当的评估方法是开发和部署代理的关键部分。


代理的常见失败模式
  1. 规划失败

    • 目标未对齐:代理生成的计划未能实现用户的目标。例如,用户询问“找到过去五年中最畅销的三款产品”,代理却只返回了最近一年的畅销产品。
    • 计划不完整:代理生成的计划缺少关键步骤,导致任务无法完成。例如,代理在提取数据后未生成最终的总结报告。
    • 计划冗长或不必要:代理生成的计划包含多余的步骤,浪费时间或资源。例如,代理在已经获取所需数据后仍调用不必要的工具。
  2. 工具调用失败

    • 工具选择错误:代理选择了不适合当前任务的工具。例如,用户询问“将 40 磅转换为千克”,但代理错误地选择了一个日期格式化工具。
    • 参数错误:代理为工具提供了无效或不完整的参数。例如,调用 fetch_product_info(product_name) 时未提供产品名称。
    • 工具输出未正确解析:代理未能正确解释工具的输出,从而导致接下来的步骤出错。例如,代理从数据库中检索了数据,但未能解析返回的 JSON 格式,导致后续任务失败。
  3. 反思失败

    • 未能检测到错误:代理未能意识到计划或执行过程中的错误。例如,代理返回了错误的数据,但未意识到结果有问题。
    • 错误的自我修正:代理意识到计划失败,但未能生成正确的替代计划。例如,代理在发现数据不完整时,生成了一个重复调用相同工具的计划,而不是尝试其他方法。
  4. 环境交互失败

    • 环境变化未适应:代理未能适应环境的变化。例如,代理尝试访问一个已经被修改或删除的 API。
    • 未能处理动态输入:代理在面对动态或不确定的环境输入时表现不佳。例如,代理在处理用户提出的模糊问题时未能生成解释性问题来澄清意图。
  5. 成本或延迟问题

    • 过度调用工具:代理调用工具的次数过多,导致高昂的 API 成本。
    • 长时间延迟:代理生成计划或执行任务所需时间过长,导致用户体验不佳。例如,代理在尝试生成一个复杂报告时耗费了数分钟,而用户期望几秒内完成。
  6. 安全与伦理问题

    • 工具误用:代理未能正确限制对敏感工具的访问。例如,代理错误地尝试删除用户数据。
    • 偏见输出:代理生成带有偏见或不适当内容的计划与结果。例如,代理在回答某些用户查询时引入了社会或文化偏见。
    • 恶意利用:代理被恶意用户利用,执行了有害任务。例如,代理被提示生成垃圾邮件或试图访问未经授权的资源。

计划失败的另一种模式是目标失败:代理未能实现目标。这可能是因为计划没有解决任务,或者解决任务时没有遵循约束条件。为了说明这一点,假设你要求模型计划一次从旧金山到印度的两周旅行,预算为 5,000 美元。代理可能会为你计划一次从旧金山到越南的旅行,也可能会为你计划一次从旧金山到印度的两周旅行,而这将使你的花费远远超出预算。

在对旅行社进行评估时,经常忽略的一个限制因素是时间。在许多情况下,代理所花费的时间并不那么重要,因为您可以将任务分配给代理,只需在任务完成后检查即可。然而,在许多情况下,随着时间的推移,代理的作用会越来越小。例如,如果您要求代理人准备一份拨款建议书,而代理人在拨款截止日期之后才完成,那么代理人的作用就不大。

一种有趣的计划失败模式是由反思错误造成的。代理坚信自己已经完成了一项任务,但实际上并没有。例如,你要求代理将 50 人分配到 30 个酒店房间。代理可能只分配了 40 人,并坚持认为任务已经完成。

要评估代理的计划失败率,一种方法是创建一个计划数据集,其中每个示例都是一个元组(任务、工具清单)。对于每个任务,使用代理生成 K 个计划。计算以下指标:

  1. 在所有生成的计划中,有多少是有效的?
  2. 对于给定任务,代理需要生成多少计划才能获得有效计划?
  3. 在所有工具调用中,有多少次是有效的?
  4. 无效工具的调用频率是多少?
  5. 使用无效参数调用有效工具的频率是多少?
  6. 使用错误参数值调用有效工具的频率是多少?

分析代理的输出模式。代理在哪类任务上失败较多?你有假设原因吗?模型经常在哪些工具上出错?有些工具对代理来说可能比较难用。您可以通过更好的提示、更多的示例或微调来提高代理使用高难度工具的能力。如果所有方法都不奏效,您可以考虑将该工具换成更容易使用的工具。

工具故障

当使用的工具正确,但工具输出错误时,就会出现工具故障。其中一种故障模式是工具输出错误。例如,图像标题器返回错误的描述,或 SQL 查询生成器返回错误的 SQL 查询。

如果代理只生成高级计划,而翻译模块参与将每个计划行动翻译为可执行命令,则可能因翻译错误而发生故障。

工具故障与工具有关。每个工具都需要独立测试。一定要将每次工具调用及其输出打印出来,以便检查和评估。如果您有翻译器,请创建基准对其进行评估。

检测工具失效需要了解应该使用哪些工具。如果您的代理经常在某个特定领域出现故障,这可能是因为它缺少该领域的工具。与人类领域专家合作,观察他们会使用哪些工具。


代理评估 (Evaluating Agents)

AI 代理的评估比传统机器学习模型的评估更复杂,因为代理不仅需要生成正确的结果,还需要在生成结果的过程中表现出合理性和可靠性。此外,代理通常需要处理动态环境,并与外部工具交互,这使得评估代理更加困难。

以下是几个关键的代理评估维度:

1. 任务完成度

任务完成度评估代理是否成功完成了用户请求的任务。这是代理性能的核心指标。

  • 成功率:代理成功完成任务的比例。例如,在 100 个任务中,代理完成了 85 个,则成功率为 85%。
  • 错误分类:具体记录任务失败的原因,例如工具调用失败、计划错误、反思错误等。

示例:在一个客户支持场景中,代理被要求回答 100 个常见问题。如果代理正确回答了 90 个问题,则成功率为 90%。剩下的 10 个问题可以进一步分类为“计划错误”(3 个)、“工具调用失败”(5 个)和“反思失败”(2 个)。


2. 计划质量

计划质量评估代理生成的计划是否合理、准确且高效。

  • 计划准确性:计划是否实现了用户的目标。
  • 计划效率:计划是否包含多余的步骤或不必要的工具调用。
  • 计划鲁棒性:计划是否能够适应环境中的变化,例如工具调用失败后是否能够生成替代计划。

示例:代理生成了一个 10 步的计划来完成一个任务。如果任务可以通过 5 步完成,则计划效率较低。


3. 工具使用

工具使用评估代理调用工具的正确性和有效性。

  • 工具选择准确率:代理选择正确工具的频率。
  • 参数准确率:代理为工具提供正确参数的频率。
  • 工具调用效率:代理调用工具的次数是否合理,是否存在不必要的调用。

示例:在一个支持多种 API 的环境中,代理调用了 50 次工具,其中 45 次选择了正确工具,则工具选择准确率为 90%。


4. 用户体验

用户体验评估代理在实际使用中的表现,包括响应时间、可解释性和交互流畅性。

  • 响应时间:代理完成任务的速度是否符合用户预期。
  • 可解释性:代理是否能够清楚地解释其计划和每一步的执行结果。
  • 交互性:代理是否能够有效处理用户的澄清或修改请求。

示例:一个代理在生成复杂计划时耗时 10 秒,但用户期望 3 秒内完成,这表明响应时间需要优化。


5. 安全与伦理性

安全与伦理性评估代理是否在执行任务时遵循安全和道德标准。

  • 安全性:代理是否能够避免误用敏感工具或泄露用户数据。
  • 偏见评估:代理生成的结果是否包含偏见或不适当的内容。
  • 用户保护:代理是否能够识别和拒绝有害或恶意请求。

示例:一个代理在用户尝试访问私人数据时正确地拒绝了请求,这表明其安全性功能表现良好。


代理评估方法 (Evaluation Methods)

  1. 模拟测试

    • 在受控环境中测试代理的性能,例如使用预定义的任务和工具调用场景。
    • 优点:易于比较代理的表现;可以控制评估中的变量。
    • 缺点:可能无法反映真实环境中的复杂性。
  2. 真实用户测试

    • 在真实场景中测试代理的性能,例如部署在客户支持系统中并记录用户的反馈。
    • 优点:能够捕捉代理在真实环境中的表现。
    • 缺点:评估过程可能较慢,且需要处理真实用户的反馈。
  3. 混合测试

    • 结合模拟测试和真实用户测试。例如,可以在部署前使用模拟测试进行初步筛选,然后在小范围真实用户中进行试点测试。
  4. 自动化评估工具

    • 开发自动化工具来监控代理的性能,例如记录工具调用日志、计划生成时间、任务完成率等指标。

代理的失败模式可能出现在规划、工具调用、反思、环境交互和成本等多个方面。为了确保代理能够稳定可靠地运行,需要对其进行全面评估。通过衡量任务完成度、计划质量、工具使用、用户体验和安全性,可以全面了解代理的性能和潜在改进方向。

代理可能会使用正确的工具生成一个有效的计划来完成任务,但可能效率不高。以下是您可能需要跟踪以评估代理效率的几件事:

  1. 代理完成一项任务平均需要多少步骤?
  2. 代理完成一项任务的平均成本是多少?
  3. 每个操作通常需要多长时间?是否有特别耗时或昂贵的操作?

您可以将这些指标与基线进行比较,基线可以是另一个代理或人工操作员。在将人工智能代理与人类代理进行比较时,请记住人类和人工智能的操作模式截然不同,因此人类认为高效的操作对人工智能来说可能是低效的,反之亦然。例如,访问 100 个网页对于一次只能访问一个网页的人类代理来说可能效率很低,但对于可以一次性访问所有网页的人工智能代理来说却微不足道。

结论

就其核心而言,代理的概念相当简单。一个代理的定义取决于它所处的环境和它所能使用的工具集。在人工智能驱动的代理中,人工智能模型是大脑,它利用工具和来自环境的反馈来计划如何最好地完成任务。工具的使用使模型的能力大大提高,因此代理模式是不可避免的。

虽然 "代理 "的概念听起来很新颖,但它们是建立在许多自早期 LLMs 就已使用的概念之上的,包括自我批判、思维链和结构化输出。

这篇文章从概念上介绍了代理如何工作以及代理的不同组成部分。在今后的文章中,我将讨论如何评估代理框架。

代理模式经常要处理超出模型上下文限制的信息。在处理信息时,对模型上下文进行补充的记忆系统可以大大增强代理的能力。由于这篇文章已经很长了,我将在以后的博文中探讨记忆系统是如何工作的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值