智能体(Agent)

本文是Google发布的智能体(Agent)白皮书的中文版,使用GPT4o进行翻译

作者:Julia Wiesinger, Patrick Marlow, Vladimir Vuskovic
翻译:GPT4o

这种推理、逻辑和对外部信息的访问相结合,并与生成式 AI 模型相连,体现了智能体(Agent)的概念。

引言

人类在处理复杂的模式识别任务方面表现出色。然而,在得出结论之前,他们通常会依赖工具——例如书籍、Google 搜索或计算器——来补充已有的知识。同样,生成式 AI 模型也可以被训练使用工具,以获取实时信息或提出实际行动建议。例如,模型可以利用数据库检索工具访问特定信息,如客户的购买历史,以便生成个性化的购物推荐。或者,基于用户的查询,模型可以调用各种 API 发送邮件回复同事,甚至代表用户完成金融交易。

为了实现这些功能,模型不仅需要访问一组外部工具,还必须具备自主规划和执行任务的能力。这种结合了推理、逻辑和外部信息访问能力的生成式 AI 模型,体现了智能体(Agent)的概念。智能体是一种超越单一生成式 AI 模型能力的程序,它能够自主决策并执行复杂任务。

本白皮书将深入探讨这些概念及其相关内容。

什么是智能体?

从最基本的层面来看,生成式 AI 智能体可以定义为一个应用程序,它通过观察世界并利用可用工具采取行动,以实现特定目标。智能体是自主的,可以独立于人类干预运行,特别是在设定了明确的目标或任务时。智能体还具有主动性,能够自主规划如何实现目标。即使没有来自人类的明确指令,智能体也能推理出下一步行动,以最终达成目标。

尽管 AI 领域的智能体概念非常广泛且强大,本白皮书将重点探讨当前生成式 AI 模型所能构建的特定类型的智能体

为了理解智能体的内部工作机制,我们首先需要介绍驱动智能体行为、行动和决策的基本组成部分。这些组件的组合可以被称为认知架构,不同的组件组合可以形成多种不同的智能体架构。从核心功能来看,智能体的认知架构主要由三个关键组成部分构成,如图 1 所示。

图 1. 通用智能体架构及其组成部分

模型 (The model )

在智能体的范畴内,模型指的是作为智能体流程中央决策者的语言模型(LM)。智能体可以使用一个或多个语言模型,这些模型的规模可以是小型或大型,并且需要具备遵循指令式推理和逻辑框架(如 ReActChain-of-ThoughtTree-of-Thoughts)的能力。根据具体的智能体架构需求,模型可以是通用模型多模态模型经过微调的专用模型

为了在生产环境中获得最佳效果,建议选择最符合目标应用的模型,并尽可能使用已在与智能体认知架构所需工具相关的数据上进行训练的模型。需要注意的是,模型本身通常不会直接包含智能体的具体配置设置(例如工具选择、编排方式或推理流程)。然而,可以通过提供示例来进一步优化模型,使其更适用于智能体的任务。这些示例可以展示智能体在不同情境下使用特定工具或推理步骤的能力,从而增强模型对任务的适应性。

工具 (The tools )

尽管基础模型在文本和图像生成方面表现出色,但它们仍然无法直接与外部世界交互工具弥补了这一缺陷,使智能体能够访问外部数据和服务,从而执行比基础模型本身更广泛的操作。工具的形式多种多样,复杂度各异,但通常与常见的 Web API 方法(如 GET、POST、PATCH 和 DELETE)保持一致。例如,一个工具可以用于更新数据库中的客户信息,或者获取天气数据,以影响智能体向用户提供的旅行推荐。借助工具,智能体可以访问和处理现实世界的信息,从而支持更专业的系统,如检索增强生成(RAG),这一技术显著扩展了智能体的能力,使其超越单纯依赖基础模型的局限性。

我们将在后文更详细地讨论工具的作用,但最重要的是要理解:工具是连接智能体内部能力与外部世界的桥梁,使其能够执行更丰富的任务。

编排层 (The orchestration layer )

编排层描述了智能体如何循环执行信息获取、内部推理,并基于推理结果采取行动或做出决策的过程。通常,该循环会持续运行,直到智能体达到目标或遇到停止条件。

编排层的复杂度取决于智能体的设计及其执行的任务。一些编排流程可能只是基于规则的简单计算,而另一些则可能涉及链式逻辑(Chained Logic),整合额外的机器学习算法,或采用概率推理技术。我们将在认知架构部分进一步探讨智能体编排层的详细实现。

智能体 vs. 模型

为了更清晰地区分智能体模型,请参考下表:

模型 智能体
知识仅限于其训练数据所涵盖的内容。 通过工具连接外部系统,扩展知识范围。
仅基于用户查询进行单次推理/预测,除非专门实现,否则不管理会话历史或持续上下文(如聊天记录)。 通过管理会话历史(如聊天记录),支持多轮推理/预测,结合编排层的决策,实现更连贯的交互。在此上下文中,“轮次”指的是智能体与外部系统的单次交互(即一次输入事件/查询 + 一次智能体响应)。
无原生工具集成。 在智能体架构中原生集成工具
无原生逻辑层,用户需要手动设计提示词(Prompt),可以采用简单问答或使用推理框架(如 CoT、ReAct 等)构造复杂提示词来引导预测。 具备原生认知架构,支持 CoT、ReAct 等推理框架,并可结合 LangChain 等预构建的智能体框架。

认知架构:智能体如何运作

想象一位繁忙厨房里的厨师,他们的目标是为餐厅顾客烹饪美味的菜肴,而这一过程涉及规划、执行和调整的循环:

  • 信息收集:获取顾客的订单,并检查储藏室和冰箱中有哪些食材。
  • 内部推理:基于收集到的信息,思考可以制作哪些菜肴以及如何搭配风味。
  • 执行操作:切菜、调味、煎烤肉类,真正将计划付诸实践。

在整个过程中,厨师会根据实际情况不断调整和优化——如果某种食材用完了,他们会调整菜谱;如果收到顾客反馈,他们可能会改进做法;每次烹饪的结果都会影响下一步的决策。这种信息获取、规划、执行和调整的循环构成了厨师用来实现目标的认知架构

与厨师类似,智能体(Agent) 也利用认知架构 来逐步处理信息、做出决策,并根据先前的结果调整后续行动,以最终实现目标。智能体的认知架构核心是编排层(Orchestration Layer),负责:

  • 维护记忆(Memory)状态(State),确保上下文的一致性
  • 进行推理(Reasoning)规划(Planning),确保智能体能够制定合理的行动方案
  • 结合提示工程(Prompt Engineering) 和相关推理框架,引导智能体更高效地执行任务,并与环境交互

当前,提示工程框架语言模型的任务规划 仍在快速发展,并催生了多种前沿方法。以下是当前最受欢迎的一些推理框架和技术(尽管列表并不穷尽):

  • ReAct(Reason + Act):一种提示工程框架,为语言模型提供推理与行动(Reason & Act)的思维策略,使其能够根据用户查询进行推理并采取相应行动,无论是否提供上下文示例。研究表明,ReAct 提示方式在多个最先进(SOTA)基线模型上均表现优异,并能提升大语言模型(LLM)的可交互性和可信度
  • Chain-of-Thought(CoT):一种提示工程框架,通过引导模型执行中间推理步骤,提升其推理能力。CoT 具有多个子技术,如:根据具体应用场景,不同的 CoT 变体各有优势和局限性。
    • Self-Consistency(自洽性)——增强推理的稳定性,提高答案一致性。
    • Active-Prompt(主动提示)——动态调整提示词,引导模型更高效地推理。
    • Multimodal CoT(多模态 CoT)——适用于涉及文本、图像、音频等多模态数据的应用。
  • Tree-of-Thoughts(ToT):一种适用于探索性任务或战略性前瞻推理提示工程框架。ToT 在Chain-of-Thought 的基础上进行了泛化,使模型能够探索多条推理链,作为问题求解的中间步骤,从而提升其在复杂问题求解中的表现。

智能体可以采用上述推理技术之一,或结合多种技术,来确定针对用户请求的最佳后续行动。例如,假设某个智能体被编程使用 ReAct 框架 来选择合适的操作和工具,其执行流程可能如下:

  1. 用户发送查询 给智能体。
  2. 智能体启动 ReAct 处理流程
  3. 智能体向模型提供提示,要求其生成下一个 ReAct 步骤及其对应的输出
  4. Question(问题):用户输入的原始问题,与提示词一同提供。
  5. Thought(思考):模型推理下一步应该做什么
  6. Action(行动):模型决定下一步采取的操作:
    1. 此时智能体可以选择工具
    2. 例如,可选的操作可能包括 [Flights, Search, Code, None],其中前三者代表模型可以选择的已知工具,None 表示“不选择工具”。
  7. Action input(行动输入):模型决定需要提供给工具的输入参数(如果需要)。
  8. Observation(观察):执行 Action + Action input 之后的结果:
    1. 该过程中的 思考(Thought)→ 行动(Action)→ 输入(Action Input)→ 观察(Observation) 可以重复 N 次,直到智能体得到充分的信息。
  9. Final answer(最终答案):模型基于所有信息生成最终回答,并返回给用户。
  10. ReAct 循环结束,智能体向用户提供最终答案
图2 智能体如何利用 ReAct 进行实时推理

图 2 所示,模型、工具和智能体配置 共同协作,以用户的原始查询为基础,提供准确、简洁的回答

如果没有工具支持,模型可能仅依赖已有的训练数据猜测答案(幻觉)。然而,在 ReAct 机制下,智能体能够调用外部工具(如 Flights API)来获取实时数据。这些额外信息提供给模型后,使其能够基于真实数据做出更准确的决策,并将综合信息反馈给用户

总结:智能体响应的质量直接取决于其推理和行动能力,包括:

是否能够选择合适的工具

所选工具的定义是否清晰

正如厨师需要新鲜食材并关注顾客反馈才能做出美味的菜肴,智能体也需要健全的推理机制和可靠的信息来源,才能提供最佳的结果。在接下来的章节,我们将深入探讨智能体如何连接实时数据,进一步提升决策能力。

工具:连接外部世界的关键

尽管语言模型(LM)信息处理 方面表现出色,但它们无法直接感知影响现实世界。这一限制使得它们在需要与外部系统或数据交互的应用场景中作用受限。换句话说,语言模型的能力受限于其训练数据的范围。无论投入多少数据进行训练,模型仍然缺乏实时交互的基本能力

那么,如何赋予模型实时、基于上下文的交互能力,使其能够访问并操作外部系统函数(Functions)、扩展(Extensions)、数据存储(Data Stores)和插件(Plugins) 都是为模型提供这一关键能力的方式。

尽管这些功能有不同的名称,但它们本质上都是工具,负责创建基础模型与外部世界的连接。这一连接使得智能体可以执行更广泛的任务,并且具备更高的准确性和可靠性

例如,工具可以让智能体调节智能家居设置更新日程表从数据库中获取用户信息,或根据特定指令发送电子邮件

截至本白皮书发布之日,Google 模型主要支持三种工具类型

  1. 扩展(Extensions)
  2. 函数(Functions)
  3. 数据存储(Data Stores)

通过为智能体配备这些工具,我们不仅让其能够理解世界,还让它能够对世界采取行动,从而开启无限可能的新应用场景。

扩展(Extensions)

扩展(Extensions) 的作用是在 API 与智能体之间建立标准化的桥梁,使智能体能够无缝调用 API,而无需关心其底层实现方式。可以将其理解为一种标准化的 API 访问方式,让智能体能够灵活地调用外部服务

假设你正在构建一个帮助用户预订航班的智能体,并计划使用 Google Flights API 来获取航班信息。然而,你可能不确定如何让智能体正确调用这个 API 端点。

图3 智能体如何与外部 API 交互

一种方式是手动编写自定义代码,让智能体能够解析用户查询、提取相关信息,并发起 API 调用。例如:

用户查询:「我想预订从奥斯汀(Austin)到苏黎世(Zurich)的航班。」

代码解析:提取「Austin」和「Zurich」作为出发地和目的地,然后调用 API。

但如果用户仅说:「我想预订一趟去苏黎世的航班。」没有提供出发城市怎么办?

此时,API 调用将因缺少必要参数而失败,你需要额外编写代码来处理这些边界情况

这种方法扩展性差,且容易出错,尤其是在遇到未覆盖的特殊场景时,系统很容易崩溃。

扩展:更强大、更可靠的 API 交互方式

相比之下,使用扩展(Extensions) 是更具弹性的方法,它在智能体与 API 之间提供了标准化的连接,并且能够自动适应不同的 API 需求。扩展的核心功能包括:

  1. 让智能体学习如何使用 API 端点,通过示例教学,使其掌握 API 的调用方式。
  2. 教会智能体所需的参数,确保 API 调用包含必要的信息,从而提高请求成功率。
图4 扩展如何连接智能体与外部 API?

扩展可以独立于智能体开发,但应作为智能体配置的一部分提供。在运行时,智能体会利用模型和示例来动态决定是否使用某个扩展,并选择最合适的扩展 来解决用户的查询。

这凸显了扩展的关键优势:其内置的示例机制允许智能体动态选择最合适的扩展来完成任务

图5 智能体与扩展及API 的一对多关系

可以将智能体选择扩展的过程类比为软件开发人员在编写代码时选择 API 端点的方式

用户想预订航班开发者调用 Google Flights API

用户想查找附近的咖啡店开发者调用 Google Maps API

同样,智能体 / 语言模型使用一组已知的扩展,来决定哪个扩展最适合当前用户查询。

如果你想体验扩展的实际效果,可以在 Gemini 应用 中进行尝试:

  1. 进入 设置(Settings) > 扩展(Extensions)
  2. 启用 Google Flights 扩展
  3. 询问 Gemini:「显示下周五从奥斯汀到苏黎世的航班信息。」

智能体将会自动调用适当的扩展 来获取实时数据,并提供准确的航班信息。

示例扩展(Sample Extensions)

为了简化 扩展(Extensions) 的使用,Google 提供了一些开箱即用(Out-of-the-box) 的扩展,这些扩展可以快速导入到项目中,并且只需最少的配置即可使用

例如,代码解释器(Code Interpreter)扩展(见 代码片段 1)允许智能体根据自然语言描述生成并运行 Python 代码

import vertexai
import pprint

PROJECT_ID = "YOUR_PROJECT_ID"
REGION = "us-central1"

vertexai.init(project=PROJECT_ID, location=REGION)

from vertexai.preview.extensions import Extension

extension_code_interpreter = Extension.from_hub("code_interpreter")
CODE_QUERY = """Write a python method to invert a binary tree in O(n) time."""

response = extension_code_interpreter.execute(
	operation_id = "generate_and_execute",
	operation_params = {"query": CODE_QUERY}
	)

print("Generated Code:")
pprint.pprint({response['generated_code']})

# The above snippet will generate the following code.
```
Generated Code:
class TreeNode:
	def init(self, val=0, left=None, right=None):
		self.val = val
		self.left = left
		self.right = right

	def invert_binary_tree(root):
			"""
			Inverts a binary tree.
			Args:
				root: The root of the binary tree.
			Returns:
				The root of the inverted binary tree.
			"""

			if not root:
				return None

			# Swap the left and right children recursively
			root.left, root.right = invert_binary_tree(root.right), invert_binary_tree(root.left)

			return root

# Example usage:
# Construct a sample binary tree
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
root.right.left = TreeNode(6)
root.right.right = TreeNode(9)

# Invert the binary tree
inverted_root = invert_binary_tree(root)
```

代码片段 1 代码解释器扩展(Code Interpreter Extension)可生成并运行 Python 代码

函数(Functions)

软件工程领域,函数(Functions)执行特定任务的独立代码模块,可以根据需要重复使用。当软件开发人员编写程序时,通常会创建多个函数来执行不同的任务,并定义何时调用 function_a 或 function_b 以及其输入参数和预期输出

智能体(Agent) 领域,函数的工作方式类似,但调用逻辑由模型控制模型可以使用一组已知的函数,基于函数的定义决定何时调用某个函数,并提供相应的参数

函数扩展 之间的主要区别包括:

  1. 模型的输出是函数及其参数,但不会直接调用 API
  2. 函数在客户端(Client-side)执行,而扩展在智能体端(Agent-side)执行

在 Google Flights 示例中,函数的设置可能如下所示:

图7 示例:Functions 如何与外部API交互

请注意,这里的主要区别在于函数(Function)和智能体(Agent)均不会直接与Google Flights API 交互。那么 API 调用究竟是如何实现的呢?

在使用函数(Functions)的情况下,调用实际 API 端点的逻辑和执行过程被转移到客户端应用程序(如图 8 和图 9所示),而不是由智能体来处理。这样,开发者就可以对应用中的数据流进行更细粒度的控制。

为什么开发者会选择使用函数而不是扩展?下面是一些常见的使用场景:

  1. API 调用需要在应用程序堆栈的其他层面上完成

例如,需要通过中间件系统前端框架来调用 API,而不是直接在智能体架构内完成。

  1. 安全或身份验证限制

如果 API 并未暴露在互联网上,或者智能体基础设施无法访问该 API,这类限制会阻止智能体直接调用 API。

  1. 时序或操作顺序限制

如果有批处理任务或人工审核(Human-in-the-loop)等流程要求,导致智能体无法实时调用 API。

  1. API 响应需要额外的数据转换逻辑

如果 API 端点未提供筛选机制来限制返回结果数量,使用客户端函数可以对 API 响应进行进一步处理或转换。

  1. 希望在不部署额外基础设施的情况下迭代开发智能体

函数调用可以作为 API 的“模拟(Stubbing)”,从而允许开发者在没有真实 API 的情况下进行功能测试和开发。

虽然函数(Functions)和扩展(Extensions)在内部架构上的差异可能较为微妙,但函数调用(Function Calling)提供了更大的控制权,并减少了对外部基础设施的依赖。对于开发者而言,这种方法是一种更灵活、更安全、更具可控性的 API 交互方式,尤其适用于需要复杂数据处理和更严格工作流控制的场景。

图 8. 区分客户端与智能体端对扩展和函数调用的控制

使用场景(Use Cases)

模型可以调用函数(Functions)处理复杂的客户端执行流程,特别是在开发者不希望语言模型直接管理 API 执行(如扩展(Extensions)所做的那样)的情况下。

示例:旅行助手智能体

假设我们正在训练一个旅行管家(Travel Concierge)智能体,用于与用户交互并帮助他们规划度假行程。智能体的目标是生成一个城市列表,该列表可以被中间件应用用于下载相关图片、获取数据等,帮助用户制定旅行计划。

用户可能会输入以下查询:

我想和家人去滑雪,但不知道去哪里比较好。

如果直接让模型生成响应,可能会得到如下输出:

当然!以下是适合家庭滑雪旅行的城市列表:

• 克雷斯特德比特(Crested Butte),科罗拉多,美国

• 惠斯勒(Whistler),不列颠哥伦比亚省,加拿大

• 采尔马特(Zermatt),瑞士

虽然这个输出包含了我们需要的城市名称,但其格式并不适合系统解析

函数调用(Function Calling)优化数据格式

借助函数调用(Function Calling),我们可以让模型以结构化格式(如 JSON)返回数据,以便其他系统更方便地解析和使用。

针对相同的用户输入,函数的 JSON 输出示例如代码片段 5

function_call {
	name: "display_cities"
	args: {
		"cities": ["Crested Butte", "Whistler", "Zermatt"],
		"preferences": "skiing"
	}
}

代码片段 5:用于显示城市列表和用户偏好的函数调用示例

上述 JSON 负载 由模型生成,然后被发送至客户端服务器(Client-side Server),以便开发者根据需要进一步处理。在本示例中,客户端服务器将使用Google Places API 查询模型提供的城市列表,获取相关的城市图片,并将其作为格式化的富内容返回给用户。

图9 函数调用的执行流程

图 9 展示了该交互的详细步骤,具体包括:

  1. 用户输入查询(例如:“我想和家人去滑雪,但不知道去哪里比较好。”)
  2. 模型解析用户意图,生成 JSON 负载,包括用户的旅行偏好和推荐的目的地列表。
  3. 客户端服务器接收 JSON 负载,并调用 Google Places API 获取相应的图片或其他信息。
  4. 客户端 UI 使用 API 返回的数据,以富格式内容向用户展示滑雪目的地的详细信息。

最终,模型的作用是提供客户端所需的参数,而实际的 API 调用由客户端 UI 负责执行

函数调用的其他应用场景

除了上述示例,函数调用(Function Calling) 还适用于许多其他场景,例如:

不希望在代码中包含凭据

例如,让语言模型推荐可用的函数,但避免在代码中硬编码 API 凭据。由于函数调用不会直接运行函数,因此可以安全地在代码中定义函数信息,而无需存储凭据。

运行耗时的异步操作

一些 API 调用可能需要数秒甚至更长时间才能返回结果,例如批量数据处理复杂查询。函数调用适用于这类异步操作,可避免阻塞主流程。

在不同的设备上运行函数

在某些应用场景中,函数的调用和执行可能需要在不同的系统或设备上进行。例如,移动设备可以生成函数调用请求,而云端服务器则负责实际执行函数逻辑。

函数调用的核心价值

函数的设计目标是让开发者能够更灵活地控制 API 调用的执行,以及整个应用程序的数据流。

图 9 示例中,开发者决定不将 API 响应数据返回给智能体,因为该数据不会影响智能体的后续决策。然而,在某些应用架构中,返回 API 数据给智能体可能是必要的,以便智能体在未来的推理、逻辑决策或行动选择中加以利用。

最终,是否返回 API 数据完全取决于应用开发者,他们需要根据具体的应用场景做出最佳选择。

函数示例代码(Function Sample Code)

为了实现滑雪度假场景中的 JSON 输出,我们将基于 gemini-1.5-flash-001 模型,逐步构建所需的各个组件。

首先,我们定义 display_cities 函数,这是一个简单的 Python 方法。

def display_cities(cities: list[str], preferences: Optional[str] = None):
	"""Provides a list of cities based on the user's search query and preferences.
	Args:
		preferences (str): The user's preferences for the search, like skiing,
		beach, restaurants, bbq, etc.
		cities (list[str]): The list of cities being recommended to the user.
	Returns:
		list[str]: The list of cities being recommended to the user.
	"""
	return cities

代码片段 6:用于显示城市列表的 Python 函数示例

接下来,我们将实例化模型,构建工具(Tool),然后将用户查询和工具传递给模型进行处理。执行以下代码后,最终输出结果将在代码片段底部展示。

from vertexai.generative_models import GenerativeModel, Tool, FunctionDeclaration

model = GenerativeModel("gemini-1.5-flash-001")

display_cities_function = FunctionDeclaration.from_func(display_cities)
tool = Tool(function_declarations=[display_cities_function])

message = "I’d like to take a ski trip with my family but I’m not sure where to go."

res = model.generate_content(message, tools=[tool])

print(f"Function Name: {res.candidates[0].content.parts[0].function_call.name}")
print(f"Function Args: {res.candidates[0].content.parts[0].function_call.args}")

> Function Name: display_cities
> Function Args: {'preferences': 'skiing', 'cities': ['Aspen', 'Vail', 'Park City']}

代码片段 7:构建工具,传递用户查询至模型,并执行函数调用

函数(Functions) 提供了一种简单明了的框架,使应用开发者能够精细控制数据流和系统执行流程,同时有效利用智能体/模型 生成关键输入。

开发者可以灵活选择是否让智能体参与(in the loop) 数据处理:

如果需要智能体继续参与,可以返回外部数据,让其影响后续推理和决策。

如果不需要智能体介入,可以省略数据返回,仅在客户端或其他系统中完成处理。

最终,是否让智能体参与,取决于具体的应用架构需求,开发者可以根据场景做出最优选择。

数据存储(Data Stores)

想象一个语言模型(Language Model) 如同一座巨大的图书馆,里面存放着它的训练数据。然而,与普通图书馆不同的是,这座图书馆不会持续新增书籍,它的知识停留在训练时的状态。这带来了一个挑战:现实世界的信息不断变化,而模型的知识却是静态的

数据存储(Data Stores) 解决了这一问题,使模型能够访问更动态、实时更新的数据,从而确保模型的响应基于最新事实,具备更强的相关性和准确性

图10 如何让智能体访问结构化和非结构化数据

在实际应用中,开发者可能需要向模型提供少量额外数据,例如电子表格(Spreadsheets)、PDF 文档等,以便智能体可以引用这些信息进行更精准的回答。

数据存储(Data Stores) 允许开发者以原始格式 向智能体提供额外数据,从而避免耗时的手动数据转换、模型重新训练或微调

图11 数据存储 增强智能体的实时数据访问能力

当开发者上传文档时,数据存储 会将其转换为向量数据库(Vector Database)中的嵌入数据(Embeddings),供智能体在需要时提取信息,以补充其推理过程或优化对用户的回答。

这种方法使智能体能够:

• 访问最新的行业报告、政策法规、公司内部文档等,提高信息的准确性和时效性

• 在不改变模型结构 的情况下增强模型的知识范围,无需重新训练或微调模型。

• 结合结构化数据(如数据库记录)和非结构化数据(如 PDF 文档) 进行更精细的推理和决策。

数据存储为智能体提供了一种灵活、高效的方式,以访问实时数据来源,并使其回答更具权威性和可信度。

实现与应用

生成式 AI 智能体(Generative AI Agents)的背景下,数据存储(Data Stores) 通常被实现为向量数据库(Vector Database),开发者希望智能体在运行时(Runtime) 访问这些数据。

虽然这里不会深入探讨向量数据库的技术细节,但需要理解的关键点是:

• 向量数据库存储数据的形式是向量嵌入(Vector Embeddings)

• 这些嵌入是一种高维向量或数学表示,用于表征提供的数据内容。

数据存储的典型应用:检索增强生成(RAG)

检索增强生成(Retrieval Augmented Generation,RAG) 是近年来数据存储在语言模型中的最常见应用之一。

RAG 旨在扩展模型的知识范围,超越其基础训练数据,通过提供额外数据源,增强模型的回答准确性和相关性。

RAG 允许模型访问的数据格式包括:

网站内容(Website Content)

结构化数据(Structured Data)

• PDF 文档

• Word 文档

• CSV 文件

• 电子表格(Spreadsheets)

非结构化数据(Unstructured Data)

• HTML 文件

• PDF 文本

• 纯文本(TXT)

图 12. 智能体与数据存储的一对多关系,数据存储可表示多种预索引数据类型

用户请求与智能体响应的底层流程(见图 13)

每个用户请求与智能体响应的循环过程通常按照以下步骤进行:

  1. 用户查询 被发送至嵌入模型(Embedding Model),以生成该查询的向量嵌入(Embeddings)
  2. 生成的查询嵌入 被与向量数据库(Vector Database)中的内容进行匹配,匹配算法可以使用SCaNN(Scalable Nearest Neighbors) 等技术。
  3. 匹配到的内容文本格式 从向量数据库中检索出来,并发送回智能体。
  4. 智能体接收用户查询和检索到的内容,然后基于这些信息生成响应或采取行动
  5. 最终响应 被发送给用户。
图 13. RAG 应用中用户请求与智能体响应的生命周期

最终,这种应用实现了一个基于向量搜索(Vector Search)的系统,使智能体能够:

  1. 将用户查询与数据存储(Data Store)进行匹配,检索相关内容。
  2. 获取原始数据,并将其提供给编排层(Orchestration Layer)语言模型(Model) 进行进一步处理。
  3. 智能体可执行下一步操作

直接向用户提供最终答案

执行额外的向量搜索,进一步优化检索结果。

图 14 展示了一个结合 RAG(检索增强生成)与 ReAct(推理/规划)机制的智能体交互示例

图 14. 基于 RAG 的应用示例,结合 ReAct 推理与规划

工具概述(Tools Recap)

扩展(Extensions)、函数调用(Function Calling)和数据存储(Data Stores) 是智能体在运行时可使用的不同类型的工具。每种工具都有其特定的用途,开发者可以根据需求独立或组合使用它们

工具类型对比

类别 扩展(Extensions) 函数调用(Function Calling) 数据存储(Data Stores)
执行位置 智能体端(Agent-Side Execution) 客户端端(Client-Side Execution) 智能体端(Agent-Side Execution)
适用场景 - 开发者希望智能体直接控制 API 交互。   - 适用于内置扩展(Pre-built Extensions),如 Vertex Search、Code Interpreter 等。   - 多步规划(Multi-Hop Planning)API 调用依赖前一操作的输出 - 安全或身份验证限制,智能体无法直接调用 API(如 API 未暴露至互联网)。   - 时间或执行顺序限制,无法实时调用 API(如批处理、人工审核等)。   - API 受限于 Google 系统之外的基础设施 - 开发者希望实现检索增强生成(RAG),结合以下数据类型:   - 网站内容(预索引域名和 URL)。   - 结构化数据(PDF、Word 文档、CSV、电子表格等)。   - 关系型 / 非关系型数据库。   - 非结构化数据(HTML、PDF、TXT 等)。

总结

扩展 适用于 智能体直接控制 API 交互,适合多步推理和内置扩展。

函数调用 提供 客户端控制 API 逻辑,适用于 API 访问受限或存在异步处理需求的场景

数据存储 用于 检索增强生成(RAG),支持智能体 访问实时或预索引数据源,以扩展其知识范围。

开发者可以根据具体需求,单独或结合使用这些工具,以优化智能体的交互能力和响应质量。

通过定向学习提升模型性能

有效使用模型的关键之一是在生成输出时选择合适的工具,尤其是在生产环境中大规模使用工具时。虽然通用训练 可以帮助模型培养这一能力,但真实世界的场景 往往需要超越训练数据的知识。可以将其类比为基础烹饪技能掌握特定菜系 之间的区别。两者都需要烹饪基础,但后者需要定向学习 以获得更精细的技能。

为帮助模型获取这种特定领域知识,可以采用以下方法:

上下文学习(In-Context Learning):在推理时,为通用模型 提供提示(Prompt)、工具(Tools)和少量示例(Few-Shot Examples),使其能够即时学习 如何在特定任务中使用这些工具。例如,ReAct 框架 就是自然语言中的一种上下文学习方法。

基于检索的上下文学习(Retrieval-Based In-Context Learning):该技术通过从外部存储(External Memory)中检索最相关的信息、工具和示例,动态填充模型的提示内容。例如,Vertex AI Extensions 中的 “Example Store”,或之前提到的基于 RAG(检索增强生成)的数据存储架构

基于微调的学习(Fine-Tuning Based Learning):在推理前,使用更大规模的特定示例数据集 对模型进行训练,使其在接收用户查询之前就能理解何时、如何使用特定工具

烹饪类比:定向学习的不同方式

上下文学习

想象一位厨师收到了一份具体的食谱(Prompt),一些关键食材(工具),以及几道示例菜品(Few-Shot Examples)。基于这些有限的信息,加上自己的烹饪基础,他需要即时推理 出最佳的烹饪方法,以符合顾客的需求。这就是上下文学习

基于检索的上下文学习

想象这位厨师在一个配备充足食材(外部数据存储)烹饪书籍(示例和工具) 的厨房里。面对顾客的订单,他可以动态选择最合适的食材和食谱,从而制作出更符合顾客口味的菜肴。这就是基于检索的上下文学习

基于微调的学习

想象我们让厨师回到学校,专门学习一种新的菜系(例如法餐或日料)。通过系统培训后,他可以更深入地理解该菜系,并在未来面对顾客订单时,能够提供更专业的菜品。这就是微调学习

结合不同方法,优化智能体能力

每种方法在速度、成本和延迟 方面各有优缺点。然而,在智能体框架(Agent Framework) 中,结合这些技术可以充分发挥各自的优势,降低缺点,从而打造更加健壮、灵活的智能体解决方案

使用 LangChain 快速构建智能体

为了提供一个可执行的真实示例,我们将使用 LangChainLangGraph 库快速构建一个智能体(Agent) 原型。这些流行的开源库 允许用户通过**“链式”组合逻辑、推理和工具调用**,构建自定义智能体,以回答用户查询。

在本示例中,我们将使用 gemini-1.5-flash-001 模型,并结合一些简单工具 处理多阶段查询(Multi-Stage Query)

使用的工具

SerpAPI(用于执行 Google 搜索)

Google Places API(用于检索地点信息)

运行代码后,智能体将利用多个工具完成查询,并返回最终结果。

from langgraph.prebuilt import create_react_agent
from langchain_core.tools import tool
from langchain_community.utilities import SerpAPIWrapper
from langchain_community.tools import GooglePlacesTool

os.environ["SERPAPI_API_KEY"] = "XXXXX"
os.environ["GPLACES_API_KEY"] = "XXXXX"

@tool
def search(query: str):
	"""Use the SerpAPI to run a Google Search."""
	search = SerpAPIWrapper()
	return search.run(query)
	
@tool
def places(query: str):
	"""Use the Google Places API to run a Google Places Query."""
	places = GooglePlacesTool()
	return places.run(query)

model = ChatVertexAI(model="gemini-1.5-flash-001")
tools = [search, places]

query = "Who did the Texas Longhorns play in football last week? What is the
address of the other team's stadium?"

agent = create_react_agent(model, tools)
input = {"messages": [("human", query)]}

for s in agent.stream(input, stream_mode="values"):
	message = s["messages"][-1]
	if isinstance(message, tuple):
		print(message)
	else:
		message.pretty_print()

代码片段 8:基于 LangChain 和 LangGraph 的智能体示例(包含工具调用)

=============================== Human Message ================================
Who did the Texas Longhorns play in football last week? What is the address
of the other team's stadium?
================================= Ai Message =================================
Tool Calls: search
Args:
query: Texas Longhorns football schedule
================================ Tool Message ================================
Name: search
{...Results: "NCAA Division I Football, Georgia, Date..."}
================================= Ai Message =================================
The Texas Longhorns played the Georgia Bulldogs last week.
Tool Calls: places
Args:
query: Georgia Bulldogs stadium
================================ Tool Message ================================
Name: places
{...Sanford Stadium Address: 100 Sanford...}
================================= Ai Message =================================
The address of the Georgia Bulldogs stadium is 100 Sanford Dr, Athens, GA
30602, USA.

代码片段 9:代码片段 8 运行后的示例输出

虽然这是一个相对简单的智能体示例,但它展示了模型(Model)、编排(Orchestration)和工具(Tools) 如何协同工作,以实现特定目标。

最后一部分,我们将探讨这些组件如何整合到Google 级别的托管产品中,例如 Vertex AI AgentsGenerative Playbooks

使用 Vertex AI Agents 构建生产级应用

本白皮书探讨了智能体的核心组件,而构建生产级应用 需要集成更多工具,如用户界面(UI)、评估框架和持续改进机制

Google 的 Vertex AI 平台 简化了这一过程,提供了一个完全托管的环境,涵盖了所有智能体开发的基础要素

Vertex AI 如何加速智能体开发?

借助自然语言界面(Natural Language Interface),开发者可以快速定义智能体的关键要素,包括:

目标(Goals)

任务指令(Task Instructions)

工具(Tools)

任务分派的子智能体(Sub-Agents)

示例(Examples)

这使得开发者可以轻松构建期望的智能体行为,无需手动管理底层基础设施。

Vertex AI 提供的开发工具

该平台还配备了一系列开发工具,用于:

测试(Testing)

评估(Evaluation)

测量智能体性能(Performance Measurement)

调试(Debugging)

优化智能体质量(Quality Improvement)

通过这些工具,开发者可以专注于构建和优化智能体,而平台自动管理基础设施、部署和维护的复杂性

Vertex AI 智能体架构示例(见图 15)

图 15 展示了一个基于 Vertex AI 平台构建的智能体架构,该架构结合了多个关键功能,包括:

Vertex Agent Builder(智能体构建工具)

Vertex Extensions(扩展)

Vertex Function Calling(函数调用)

Vertex Example Store(示例存储)

这一架构包含了构建生产级应用所需的核心组件,支持企业级 AI 解决方案的开发、测试和部署。

图 15. 基于 Vertex AI 平台构建的端到端智能体架构示例

你可以在官方文档中体验此预构建智能体架构的示例。

总结

本白皮书探讨了生成式 AI 智能体(Generative AI Agents)核心构建模块组成方式 以及如何通过认知架构(Cognitive Architectures)有效实现 这些智能体。以下是关键要点:

1. 智能体扩展语言模型的能力

• 智能体通过工具(Tools) 访问实时信息、建议现实世界的操作,并自主规划和执行复杂任务

• 智能体可以结合一个或多个语言模型,决定何时、如何转换状态,并调用外部工具完成单一模型难以独立完成的复杂任务

2. 编排层(Orchestration Layer)是智能体的核心

编排层 是智能体的认知架构(Cognitive Architecture),负责推理、规划、决策和行动

不同的推理技术(如 ReAct、Chain-of-Thought、Tree-of-Thoughts)提供了一种框架,使智能体能够吸收信息、执行内部推理,并生成精准的决策或响应

3. 工具(Tools)是智能体连接外部世界的关键

扩展(Extensions):为智能体提供与外部 API 的桥梁,支持API 调用实时信息检索

函数(Functions):提供更细粒度的控制,通过智能体和客户端分工协作,使智能体生成函数参数,而执行过程由客户端管理

数据存储(Data Stores):允许智能体访问结构化或非结构化数据,支持数据驱动的应用,超越模型原始训练数据的局限性。

智能体的未来发展

智能体技术仍处于快速发展阶段,未来将迎来更强大的推理能力和更复杂的工具集成。其中,以下趋势值得关注:

智能体链(Agent Chaining) 将成为主流:

• 通过组合多个专长智能体,每个智能体专注于特定领域或任务,形成**“智能体专家混合体(Mixture of Agent Experts)”**,从而在不同产业和问题领域提供卓越的解决方案。

构建复杂智能体架构需要迭代优化

实验与优化是关键,智能体架构应围绕具体业务需求 进行持续改进。

• 由于生成式模型的动态特性,每个智能体都是独特的,因此需要针对不同应用场景定制解决方案

结论

通过充分利用智能体的核心组件(模型、编排、工具),我们可以扩展语言模型的能力,构建出能创造现实价值的 AI 应用