原文:https://www.kaggle.com/whitepaper-agents当一个 Generative AI 模型同时具备推理能力、逻辑能力,并能够访问外部信息时,这种能力的融合就形成了“智能体(Agent)”这一概念。人类在处理复杂、无序的模式识别任务方面能力卓越,但在做出判断之前,往往需要借助工具——例如书籍、 Google Search 或计算器——来补充已有知识。类似地, Generative AI 模型也可以被训练去调用各种工具,从而获取实时信息或给出现实世界中的行动建议。例如,模型可以通过数据库检索工具获取特定数据,比如客户的购买历史,从而生成个性化的购物推荐。又或者,根据用户的请求,模型可以调用不同的 API,帮你向同事发送邮件回复,甚至代为完成一笔金融交易。要实现这些能力,模型不仅需要能够接入一系列外部工具,还必须具备以自我驱动方式进行任务规划与执行的能力。当推理能力、逻辑能力以及对外部信息的访问与 Generative AI 模型相结合时,就形成了“智能体(Agent)”这一概念——也就是一种能够超越单一 Generative AI 模型能力的程序。本文白皮书将对上述内容及其相关方面进行更深入的分析与探讨。从最基础的角度来看, Generative AI Agent 可以理解为一种应用系统:它通过观察外部世界,并借助自身可用的工具采取行动,从而实现既定目标。智能体具有自治性,在被赋予明确目标或任务时,能够在无需人类干预的情况下独立运行。同时,它们在实现目标的过程中也具备主动性——即使没有人类提供明确的指令,智能体也可以通过推理判断下一步该做什么,以逐步达成最终目标。虽然 AI 领域中“智能体”的概念本身非常广泛且能力强大,但本白皮书主要聚焦于当前 Generative AI 模型所能够构建的特定类型的智能体。为了更好地理解智能体是如何运作的,我们需要先介绍驱动其行为、动作以及决策的核心基础组件。这些组件组合在一起,构成了所谓的认知架构(Cognitive architecture)。通过不同方式对这些组件进行组合,可以形成多种不同的架构形式。围绕核心能力来看,一个智能体的认知架构主要由三个关键组件构成,如图 1 所示。图1:智能体Agent的通用架构及其组成部分
在智能体(Agent)体系中,“模型”通常指承担核心决策角色的语言模型(LM)。一个智能体可以使用一个或多个不同规模(小 / 大)的 LM,只要它们能够支持基于指令的推理与逻辑框架,例如 ReAct、 Chain-of-Thought 或 Tree-of-Thoughts。根据具体需求,模型可以是通用型模型、多模态模型,或者针对特定场景进行过微调的模型。为了在生产环境中取得更好的效果,应选择最契合目标应用的模型,并尽量确保该模型已经学习过与你在认知架构中所使用工具相关的数据模式。需要强调的是,模型本身通常不会基于智能体的具体配置(例如工具选择或推理编排方式)进行训练。不过,可以通过提供示例数据来进一步增强模型在智能体任务中的表现,这些示例可以展示智能体如何在不同场景下调用工具以及执行推理步骤,从而提升整体能力。尽管基础模型(Foundational models)在文本和图像生成方面已经非常强大,但由于无法直接与外部世界交互,其能力仍然受到一定限制。而“工具”的引入正是为了解决这一问题——它让智能体能够连接外部数据与服务,从而执行远超模型自身能力范围的操作。工具的形式多种多样,复杂度也不尽相同,但通常基于常见的 Web API 调用方式,例如 GET、POST、PATCH 和 DELETE。举例来说,工具可以用来更新数据库中的客户信息,或获取实时天气数据,从而影响智能体为用户生成的旅行建议。通过使用工具,智能体能够接入并处理真实世界的数据,这也使其能够支持更复杂的系统,例如检索增强生成(RAG),大幅提升其能力边界,超越基础模型单独所能达到的水平。后文会对工具展开更详细的说明,但这里最关键的一点是:工具充当了连接智能体内部能力与外部世界的桥梁,使其具备更丰富的应用可能性。编排层可以理解为智能体运行的“控制循环”,它决定了智能体如何接收信息、进行内部推理,并据此做出下一步的行动或决策。通常,这一循环会不断重复,直到智能体完成目标或达到预设的停止条件。根据不同的任务和智能体设计,编排层的复杂程度差异很大:简单场景下,它可能只是基于规则的计算流程;而在复杂场景中,则可能包含多步链式逻辑、结合额外的机器学习算法,甚至引入概率推理等方法。关于编排层的具体实现方式,我们将在后续的认知架构部分进行更深入的讲解。为了更直观地理解智能体与模型之间的差异,可以参考下面的对比表: | |
| 可以通过工具连接外部系统,从而不断扩展其可获取的知识范围 |
| 只针对用户输入进行一次性的推理或预测,且默认不具备会话历史或上下文管理能力(除非额外实现) | 能够维护会话历史,从而支持多轮交互,并结合用户输入以及编排层中的决策持续进行推理。在这里,“一轮(turn)”指的是一次完整的交互过程,即一次输入和一次响应 |
| |
| 默认没有内建的逻辑执行层,需要用户通过设计Prompt来引导其推理(例如使用 CoT、ReAct 等方法) | 内置了认知架构,可以直接利用这些推理框架,甚至结合如 LangChain 这样的现成智能体框架来完成更复杂的任务 |
可以把智能体的运作方式想象成一位在繁忙厨房中工作的厨师:他的目标是为顾客做出美味的菜品,而这一过程通常需要不断地进行规划、执行以及根据情况进行调整,形成一个循环。- 他们首先收集相关信息,比如顾客点了什么菜,以及厨房现有的食材情况(储藏室和冰箱)。
- 接着,根据这些信息进行思考和判断,决定可以做哪些菜,以及如何搭配风味。
- 然后开始实际操作,完成菜品制作,例如切菜、调配香料、煎肉等。
在整个过程中,厨师会在每一个环节根据实际情况不断调整:当食材减少或收到顾客反馈时,他们会持续优化原有计划,并结合之前的结果来决定下一步该怎么做。这种“获取信息 → 制定计划 → 执行操作 → 动态调整”的循环过程,正体现了一种帮助厨师达成目标的认知架构。类似地,智能体(Agents)也依赖认知架构来实现目标:它们通过不断地处理信息、做出合理决策,并根据已有结果持续优化后续行动。在这一体系中,编排层(Orchestration layer)是核心组件,负责管理记忆、状态,以及推理与规划过程。它结合快速发展的提示工程(Prompt engineering)及相关框架,引导智能体进行推理和决策,从而更高效地与环境交互并完成任务。当前,围绕语言模型的提示工程和任务规划的研究正快速演进,已经涌现出多种有潜力的方法。以下列举的是截至本文发布时较为主流的一些框架和推理技术(并非完整列表):- ReAct 是一种提示工程框架,它为语言模型提供了一套“先推理、再行动”的思考策略,使模型能够针对用户问题进行推理并执行相应操作,无论是否提供上下文示例(In-context examples)。实践表明,ReAct 在效果上优于多种当前主流的 SOTA 基线方法,同时还能提升大语言模型(LLMs)与人类交互时的可用性和可信度。
- Chain-of-Thought(CoT)是一类提示工程方法,通过引入“中间推理步骤”,让模型能够逐步展开思考,从而具备更强的推理能力。围绕 CoT 还发展出了多种变体技术,例如 self-consistency、active-prompt 和 multimodal CoT,不同方法在不同应用场景下各有优势与局限。
- Tree-of-thoughts(ToT)则是一种更适用于探索性问题或需要前瞻性规划任务的提示工程框架。它是在 Chain-of-thought 的基础上进一步扩展而来,使模型可以同时探索多条思维路径,并将这些路径作为中间推理过程,从而提升语言模型在复杂问题求解中的表现。
智能体(Agents)可以结合上述某一种或多种推理技术,来决定在面对用户请求时下一步最合适的行动。例如,假设有一个智能体被设计为使用 ReAct 框架来判断应采取的操作以及调用哪些工具,那么其处理流程大致会按照如下步骤展开:- 智能体向模型发送提示(Prompt),引导其生成下一步的 ReAct 推理步骤及对应结果,具体包括:
- Question:用户提出的问题(作为输入提供给模型)
- Thought:模型对“下一步该做什么”的思考过程
- 例如,可选行动包括 [Flights, Search, Code, None],其中前三个代表可用工具,最后一个表示不使用工具
- Action input:若选择使用工具,模型需要给出传入工具的参数或输入
- 上述 Thought / Action / Action input / Observation 的过程可以根据需要重复多次
- Final answer:模型最终生成并返回给用户的答案
图2:在编排层中集成 ReAct 推理机制的智能体示例
如图 2 所示,模型、工具以及智能体的整体配置相互配合,使得系统能够基于用户的原始问题,给出更可靠且简洁的回答。虽然模型本可以仅凭已有知识进行“猜测”(hallucinated)来生成答案,但它实际上选择调用工具(Flights)去获取实时的外部信息。在获得这些真实数据后,模型能够基于更充分的事实做出判断,并将整理后的结果准确地反馈给用户。总体来看,智能体输出结果的质量,很大程度上取决于模型在任务中进行推理与行动的能力——既包括能否选择合适的工具,也包括这些工具本身的定义是否合理。就像厨师需要用新鲜食材并根据顾客反馈不断调整菜品一样,智能体同样依赖扎实的推理能力和可靠的数据,才能产出最优结果。接下来一节,我们将进一步探讨智能体获取和连接实时数据的多种方式。虽然语言模型在信息理解和处理方面非常强大,但它们本身无法直接感知或影响现实世界,这使得它们在需要与外部系统或数据交互的场景中受到限制。从某种程度上讲,语言模型的能力边界取决于其训练数据——无论数据规模多大,这一限制始终存在。那么,如何让模型具备实时、具备上下文感知能力的外部交互能力呢?答案就是引入工具,例如 Functions、Extensions、Data Stores 和 Plugins,这些机制可以为模型补齐与外界交互的能力。尽管形式和名称不同,“工具”本质上都是连接基础模型(foundational models)与外部系统和数据的桥梁。有了这层连接,智能体不仅能执行更多类型的任务,还能显著提升结果的准确性和可靠性。例如,它可以控制智能家居设备、管理日历、查询数据库中的用户信息,甚至根据指令自动发送邮件。在当前阶段(截至本文发布), Google 模型主要支持三类工具:Extensions、Functions 和 Data Stores。通过引入这些工具,智能体不再只是“理解世界”,还能够“作用于世界”,从而释放出更广泛的应用潜力与创新空间。可以把 Extensions 理解为一种“标准化适配层”,它连接了 API 与智能体,使智能体无需关心底层实现细节,就可以直接调用各种 API。例如,假设你开发了一个用于帮助用户预订机票的智能体,并计划使用 Google Flights API 来获取航班信息,但问题在于:如何让智能体真正发起这些 API 调用?Extensions 正是用来解决这一问题的,它让智能体能够更自然、无缝地对接外部服务。图 3:智能体与外部 API 之间的交互方式示意图
一种常见做法是编写自定义代码:先接收用户请求,从中解析出关键信息,再据此调用 API。例如,在机票预订场景中,如果用户说“我想订一张从 Austin 飞往 Zurich 的机票”,系统就需要先识别出 “Austin” 和 “Zurich” 这两个关键信息,然后再发起 API 请求。但问题在于,如果用户只说“我想订一张去 Zurich 的机票”,却没有提供出发城市,该怎么办?由于缺少必要参数,API 调用会失败,这就需要额外编写代码来处理这些边界情况(edge cases)。这种方式不仅开发成本高,而且扩展性很差——一旦用户输入超出预设规则范围,系统就很容易出错,因此并不是一种理想的解决方案。一种更稳健、更可靠的方式是引入 Extension。它通过标准化的方式连接智能体与 API,主要体现在两点:- 明确告知智能体调用 API 所需的参数,从而确保调用能够成功执行。
图 4:通过 Extensions 实现智能体与外部 API 的连接
Extensions 可以独立开发,但在实际使用时需要作为智能体配置的一部分接入。在运行过程中,智能体会结合模型能力和示例信息,判断是否需要调用 Extension,以及应该选择哪一个来完成用户任务。这也体现了 Extensions 的核心优势:它内置示例机制,使智能体能够根据具体任务动态选择最合适的 Extension,从而提升整体灵活性与效果。图5:智能体、Extensions 与 API 之间的“一对多”关系示意图
可以把这个过程理解为软件开发者在解决用户需求时选择合适 API 的过程:如果用户要订机票,就调用 Google Flights API;如果用户想找附近的咖啡店,就调用 Google Maps API。同样地,在智能体系统中,Agent / Model 会基于已有的一组 Extensions,自动判断哪一个最适合当前用户请求,从而完成任务。如果你想亲自体验 Extensions,可以在 Gemini 应用中打开 Settings > Extensions,启用你感兴趣的扩展。例如,开启 Google Flights 扩展后,你可以向 Gemini 提问:“Show me flights from Austin to Zurich leaving next Friday.”,体验其效果。为了降低使用门槛, Google 提供了一些开箱即用的 Extensions,开发者可以将其快速集成到项目中,并通过简单配置直接使用。例如,Snippet 1 中的 Code Interpreter 扩展,就可以根据自然语言描述自动生成并执行 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)```
总的来说,Extensions 让智能体能够以多种方式感知、连接并作用于外部世界。而具体调用哪个 Extension,以及如何调用,都是由预先定义在配置中的示例(Examples)来引导的,从而使整个过程更加智能和灵活。在软件工程中,函数是用于完成特定任务的独立代码模块,可以被反复调用。开发者在编写程序时,通常会设计多个函数来处理不同功能,同时明确规定何时调用哪个函数,以及各自的输入输出。在智能体体系中,这一机制依然适用,只不过“做决策的人”从开发者变成了模型。模型会根据函数的定义,从已有函数集合中判断应该调用哪一个 Function,并确定所需的参数。不过,Functions 与 Extensions 存在一些关键区别:- 模型只会输出要调用的 Function 及其参数,并不会直接执行 API 请求;
- Functions 通常在客户端执行,而 Extensions 则是在智能体侧运行。
继续以 Google Flights 为例,一个典型的函数调用配置可以参考图 7。图 7:函数与外部 API 的交互方式示意图
需要注意,这里的关键区别在于:无论是 Function 还是智能体本身,都不会直接调用 Google Flights API。那么,真正的 API 请求是如何完成的呢?在 Functions 模式下,API 调用的具体逻辑和执行过程会从智能体中抽离出来,交由客户端应用来完成(如图 8 和图 9 所示)。这种设计让开发者可以对数据流和调用过程进行更精细的控制。开发者之所以选择 Functions 而不是 Extensions,通常有以下几种典型原因:- API 调用需要在智能体之外的系统层完成,例如通过中间件或前端框架处理;
- 出于安全或认证考虑,智能体无法直接访问 API(例如 API 未对外开放,或对智能体不可见);
- 由于执行时序限制,API 调用无法实时完成,例如需要批处理或人工审核等流程;
- 在某些情况下,API 返回的数据还需要进一步处理,而这些处理逻辑智能体本身无法完成。例如,如果某个 API 不支持结果过滤(如限制返回条数),那么开发者可以在客户端通过 Functions 对返回结果进行二次加工;
- 此外,如果开发者希望在不额外部署 API 服务的情况下快速迭代智能体能力,也可以使用 Function Calling 来模拟(stubbing)API 调用,从而加快开发流程。
虽然从架构上看(如图 8),Functions 与 Extensions 的差异并不算大,但 Functions 提供了更强的控制能力,并减少了对外部系统的依赖,这使其在实际开发中成为一个非常有吸引力的选择。图 8:Extensions 与 Function Calling 在客户端与智能体侧控制职责的划分示意图
在一些场景下,开发者希望由客户端来控制复杂的执行流程,而不是让语言模型直接负责 API 调用(这正是 Extensions 的典型方式)。这时,就可以通过调用函数( Functions )来实现。举个例子:假设我们构建了一个“旅行管家”( travel concierge )智能体,用于帮助用户规划度假行程。我们的目标是让智能体输出一组推荐城市列表,然后由中间件系统基于这些城市去获取图片、数据等信息,用于后续的行程规划。用户可能会这样提问:如果直接让模型生成回答,可能会得到类似这样的结果:虽然这些信息是我们需要的(城市名称),但这种自然语言格式并不方便程序解析。而通过 Function Calling,我们可以让模型以结构化格式(例如 JSON )输出结果,从而让下游系统更容易处理和使用这些数据。对于同样的用户输入,模型可以返回类似 Snippet 5 中那样的 JSON 结构结果。function_call { name: "display_cities" args: { "cities": ["Crested Butte", "Whistler", "Zermatt"], "preferences": "skiing" } }
这段 JSON 数据由模型生成后,会发送到客户端服务器,由开发者根据需要进行后续处理。在这个例子中,客户端会调用 Google Places API,根据模型返回的城市列表去查询对应的图片资源,并将这些内容整理成结构化的富媒体信息,再返回给用户。整个流程可以通过图 9 的时序图清晰地看到,它按步骤展示了从模型生成 JSON,到客户端处理,再到最终返回结果的完整交互过程。图 9:用于说明一次 Function Call 从触发到完成全过程的时序图
在图 9 的这个例子中,模型的作用是根据上下文“补全参数”,为客户端 UI 提供调用 Google Places API 所需的关键信息。而真正的 API 请求是由客户端完成的,模型只是提供了结构化的调用参数。这只是 Function Calling 的一种典型用法,实际还有很多适用场景,例如:- 当你希望模型推荐可用函数,但又不希望在代码中暴露敏感凭证时(因为函数不会被模型直接执行);
- 当任务是异步的、耗时较长(例如超过几秒)时,Function Calling 更加适合;
- 当函数需要在不同设备或系统中执行,而不是在生成调用请求的系统中执行时。
需要特别注意的是,Functions 的核心价值在于“控制权”——它让开发者不仅可以控制 API 是否调用、何时调用,还可以掌控整个应用的数据流转过程。在图 9 的设计中,开发者选择不把 API 返回结果再传回智能体,因为这些数据对后续决策没有帮助。但在其他系统架构下,也可以将这些外部数据反馈给智能体,从而影响其后续的推理、决策和行动。归根结底,是否回传数据、如何编排流程,都取决于具体应用场景,由开发者来权衡设计。为了在“滑雪度假推荐”这个场景中实现前面提到的结构化输出,我们需要搭建一套完整的组件,使其能够配合 gemini-2.0-flash-001 模型运行。第一步,是先定义一个基础函数 —— display_cities,并将其实现为一个简单的 Python 方法,作为后续 Function Calling 的核心调用单元。from typing import Optional 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
接下来,我们会完成几个关键步骤:初始化模型、构建 Tool,并将用户请求连同这些 tools 一并传入模型。当执行下面这段代码时,模型就会基于这些输入生成结果,其输出效果可以在代码示例的末尾看到。from google.genai import Client, types client = Client( vertexai=True, project="PROJECT_ID", location="us-central1" ) res = client.models.generate_content( model="gemini-2.0-flash-001", model="I'd like to take a ski trip with my family but I'm not sure where to go?", config=types.GenerateContentConfig( tools=[display_cities], automatic_function_calling=types.AutomaticFunctionCallingConfig(disable=True), tool_config=types.ToolConfig( function_calling_config=types.FunctionCallingConfig(mode='ANY') ) ) ) 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', 'Park City', 'Whistler']}
总结来看,Functions 提供了一种清晰且易用的机制,让开发者能够精细地掌控整个应用中的数据流转和执行流程,同时又能充分利用智能体 / 模型来生成关键参数或输入。开发者可以根据系统设计,自主决定是否将外部数据返回给智能体,使其持续参与决策(即保持“in the loop”),也可以在不需要时将其排除在外。这种灵活性使 Functions 能很好地适配不同的应用架构需求。可以把语言模型看作一个巨大的“知识图书馆”,其中存放的是训练阶段学习到的内容。但这个图书馆是“静态的”——它不会像现实世界那样不断更新新知识。这就带来了一个问题:现实世界的信息是持续变化的,而模型本身无法自动获取最新数据。为了解决这个问题,就引入了 Data Stores。它可以为模型提供动态、最新的数据来源,让模型的回答更加真实、准确,并保持与当前环境的相关性。一个常见的使用场景是:开发者需要给模型补充一些额外数据,比如一份 Excel 表格或 PDF 文档,让模型在回答问题时能够参考这些最新内容。图 10:智能体如何与结构化数据和非结构化数据进行交互
Data Stores 的核心价值在于:开发者可以直接把原始数据(无需预处理)交给智能体使用,而不需要进行复杂的数据转换、重新训练模型或做 fine-tuning。在内部,Data Store 会自动将这些文档转换为向量数据库中的 embeddings(向量表示)。智能体可以基于这些向量快速检索和提取关键信息,从而为下一步决策或生成回答提供更准确的数据支持。图 11:数据存储( Data Stores )将智能体连接到各种类型的实时数据源
在生成式 AI 智能体体系中,Data Stores 通常以“向量数据库”的形式存在,作为智能体在运行时可以访问的外部知识库。这里的核心概念是:数据会被转换为向量嵌入( embeddings ),也就是一种高维的数学表示形式,使模型能够基于语义进行检索和理解,而不仅仅是关键词匹配。当前最典型的应用场景,就是 检索增强生成( Retrieval Augmented Generation,RAG )。通过这种方式,模型可以突破训练数据的限制,从外部数据源中获取更多实时或专有知识,从而显著提升回答的准确性和覆盖范围。这些外部数据可以来自多种形式,例如:- 各类结构化文档(PDF、Word、CSV、电子表格等);
- 各类非结构化内容(HTML、PDF、TXT 等文本数据);
图 12:展示智能体与多个 Data Stores 的一对多关系,每个 Data Store 可以存放不同类型的预先索引的数据
每次用户请求与智能体响应的循环流程通常如下(见图 13):- 用户输入的查询首先被送入嵌入模型( embedding model ),生成对应的向量表示 ;
- 这些查询向量会与向量数据库中的内容进行匹配(可使用 SCaNN 等匹配算法) ;
- 匹配到的相关内容以文本形式从数据库中提取,并返回给智能体 ;
- 智能体综合用户查询和检索到的内容,生成相应的回答或执行相应动作 ;
- 最终生成的结果返回给用户,实现完整的问答或操作闭环;
图 13:展示在 检索增强生成(RAG) 应用中,用户请求从输入到智能体生成最终响应的完整流程
最终,这类应用可以让智能体通过 向量搜索 将用户查询与已有数据存储匹配,检索原始内容,并将信息传递给 编排层和模型 进行进一步处理。之后,智能体可能会直接向用户提供最终答案,或者进行额外的向量搜索来进一步精炼结果。图 14 展示了一个结合 RAG 和 ReAct 推理/规划 的智能体示例交互流程。图 14:展示了一个结合 RAG 与 ReAct 推理/规划 的智能体应用示例
总的来说,extensions、functions 和 data stores 是智能体在运行时可使用的几类工具。每种工具都有其独特功能,开发者可以根据需求选择单独使用,或者将它们组合起来以实现更复杂的任务。 | | | |
| | | |
| - 开发者希望智能体能够自主管理与 API 端点的交互;
- 在使用原生预构建 Extensions时非常实用;
- 支持 多步规划和 API 调用,即下一步操作可以根据前一步操作或 API 调用的结果来决定;
| - 时序或操作顺序限制:智能体无法实时发起 API 调用(例如批量处理或需要人工审核的场景);
- 访问限制:API 未对互联网开放,或者 Google 系统无法直接访问;
| - 结构化数据(如 PDF、Word 文档、CSV 文件、电子表格等) ;
- 非结构化数据(如 HTML、PDF、TXT 等);
|
模型能否高效生成输出,很大程度上取决于它选择正确工具的能力,尤其是在生产环境中大规模使用工具时。虽然通用训练能让模型掌握这一基本能力,但现实场景往往需要超出训练数据的专业知识。这就像掌握基础烹饪技能和精通某一特定菜系的区别:两者都需要基础知识,但精通特定菜系需要针对性的学习来获得更精细的结果。- 上下文学习(In-context learning):在推理过程中为模型提供Prompt、工具和少量示例,让模型“即时学习”如何以及何时使用这些工具来完成任务。ReAct 框架就是自然语言任务中这种方法的典型示例。
- 基于检索的上下文学习(Retrieval-based in-context learning):通过从外部存储检索最相关的信息、工具和示例,动态丰富模型提示。例如,Vertex AI 扩展中的 “Example Store”,或前文提到的基于 RAG 架构的数据存储。
- 微调学习(Fine-tuning based learning):在推理前使用大量特定示例数据对模型进行训练,使模型在接收用户查询前就能理解何时以及如何使用特定工具。
为了更直观地理解这些针对性学习方法,我们可以再次借用烹饪的比喻。- 想象一下,一位厨师收到了一份具体食谱(Prompt)、一些关键食材(相关工具)和几道示例菜品(少量示例),来自顾客的需求。依靠这些有限信息和他对烹饪的一般知识,厨师需要“即兴”制作出最符合食谱和顾客口味的菜肴——这就是上下文学习(In-context learning)的概念。
- 现在再想象,厨师在一个物资丰富的厨房里(外部数据存储),里面有各种食材和烹饪书(示例与工具)。他可以根据需要动态选择食材和参考书籍,使菜肴更贴近顾客的食谱和偏好。借助现有知识与新获取的信息,他能制作出更加精细、信息充足的菜肴,这就是基于检索的上下文学习(retrieval-based in-context learning)。
- 最后,假设我们让厨师回学校学习新的菜系或多种菜系(在更大、特定示例数据集上的预训练)。这样,当他面对之前未见过的顾客食谱时,就能用更深入的理解来应对。如果希望厨师在特定菜系(知识领域)表现卓越,这就是最合适的方法——微调学习(fine-tuning based learning)。
每种学习方法在速度、成本和延迟上各有优劣,但通过将它们结合到智能体框架中,我们可以发挥各自优势、弥补不足,从而打造更稳健、灵活的解决方案。为了展示一个可直接运行的智能体实例,我们将用 LangChain 和 LangGraph 库快速搭建一个原型。这些开源库非常受欢迎,用户可以通过将逻辑、推理和工具调用“串联”起来,构建能够回答用户查询的智能体。我们会使用 gemini-2.0-flash-001 模型,并结合一些简单工具来处理用户的多阶段查询,如代码片段 8 所示。在这个示例中,我们使用的工具包括 SerpAPI(用于 Google 搜索)和 Google Places API。运行代码片段 8 后,可以在代码片段 9 中看到示例输出。from langgraph.prebuilt import create_react_agent from langchain_core.tools import tool from langchain_community.utilities import SerpAPIWrapper from langchain_community.tools import GooglePlacesToolos.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-2.0-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()
============================== 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.
虽然这个智能体示例比较基础,但它清楚地展示了模型、编排层和工具如何协同运作,以达成特定目标。在最后一节,我们将进一步了解这些组件如何在 Google 级别的托管产品中协同工作,例如 Vertex AI 智能体和 Generative Playbooks。虽然本白皮书介绍了智能体的核心组件,但要构建真正的生产级应用,还需要结合额外的工具,如用户界面、评估框架和持续改进机制。Google 的 Vertex AI 平台通过提供完整的托管环境简化了这一过程,该环境已包含前文提到的所有基础元素。开发者可以通过自然语言界面快速定义智能体的关键组成——包括目标、任务指令、工具、用于任务分配的子智能体以及示例——轻松构建所需的系统行为。此外,平台还提供了测试、评估、性能监控、调试和质量优化等开发工具,让开发者可以专注于智能体的设计与优化,而不必操心基础设施、部署和运维的复杂性。图 15 展示了一个在 Vertex AI 平台上构建的智能体示例架构,使用了 Vertex Agent Builder、Vertex Extensions、Vertex Function Calling 和 Vertex Example Store 等功能,涵盖了生产级应用所需的核心组件。图 15:在 Vertex AI 平台上构建的端到端智能体示例架构
你可以在官方文档中体验这一预先构建的智能体架构示例。在本白皮书中,我们介绍了生成式 AI 智能体的核心构建模块、组成方式,以及如何通过认知架构来高效实现它们。几个关键结论如下:- 智能体可以通过使用工具访问实时信息、提供实际操作建议,并自主规划和执行复杂任务,从而完成语言模型单独难以或无法完成的工作。它们可以结合一个或多个语言模型来决定何时切换状态,并合理调用外部工具处理复杂任务。
- 智能体的核心是编排层,它是一种认知架构,用于组织推理、规划和决策,并指导行动。通过 ReAct、Chain-of-Thought、Tree-of-Thoughts 等推理技术,编排层能够收集信息、进行内部推理,并生成合理的决策或回答。
- 工具,如 Extensions、Functions 和 Data Stores,是智能体通向外部世界的钥匙,使其能够与外部系统交互并访问超出训练数据的知识。Extensions 让智能体能调用外部 API 并获取实时信息;Functions 允许开发者更精细地控制操作,使智能体生成参数后由客户端执行; Data Stores 为智能体提供访问结构化和非结构化数据的能力,从而实现数据驱动的应用。
未来,智能体将继续发展,能够解决更加复杂的问题。通过“智能体链”(Agent Chaining),可以组合不同领域的专长智能体,形成“专家混合”(Mixture of Agent experts),在各行业和任务中实现卓越表现。需要注意的是,构建复杂的智能体架构是一个迭代过程,需要不断实验和优化,以满足特定的业务需求。每个智能体都是独一无二的,但通过充分利用各个基础组件的优势,我们可以打造出强大的应用,扩展语言模型的能力,并创造切实的现实价值。