谷歌 AI Agent 白皮书:2025 年迎来 AI 智能体时代
摘要
在这份白皮书中,讨论了生成式人工智能 Agent 的基础构建块、它们的组成以及以认知架构的形式实现这些有效方法的方法。这份白皮书的一些关键要点包括:
Agent 通过利用工具访问实时信息、建议现实世界中的行动并自主规划和执行复杂任务来扩展语言模型的能力。Agent 可以利用一个或多个语言模型,决定何时以及如何在状态之间进行过渡,并使用外部工具完成任何数量的复杂任务,这些任务对于该模型来说可能难以完成甚至不可能完成。
委托人的操作核心是协调层,这是一种认知架构,它结构化推理、规划和决策,并指导其行动。各种推理技术如 ReAct、Chain-of-Thought 和 Tree-of-Thought 提供了协调层获取信息、进行内部推理并生成有根据的决定或响应的框架。
工具,例如扩展、函数和数据存储,是 Agent 与外部世界之间的钥匙,允许它们与其他系统交互并访问超出其训练数据的知识。扩展为 Agent 和外部 API 提供桥梁,使 Agent 能够执行 API 调用并检索实时信息。函数通过分工提供了更细致的控制,让开发人员可以生成可以在客户端执行的功能参数。数据存储为 Agent 提供对结构化或非结构化数据的访问权限,从而实现基于数据的应用程序。
Agent 的未来充满了令人兴奋的进步,我们才刚刚开始触及可能存在的可能性。随着工具变得越来越复杂,并且推理能力得到增强,Agent 将被赋予解决日益复杂的难题的能力。此外,'Agent 链'战略方法将继续获得动力。
什么是 Agent?
重点介绍了生成式 AI 模型能够构建的具体类型的 Agent。为了了解 Agent 的内部运作,首先让我们介绍驱动 Agent 行为、行动和决策的基础组件。这些组件的组合可以描述为认知架构,并且可以通过混合匹配这些组件来实现许多这样的架构。专注于核心功能,图 1 中显示了 Agent 的认知架构中的三个基本组件。
[图 1:Agent 架构和组件]
模型(Model)
在 Agent 的范围内,模型指的是将被用作集中决策者的语言模型(LM)。Agent 使用的模型可以是任何大小的小型/大型的任意数量的 LM,这些 LM 都可以遵循基于指令的推理和逻辑框架,如 ReAct、Chain-of-Thought 或 Tree-of-Thought。模型可以是一般用途、多模态或根据您特定 Agent 架构的需求进行微调的。
为了获得最佳生产结果,你应该利用最适合你所期望的应用程序的模型,并且最好是在使用计划用于认知架构中的工具的数据签名上进行了训练。值得注意的是,该模型通常不会与 Agent 的具体配置设置(即工具选择、编排/推理设置)一起进行培训。然而,通过向它提供展示 Agent 能力的例子来进一步细化模型也是可能的,包括 Agent 使用特定工具或各种上下文下的推理步骤实例。
工具(Tools)
基础模型,尽管其文本和图像生成令人印象深刻,但仍然受到无法与外部世界交互的限制。工具填补了这一差距,使 Agent 能够与外部数据和服务进行交互,并解锁了单一的基础模型所不能实现的一系列更广泛的操作。工具可以采取多种形式,并具有不同的复杂程度,但通常会遵循常见的 Web API 方法,如 GET、POST、PATCH 和 DELETE 等。
例如,一个工具可以更新数据库中的客户信息或获取天气数据以影响 Agent 向用户提供的旅行推荐。借助工具,Agent 可以访问并处理现实世界的资讯。这赋予他们支持更多专门系统的能力,如检索增强生成(RAG),该系统显著扩展了 Agent 在自身能力之外所能实现的可能性。我们将在下面详细讨论工具,但最重要的是要理解,工具是连接 Agent 内部能力和外部世界的桥梁,从而解锁了一种更广泛的可能。
编排层(Orchestration layer)
协调层描述了一个循环过程,它规定了 Agent 如何获取信息、进行一些内部推理,并使用这种推理来告知其下一步行动或决策。一般来说,这个循环会持续到一个 Agent 达到目标或停止点为止。
协调层的复杂性取决于执行的任务和 Agent 本身。有些循环可以是简单的计算与决策规则,而其他可能包含连锁逻辑、涉及额外的机器学习算法或其他概率推理技术。在认知架构部分我们将讨论更多关于 Agent 协调层的具体实现细节。
Agents vs. models
为了更清楚地了解 Agent 和模型之间的区别,考虑以下图表:
| Models | Agents |
|---|
| 知识仅限于他们的训练数据中可用的内容。 | 知识通过工具与外部系统的连接而扩展 |
| 基于用户查询的单一推理/预测。除非为模型显式实现,否则不存在会话历史或连续上下文的管理。聊天记录) | 管理的会话历史 (即聊天记录) 允许基于用户查询和编排层做出的决策进行多轮推理/预测。在这种情况下,'回合'被定义为交互系统和 Agent 之间的交互。1 个传入事件/查询和 1 个 Agent 响应) |
| 没有本地工具实现。 | 工具在 Agent 体系结构中本地实现。 |
| 没有实现本机逻辑层。用户可以将提示作为简单的问题或用户推理框架(CoT、ReAct 等)来形成复杂的提示,以指导模型进行预测。 | 本机认知架构,使用推理框架,如 CoT、ReAct 或其他预构建 Agent 框架,如 LangChain。 |
Agent 如何运行?
想象一个厨房里的厨师 Agent。他们的目标是为餐厅顾客创造美味佳肴,这涉及一些计划、执行和调整的循环过程。
他们收集信息,比如顾客的订单和冰箱里的配料。
他们根据刚刚收集到的信息,进行一些内部推理,以确定可以创建哪些菜肴和风味轮廓。
他们采取行动来制作这道菜:切蔬菜,混合香料,煎肉。
在每个过程中,厨师根据需要进行调整,并随着原料的耗尽或客户反馈而不断细化他们的计划。他们使用之前的成果来确定下一步行动方案。这种信息摄入、规划、执行和调整的循环描述了厨师所采用的架构,以实现其目标。
就像厨师一样,Agent 可以通过迭代处理信息、做出明智的决策并根据先前输出来细化下一步行动,从而使用认知架构达到他们的最终目标。
Agent 的认知架构的核心是协调层,负责维护记忆、状态、推理和计划。它利用快速发展的提示工程领域及其相关框架来引导推理和规划,使 Agent 能够更有效地与环境互动,并完成任务。关于语言模型的提示工程框架和任务规划的研究正在迅速发展,产生了各种有前途的方法。虽然这不是一个详尽的列表,但这些都是在本文发表时最流行的框架和技术:
- ReAct:是一个提示工程框架,为语言模型提供了一种推理和对用户查询采取行动的思维过程策略。ReAct 提示已显示出优于几个最先进的基准,并提高了人类与 LLM 的互操作性和信任度。
- Chain-of-Thought(CoT):一种通过中间步骤实现推理能力的提示工程框架。CoT 包括各种子技术,如自我一致性、主动提示和多模态 CoT,每种技术都有其优点和缺点,具体取决于特定的应用程序。
- Tree-of-thoughts(ToT):一种适用于探索或战略前瞻任务的提示工程框架。它超越了链式思维提示,并允许模型探索各种思维链条,这些思维链条作为语言模型解决一般问题的中间步骤。
Agent 可以利用上述推理技术之一,或许多其他技术来选择给定用户请求的下一个最佳操作。
例如,请考虑一个被编程为使用 ReAct 框架选择正确动作和工具以响应用户查询的 Agent。
事件序列可能会像这样进行:
- 用户向 Agent 发送查询
- Agent 开始启动 ReAct
- Agent 向模型提供提示,要求它生成下一个 ReAct 步骤及其相应的输出:
- 思想/行动/输入/观察可以重复 N 次,根据需要
- i. 这是工具选择发生的地方
- ii. 例如,一个动作可以是 [航班、搜索、代码、无] 之一,在前三个代表模型可以选择的已知工具中,最后一个表示'没有选择工具'
- 问题:用户查询输入的问题,提供提示
- 思想:模型关于下一步应该做什么的想法
- 行动:模型对下一步采取什么行动的决定
- 动作输入:模型决定向工具提供什么输入(如果有)
- 观察:操作的结果/操作输入
- 最终答案:模型对原始用户查询的最终回答
- React 循环结束,最终答案返回给用户。
[图 2:Agent 案例在编排层中使用 ReAct 推理]
如图 2 所示,模型、工具和 Agent 配置一起工作以根据用户的原始查询提供了简洁响应。尽管模型可以基于其先前知识猜测答案(幻觉),但它使用了一个工具 (航班搜索),来查找实时外部信息。这些额外的信息被提供给模型,允许它基于真实事实数据做出更明智的决定,并将此信息汇总回用户。
工具(Tools):通往外界的钥匙
虽然语言模型擅长处理信息,但它们缺乏直接感知和影响现实世界的能力。这限制了它们在需要与外部系统或数据交互的情况下使用性。这意味着,在某种程度上,一个语言模型只取决于它从训练数据中学习到的东西有多好。但是无论我们向模型扔多少数据,它们仍然缺乏与外界互动的基本能力。那么如何才能让我们的模型具备实时、上下文意识的对外部系统的交互能力呢?功能、扩展程序、数据存储和插件都是提供这种关键能力给模型的方法。
虽然它们有很多名字,但工具是将我们的基础模型与外部世界联系起来的东西。这个对外部系统和数据的链接允许我们的 Agent 执行更广泛的任务,并且更加准确可靠地完成这些任务。
例如,工具可以使得 Agent 能够调整智能家居设置、更新日历、从数据库中获取用户信息或根据特定指令发送电子邮件。
截至本文发布日期,谷歌模型能够与三种主要工具类型进行交互:扩展、函数和数据存储。通过为 Agent 配备工具,我们解锁了他们不仅理解世界而且还能行动的巨大潜力,打开了无数新的应用程序和可能性的大门。
扩展(Extensions)
要理解扩展,最简单的方法是将它们视为以标准化方式在 API 和 Agent 之间建立桥梁的方式,允许 Agent 无缝执行 API 而无需考虑其底层实现。假设您已经构建了一个具有帮助用户预订航班目标的 Agent。你知道你想使用 Google Flights API 来检索航班信息,但你不确定你的 Agent 如何会调用这个 API 端点。
[图 3:Agent 如何与外部 API 交互?]
一种方法是实施自定义代码,该代码会处理传入的用户查询、解析查询以获取相关信息,并然后调用 API。
例如,在航班预订使用案例中,用户可能会说'我想从奥斯汀预订到苏黎世的航班。'在这种情况下,我们的自定义代码解决方案需要在尝试调用 API 之前提取出'奥斯汀'和'苏黎世'作为相关的实体来自用户的查询。
但是,如果用户说'我想预订飞往苏黎世的航班',并且从未提供出发城市呢?如果没有所需的必要数据,API 调用将失败,并且还需要更多代码来捕获像这种情况这样的边缘和角落情况。这种方法不可扩展,并且很容易在任何超出已实现的自定义代码范围的情景下崩溃。
更好的方法是使用扩展。通过:
- 使用示例向 Agent 商展示如何使用 API 端点。
- 教给 Agent 需要成功调用 API 端点的哪些参数或参数。
[图 4:扩展连接 Agent 到外部 API]
扩展可以独立于 Agent 进行构建,但应作为 Agent 配置的一部分提供。Agent 在运行时使用模型和示例来决定是否适合解决用户的查询。这突出了扩展的关键优势之一——其内置的示例类型,允许 Agent 动态选择最合适的扩展以完成任务。
[图 5:Agent、扩展和 API 之间的一对一关系]
想想软件开发人员在解决和解决方案时如何决定使用哪个 API 端点。
- 如果用户想预订航班,开发者可能会使用 Google Flights API;
- 如果用户想知道离他们当前位置最近的咖啡店在哪里,开发者可能会使用 Google Maps API。
同样地,在这个层面上,Agent/模型堆栈会使用一组已知扩展来决定哪一个最适合用户的查询。如果你想看看这些扩展的实际效果,你可以通过进入设置>扩展并启用你想要测试的任何内容来尝试 Gemini 应用程序中的它们。例如,您可以启用 Google Flights 扩展然后询问 Gemini'显示从奥斯汀到苏黎世的航班,下周五离开。'
[图 7:函数如何与外部 API 交互?]
这里的主要区别在于函数或 Agent 都不会直接与 Google Flights API 交互。那么 API 调用是如何发生的呢?
通过功能,调用实际 API 端点的逻辑和执行被从 Agent 卸载到客户端应用程序上,如图 8 和图 9 所示。这为开发人员提供了更精细的数据流控制权。选择使用函数而不是扩展的原因有很多,但一些常见的用例包括:
- 需要在应用程序堆栈的另一层进行 API 调用,而不能在直接 Agent 架构流之外(例如中间件系统、前端框架等)
- 安全或身份验证限制,这些限制阻止 Agent 直接调用 API(例如,API 未暴露到互联网上,或者无法通过 Agent 基础架构访问)
- 时间或操作顺序约束,这些约束会阻止 Agent 在实时情况下调用 API。(例如批处理作业、人机交互审核等)
- 需要对 Agent 无法执行的 API 响应应用额外的数据转换逻辑。例如,考虑一个不提供限制返回结果数量过滤机制的 API 端点。在客户端使用函数为开发人员提供了更多机会来实现这些转换。
- 开发人员希望在不部署额外基础设施的情况下迭代 Agent 开发(即,函数调用可以像'API 端点的占位符'一样工作)
如图 8 所示,两种方法之间的内部架构差异微妙。但是,额外的控制和对外部基础设施的解耦依赖使函数调用成为开发人员的一个有吸引力的选择。
[图 8:客户界定 vs Agent 侧控制扩展和功能调用]
一个模型可以用来调用函数,以处理复杂的客户端执行流程,其中 Agent 开发人员可能不希望语言模型管理 API 的执行(如扩展)。让我们考虑以下示例,在该示例中,正在训练一个 Agent 作为旅行顾问与想要预订度假行程的用户进行交互。目标是让 Agent 生成我们可以在我们的中间件应用程序中下载图像、数据等的城市列表,用于用户的行程规划。用户可能会说类似的话:
我想和家人一起去滑雪,但我不知道去哪里。
在典型的提示模型中,输出可能看起来像以下内容:当然可以,这里有一份您可以考虑的家庭滑雪旅行的城市列表。
- 美国科罗拉多州克雷斯特·布特
- 加拿大不列颠哥伦比亚省惠斯勒
- 瑞士策马特
虽然上面的输出包含我们所需的数据(城市名称),但格式并不适合解析。通过函数调用,我们可以教模型以一种更方便其他系统解析的结构化风格(如 JSON)来格式化此输出。
[图 9:显示函数调用生命周期的序列图]
图 9 中的示例结果是,模型被用来'填补空白',以满足客户端 UI 所需的参数来调用 Google Places API。客户端 UI 使用由模型在返回的函数中提供的参数管理实际 API 调用。这只是一个函数调用的应用场景,但还有许多其他需要考虑的情况:
- 您希望语言模型建议您在代码中可以使用的功能,但不想将凭证包含在您的代码中。因为函数调用不会运行该函数,因此您不需要在带有函数信息的代码中包括凭证。
- 您正在运行需要超过几秒钟的异步操作。这些场景与函数调用配合得很好,因为它是异步操作。
- 您想要在与产生函数调用及其参数的系统不同的设备上运行功能。
关于函数的一个关键点是,它们旨在为开发人员提供对不仅 API 调用的执行,而且整个应用程序的数据流的更多控制。在图 9 中的示例中,开发人员选择不将 API 信息返回给 Agent,因为这与 Agent 可能采取的未来行动无关。然而,根据应用程序的架构,将外部 API 调用数据返回到 Agent 以影响未来的推理、逻辑和操作选择可能是有意义的。最终,应用程序开发人员需要决定什么最适合特定的应用程序。
数据存储(Data stores)
想象一下,语言模型就像一个庞大的图书馆,包含其训练数据。但与不断获得新卷的图书馆不同,这个图书馆保持静止不动,只保留了最初培训的知识。这提出了一个问题,因为现实世界中的知识一直在不断发展。数据存储通过提供对更动态和更新信息的访问来解决这一限制,并确保模型的回答始终基于事实性和相关性。
考虑一个常见的场景,开发人员可能需要向模型提供少量额外数据,也许是以电子表格或 PDF 的形式。
[图 10:Agent 如何与结构化和非结构化数据交互?]
数据存储允许开发人员以原始格式向 Agent 提供额外的数据,从而消除了耗时的数据转换、模型重新训练或精细调整的需要。数据存储将传入文档转换为一组向量数据库嵌入,这些嵌入是 Agent 可以用来提取其下一步操作或对用户响应所需的信息。
[图 11:数据存储连接 Agent 到各种类型的新实时数据源]
在生成型人工智能 Agent 的背景下,数据存储通常被实现为开发人员希望 Agent 在运行时访问的向量数据库。虽然我们不会在这里深入探讨向量数据库,但关键要点是它们以矢量嵌入的形式存储数据,这是一种高维向量或对提供的数据进行数学表示的方式。最近使用语言模型的一个最常见示例就是检索增强的应用程序。
基于 RAG 的应用程序。这些应用程序旨在通过向模型提供各种格式的数据,从而扩展模型知识的广度和深度,超越基础训练数据:
- 网站内容
- 结构化数据,如 PDF、Word 文档、CSV、电子表格等格式。
- 未结构化的数据,如 HTML、PDF、TXT 等格式。
[图 12:Agent 和数据存储之间的一对多关系,可以表示各种类型的预索引数据]
每个用户请求和 Agent 响应循环的底层过程通常如图 13 所示进行建模。
- 将用户查询发送到嵌入模型以生成查询的嵌入
- 接下来,查询嵌入向量将与矢量数据库中的内容使用匹配算法(如 ScaNN)进行匹配。
- 匹配的内容以文本格式从向量数据库中检索并发送回 Agent。
- Agent 程序接收用户查询和检索内容,然后制定响应或操作。
- 最终响应发送给用户。
[图 13:基于 RAG 的应用程序中用户请求和 Agent 响应的生命周期]
最终结果是一个应用程序,允许 Agent 通过矢量搜索匹配用户的查询到已知的数据存储,并检索原始内容并将其提供给编排层和模型进行进一步处理。下一步可能是向用户提供最终答案,或者执行额外的矢量搜索以进一步细化结果。
一个使用 ReAct 推理/规划实现 RAG 的 Agent 样本交互可以在图 14 中看到。
[图 14:基于 RAG 的应用程序示例,带有 ReAct 推理和计划]
工具总结(Tools recap)
总结一下,扩展、功能和数据存储构成了可供 Agent 在运行时使用的几种不同工具类型。每个都有自己的目的,并且可以根据 Agent 开发人员的意愿一起或独立使用。
| 扩展 | 函数调用 | 数据存储 |
|---|
| 执行 | Agent-Side 执行 | Client-Side 执行 | Agent-Side 执行 |
| 用例 | • 开发者希望 Agent 能够控制与 API 端点的交互 • 在利用原生预构建扩展(例如 Vertex 搜索、代码解释器等)时很有用 • 多跳规划和 API 调用(即 Agent 的下一个操作取决于前一个操作/ API 调用的输出) | • 安全或身份验证限制使 Agent 无法直接调用 API。 • 时间限制或操作顺序限制使 Agent 无法实时调用 API。(例如:批处理操作、人工审核等) • 未向互联网公开的 API,或 Google 系统无法访问的 API。 | • 开发人员希望使用以下任何一种数据类型来实现检索增强生成(RAG): • 来自预先索引的域和 URL 的网站内容 • 以 PDF、Word 文档、CSV、电子表格等格式存在的结构化数据 • 关系型/非关系型数据库 • 以 HTML、PDF、TXT 等格式存在的非结构化数据 |
通过目标学习增强模型性能(Enhancing model performance with targeted learning)
有效使用模型的关键方面之一是它们在生成输出时选择正确工具的能力,尤其是在生产中大规模使用工具的情况下。虽然一般培训有助于模型发展这种技能,但现实世界场景往往需要超出训练数据的知识。想象一下这就像基本烹饪技巧和掌握特定菜系之间的区别。两者都需要基础的烹饪知识,但是后者要求有针对性的学习以获得更细致的结果。
为了帮助模型获取这种特定知识,存在几种方法:
- 在上下文中学习:这种方法在推理时提供了一个带有提示、工具和少量示例的通用模型,这使它能够'实时'学习如何以及何时使用这些工具来完成特定任务。ReAct 框架是自然语言中这种方法的一个例子。
- 基于检索的上下文学习:该技术通过从外部内存中检索最相关的信息、工具和关联示例,动态地将模型提示填充为最相关的信息。一个例子是 Vertex AI 扩展中的'示例存储'或前面提到过的基于 RAG 架构的数据存储。
- 精确调整学习:这种方法涉及在推理之前使用特定示例的大数据集对模型进行训练。这有助于模型了解何时以及如何在收到任何用户查询之前应用某些工具。
为了提供对每个目标学习方法的额外见解,让我们重新审视我们的烹饪类比。
想象一下,一位厨师从客户那里收到了特定的食谱(提示)、一些关键食材(相关工具)和几道示例菜肴(少量示例)。基于这些有限的信息以及厨师对烹饪的一般知识,他们需要根据食谱和客户的偏好来确定如何'即兴'准备最接近的菜肴。这就是在上下文中学习。
现在让我们想象一下我们的厨师在一个厨房里,这个厨房有一个装满各种配料和食谱(示例和工具)的储藏室(外部数据存储)。现在厨师可以动态地从储藏室中选择配料和食谱,并更好地与客户的配方和偏好保持一致。这使厨师能够利用现有知识和新知识来创建更知情且精炼的菜肴。这是一种基于检索的上下文学习。
最后,让我们想象一下我们把厨师送回学校学习新的烹饪或一系列的烹饪(在特定示例的大数据集上进行预训练)。这使厨师能够以更深入的理解来应对未来的未见过的客户食谱。如果我们要让厨师精通于特定的烹饪知识领域,则这种方法是完美的。这是一种基于微调的学习方法。
这些方法在速度、成本和延迟方面都具有独特的优点和缺点。然而,通过将这些技术结合到 Agent 框架中,我们可以利用各种优势并最小化其劣势,从而实现更稳健且可适应性强的解决方案。
使用 Vertex AI Agent 的生产应用程序(Production applications with Vertex AI agents)
虽然这篇白皮书探讨了 Agent 的核心组件,但构建生产级应用程序需要将它们与用户界面、评估框架和持续改进机制等其他工具集成在一起。Google 的 Vertex AI 平台通过提供涵盖所有早期基本要素的完全托管环境简化了这一过程。使用自然语言接口,开发人员可以快速定义其 Agent 的关键元素 - 目标、任务说明、工具、用于任务委派的子 Agent 以及示例 - 以轻松构造所需系统行为。此外,该平台还附带了一组开发工具,允许进行测试、评估、测量 Agent 性能、调试并提高开发 Agent 的整体质量。这使开发人员能够专注于构建和完善他们的 Agent,而基础设施、部署和维护的复杂性则由平台本身管理。
[图 15:基于 Vertex AI 平台构建的端到端 Agent 架构示例]
在图 15 中,我们提供了一个使用诸如 Vertex Agent Builder、Vertex 扩展程序、Vertex 函数调用和 Vertex 示例存储等特性构建的 Agent 的示例架构。该架构包括许多生产就绪应用程序所需的各个组件。