有效的记忆管理对于智能 Agent 保留信息至关重要。与人类类似,Agent 需要不同类型的记忆才能高效运行。本章深入探讨记忆管理,特别关注 Agent 的即时(短期)和持久(长期)记忆需求。
在 Agent 系统中,记忆指代 Agent 保留并利用过去交互、观察和学习经验中信息的能力。这种能力使 Agent 能够做出明智决策、维护对话上下文并随时间持续改进。Agent 记忆通常分为两大主要类型:
记忆管理对于 Agent 跟踪信息并随时间智能执行至关重要。这是 Agent 超越基本问答能力的必要条件。主要应用包括:
记忆使 Agent 能够维护历史、学习、个性化交互并管理复杂的时间依赖问题
Google Agent Developer Kit(ADK)提供了结构化的上下文和记忆管理方法,包含实际应用组件。深入理解 ADK 的 Session、State 和 Memory 对于构建需要保留信息的 Agent 至关重要。
与人类交互类似,Agent 需要能够回忆先前交流才能进行连贯自然的对话。ADK 通过三个核心概念及其关联服务简化了上下文管理。
与 Agent 的每次交互均可视为独特对话线程。Agent 可能需要访问早期交互数据。ADK 将其结构化如下:
ADK 为构建复杂、有状态和上下文感知 Agent 所需的关键组件提供专用服务。SessionService 通过处理 Session 对象的启动、记录和终止来管理聊天线程,而 MemoryService 监督长期知识(Memory)的存储和检索
SessionService 和 MemoryService 均提供多种配置选项,允许用户根据应用需求选择存储方法。记忆选项适用于测试目的,但数据不会在重启后保留。对于持久存储和可扩展性,ADK 还支持数据库和基于云的服务
ADK 中的 Session 对象旨在跟踪和管理单个聊天线程。在与 Agent 开始对话时,SessionService 生成一个 Session 对象,表示为 google.adk.sessions.Session。此对象封装了与特定对话线程相关的所有数据,包括唯一标识符(id、app_name、user_id)、作为 Event 对象的事件的时间顺序记录、用于会话特定临时数据的存储区域(称为 state)以及指示最后更新的时间戳(last_update_time)。开发人员通常通过 SessionService 间接与 Session 对象交互。SessionService 负责管理对话会话的生命周期,包括启动新会话、恢复先前的会话、记录会话活动(包括状态更新)、识别活动会话以及管理会话数据的删除。ADK 提供几种具有不同存储机制的 SessionService 实现,用于会话历史和临时数据,例如 InMemorySessionService,适合测试但不提供跨应用程序重启的数据持久性。
1 | ## 示例:使用 InMemorySessionService |
然后是 DatabaseSessionService,如果您想可靠地保存到您管理的数据库。
1 | ## 示例:使用 DatabaseSessionService |
此外,还有 VertexAiSessionService,它使用 Vertex AI 基础设施在 Google Cloud 上进行可扩展的生产。
1 | ## 示例:使用 VertexAiSessionService |
选择适当的 SessionService 至关重要,因为它决定了 Agent 的交互历史和临时数据的存储方式及其持久性。
每次消息交换都涉及一个循环过程:接收消息,Runner 使用 SessionService 检索或建立 Session,Agent 使用 Session 的上下文(状态和历史交互)处理消息,Agent 生成响应并可能更新状态,Runner 将其封装为 Event,session_service.append_event 方法记录新事件并更新存储中的状态。然后 Session 等待下一条消息。理想情况下,当交互结束时使用 delete_session 方法终止会话。此过程说明了 SessionService 如何通过管理特定于 Session 的历史和临时数据来维护连续性。
在 ADK 中,每个代表聊天线程的 Session 都包含 state 组件,类似于 Agent 在特定对话期间的临时工作记忆。虽然 session.events 记录整个聊天历史,但 session.state 存储和更新与活动聊天相关的动态数据点
从根本上讲,session.state 作为字典运行,以键值对形式存储数据。其核心功能是使 Agent 能够保留和管理对连贯对话至关重要的详细信息,如用户偏好、任务进度、增量数据收集或影响后续 Agent 操作的条件标志
状态结构包含字符串键与可序列化 Python 类型值的配对,包括字符串、数字、布尔值、列表及包含这些基本类型的字典。State 是动态的,在整个对话过程中不断演变。这些更改的持久性取决于配置的 SessionService
可使用键前缀定义数据范围和持久性来组织状态。无前缀的键是会话特定的
Agent 通过单个 session.state 字典访问所有状态数据。SessionService 处理数据检索、合并和持久性。应在通过 session_service.append_event() 向会话历史添加 Event 时更新状态。这确保了准确跟踪、在持久服务中的正确保存以及状态更改的安全处理
1 | ## 从 Google Agent Developer Kit (ADK) 导入必要的类 |
在幕后,Runner 看到您的 output_key,并在调用 append_event 时自动创建具有 state_delta 的必要操作。
1 | import time |
此代码演示了一种基于工具的方法来管理应用程序中的用户会话状态。它定义了一个函数 log_user_login,充当工具。此工具负责在用户登录时更新会话状态。
该函数接受由 ADK 提供的 ToolContext 对象,以访问和修改会话的状态字典。在工具内部,它递增 user:login_count,将 task_status 设置为”active”,记录 user:last_login_ts(时间戳),并添加临时标志 temp:validation_needed。
代码的演示部分模拟了如何使用此工具。它设置了内存会话服务并创建了具有一些预定义状态的初始会话。然后手动创建 ToolContext 以模拟 ADK Runner 执行工具的环境。使用此模拟上下文调用 log_user_login 函数。最后,代码再次检索会话以显示状态已通过工具的执行更新。目标是展示将状态更改封装在工具中如何使代码比直接在工具外部操作状态更清晰、更有组织。
请注意,强烈不建议在检索会话后直接修改 session.state 字典,因为它会绕过标准事件处理机制。这种直接更改不会记录在会话的事件历史中,可能不会被选定的 SessionService 持久化,可能导致并发问题,并且不会更新时间戳等基本元数据。更新会话状态的推荐方法是在 LlmAgent 上使用 output_key 参数(专门用于 Agent 的最终文本响应)或在通过 session_service.append_event() 追加事件时在 EventActions.state_delta 中包含状态更改。session.state 应主要用于读取现有数据。
总而言之,在设计状态时,保持简单,使用基本数据类型,为键提供清晰的名称并正确使用前缀,避免深度嵌套,并始终使用 append_event 过程更新状态。
在 Agent 系统中,Session 组件维护当前聊天历史(events)和特定于单个对话的临时数据(state)的记录。然而,为使 Agent 在多次交互中保留信息或访问外部数据,需要长期知识管理。这由 MemoryService 促进实现
1 | ## 示例:使用 InMemoryMemoryService |
Session 和 State 可概念化为单个聊天会话的短期记忆,而由 MemoryService 管理的长期知识则充当持久且可搜索的存储库。此存储库可能包含来自多个过往交互或外部来源的信息。由 BaseMemoryService 接口定义的 MemoryService 为管理这种可搜索的长期知识建立了标准。其主要功能包括添加信息(涉及从会话中提取内容并使用 add_session_to_memory 方法存储)以及检索信息(允许 Agent 查询存储并使用 search_memory 方法接收相关数据)
ADK 提供了几种实现来创建这种长期知识存储。InMemoryMemoryService 提供适合测试目的的临时存储解决方案,但数据不会在应用重启后保留。对于生产环境,通常使用 VertexAiRagMemoryService。此服务利用 Google Cloud 的检索增强生成(RAG)服务,实现可扩展、持久和语义搜索功能(另请参阅第 14 章关于 RAG)
1 | ## 示例:使用 VertexAiRagMemoryService |
在 LangChain 和 LangGraph 中,Memory 是创建智能自然对话应用的关键组件。它使 AI Agent 能够记住过去交互信息、从反馈中学习并适应用户偏好。LangChain 的记忆功能通过引用存储历史来丰富当前提示,然后记录最新交换供将来使用,从而提供此基础。随着 Agent 处理更复杂任务,这种能力对效率和用户满意度变得至关重要
短期记忆: 这是线程范围的,意味着它跟踪单个会话或线程内正在进行的对话。它提供即时上下文,但完整历史可能挑战 LLM 的上下文窗口,导致错误或性能下降。LangGraph 将短期记忆作为 Agent 状态的一部分管理,该状态通过检查点器持久化,允许随时恢复线程
长期记忆: 存储跨会话的用户特定或应用级数据,在对话线程间共享。它保存在自定义”命名空间”中,可在任何线程的任何时间调用。LangGraph 提供存储来保存和调用长期记忆,使 Agent 能无限期保留知识
LangChain 提供了多种工具管理对话历史,从手动控制到链内自动集成
ChatMessageHistory:手动记忆管理 对于在正式链外直接简单控制对话历史,ChatMessageHistory 类是理想选择。它允许手动跟踪对话交换
1 | from langchain.memory import ChatMessageHistory |
ConversationBufferMemory:链的自动化记忆。要将记忆直接集成到链中,ConversationBufferMemory 是一个常见的选择。它保存对话的缓冲区并使其可用于您的提示词。其行为可以通过两个关键参数自定义:
1 | from langchain.memory import ConversationBufferMemory |
将此内存集成到 LLMChain 中允许模型访问对话的历史并提供上下文相关的响应
1 | from langchain_openai import OpenAI |
为了提高聊天模型的有效性,建议通过设置 return_messages=True 使用消息对象的结构化列表。
1 | from langchain_openai import ChatOpenAI |
长期记忆类型:长期记忆允许系统在不同对话中保留信息,提供更深层次上下文和个性化。可分解为类似人类记忆的三种类型:
下面是演示 Agent 如何使用反思来更新存储在 LangGraph BaseStore 中的程序记忆的伪代码
1 | ## 更新 agent 指令的节点 |
LangGraph 将长期记忆存储为存储中的 JSON 文档。每个记忆都在自定义命名空间(如文件夹)和不同的键(如文件名)下组织。这种分层结构允许轻松组织和检索信息。以下代码演示了如何使用 InMemoryStore 放置、获取和搜索记忆。
1 | from langgraph.store.memory import InMemoryStore |
Memory Bank 是 Vertex AI Agent Engine 中的托管服务,为 Agent 提供持久长期内存。该服务使用 Gemini 模型异步分析对话历史以提取关键事实和用户偏好
此信息持久存储,按定义范围(如用户 ID)组织,并智能更新以整合新数据并解决矛盾。开始新会话时,Agent 通过完全数据调用或使用嵌入的相似性搜索检索相关记忆。此过程允许 Agent 跨会话维护连续性并根据回忆信息个性化响应
Agent 的 runner 与 VertexAiMemoryBankService 交互,后者首先初始化。此服务处理 Agent 对话期间生成记忆的自动存储。每个记忆标记有唯一 USER_ID 和 APP_NAME,确保将来准确检索
1 | from google.adk.memory import VertexAiMemoryBankService |
Memory Bank 提供与 Google ADK 的无缝集成,提供即开即用体验。对于使用其他 Agent 框架(如 LangGraph 和 CrewAI)的用户,Memory Bank 还通过直接 API 调用提供支持。演示这些集成的在线代码示例可供感兴趣读者使用
是什么::Agent 系统需要记住过去交互信息以执行复杂任务并提供连贯体验。没有记忆机制,Agent 是无状态的,无法维护对话上下文、从经验中学习或为用户个性化响应。这从根本上将其限制在简单一次性交互中,无法处理多步骤过程或不断变化的用户需求。核心问题是如何有效管理单个对话的即时临时信息和随时间收集的大量持久知识
为什么: 标准化解决方案是实现区分短期和长期存储的双组件记忆系统。短期的上下文记忆在 LLM 的上下文窗口内保存最近交互数据以维护对话流程。对于必须持久的信息,长期记忆解决方案使用外部数据库(通常是向量存储)实现高效语义检索。像 Google ADK 这样的 Agent 框架提供特定组件来管理此过程,如用于对话线程的 Session 和用于其临时数据的 State。专用的 MemoryService 用于与长期知识库交互,允许 Agent 检索相关的过去信息并将其纳入当前上下文
经验法则: 当 Agent 需要做的不仅仅是回答单个问题时使用此模式。对于必须在整个对话中维护上下文、跟踪多步骤任务进度或通过回忆用户偏好和历史来个性化交互的 Agent,这是必不可少的。每当 Agent 预期基于过去成功、失败或新获得信息进行学习或适应时,实现记忆管理
视觉摘要

图 1:内存管理设计模式
快速回顾内存管理的核心要点:
本章深入探讨了 Agent 系统内存管理的重要工作,展示了短暂上下文与长期持久知识间的区别。我们讨论了这些内存类型的设置方式以及在构建更智能 Agent 时的应用场景。我们详细了解了 Google ADK 如何提供 Session、State 和 MemoryService 等特定组件来处理此过程。既然已介绍 Agent 如何记住事物(短期和长期),我们可以继续探讨它们如何学习和适应。下一个模式”学习和适应”关注 Agent 根据新经验或数据改变其思考、行动或所知的方式
虽然单体 Agent 架构对于定义明确的问题可能是有效的,但在面对复杂的多领域任务时,其能力往往受到限制。多 Agent 协作模式通过将系统构建为由不同专门化 Agent 组成的协作集合来解决这些限制。这种方法基于任务分解原则,其中高级目标被分解为离散的子问题。然后将每个子问题分配给拥有最适合该任务的特定工具、数据访问或推理能力的 Agent。
例如,一个复杂的研究查询可能被分解并分配给研究 Agent 进行信息检索、数据分析 Agent 进行统计处理,以及综合 Agent 生成最终报告。这种系统的效能不仅仅源于劳动分工,而是关键依赖于 Agent 间通信的机制。这需要标准化的通信协议和共享本体,允许 Agent 交换数据、委托子任务并协调其行动以确保最终输出的连贯性。
这种分布式架构提供了几个优势,包括增强的模块化、可扩展性和稳健性,因为单个 Agent 的故障不一定会导致整个系统故障。协作允许产生协同结果,其中多 Agent 系统的集体性能超过集合内任何单个 Agent 的潜在能力。
多 Agent 协作模式涉及设计系统,其中多个独立或半独立的 Agent 协同工作以实现共同目标。每个 Agent 通常具有定义的角色、与总体目标一致的特定目标,并且可能访问不同的工具或知识库。此模式的力量在于这些 Agent 之间的交互和协同作用。
协作可以采取各种形式:
顺序交接: 一个 Agent 完成任务并将其输出传递给另一个 Agent 以进行管道中的下一步(类似于规划模式,但明确涉及不同的 Agent)。
并行处理: 多个 Agent 同时处理问题的不同部分,然后它们的结果稍后被组合。
辩论和共识: 多 Agent 协作,其中具有不同观点和信息来源的 Agent 进行讨论以评估选项,最终达成共识或更明智的决策。
层次结构: 管理者 Agent 可能根据其工具访问或插件能力动态地将任务委托给工作 Agent,并综合其结果。每个 Agent 还可以处理相关的工具组,而不是单个 Agent 处理所有工具。
专家团队: 在不同领域具有专业知识的 Agent(例如,研究员、作家、编辑)协作产生复杂输出。
多 Agent 系统(见图 1)从根本上包括 Agent 角色和职责的界定、Agent 通过其交换信息的通信渠道的建立,以及指导其协作努力的任务流或交互协议的制定。

图 1:多 Agent 系统示例
像 CrewAI 和 Google ADK 这样的框架旨在通过提供 Agent、任务及其交互程序的规范结构来促进这种范式。这种方法对于需要各种专业知识、包含多个离散阶段或利用并发处理和跨 Agent 信息确认优势的挑战特别有效。
多 Agent 协作是一种适用于众多领域的强大模式:
界定专门 Agent 并细致编排其相互关系的能力使开发人员能够构建展现增强模块化、可扩展性以及处理单个集成 Agent 无法解决的复杂性的系统。
理解 Agent 交互和通信的复杂方式对于设计有效的多 Agent 系统至关重要。如图 2 所示,存在一系列相互关系和通信模型,从最简单的单 Agent 场景到复杂的、定制设计的协作框架。每个模型都呈现独特的优势和挑战,影响多 Agent 系统的整体效率、稳健性和适应性。
1. 单 Agent: 在最基本的层面上,”单 Agent”在没有与其他实体直接交互或通信的情况下自主运行。虽然此模型易于实现和管理,但其能力固有地受到单个 Agent 范围和资源的限制。它适用于可分解为独立子问题的任务,每个子问题都可由单个自给自足的 Agent 解决。
2. 网络: “网络”模型代表了向协作迈出的重要一步,其中多个 Agent 以去中心化方式直接相互交互。通信通常以点对点方式进行,允许共享信息、资源甚至任务。此模型促进弹性,因为一个 Agent 的故障不一定会使整个系统瘫痪。然而,管理通信开销并确保大型非结构化网络中的连贯决策可能具有挑战性。
3. 监督者: 在”监督者”模型中,专用 Agent(”监督者”)监督和协调一组下属 Agent 的活动。监督者充当通信、任务分配和冲突解决的中心枢纽。这种层次结构提供了清晰的权限线,可以简化管理和控制。然而,它引入了单点故障(监督者),如果监督者被大量下属或复杂任务压倒,可能会成为瓶颈。
4. 监督者作为工具: 此模型是”监督者”概念的细微扩展,其中监督者的角色不太关乎直接命令和控制,而更多关乎向其他 Agent 提供资源、指导或分析支持。监督者可能提供工具、数据或计算服务,使其他 Agent 能够更有效地执行其任务,而不必规定其每一个行动。这种方法旨在利用监督者的能力,而不施加严格的自上而下控制。
5. 层次化: “层次化”模型扩展了监督者概念,创建了多层组织结构。这涉及多个监督者级别,高级监督者监督低级监督者,最终在最低层有一组操作 Agent。此结构非常适合可分解为子问题的复杂问题,每个子问题由层次结构的特定层管理。它提供了一种结构化的可扩展性和复杂性管理方法,允许在定义的边界内进行分布式决策。

图 2:Agent 以各种方式进行通信和交互。
6. 自定义: “自定义”模型代表了多 Agent 系统设计的终极灵活性。它允许创建根据给定问题或应用程序的特定要求精确定制的独特相互关系和通信结构。这可能涉及结合前述模型元素的混合方法,或从环境的独特约束和机会中产生的全新设计。自定义模型通常源于需要针对特定性能指标进行优化、处理高度动态的环境或将特定领域知识纳入系统架构。设计和实现自定义模型通常需要对多 Agent 系统原理有深入理解,并仔细考虑通信协议、协调机制和涌现行为。
总之,为多 Agent 系统选择相互关系和通信模型是关键的设计决策。每个模型提供不同的优势和劣势,最佳选择取决于诸如任务复杂性、Agent 数量、期望的自主程度、对稳健性的需求以及可接受的通信开销等因素。多 Agent 系统的未来进展可能会继续探索和完善这些模型,以及开发协作智能的新范式。
此 Python 代码使用 CrewAI 框架定义了一个 AI 驱动的团队来生成关于 AI 趋势的博客文章。它首先设置环境,从 .env 文件加载 API 密钥。应用程序的核心涉及定义两个 Agent:一个研究员用于查找和总结 AI 趋势,一个作家用于基于研究创建博客文章。
相应地定义了两个任务:一个用于研究趋势,另一个用于撰写博客文章,写作任务依赖于研究任务的输出。然后将这些 Agent 和任务组装成一个团队,指定顺序流程,其中任务按顺序执行。团队使用 Agent、任务和语言模型(特别是”gemini-2.0-flash”模型)初始化。主函数使用 kickoff() 方法执行此团队,编排 Agent 之间的协作以产生所需的输出。最后,代码打印团队执行的最终结果,即生成的博客文章。
1 | import os |
我们现在将深入研究 Google ADK 框架中的更多示例,特别强调层次化、并行和顺序协调范式,以及将 Agent 实现为操作工具。
以下代码示例演示了通过创建父子关系在 Google ADK 中建立层次化 Agent 结构。代码定义了两种类型的 Agent:LlmAgent 和从 BaseAgent 派生的自定义 TaskExecutor Agent。TaskExecutor 专为特定的非 LLM 任务而设计,在此示例中,它只是生成”任务成功完成”事件。使用指定的模型和指令初始化名为 greeter 的 LlmAgent,以充当友好的欢迎者。自定义 TaskExecutor 实例化为 task_doer。创建名为 coordinator 的父 LlmAgent,也带有模型和指令。coordinator 的指令引导它将欢迎委托给 greeter,将任务执行委托给 task_doer。greeter 和 task_doer 作为子 Agent 添加到 coordinator,建立父子关系。然后代码断言此关系设置正确。最后,它打印一条消息,指示已成功创建 Agent 层次结构。
1 | from google.adk.agents import LlmAgent, BaseAgent |
此代码摘录说明了在 Google ADK 框架中使用 LoopAgent 建立迭代工作流。代码定义了两个 Agent:ConditionChecker 和 ProcessingStep。ConditionChecker 是一个自定义 Agent,检查会话状态中的”status”值。如果”status”为”completed”,ConditionChecker 升级事件以停止循环。否则,它生成事件以继续循环。ProcessingStep 是使用”gemini-2.0-flash-exp”模型的 LlmAgent。其指令是执行任务,如果是最后一步则将会话”status”设置为”completed”。创建名为 StatusPoller 的 LoopAgent。StatusPoller 配置为 max_iterations=10。StatusPoller 包括 ProcessingStep 和 ConditionChecker 实例作为子 Agent。LoopAgent 将顺序执行子 Agent 最多 10 次迭代,如果 ConditionChecker 发现状态为”completed”则停止。
1 | import asyncio |
此代码摘录阐明了 Google ADK 中的 SequentialAgent 模式,专为构建线性工作流而设计。此代码使用 google.adk.agents 库定义顺序 Agent 管道。管道由两个 Agent 组成,step1 和 step2。step1 命名为”Step1_Fetch”,其输出将存储在会话状态中的键”data”下。step2 命名为”Step2_Process”,并被指示分析存储在 session.state[“data”] 中的信息并提供摘要。名为”MyPipeline”的 SequentialAgent 编排这些子 Agent 的执行。当使用初始输入运行管道时,step1 将首先执行。来自 step1 的响应将保存到键”data”下的会话状态中。随后,step2 将执行,根据其指令利用 step1 放入状态的信息。此结构允许构建工作流,其中一个 Agent 的输出成为下一个 Agent 的输入。这是创建多步 AI 或数据处理管道的常见模式。
1 | from google.adk.agents import SequentialAgent, LlmAgent # Changed Agent to LlmAgent |
以下代码示例说明了 Google ADK 中的 ParallelAgent 模式,它促进多个 Agent 任务的并发执行。data_gatherer 设计为并发运行两个子 Agent:weather_fetcher 和 news_fetcher。weather_fetcher Agent 被指示获取给定位置的天气并将结果存储在 session.state[“weather_data”] 中。同样,news_fetcher Agent 被指示检索给定主题的头条新闻故事并将其存储在 session.state[“news_data”] 中。每个子 Agent 都配置为使用”gemini-2.0-flash-exp”模型。ParallelAgent 编排这些子 Agent 的执行,允许它们并行工作。来自 weather_fetcher 和 news_fetcher 的结果将被收集并存储在会话状态中。最后,示例展示了如何在 Agent 执行完成后从 final_state 访问收集的天气和新闻数据。
1 | from google.adk.agents import LlmAgent, ParallelAgent # Changed Agent to LlmAgent |
提供的代码段示例了 Google ADK 中的”Agent 作为工具”范式,使 Agent 能够以类似于函数调用的方式利用另一个 Agent 的能力。具体来说,代码使用 Google 的 LlmAgent 和 AgentTool 类定义了一个图像生成系统。它由两个 Agent 组成:父 artist_agent 和子 Agent image_generator_agent。generate_image 函数是一个简单的工具,模拟图像创建,返回模拟图像数据。image_generator_agent 负责根据其接收的文本提示词使用此工具。artist_agent 的角色是首先发明一个创意图像提示词。然后它通过 AgentTool 包装器调用 image_generator_agent。AgentTool 充当桥梁,允许一个 Agent 将另一个 Agent 用作工具。当 artist_agent 调用 image_tool 时,AgentTool 使用艺术家发明的提示词调用 image_generator_agent。image_generator_agent 然后使用该提示词使用 generate_image 函数。最后,生成的图像(或模拟数据)通过 Agent 返回。此架构演示了一个分层 Agent 系统,其中更高级别的 Agent 编排较低级别的专门 Agent 以执行任务。
1 | from google.adk.agents import LlmAgent |
是什么: 复杂问题通常超出单个单体基于 LLM 的 Agent 的能力。单个 Agent 可能缺乏解决多方面任务所有部分所需的多样化专业技能或对特定工具的访问。此限制造成瓶颈,降低系统的整体效率和可扩展性。因此,处理复杂的多领域目标变得低效,并可能导致不完整或次优的结果。
为什么: 多 Agent 协作模式通过创建多个协作 Agent 的系统提供了标准化解决方案。复杂问题被分解为更小的更易于管理的子问题。然后将每个子问题分配给具有解决它所需的精确工具和能力的专门 Agent。这些 Agent 通过定义的通信协议和交互模型(如顺序交接、并行工作流或层次化委托)协同工作。这种 Agent 化的分布式方法创造了协同效应,使团队能够实现任何单个 Agent 都无法实现的结果。
经验法则: 当任务对于单个 Agent 来说太复杂并且可以分解为需要专业技能或工具的不同子任务时,使用此模式。它非常适合受益于多样化专业知识、并行处理或具有多个阶段的结构化工作流的问题,例如复杂的研究和分析、软件开发或创意内容生成。
视觉摘要

图 3:多 Agent 设计模式
本章探讨了多 Agent 协作模式,展示了在系统内编排多个专门 Agent 的好处。我们研究了各种协作模型,强调该模式在跨不同领域解决复杂多方面问题中的关键作用。理解 Agent 协作自然会引出对其与外部环境交互的探究。
智能行为通常不仅仅涉及对即时输入做出反应。它需要远见、将复杂任务分解为更小的可管理步骤,以及制定实现期望结果的策略。这就是规划模式发挥作用的地方。规划的核心是 Agent 或 Agent 系统制定一系列行动以从初始状态向目标状态移动的能力。
在 AI 的背景下,将规划 Agent 视为您委托复杂目标的专家是有帮助的。当您要求它”组织团队外出活动”时,您定义的是”什么”——目标及其约束——而不是”如何”。Agent 的核心任务是自主规划实现该目标的路线。它必须首先理解初始状态(例如,预算、参与者人数、期望日期)和目标状态(成功预订的外出活动),然后发现连接它们的最佳行动序列。计划并不是预先知道的;它是响应请求而创建的。
这个过程的标志是适应性。初始计划仅仅是一个起点,而不是僵化的脚本。Agent 的真正力量在于其整合新信息并引导项目绕过障碍的能力。例如,如果首选场地变得不可用或选择的餐饮服务商已完全预订,一个有能力的 Agent 不会简单地失败。它会适应:记录新的约束,重新评估选项,并制定新计划,也许通过建议替代场地或日期。
然而,认识到灵活性和可预测性之间的权衡至关重要。动态规划是一个特定的工具,而不是通用解决方案。当问题的解决方案已经被充分理解且可重复时,将 Agent 限制为预定的固定工作流更有效。这种方法限制 Agent 的自主性以减少不确定性和不可预测行为的风险,保证可靠和一致的结果。因此,使用规划 Agent 与简单任务执行 Agent 的决定取决于一个问题:是否需要发现”如何”,还是已经知道?
规划模式是自主系统中的核心计算过程,使 Agent 能够综合一系列行动以实现指定目标,特别是在动态或复杂环境中。这个过程将高级目标转换为由离散可执行步骤组成的结构化计划。
在过程任务自动化等领域,规划用于编排复杂的工作流。例如,像新员工入职这样的业务流程可以分解为定向的子任务序列,例如创建系统帐户、分配培训模块和与不同部门协调。Agent 生成一个计划以逻辑顺序执行这些步骤,调用必要的工具或与各种系统交互以管理依赖关系。
在机器人和自主导航中,规划对于状态空间遍历是基础性的。一个系统,无论是物理机器人还是虚拟实体,都必须生成路径或行动序列以从初始状态转换到目标状态。这涉及优化时间或能源消耗等指标,同时遵守环境约束,如避开障碍物或遵守交通规则。
此模式对于结构化信息综合也至关重要。当被要求生成像研究报告这样的复杂输出时,Agent 可以制定一个包括信息收集、数据总结、内容结构化和迭代完善的不同阶段的计划。同样,在涉及多步问题解决的客户支持场景中,Agent 可以创建并遵循诊断、解决方案实施和升级的系统计划。
从本质上讲,规划模式允许 Agent 从简单的反应性行动转向目标导向的行为。它提供了解决需要一系列相互依赖操作的问题所必需的逻辑框架。
以下部分将演示使用 Crew AI 框架实现规划模式。此模式涉及一个 Agent,它首先制定多步计划以解决复杂查询,然后顺序执行该计划。
1 | import os |
此代码使用 CrewAI 库创建一个 AI Agent,该 Agent 规划并撰写关于给定主题的摘要。它首先导入必要的库,包括 CrewAI 和 langchain_openai,并从 .env 文件加载环境变量。明确定义了一个 ChatOpenAI 语言模型供 Agent 使用。创建了一个名为 planner_writer_agent 的 Agent,具有特定的角色和目标:规划然后撰写简洁的摘要。Agent 的背景故事强调其在规划和技术写作方面的专业知识。定义了一个任务,明确描述首先创建计划,然后撰写关于”强化学习在 AI 中的重要性”主题的摘要,并为预期输出指定了特定格式。组建了一个包含 Agent 和任务的团队,设置为顺序处理它们。最后,调用 crew.kickoff() 方法执行定义的任务并打印结果。
Google Gemini DeepResearch(见图 1)是一个基于 Agent 的系统,设计用于自主信息检索和综合。它通过多步 Agent 管道运行,动态和迭代地查询 Google 搜索以系统地探索复杂主题。该系统设计用于处理大量基于网络的资源,评估收集的数据的相关性和知识差距,并执行后续搜索以解决它们。最终输出将经过审核的信息整合成一个结构化的多页摘要,并附有原始来源的引用。
进一步扩展,该系统的运行不是单个查询-响应事件,而是一个受管理的长时间运行过程。它首先将用户的提示词分解为多点研究计划(见图 1),然后呈现给用户审查和修改。这允许在执行之前协作塑造研究轨迹。一旦计划获得批准,Agent 管道就会启动其迭代搜索和分析循环。这不仅仅是执行一系列预定义的搜索;Agent 根据收集的信息动态制定和完善其查询,主动识别知识差距、确认数据点并解决差异。

图 1:Google Deep Research Agent 生成使用 Google 搜索作为工具的执行计划。
关键的架构组件是系统异步管理此过程的能力。这种设计确保了调查(可能涉及分析数百个来源)对单点故障具有弹性,并允许用户脱离并在完成时收到通知。系统还可以集成用户提供的文档,将来自私有来源的信息与其基于网络的研究相结合。最终输出不仅仅是发现的串联列表,而是一个结构化的多页报告。在综合阶段,模型对收集的信息进行批判性评估,识别主要主题并将内容组织成具有逻辑部分的连贯叙述。该报告设计为交互式的,通常包括音频概述、图表和指向原始引用来源的链接等功能,允许用户验证和进一步探索。除了综合结果外,模型还明确返回它搜索和咨询的完整来源列表(见图 2)。这些作为引用呈现,提供完全的透明度和对主要信息的直接访问。整个过程将简单的查询转换为全面的、综合的知识体。

图 2:Deep Research 计划执行的示例,导致使用 Google 搜索作为工具搜索各种网络来源。
通过减轻手动数据获取和综合所需的大量时间和资源投资,Gemini DeepResearch 为信息发现提供了更结构化和详尽的方法。该系统的价值在跨各个领域的复杂、多方面研究任务中尤为明显。
例如,在竞争分析中,可以指示 Agent 系统地收集和整理关于市场趋势、竞争对手产品规格、来自各种在线来源的公众情绪和营销策略的数据。这个自动化过程取代了手动跟踪多个竞争对手的繁重任务,使分析师能够专注于更高层次的战略解释而不是数据收集(见图 3)。

图 3:Google Deep Research Agent 生成的最终输出,代表我们分析使用 Google 搜索作为工具获得的来源。
同样,在学术探索中,该系统作为进行广泛文献综述的强大工具。它可以识别和总结基础论文,追踪概念在众多出版物中的发展,并绘制特定领域内新兴研究前沿的地图,从而加速学术探究的初始和最耗时的阶段。
这种方法的效率源于迭代搜索和过滤周期的自动化,这是手动研究的核心瓶颈。通过系统处理比人类研究人员在可比时间框架内通常可行的更大量和更多样化的信息来源来实现全面性。这种更广泛的分析范围有助于减少选择偏差的潜力,并增加发现不太明显但可能至关重要的信息的可能性,从而导致对主题更稳健和充分支持的理解。
OpenAI Deep Research API 是一个专门设计用于自动化复杂研究任务的工具。它利用一个先进的 Agent 模型,可以独立推理、规划和从现实世界来源综合信息。与简单的问答模型不同,它接受高级查询并自主将其分解为子问题,使用其内置工具执行网络搜索,并提供结构化的、富含引用的最终报告。该 API 提供对整个过程的直接程序化访问,在撰写本文时使用 o3-deep-research-2025-06-26 等模型进行高质量综合,以及更快的 o4-mini-deep-research-2025-06-26 用于延迟敏感的应用程序。
Deep Research API 很有用,因为它自动化了原本需要数小时的手动研究,提供适合为业务战略、投资决策或政策建议提供信息的专业级、数据驱动的报告。其主要好处包括:
要使用 API,您向 client.responses.create 端点发送请求,指定模型、输入提示词和 Agent 可以使用的工具。输入通常包括定义 Agent 角色和期望输出格式的 system_message,以及 user_query。您还必须包括 web_search_preview 工具,并可以选择添加其他工具,如 code_interpreter 或自定义 MCP 工具(见第 10 章)用于内部数据。
1 | from openai import OpenAI |
此代码片段利用 OpenAI API 执行”深度研究”任务。它首先使用您的 API 密钥初始化 OpenAI 客户端,这对于身份验证至关重要。然后,它将 AI Agent 的角色定义为专业研究员,并设置用户关于司美格鲁肽经济影响的研究问题。代码构造对 o3-deep-research-2025-06-26 模型的 API 调用,提供定义的系统消息和用户查询作为输入。它还请求推理的自动摘要并启用网络搜索功能。进行 API 调用后,它提取并打印最终生成的报告。
随后,它尝试访问并显示报告注释中的内联引用和元数据,包括引用文本、标题、URL 和报告中的位置。最后,它检查并打印模型采取的中间步骤的详细信息,例如推理步骤、网络搜索调用(包括执行的查询)以及如果使用了代码解释器的任何代码执行步骤。
是什么: 复杂问题通常无法通过单个操作解决,需要远见才能实现期望的结果。没有结构化的方法,Agent 系统难以处理涉及多个步骤和依赖关系的多方面请求。这使得将高级目标分解为一系列可管理的更小可执行任务变得困难。因此,系统无法有效地制定策略,在面对复杂目标时导致不完整或不正确的结果。
为什么: 规划模式通过让 Agent 系统首先创建一个连贯的计划来解决目标提供了标准化解决方案。它涉及将高级目标分解为一系列更小的可操作步骤或子目标。这允许系统管理复杂的工作流、编排各种工具并以逻辑顺序处理依赖关系。LLM 特别适合这一点,因为它们可以基于其庞大的训练数据生成合理且有效的计划。这种结构化方法将简单的反应性 Agent 转变为战略执行者,可以主动朝着复杂目标工作,甚至在必要时调整其计划。
经验法则: 当用户的请求太复杂而无法通过单个操作或工具处理时使用此模式。它非常适合自动化多步流程,例如生成详细的研究报告、新员工入职或执行竞争分析。每当任务需要一系列相互依赖的操作以达到最终的综合结果时,应用规划模式。
视觉摘要
图 4;规划设计模式
总之,规划模式是将 Agent 系统从简单的反应性响应者提升为战略性、目标导向的执行者的基础组件。现代大型语言模型为此提供了核心能力,自主地将高级目标分解为连贯的可操作步骤。此模式从简单的顺序任务执行(如 CrewAI Agent 创建并遵循写作计划所演示的)扩展到更复杂和动态的系统。Google DeepResearch Agent 体现了这种高级应用,创建基于持续信息收集而适应和演化的迭代研究计划。最终,规划为复杂问题的人类意图和自动化执行之间提供了必要的桥梁。通过构建问题解决方法,此模式使 Agent 能够管理复杂的工作流并提供全面的综合结果。
到目前为止,我们讨论的 Agent 模式主要涉及编排语言模型之间的交互和管理 Agent 内部工作流中的信息流(链式、路由、并行化、反思)。然而,要使 Agent 真正有用并与现实世界或外部系统交互,它们需要使用工具的能力。
工具使用模式通常通过一种称为函数调用的机制实现,使 Agent 能够与外部 API、数据库、服务交互,甚至执行代码。它允许位于 Agent 核心的大型语言模型(LLM)根据用户请求或任务当前状态,决定何时以及如何使用特定的外部函数。
该过程通常包括:
此模式是基础性的,因为它打破了 LLM 训练数据的限制,允许它访问最新信息、执行它内部无法完成的计算、与用户特定数据交互或触发现实世界的行动。函数调用是连接 LLM 推理能力与可用的大量外部功能之间差距的技术机制。
虽然”函数调用”准确描述了调用特定预定义代码函数的过程,但考虑更广泛的”工具调用”概念会更有益。这个更广泛的术语承认 Agent 的能力可以远远超出简单的函数执行。”工具”可以是传统函数,也可以是复杂的 API 端点、数据库查询请求,甚至是针对其他专门 Agent 的指令。这种视角使我们能够设想更复杂的系统,例如,主 Agent 可能将复杂的数据分析任务委托给专用的”分析师 Agent”,或通过 API 查询外部知识库。以”工具调用”的思维方式,能更好地捕捉 Agent 作为跨数字资源和其他智能实体生态系统的编排者的全部潜力。
像 LangChain、LangGraph 和 Google Agent Developer Kit (ADK) 这样的框架为定义工具并将它们集成到 Agent 工作流中提供了强大的支持,通常利用现代 LLM(如 Gemini 或 OpenAI 系列中的那些)的原生函数调用能力。在这些框架的”画布”上,您定义工具,然后配置 Agent(通常是 LLM Agent)以意识到并能够使用这些工具。
工具使用是构建强大、交互式和外部感知 Agent 的基石模式。
工具使用模式几乎适用于 Agent 需要超越生成文本来执行操作或检索特定动态信息的任何场景:
工具使用将语言模型从文本生成器转变为能够在数字或物理世界中感知、推理和行动的 Agent(见图 1)

图 1:Agent 使用工具的一些示例
在 LangChain 框架中实现工具使用是一个两阶段过程。首先,定义一个或多个工具,通常通过封装现有的 Python 函数或其他可运行组件。随后,将这些工具绑定到语言模型,从而赋予模型在确定需要外部函数调用以满足用户查询时生成结构化工具使用请求的能力。
以下实现将通过定义一个简单的函数来模拟信息检索工具,以此演示此原理。随后,将构建并配置一个 Agent 以利用此工具响应用户输入。执行此示例需要安装核心 LangChain 库和特定于模型的提供程序包。此外,使用所选语言模型服务的适当身份验证(通常通过在本地环境中配置的 API 密钥)是必要的先决条件。
1 | import os, getpass |
代码使用 LangChain 库和 Google Gemini 模型设置了一个工具调用 Agent。它定义了一个 search_information 工具,模拟为特定查询提供事实答案。该工具对”weather in london”、”capital of france”和”population of earth”有预定义的响应,以及其他查询的默认响应。初始化了一个 ChatGoogleGenerativeAI 模型,确保其具有工具调用能力。创建了一个 ChatPromptTemplate 来指导 Agent 的交互。使用 create_tool_calling_agent 函数将语言模型、工具和提示词组合成一个 Agent。然后设置一个 AgentExecutor 来管理 Agent 的执行和工具调用。定义了 run_agent_with_tool 异步函数以使用给定查询调用 Agent 并打印结果。main 异步函数准备多个要并发运行的查询。这些查询旨在测试 search_information 工具的特定和默认响应。最后,asyncio.run(main()) 调用执行所有 Agent 任务。代码包括在继续 Agent 设置和执行之前成功 LLM 初始化的检查。
此代码提供了如何在 CrewAI 框架中实现函数调用(工具)的实际示例。它设置了一个简单的场景,其中 Agent 配备了查找信息的工具。该示例专门演示了使用此 Agent 和工具获取模拟股票价格。
1 | ## pip install crewai langchain-openai |
此代码演示了使用 CrewAI 库模拟财务分析任务的简单应用程序。它定义了一个自定义工具 get_stock_price,模拟查找预定义股票代码的价格。该工具设计为对有效代码返回浮点数,或对无效代码引发 ValueError。创建了一个名为 financial_analyst_agent 的 CrewAI Agent,角色为高级财务分析师。该 Agent 被赋予 get_stock_price 工具进行交互。定义了一个任务 analyze_aapl_task,专门指示 Agent 使用工具查找 AAPL 的模拟股票价格。任务描述包括关于使用工具时如何处理成功和失败情况的明确说明。组建了一个团队,包含 financial_analyst_agent 和 analyze_aapl_task。为 Agent 和团队启用了详细设置,以在执行期间提供详细日志。脚本的主要部分在标准 if name == “main“: 块中使用 kickoff() 方法运行团队的任务。在启动团队之前,它会检查是否设置了 OPENAI_API_KEY 环境变量,这是 Agent 运行所必需的。然后将团队执行的结果(即任务的输出)打印到控制台。代码还包括基本日志配置,以更好地跟踪团队的行动和工具调用。它使用环境变量进行 API 密钥管理,尽管它指出对于生产环境建议使用更安全的方法。简而言之,核心逻辑展示了如何定义工具、Agent 和任务,以在 CrewAI 中创建协作工作流。
1 | from google.adk.agents import Agent |
此代码演示了如何使用 Python 的 Google ADK 创建和使用由 Google ADK 驱动的基本 Agent。该 Agent 设计为通过利用 Google 搜索作为工具来回答问题。首先,从 IPython、google.adk 和 google.genai 导入必要的库。定义了应用程序名称、用户 ID 和会话 ID 的常量。创建了一个名为”basic_search_agent”的 Agent 实例,带有描述和说明指示其目的。它被配置为使用 Google 搜索工具,这是 ADK 提供的预构建工具。初始化 InMemorySessionService(见第 8 章)以管理 Agent 的会话。为指定的应用程序、用户和会话 ID 创建新会话。实例化 Runner,将创建的 Agent 与会话服务链接。此运行器负责在会话中执行 Agent 的交互。定义了辅助函数 call_agent 以简化向 Agent 发送查询和处理响应的过程。在 call_agent 内部,用户的查询被格式化为具有角色”user”的 types.Content 对象。使用用户 ID、会话 ID 和新消息内容调用 runner.run 方法。runner.run 方法返回表示 Agent 操作和响应的事件列表。代码遍历这些事件以查找最终响应。如果事件被识别为最终响应,则提取该响应的文本内容。提取的 Agent 响应然后打印到控制台。最后,使用查询”最新的 AI 新闻是什么?”调用 call_agent 函数以演示 Agent 的运行情况。
代码执行: Google ADK 具有用于专门任务的集成组件,包括用于动态代码执行的环境。built_in_code_execution 工具为 Agent 提供沙盒 Python 解释器。这允许模型编写和运行代码以执行计算任务、操作数据结构和执行程序脚本。这种功能对于解决需要确定性逻辑和精确计算的问题至关重要,这超出了概率语言生成本身的范围。
1 | import os, getpass |
此脚本使用 Google 的 Agent Development Kit (ADK) 创建一个通过编写和执行 Python 代码解决数学问题的 Agent。它定义了一个 LlmAgent,专门指示其充当计算器,为其配备 built_in_code_execution 工具。主要逻辑位于 call_agent_async 函数中,该函数向 Agent 的运行器发送用户查询并处理结果事件。在此函数内部,异步循环遍历事件,打印生成的 Python 代码及其执行结果以进行调试。代码仔细区分这些中间步骤和包含数值答案的最终事件。最后,main 函数使用两个不同的数学表达式运行 Agent,以演示其执行计算的能力。
企业搜索: 此代码使用 Python 中的 google.adk 库定义了一个 Google ADK 应用程序。它专门使用 VSearchAgent,该 Agent 旨在通过搜索指定的 Vertex AI 搜索数据存储来回答问题。代码初始化一个名为”q2_strategy_vsearch_agent”的 VSearchAgent,提供描述、要使用的模型(”gemini-2.0-flash-exp”)和 Vertex AI 搜索数据存储的 ID。DATASTORE_ID 预期设置为环境变量。然后为 Agent 设置 Runner,使用 InMemorySessionService 管理对话历史。定义了异步函数 call_vsearch_agent_async 以与 Agent 交互。此函数接受查询,构造消息内容对象,并调用运行器的 run_async 方法将查询发送到 Agent。然后该函数将 Agent 的响应流式传输回控制台。它还打印有关最终响应的信息,包括来自数据存储的任何源归因。包含错误处理以捕获 Agent 执行期间的异常,提供有关潜在问题(如数据存储 ID 不正确或缺少权限)的信息性消息。提供了另一个异步函数 run_vsearch_example 以演示如何使用示例查询调用 Agent。主执行块检查 DATASTORE_ID 是否已设置,然后使用 asyncio.run 运行示例。它包括检查以处理在已有运行事件循环的环境(如 Jupyter 笔记本)中运行代码的情况。
1 | import asyncio |
总的来说,此代码为构建利用 Vertex AI 搜索根据存储在数据存储中的信息回答问题的对话式 AI 应用程序提供了基本框架。它演示了如何定义 Agent、设置运行器以及在流式传输响应的同时异步与 Agent 交互。重点是从特定数据存储检索和综合信息以回答用户查询。
Vertex Extensions: Vertex AI 扩展是一个结构化的 API 包装器,使模型能够连接到外部 API 以进行实时数据处理和操作执行。扩展提供企业级安全性、数据隐私和性能保证。它们可用于生成和运行代码、查询网站以及分析来自私有数据存储的信息等任务。Google 为常见用例提供预构建扩展,如代码解释器和 Vertex AI 搜索,并可选择创建自定义扩展。扩展的主要好处包括强大的企业控制和与其他 Google 产品的无缝集成。扩展和函数调用之间的关键区别在于它们的执行:Vertex AI 自动执行扩展,而函数调用需要用户或客户端手动执行。
是什么: 大型语言模型(LLM)是强大的文本生成器,但它们基本上与外部世界断开连接。它们的知识是静态的,仅限于训练数据,并且缺乏执行操作或检索实时信息的能力。这种固有的限制阻止它们完成需要与外部 API、数据库或服务交互的任务。没有通往这些外部系统的桥梁,它们解决现实世界问题的效用受到严重限制。
为什么: 工具使用模式(通常通过函数调用实现)为此问题提供了标准化解决方案。它的工作原理是以 LLM 可以理解的方式向其描述可用的外部函数或”工具”。基于用户的请求,Agent LLM 可以决定是否需要工具,并生成指定要调用哪个函数以及使用什么参数的结构化数据对象(如 JSON)。编排层执行此函数调用,检索结果,并将其反馈给 LLM。这允许 LLM 将最新的外部信息或操作结果合并到其最终响应中,有效地赋予其行动能力。
经验法则: 当 Agent 需要突破 LLM 的内部知识并与外部世界交互时,使用工具使用模式。这对于需要实时数据(例如,检查天气、股票价格)、访问私有或专有信息(例如,查询公司数据库)、执行精确计算、执行代码或触发其他系统中的操作(例如,发送电子邮件、控制智能设备)的任务至关重要。
视觉摘要:

图 2:工具使用设计模式
工具使用模式是将大型语言模型的功能范围扩展到其固有文本生成能力之外的关键架构原则。通过为模型配备与外部软件和数据源交互的能力,此范式允许 Agent 执行操作、进行计算并从其他系统检索信息。此过程涉及模型在确定满足用户查询需要时生成调用外部工具的结构化请求。LangChain、Google ADK 和 CrewAI 等框架提供结构化抽象和组件,促进这些外部工具的集成。这些框架管理向模型公开工具规范并解析其后续工具使用请求的过程。这简化了可以与外部数字环境交互并在其中采取行动的复杂 Agent 系统的开发。
在前面的章节中,我们探讨了基础的 Agent 模式:顺序执行的链式、动态路径选择的路由以及并发任务执行的并行化。这些模式使 Agent 能够更高效、更灵活地执行复杂任务。然而,即使采用复杂的工作流,Agent 的初始输出或计划也可能并非最优、准确或完整。这正是反思模式发挥关键作用之处。
反思模式涉及 Agent 评估其自身工作、输出或内部状态,并利用该评估来提升性能或优化响应。这是一种自我纠正或自我改进机制,允许 Agent 基于反馈、内部评审或与预期标准的对比,迭代优化其输出或调整策略。反思有时可由专门的 Agent 来促进,其特定职责是分析初始 Agent 的输出。
与简单顺序链(输出直接传递至下一步)或路径选择的路由不同,反思引入了反馈循环。Agent 不仅产生输出,还会检查该输出(或其生成过程),识别潜在问题或改进空间,并运用这些洞察生成更好的版本或调整后续行动。
该过程通常包含以下步骤:
反思模式的一个关键且高效的实现是将流程分离为两个不同的逻辑角色:生产者和评审者。这通常被称为”生成器-评审者”或”生产者-审查者”模型。虽然单个 Agent 可执行自我反思,但使用两个专门 Agent(或两个具有不同系统提示的独立 LLM 调用)通常能产生更稳健和客观的结果。
生产者 Agent:此 Agent 的主要职责是执行任务的初始工作。它完全专注于内容生成,无论是编写代码、起草博客文章还是制定计划。它接收初始提示并生成输出的第一版
评审者 Agent:此 Agent 的唯一目的是评估生产者生成的输出。它被赋予不同的指令集,通常承担特定角色(如”高级软件工程师”、”严谨的事实核查员”)。评审者的指令引导其根据特定标准分析生产者工作,包括事实准确性、代码质量、风格要求或完整性。其设计目标是发现缺陷、提出改进建议并提供结构化反馈
这种关注点分离非常有效,因为它避免了 Agent 审查自身工作时可能产生的”认知偏差”。评审者 Agent 以全新视角处理输出,完全专注于发现错误和改进空间。评审者的反馈随后传回生产者 Agent,生产者 Agent 以此为指南生成新的优化版本。提供的 LangChain 和 ADK 代码示例均实现了这种双 Agent 模型:LangChain 示例使用特定的”reflector_prompt”创建评审者角色,而 ADK 示例明确定义了生产者和审查者 Agent。
实现反思通常需要在 Agent 工作流中构建这些反馈循环。这可通过代码中的迭代循环实现,或使用支持基于评估结果进行状态管理和条件转换的框架。虽然单步评估和优化可在 LangChain/LangGraph、ADK 或 Crew.AI 链中实现,但真正的迭代反思通常涉及更复杂的编排。
反思模式对于构建能够产出高质量输出、处理精细任务并展现一定自我意识和适应性的 Agent 至关重要。它推动 Agent 从单纯执行指令转向更复杂的问题解决和内容生成形式。
值得注意的是反思与目标设定和监控(见第 11 章)的交叉点。目标为 Agent 的自我评估提供最终基准,而监控跟踪其进展。在许多实际案例中,反思可能充当纠正引擎,利用监控反馈分析偏差并调整策略。这种协同作用将 Agent 从被动执行者转变为有目的地自适应工作以实现目标。
此外,当 LLM 保持对话记忆(见第 8 章)时,反思模式的有效性显著增强。对话历史为评估阶段提供关键上下文,使 Agent 不仅能孤立评估输出,还能在先前交互、用户反馈和演进目标的背景下进行评估。这使 Agent 能从过去的评审中学习并避免重复错误。没有记忆时,每次反思都是独立事件;有了记忆,反思成为累积过程,每个周期都基于前一个周期,从而实现更智能和上下文感知的优化。
反思模式在输出质量、准确性或复杂约束遵循度至关重要的场景中极具价值:
反思为 Agent 系统增加了元认知层,使其能从自身输出和过程中学习,从而产生更智能、可靠和高质量的结果
实现完整的迭代反思过程需要状态管理和循环执行机制。虽然这些在基于图的框架(如 LangGraph)中内置处理或通过自定义程序代码实现,但单个反思周期的基本原理可通过 LCEL(LangChain 表达式语言)的组合语法有效演示。
此示例使用 Langchain 库和 OpenAI 的 GPT-4o 模型实现反思循环,迭代生成并优化计算数字阶乘的 Python 函数。该过程从任务提示开始,生成初始代码,然后基于模拟高级软件工程师角色的评审反复反思代码,在每次迭代中优化代码,直至评审阶段确认代码完美或达到最大迭代次数。最后打印优化后的代码。
首先确保安装必要库:
1 | pip install langchain langchain-community langchain-openai |
您还需要使用所选语言模型的 API 密钥配置环境(如 OpenAI、Google Gemini、Anthropic)
1 | import os |
代码首先设置环境,加载 API 密钥,并使用低温度初始化强大的语言模型(如 GPT-4o)以获得专注输出。核心任务由提示定义,要求创建计算数字阶乘的 Python 函数,包括文档字符串、边界情况(0 的阶乘)和负输入错误处理的特定要求。run_reflection_loop 函数协调迭代优化过程。在循环中,第一次迭代时语言模型根据任务提示生成初始代码,后续迭代中则基于前一步的评审优化代码。单独的”反思者”角色(同样由语言模型扮演但使用不同系统提示)充当高级软件工程师,根据原始任务要求评审生成的代码。此评审以问题项目符号列表或短语 ‘CODE_IS_PERFECT’(如无问题)形式提供。循环持续至评审指示代码完美或达到最大迭代次数。对话历史被维护并在每一步传递给语言模型,为生成/优化和反思阶段提供上下文。最后,脚本在循环结束后打印最终生成的代码版本
现在让我们看一个使用 Google ADK 实现的概念性代码示例。具体而言,代码通过采用生成器-评审者结构来展示,其中一个组件(生成器)产生初始结果或计划,另一个组件(评审者)提供批判性反馈或评审,引导生成器朝向更优化或准确的最终输出
1 | from google.adk.agents import SequentialAgent, LlmAgent |
此代码演示了在 Google ADK 中使用顺序 Agent 管道生成和审查文本。它定义了两个 LlmAgent 实例:generator 和 reviewer。generator Agent 设计用于创建关于给定主题的初始草稿段落,被指示撰写简短信息丰富的文章,并将其输出保存至状态键 draft_text。reviewer Agent 作为生成器产出文本的事实核查员,被指示从 draft_text 读取文本并验证其事实准确性。评审者的输出是包含两个键的结构化字典:status 和 reasoning。status 指示文本为”ACCURATE”或”INACCURATE”,reasoning 则提供状态解释。此字典保存至状态键 review_output。创建名为 review_pipeline 的 SequentialAgent 来管理两个 Agent 的执行顺序,确保生成器先运行,然后是评审者。整体执行流程为:生成器产出文本并保存至状态,随后评审者从状态读取文本,执行事实核查,并将其发现(状态和推理)保存回状态。此管道允许使用独立 Agent 进行结构化内容创建和审查过程。注意: 对于感兴趣者,还提供了利用 ADK 的 LoopAgent 的替代实现。
结束前需考虑,虽然反思模式显著提升输出质量,但也带来重要权衡。迭代过程虽强大,但可能导致更高成本和延迟,因为每个优化循环可能需要新的 LLM 调用,使其对时间敏感应用并非最优选择。此外,该模式内存密集;随着每次迭代,对话历史扩展,包含初始输出、评审和后续优化
是什么: Agent 的初始输出通常次优,存在不准确、不完整或未满足复杂要求的问题。基础 Agent 工作流缺乏 Agent 识别和修复自身错误的内置流程。这通过让 Agent 评估自身工作,或更稳健地引入独立逻辑 Agent 充当评审者来解决,防止无论质量如何初始响应都成为最终结果
为什么: 反思模式通过引入自我纠正和优化机制提供解决方案。它建立反馈循环,其中”生产者” Agent 生成输出,然后”评审者” Agent(或生产者自身)根据预定义标准进行评估。随后使用此评审生成改进版本。这种生成、评估和优化的迭代过程逐步提升最终结果质量,从而产生更准确、连贯和可靠的结果
经验法则: 当最终输出的质量、准确性和细节比速度和成本更重要时使用反思模式。它对生成精炼长篇内容、编写调试代码以及创建详细计划等任务特别有效。当任务需要通用生产者 Agent 可能遗漏的高客观性或专门评估时,使用独立评审者 Agent
视觉摘要

图 1:反思设计模式,自我反思

图 2:反思设计模式,生产者和评审者 Agent
反思模式为 Agent 工作流中的自我纠正提供关键机制,实现超越单次执行的迭代改进。这是通过创建循环实现的:系统生成输出,根据特定标准评估,然后使用该评估产生优化结果。此评估可由 Agent 自身(自我反思)执行,或通常更有效地由不同评审者 Agent 执行,这代表了模式内的关键架构选择
虽然完全自主的多步反思过程需要强大的状态管理架构,但其核心原理可在单个生成-评审-优化周期中有效演示。作为控制结构,反思可与其他基础模式集成,以构建更健壮和功能更复杂的 Agent 系统
以下是有关反思模式和相关概念的一些进一步阅读资源:
在前面的章节中,我们探讨了用于顺序工作流的提示链和用于动态决策及不同路径间转换的路由。虽然这些模式不可或缺,但许多复杂的 Agent 任务涉及多个可同时执行而非顺序执行的子任务。这正是并行化模式变得至关重要的场景。
并行化涉及并发执行多个组件,包括 LLM 调用、工具使用乃至整个子 Agent(见图 1)。与等待一个步骤完成再开始下一个步骤不同,并行执行允许独立任务同时运行,从而显著缩短可分解为独立部分的任务的总执行时间。
设想一个旨在研究主题并总结其发现的 Agent。顺序方法可能如下:
而并行方法则可改为:
其核心思想在于识别工作流中不依赖其他部分输出的环节并并行执行。这在处理具有延迟的外部服务(如 API 或数据库)时尤其有效,因为您可以并发发出多个请求。
实现并行化通常需要支持异步执行或多线程/多进程的框架。现代 Agent 框架在设计时已充分考虑异步操作,使您能够轻松定义可并行运行的步骤。

图 1. 带有子 Agent 的并行化示例
像 LangChain、LangGraph 和 Google ADK 这样的框架提供了并行执行机制。在 LangChain 表达式语言(LCEL)中,您可以通过使用运算符(如 | 用于顺序)组合可运行对象来实现并行执行,并通过构建支持分支并发执行的链或图。LangGraph 凭借其图结构,允许您定义可从单个状态转换执行的多个节点,从而在工作流中有效启用并行分支。Google ADK 提供了强大的原生机制来促进和管理 Agent 的并行执行,显著提升了复杂多 Agent 系统的效率和可扩展性。ADK 框架的这一固有能力使开发人员能够设计并实现多个 Agent 并发而非顺序操作的解决方案。
并行化模式对于提升 Agent 系统的效率和响应能力至关重要,特别是在处理涉及多个独立查询、计算或与外部服务交互的任务时。这是优化复杂 Agent 工作流性能的关键技术。
并行化是优化 Agent 性能的强大模式,适用于多种应用场景:
并行化是 Agent 设计中的基础优化技术,使开发人员能够通过利用独立任务的并发执行来构建更高性能和响应更快的应用程序。
LangChain 框架中的并行执行由 LangChain 表达式语言(LCEL)实现。主要方法是在字典或列表结构中组织多个可运行组件。当该集合作为输入传递给链中的后续组件时,LCEL 运行时会并发执行其中包含的可运行对象。
在 LangGraph 中,这一原理应用于图的拓扑结构。并行工作流通过设计图结构来定义,使得多个无直接顺序依赖关系的节点可从单个公共节点启动。这些并行路径独立执行,其结果可在图中的后续汇聚点进行聚合。
以下实现展示了使用 LangChain 框架构建的并行处理工作流。该工作流设计用于响应单个用户查询并发执行多个独立操作。这些并行过程被实例化为不同的链或函数,各自的输出随后被聚合成统一结果。
此实现的先决条件包括安装必要的 Python 包,如 langchain、langchain-community 以及模型提供商库(如 langchain-openai)。此外,还需在本地环境中配置所选语言模型的有效 API 密钥以完成身份验证。
1 | import os |
提供的 Python 代码实现了一个 LangChain 应用程序,旨在通过并行执行高效处理给定主题。请注意,asyncio 提供的是并发性而非真正的并行性。它通过事件循环在单线程上实现这一点,在任务空闲时(如等待网络请求)智能地在任务间切换。这创造了多个任务同时进行的效果,但代码实际上仍由单个线程执行,受 Python 全局解释器锁(GIL)限制。
代码首先从 langchain_openai 和 langchain_core 导入必要模块,包括语言模型、提示模板、输出解析器和可运行结构组件。代码尝试初始化 ChatOpenAI 实例,使用”gpt-4o-mini”模型并设置温度参数以控制创造性。语言模型初始化采用 try-except 块以确保健壮性。随后定义三个独立的 LangChain”链”,每个链设计用于对输入主题执行不同任务:第一个链负责简洁总结主题,第二个链生成与主题相关的三个有趣问题,第三个链从输入主题中识别 5-10 个关键术语并以逗号分隔。每个独立链都由针对特定任务定制的 ChatPromptTemplate、初始化的语言模型和用于字符串格式输出的 StrOutputParser 组成。
然后构建 RunnableParallel 块来捆绑这三个链以实现同时执行。此并行可运行对象还包含 RunnablePassthrough 以确保原始输入主题可用于后续步骤。为最终综合步骤定义了单独的 ChatPromptTemplate,接收摘要、问题、关键术语和原始主题作为输入以生成全面答案。完整的端到端处理链(full_parallel_chain)通过将 map_chain(并行块)连接到综合提示模板,再接入语言模型和输出解析器来创建。提供的异步函数 run_parallel_example 演示了如何调用此完整并行链,该函数接收主题作为输入并使用 invoke 运行异步链。最后,标准 Python if name == “main“: 块展示了如何使用示例主题”太空探索的历史”执行 run_parallel_example,通过 asyncio.run 管理异步执行。
本质上,此代码建立了一个工作流,对给定主题同时执行多个 LLM 调用(用于总结、生成问题和提取术语),最终通过另一个 LLM 调用整合结果。这展示了在 Agent 工作流中使用 LangChain 实现并行化的核心思想。
现在让我们关注 Google ADK 框架中说明这些概念的具体示例。我们将探讨如何应用 ADK 原语(如 ParallelAgent 和 SequentialAgent)来构建利用并发执行提升效率的 Agent 流程。
1 | from google.adk.agents import LlmAgent, ParallelAgent, SequentialAgent |
此代码定义了一个用于研究和综合可持续技术进展信息的多 Agent 系统。系统设置了三个 LlmAgent 实例作为专门的研究员:ResearcherAgent_1 专注于可再生能源,ResearcherAgent_2 研究电动汽车技术,ResearcherAgent_3 调查碳捕获方法。每个研究员 Agent 配置使用 GEMINI_MODEL 和 google_search 工具,被指示用 1-2 句话简洁总结发现,并通过 output_key 将摘要存储在会话状态中。
随后创建名为 ParallelWebResearchAgent 的 ParallelAgent 来并发运行这三个研究员 Agent,实现并行研究以节省时间。当所有子 Agent(研究员)完成并填充状态后,ParallelAgent 结束执行。
接下来定义 MergerAgent(同样是 LlmAgent)来综合研究结果。该 Agent 以并行研究员存储在会话状态中的摘要作为输入,其指令强调输出必须严格基于提供的输入摘要,禁止添加外部知识。MergerAgent 旨在将组合的发现结构化为带有各主题标题和简短总体结论的报告。
最后创建名为 ResearchAndSynthesisPipeline 的 SequentialAgent 来协调整个工作流。作为主控制器,该主 Agent 首先执行 ParallelAgent 进行研究,待其完成后执行 MergerAgent 综合收集的信息。sequential_pipeline_agent 被设置为 root_agent,作为运行此多 Agent 系统的入口点。整个过程旨在高效地从多个来源并行收集信息,并将其整合为单一结构化报告。
是什么: 许多 Agent 工作流包含多个必须完成才能达成最终目标的子任务。纯顺序执行(每个任务等待前一个完成)通常低效且缓慢。当任务依赖外部 I/O 操作(如调用不同 API 或查询多个数据库)时,这种延迟成为主要瓶颈。若无并发执行机制,总处理时间等于所有单个任务持续时间之和,严重制约系统整体性能和响应能力。
为什么: 并行化模式通过启用独立任务的同时执行提供标准化解决方案。该模式通过识别工作流中不依赖彼此即时输出的组件(如工具使用或 LLM 调用)来实现。像 LangChain 和 Google ADK 这样的 Agent 框架提供内置构造来定义和管理这些并发操作。例如,主进程可调用多个并行运行的子任务,等待所有子任务完成后再继续下一步。通过同时而非顺序执行这些独立任务,该模式显著减少总执行时间。
经验法则: 当工作流包含多个可同时运行的独立操作时使用此模式,例如从多个 API 获取数据、处理不同数据块或生成多个内容片段供后续综合。
视觉摘要

图 2:并行化设计模式
以下是本章的核心要点:
并行化模式是通过并发执行独立子任务来优化计算工作流的方法。该模式有效减少整体延迟,在涉及多个模型推理或对外部服务调用的复杂操作中尤为显著。
不同框架为此模式提供了不同的实现机制。在 LangChain 中,通过 RunnableParallel 等构造显式定义并同时执行多个处理链。而 Google Agent Developer Kit (ADK) 等框架则通过多 Agent 委托实现并行化,由主协调器模型将不同子任务分配给可并发操作的专门 Agent。
通过将并行处理与顺序(链式)和条件(路由)控制流相结合,可以构建能够高效管理各类复杂任务的复杂、高性能计算系统。
以下是有关并行化模式和相关概念的一些进一步阅读资源:
虽然通过提示词链进行顺序处理是执行确定性、线性工作流的基础技术,但其适用性在需要自适应响应的场景中受到限制。现实世界的 Agent 系统必须经常根据偶然因素在多个潜在行动之间进行仲裁,例如环境状态、用户输入或前一操作的结果。这种动态决策能力,控制流向不同的专门函数、工具或子流程,是通过一种称为路由的机制实现的。
路由将条件逻辑引入 Agent 的操作框架,使其能够从固定执行路径转变为这样一种模型:Agent 动态评估特定标准以从一组可能的后续行动中进行选择。这允许更灵活和上下文感知的系统行为。
例如,一个设计用于客户查询的 Agent,当配备路由功能时,可以首先对传入查询进行分类以确定用户的意图。基于此分类,它可以将查询定向到专门的 Agent 进行直接问答、用于帐户信息的数据库检索工具,或用于复杂问题的升级程序,而不是默认使用单一的预定响应路径。因此,使用路由的更复杂 Agent 可以:
路由模式的核心组件是执行评估并指导流程的机制。这种机制可以通过几种方式实现:
路由机制可以在 Agent 操作周期内的多个节点实现。它们可以在开始时应用以对主要任务进行分类,在处理链内的中间点应用以确定后续操作,或在子程序期间应用以从给定集合中选择最合适的工具。
诸如 LangChain、LangGraph 和 Google 的 Agent Developer Kit (ADK) 等计算框架提供了用于定义和管理这种条件逻辑的显式构造。凭借其基于状态的图架构,LangGraph 特别适合复杂的路由场景,其中决策取决于整个系统的累积状态。类似地,Google 的 ADK 提供了用于构建 Agent 能力和交互模型的基础组件,这些组件作为实现路由逻辑的基础。在这些框架提供的执行环境中,开发人员定义可能的操作路径以及决定计算图中节点之间转换的函数或基于模型的评估。
路由的实现使系统能够超越确定性顺序处理。它促进了更自适应的执行流的开发,可以动态且适当地响应更广泛的输入和状态变化。
路由模式是自适应 Agent 系统设计中的关键控制机制,使它们能够动态改变其执行路径以响应可变输入和内部状态。其效用通过提供必要的条件逻辑层跨越多个领域。
在人机交互中,例如虚拟助手或 AI 驱动的导师,路由用于解释用户意图。对自然语言查询的初始分析确定最合适的后续操作,无论是调用特定信息检索工具、升级到人工操作员,还是根据用户表现选择课程中的下一个模块。这使系统能够超越线性对话流并进行上下文响应。
在自动化数据和文档处理管道中,路由作为分类和分发功能。传入的数据,如电子邮件、支持票据或 API 有效载荷,根据内容、元数据或格式进行分析。然后系统将每个项目定向到相应的工作流,例如销售线索摄入流程、JSON 或 CSV 格式的特定数据转换函数,或紧急问题升级路径。
在涉及多个专门工具或 Agent 的复杂系统中,路由充当高级调度器。由用于搜索、总结和分析信息的不同 Agent 组成的研究系统将使用路由器根据当前目标将任务分配给最合适的 Agent。类似地,AI 编码助手使用路由来识别编程语言和用户意图——调试、解释或翻译——然后将代码片段传递给正确的专门工具。
最终,路由提供了创建功能多样化和上下文感知系统所必需的逻辑仲裁能力。它将 Agent 从预定义序列的静态执行器转变为可以在变化条件下就完成任务的最有效方法做出决策的动态系统。
在代码中实现路由涉及定义可能的路径和决定采取哪条路径的逻辑。像 LangChain 和 LangGraph 这样的框架为此提供了特定的组件和结构。LangGraph 基于状态的图结构对于可视化和实现路由逻辑特别直观。
此代码演示了使用 LangChain 和 Google 的生成式 AI 的简单类 Agent 系统。它设置了一个”协调器”,根据请求的意图(预订、信息或不清楚)将用户请求路由到不同的模拟”子 Agent”处理程序。系统使用语言模型对请求进行分类,然后将其委托给适当的处理函数,模拟多 Agent 架构中常见的基本委托模式。
首先,确保您已安装必要的库:
1 | pip install langchain langgraph google-cloud-aiplatform langchain-google-genai google-adk deprecated pydantic |
您还需要使用您选择的语言模型的 API 密钥设置环境(例如,OpenAI、Google Gemini、Anthropic)。
1 | ## Copyright (c) 2025 Marco Fago |
如上所述,这段 Python 代码使用 LangChain 库和 Google 的生成式 AI 模型(特别是 gemini-2.5-flash)构建了一个简单的类 Agent 系统。详细来说,它定义了三个模拟子 Agent 处理程序:booking_handler、info_handler 和 unclear_handler,每个都设计用于处理特定类型的请求。
核心组件是 coordinator_router_chain,它利用 ChatPromptTemplate 指示语言模型将传入的用户请求分类为三个类别之一:’booker’、’info’ 或 ‘unclear’。然后路由链的输出由 RunnableBranch 使用,将原始请求委托给相应的处理函数。RunnableBranch 检查来自语言模型的决策,并将请求数据定向到 booking_handler、info_handler 或 unclear_handler。coordinator_agent 结合了这些组件,首先路由请求以做出决策,然后将请求传递给选定的处理程序。最终输出从处理程序的响应中提取。
main 函数通过三个示例请求演示了系统的用法,展示了不同的输入如何被路由并由模拟 Agent 处理。包含了语言模型初始化的错误处理以确保健壮性。代码结构模仿了基本的多 Agent 框架,其中中央协调器根据意图将任务委托给专门的 Agent。
Agent Development Kit (ADK) 是一个用于工程化 Agent 系统的框架,为定义 Agent 的能力和行为提供了结构化环境。与基于显式计算图的架构相比,ADK 范式中的路由通常通过定义一组离散的”工具”来实现,这些工具代表 Agent 的功能。响应用户查询选择适当工具由框架的内部逻辑管理,该逻辑利用底层模型将用户意图与正确的功能处理程序匹配。
此 Python 代码演示了使用 Google ADK 库的 Agent Development Kit (ADK) 应用程序示例。它设置了一个”协调器” Agent,根据定义的指令将用户请求路由到专门的子 Agent(”Booker”用于预订,”Info”用于一般信息)。然后子 Agent 使用特定工具模拟处理请求,展示了 Agent 系统中的基本委托模式。
1 | ## Copyright (c) 2025 Marco Fago |
此脚本由一个主协调器 Agent 和两个专门的子 Agent 组成:Booker 和 Info。每个专门的 Agent 都配备了一个 FunctionTool,它包装了一个模拟操作的 Python 函数。booking_handler 函数模拟处理航班和酒店预订,而 info_handler 函数模拟检索一般信息。unclear_handler 作为协调器无法委托的请求的后备包含在内,尽管当前协调器逻辑在主 run_coordinator 函数中没有明确使用它进行委托失败。
协调器 Agent 的主要角色,如其指令中定义的,是分析传入的用户消息并将它们委托给 Booker 或 Info Agent。这种委托由 ADK 的自动流机制自动处理,因为协调器定义了 sub_agents。run_coordinator 函数设置了一个 InMemoryRunner,创建一个用户和会话 ID,然后使用运行器通过协调器 Agent 处理用户的请求。runner.run 方法处理请求并产生事件,代码从 event.content 中提取最终响应文本。
main 函数通过使用不同请求运行协调器来演示系统的用法,展示了它如何将预订请求委托给 Booker,将信息请求委托给 Info Agent。
是什么: Agent 系统必须经常响应各种各样的输入和情况,这些无法由单一的线性流程处理。简单的顺序工作流缺乏基于上下文做出决策的能力。没有为特定任务选择正确工具或子流程的机制,系统仍然是僵化和非自适应的。这种限制使得难以构建能够管理现实世界用户请求的复杂性和可变性的复杂应用程序。
为什么: 路由模式通过将条件逻辑引入 Agent 的操作框架提供了标准化解决方案。它使系统能够首先分析传入查询以确定其意图或性质。基于此分析,Agent 动态地将控制流定向到最合适的专门工具、功能或子 Agent。这个决策可以由各种方法驱动,包括提示 LLM、应用预定义规则或使用基于嵌入的语义相似性。最终,路由将静态的预定执行路径转变为能够选择最佳可能操作的灵活和上下文感知工作流。
经验法则: 当 Agent 必须根据用户输入或当前状态在多个不同的工作流、工具或子 Agent 之间做出决策时,使用路由模式。它对于需要对传入请求进行分类或分类以处理不同类型任务的应用程序至关重要,例如客户支持机器人区分销售查询、技术支持和帐户管理问题。

图 1:路由模式,使用 LLM 作为路由器
路由模式是构建真正动态和响应式 Agent 系统的关键步骤。通过实现路由,我们超越了简单的线性执行流,使我们的 Agent 能够就如何处理信息、响应用户输入以及利用可用工具或子 Agent 做出智能决策。
我们已经看到路由如何应用于各个领域,从客户服务聊天机器人到复杂的数据处理管道。分析输入并有条件地指导工作流的能力是创建能够处理现实世界任务固有可变性的 Agent 的基础。
使用 LangChain 和 Google ADK 的代码示例展示了实现路由的两种不同但有效的方法。LangGraph 基于图的结构提供了定义状态和转换的可视化和显式方式,使其成为具有复杂路由逻辑的复杂多步工作流的理想选择。另一方面,Google ADK 通常专注于定义不同的能力(工具)并依赖框架将用户请求路由到适当工具处理程序的能力,这对于具有明确定义的离散操作集的 Agent 可能更简单。
掌握路由模式对于构建能够智能地导航不同场景并根据上下文提供定制响应或操作的 Agent 至关重要。它是创建多功能和健壮 Agent 应用程序的关键组件。
提示词链(Prompt Chaining),有时也称为管道模式(Pipeline pattern),是利用大型语言模型(LLM)处理复杂任务时的一种强大范式。提示词链不是期望 LLM 在单一的、整体化的步骤中解决复杂问题,而是采用分而治之的策略。其核心思想是将原始复杂问题分解为一系列更小、更易管理的子问题。每个子问题通过专门设计的提示词单独处理,并且一个提示词的输出会作为输入传递给链中的下一个提示词。
这种顺序处理技术为与 LLM 的交互引入了模块化和清晰性。通过分解复杂任务,更容易理解和调试每个单独的步骤,使整个过程更加健壮和可解释。链中的每一步都可以精心设计和优化,专注于更大问题的特定方面,从而产生更准确和聚焦的输出。
一个步骤的输出作为下一个步骤的输入至关重要。这种信息传递建立了依赖链(因此得名),其中先前操作的上下文和结果指导后续处理。这使得 LLM 能够在其先前工作的基础上构建,完善理解,并逐步接近期望的解决方案。
此外,提示词链不仅仅是分解问题;它还支持外部知识和工具的集成。在每一步,LLM 都可以被指示与外部系统、API 或数据库交互,丰富其超越内部训练数据的知识和能力。这种能力极大地扩展了 LLM 的潜力,使它们不仅仅作为独立模型运行,而是作为更广泛智能系统的组成部分。
提示词链的重要性超越了简单的问题解决。它是构建复杂 AI Agent 的基础技术。这些 Agent 可以利用提示词链在动态环境中自主规划、推理和行动。通过战略性地构建提示词序列,Agent 可以参与需要多步推理、规划和决策的任务。这样的 Agent 工作流可以更紧密地模拟人类思维过程,从而实现与复杂领域和系统更自然有效的交互。
单一提示词的局限性: 对于多方面的任务,为 LLM 使用单一的复杂提示词可能效率低下,导致模型在约束和指令方面遇到困难,可能导致指令忽略(提示词的某些部分被忽视)、上下文漂移(模型失去对初始上下文的跟踪)、错误传播(早期错误被放大)、需要更长上下文窗口(模型获得的信息不足无法响应)以及幻觉(认知负荷增加导致错误信息的可能性)。例如,一个要求分析市场研究报告、总结发现、识别带数据点的趋势并起草电子邮件的查询可能会失败,因为模型可能总结得很好,但未能提取数据或正确起草电子邮件。
通过顺序分解增强可靠性: 提示词链通过将复杂任务分解为聚焦的顺序工作流来解决这些挑战,显著提高了可靠性和控制力。基于上面的例子,管道或链式方法可以描述如下:
这种分解允许对流程进行更精细的控制。每一步都更简单且更清晰,这减少了模型的认知负荷,并导致更准确和可靠的最终输出。这种模块化类似于计算管道,其中每个函数在执行特定操作后将结果传递给下一个。为了确保每个特定任务的准确响应,可以在每个阶段为模型分配不同的角色。例如,在给定的场景中,初始提示词可以被指定为”市场分析师”,后续提示词为”贸易分析师”,第三个提示词为”专家文档撰写者”,依此类推。
结构化输出的作用: 提示词链的可靠性高度依赖于步骤之间传递的数据完整性。如果一个提示词的输出不明确或格式不佳,后续提示词可能由于错误的输入而失败。为了缓解这一问题,指定结构化输出格式(如 JSON 或 XML)至关重要。
例如,趋势识别步骤的输出可以格式化为 JSON 对象:
1 | { |
这种结构化格式确保数据是机器可读的,可以精确解析并插入到下一个提示词中,而不会产生歧义。这种做法最大限度地减少了解释自然语言可能产生的错误,是构建健壮的多步骤 LLM 系统的关键组成部分。
提示词链是一种多用途模式,在构建 Agent 系统时适用于广泛的场景。其核心效用在于将复杂问题分解为顺序的、可管理的步骤。以下是几个实际应用和用例:
1. 信息处理工作流: 许多任务涉及通过多次转换处理原始信息。例如,总结文档、提取关键实体,然后使用这些实体查询数据库或生成报告。提示词链可能如下所示:
这种方法应用于自动化内容分析、AI 驱动的研究助手开发和复杂报告生成等领域。
2. 复杂查询回答: 回答需要多步推理或信息检索的复杂问题是一个主要用例。例如,”1929 年股市崩盘的主要原因是什么,政府政策如何应对?”
这种顺序处理方法是开发能够进行多步推理和信息综合的 AI 系统的核心。当查询无法从单个数据点回答,而是需要一系列逻辑步骤或来自不同来源的信息集成时,需要这样的系统。
例如,设计用于生成关于特定主题的综合报告的自动化研究 Agent 执行混合计算工作流。最初,系统检索大量相关文章。从每篇文章中提取关键信息的后续任务可以为每个来源并发执行。此阶段非常适合并行处理,其中独立的子任务同时运行以最大化效率。
然而,一旦完成单个提取,过程就变得本质上是顺序的。系统必须首先整理提取的数据,然后将其综合成连贯的草稿,最后审查和完善此草稿以生成最终报告。这些后期阶段中的每一个在逻辑上都依赖于前一个阶段的成功完成。这就是应用提示词链的地方:整理的数据作为综合提示词的输入,生成的综合文本成为最终审查提示词的输入。因此,复杂操作经常将独立数据收集的并行处理与综合和完善的依赖步骤的提示词链结合起来。
3. 数据提取和转换: 将非结构化文本转换为结构化格式通常通过迭代过程实现,需要顺序修改以提高输出的准确性和完整性。
这种顺序处理方法特别适用于从表单、发票或电子邮件等非结构化来源进行数据提取和分析。例如,解决复杂的光学字符识别(OCR)问题,如处理 PDF 表单,通过分解的多步方法更有效地处理。
最初,使用大型语言模型从文档图像执行主要文本提取。随后,模型处理原始输出以规范化数据,在这一步中,它可能将数字文本(如”一千零五十”)转换为其数字等价物 1050。LLM 的一个重大挑战是执行精确的数学计算。因此,在随后的步骤中,系统可以将任何所需的算术运算委托给外部计算器工具。LLM 识别必要的计算,将规范化的数字馈送到工具,然后合并精确的结果。这种文本提取、数据规范化和外部工具使用的链式序列实现了最终的准确结果,这通常很难从单个 LLM 查询中可靠地获得。
4. 内容生成工作流: 复杂内容的创作是一个程序化任务,通常分解为不同的阶段,包括初始构思、结构大纲、起草和后续修订。
这种方法用于一系列自然语言生成任务,包括创意叙事、技术文档和其他形式的结构化文本内容的自动创作。
5. 具有状态的对话 Agent: 尽管全面的状态管理架构采用比顺序链接更复杂的方法,提示词链提供了保持对话连续性的基础机制。这种技术通过将每个对话轮次构建为新提示词来维护上下文,该提示词系统地合并来自对话序列中先前交互的信息或提取的实体。
这一原则是开发对话 Agent 的基础,使它们能够在扩展的、多轮对话中保持上下文和连贯性。通过保留对话历史,系统可以理解并适当响应依赖于先前交换信息的用户输入。
6. 代码生成和完善: 功能代码的生成通常是一个多阶段过程,需要将问题分解为逐步执行的离散逻辑操作序列。
在 AI 辅助软件开发等应用中,提示词链的效用源于其将复杂编码任务分解为一系列可管理的子问题的能力。这种模块化结构降低了每一步大型语言模型的操作复杂性。至关重要的是,这种方法还允许在模型调用之间插入确定性逻辑,实现中间数据处理、输出验证和工作流中的条件分支。通过这种方法,一个可能导致不可靠或不完整结果的单一多面请求被转换为由底层执行框架管理的结构化操作序列。
7. 多模态和多步推理: 分析具有不同模态的数据集需要将问题分解为更小的、基于提示词的任务。例如,解释包含带嵌入文本的图片、突出显示特定文本段的标签以及解释每个标签的表格数据的图像,需要这样的方法。
实现提示词链的范围从脚本中的直接顺序函数调用到利用专门设计用于管理控制流、状态和组件集成的框架。诸如 LangChain、LangGraph、Crew AI 和 Google Agent Development Kit (ADK) 等框架提供了用于构建和执行这些多步过程的结构化环境,这对于复杂架构特别有利。
出于演示目的,LangChain 和 LangGraph 是合适的选择,因为它们的核心 API 明确设计用于组合操作链和图。LangChain 为线性序列提供基础抽象,而 LangGraph 扩展了这些能力以支持状态化和循环计算,这对于实现更复杂的 Agent 行为是必需的。此示例将专注于基础线性序列。
以下代码实现了一个两步提示词链,作为数据处理管道运行。初始阶段旨在解析非结构化文本并提取特定信息。后续阶段然后接收此提取的输出并将其转换为结构化数据格式。
要复制此过程,必须首先安装所需的库。这可以使用以下命令完成:
1 | pip install langchain langchain-community langchain-openai langgraph |
请注意,langchain-openai 可以替换为不同模型提供商的适当包。随后,必须为选定的语言模型提供商(如 OpenAI、Google Gemini 或 Anthropic)配置执行环境所需的 API 凭据。
1 | import os |
这段 Python 代码演示了如何使用 LangChain 库处理文本。它利用两个独立的提示词:一个从输入字符串中提取技术规格,另一个将这些规格格式化为 JSON 对象。ChatOpenAI 模型用于语言模型交互,StrOutputParser 确保输出为可用的字符串格式。LangChain 表达式语言(LCEL)用于优雅地将这些提示词和语言模型链接在一起。第一个链 extraction_chain 提取规格。然后 full_chain 获取提取的输出并将其用作转换提示词的输入。提供了描述笔记本电脑的示例输入文本。full_chain 通过这两个步骤调用此文本进行处理。最后打印最终结果,这是一个包含提取和格式化规格的 JSON 字符串。
上下文工程(见图 1)是在 token 生成之前系统地设计、构建和向 AI 模型提供完整信息环境的学科。这种方法论断言,模型输出的质量较少依赖于模型架构本身,而更多依赖于所提供上下文的丰富性。

图 1:上下文工程是为 AI 构建丰富、全面的信息环境的学科,因为此上下文的质量是实现高级 Agent 性能的主要因素。
它代表了从传统提示工程的重大演进,传统提示工程主要关注优化用户即时查询的措辞。上下文工程将此范围扩展到包括多个信息层,例如系统提示词,这是定义 AI 操作参数的基础指令集——例如,*”你是一名技术作家;你的语气必须正式而精确。”* 上下文通过外部数据进一步丰富。这包括检索的文档,其中 AI 主动从知识库中获取信息以告知其响应,例如提取项目的技术规格。它还包含工具输出,这是 AI 使用外部 API 获取实时数据的结果,例如查询日历以确定用户的可用性。这些显式数据与关键的隐式数据结合,如用户身份、交互历史和环境状态。核心原则是,即使是高级模型,在提供有限或构建不良的操作环境视图时,也会表现不佳。
因此,这种实践将任务从仅仅回答问题重新定义为为 Agent 构建全面的操作图景。例如,上下文工程化的 Agent 不仅会响应查询,而且首先会整合用户的日历可用性(工具输出)、与电子邮件收件人的专业关系(隐式数据)以及之前会议的笔记(检索的文档)。这使得模型能够生成高度相关、个性化和实用的输出。”工程”组件涉及创建健壮的管道以在运行时获取和转换此数据,并建立反馈循环以持续改进上下文质量。
要实现这一点,可以使用专门的调优系统来大规模自动化改进过程。例如,像 Google 的 Vertex AI 提示词优化器这样的工具可以通过系统地根据一组样本输入和预定义的评估指标评估响应来提高模型性能。这种方法对于在不同模型之间调整提示词和系统指令而无需大量手动重写非常有效。通过向这样的优化器提供样本提示词、系统指令和模板,它可以以编程方式完善上下文输入,为实现复杂上下文工程所需的反馈循环提供结构化方法。
这种结构化方法是区分基本 AI 工具与更复杂、上下文感知系统的关键。它将上下文本身视为主要组件,对 Agent 知道什么、何时知道以及如何使用该信息给予关键重要性。这种实践确保模型对用户的意图、历史和当前环境有全面的理解。最终,上下文工程是将无状态聊天机器人提升为高度能干、情境感知系统的关键方法论。
是什么: 复杂任务在单个提示词内处理时通常会使 LLM 不堪重负,导致严重的性能问题。模型的认知负荷增加了错误的可能性,如忽略指令、失去上下文和生成错误信息。单体提示词难以有效管理多个约束和顺序推理步骤。这导致不可靠和不准确的输出,因为 LLM 未能解决多方面请求的所有方面。
为什么: 提示词链通过将复杂问题分解为一系列较小的、相互关联的子任务来提供标准化解决方案。链中的每一步使用聚焦的提示词执行特定操作,显著提高可靠性和控制力。一个提示词的输出作为下一个提示词的输入传递,创建逐步构建最终解决方案的逻辑工作流。这种模块化的分而治之策略使过程更易于管理、更易于调试,并允许在步骤之间集成外部工具或结构化数据格式。这种模式是开发能够规划、推理和执行复杂工作流的复杂多步 Agent 系统的基础。
经验法则: 当任务对于单个提示词过于复杂、涉及多个不同的处理阶段、需要在步骤之间与外部工具交互,或者在构建需要执行多步推理并维护状态的 Agent 系统时,使用此模式。
视觉摘要

图 2:提示词链模式:Agent 从用户接收一系列提示词,每个 Agent 的输出作为链中下一个 Agent 的输入。
以下是一些关键要点:
通过将复杂问题分解为一系列更简单、更易于管理的子任务,提示词链为指导大型语言模型提供了一个健壮的框架。这种”分而治之”策略通过一次专注于一个特定操作,显著提高了输出的可靠性和控制力。作为基础模式,它支持开发能够进行多步推理、工具集成和状态管理的复杂 AI Agent。最终,掌握提示词链对于构建能够执行远超单个提示词能力的复杂工作流的健壮、上下文感知系统至关重要。
在本书中,我们从 Agentic AI 的基础概念出发,一路探索到复杂自主系统的实际实现。我们从这样一个前提开始:构建智能 Agent 就像在技术画布上创作一幅复杂的艺术作品——这个过程不仅需要一个强大的认知引擎(如大型语言模型),还需要一套稳健的架构蓝图。这些蓝图,或者说 Agentic 模式,提供了将简单的被动模型转变为能够进行复杂推理和行动的主动的、目标导向的实体所需的结构和可靠性。
本结论章节将综合我们探索的核心原则。我们将首先回顾关键的 Agentic 模式,将它们组织成一个连贯的框架,强调它们的集体重要性。接下来,我们将研究如何将这些单独的模式组合成更复杂的系统,创造强大的协同效应。最后,我们将展望 Agent 开发的未来,探索将塑造下一代智能系统的新兴趋势和挑战。
本指南中详细介绍的 21 种模式代表了 Agent 开发的全面工具包。虽然每种模式都针对特定的设计挑战,但可以通过将它们归类到反映智能 Agent 核心能力的基础类别中来整体理解它们。
核心执行和任务分解: 在最基本的层面上,Agent 必须能够执行任务。提示词链、路由、并行化和规划这些模式构成了 Agent 行动能力的基石。提示词链提供了一种简单而强大的方法,将问题分解为一系列离散步骤的线性序列,确保一个操作的输出在逻辑上为下一个操作提供信息。当工作流需要更动态的行为时,路由引入了条件逻辑,允许 Agent 根据输入的上下文选择最合适的路径或工具。并行化通过启用独立子任务的并发执行来优化效率,而规划模式则将 Agent 从单纯的执行者提升为战略家,能够制定多步骤计划以实现高层次目标。
与外部环境的交互: Agent 通过与其直接内部状态之外的世界交互,其效用得到显著增强。工具使用(函数调用)模式在这里至关重要,为 Agent 提供了利用外部 API、数据库和其他软件系统的机制。这将 Agent 的操作建立在真实世界的数据和能力之上。为了有效使用这些工具,Agent 通常必须从庞大的存储库中访问特定的相关信息。知识检索模式,特别是检索增强生成(RAG),通过使 Agent 能够查询知识库并将该信息纳入其响应中来解决这个问题,使它们更加准确和具有上下文意识。
状态、学习和自我改进: 为了使 Agent 能够执行多于单轮任务,它必须具备维护上下文和随时间改进的能力。内存管理模式对于赋予 Agent 短期对话上下文和长期知识保留至关重要。除了简单的记忆,真正智能的 Agent 还表现出自我改进的能力。反思和自我纠正模式使 Agent 能够批评自己的输出,识别错误或缺陷,并迭代地改进其工作,从而产生更高质量的最终结果。学习和适应模式更进一步,允许 Agent 的行为根据反馈和经验而演变,使其随时间变得更加有效。
协作和通信: 许多复杂问题最好通过协作来解决。多 Agent 协作模式允许创建系统,其中多个专门的 Agent(每个都有不同的角色和能力集)共同努力实现共同目标。这种劳动分工使系统能够处理对单个 Agent 来说难以解决的多方面问题。此类系统的有效性取决于清晰高效的通信,这是 Agent 间通信(A2A)和模型上下文协议(MCP)模式所要解决的挑战,它们旨在标准化 Agent 和工具如何交换信息。
这些原则通过各自的模式应用时,为构建智能系统提供了一个稳健的框架。它们指导开发人员创建不仅能够执行复杂任务,而且结构化、可靠和适应性强的 Agent。
Agentic 设计的真正力量不是来自孤立地应用单一模式,而是来自巧妙地组合多种模式以创建复杂的多层系统。Agentic 画布很少由单一的简单工作流填充;相反,它成为相互连接的模式的织锦,这些模式协同工作以实现复杂的目标。
考虑开发一个自主 AI 研究助手,这项任务需要规划、信息检索、分析和综合的组合。这样的系统将是模式组合的典型例子:
初始规划: 用户查询,例如”分析量子计算对网络安全格局的影响”,首先会被规划器 Agent 接收。该 Agent 将利用规划模式将高层次请求分解为结构化的多步骤研究计划。该计划可能包括诸如”识别量子计算的基础概念”、”研究常见的加密算法”、”查找有关量子威胁对加密的专家分析”和”将发现综合成结构化报告”等步骤。
使用工具使用进行信息收集: 为了执行该计划,Agent 将严重依赖工具使用模式。计划的每一步都将触发对 Google 搜索或 vertex_ai_search 工具的调用。对于更结构化的数据,它可能使用工具查询学术数据库(如 ArXiv)或金融数据 API。
协作分析和写作: 单个 Agent 可能会处理这个问题,但更稳健的架构将采用多 Agent 协作。”研究员” Agent 可以负责执行搜索计划和收集原始信息。它的输出——摘要和来源链接的集合——然后将传递给”作家” Agent。这个专家 Agent 使用初始计划作为其大纲,将收集的信息综合成连贯的草稿。
迭代反思和改进: 初稿很少是完美的。反思模式可以通过引入第三个”批评家” Agent 来实现。该 Agent 的唯一目的是审查作家的草稿,检查逻辑不一致、事实不准确或缺乏清晰度的领域。其批评将反馈给作家 Agent,然后作家 Agent 将利用自我纠正模式来改进其输出,纳入反馈以产生更高质量的最终报告。
状态管理: 在整个过程中,内存管理系统将是必不可少的。它将维护研究计划的状态,存储研究员收集的信息,保存作家创建的草稿,并跟踪批评家的反馈,确保在整个多步骤、多 Agent 工作流中保持上下文。
在这个例子中,至少有五种不同的 Agentic 模式被编织在一起。规划模式提供高层次结构,工具使用将操作建立在真实世界数据上,多 Agent 协作实现专业化和劳动分工,反思确保质量,内存管理保持连贯性。这种组合将一组单独的能力转变为一个强大的自主系统,能够处理对单个提示词或简单链来说过于复杂的任务。
将 Agentic 模式组合成复杂系统(如我们的 AI 研究助手所示)不是故事的结束,而是软件开发新篇章的开始。展望未来,几个新兴趋势和挑战将定义下一代智能系统,推动可能性的边界,并要求其创建者具有更高的复杂性。
迈向更先进的 Agentic AI 的旅程将以追求更大的自主性和推理能力为标志。我们讨论的模式为目标导向的行为提供了脚手架,但未来将需要能够应对模糊性、执行抽象和因果推理,甚至表现出一定程度常识的 Agent。这可能涉及与新颖模型架构和神经符号方法的更紧密集成,这些方法将 LLM 的模式匹配优势与经典 AI 的逻辑严谨性相结合。我们将看到从人机协同系统(其中 Agent 是副驾驶)向人机在环系统的转变,其中 Agent 被信任以最少的监督执行复杂的、长时间运行的任务,仅在目标完成或发生关键异常时报告。
这种演变将伴随着 Agentic 生态系统和标准化的兴起。多 Agent 协作模式突出了专门 Agent 的力量,未来将看到开放市场和平台的出现,开发人员可以在其中部署、发现和编排 Agent 即服务的舰队。为了使这一切成功,模型上下文协议(MCP)和 Agent 间通信(A2A)背后的原则将变得至关重要,导致 Agent、工具和模型如何交换不仅是数据,还有上下文、目标和能力的行业标准。
这种不断增长的生态系统的一个典型例子是”Awesome Agents” GitHub 存储库,这是一个宝贵的资源,作为开源 AI Agent、框架和工具的精选列表。它通过组织从软件开发到自主研究和对话式 AI 等应用的尖端项目来展示该领域的快速创新。
然而,这条道路并非没有其巨大的挑战。安全性、一致性和稳健性的核心问题将变得更加关键,因为 Agent 变得更加自主和互连。我们如何确保 Agent 的学习和适应不会导致它偏离其最初目的?我们如何构建对对抗性攻击和不可预测的真实世界场景具有弹性的系统?回答这些问题将需要一套新的”安全模式”和专注于测试、验证和道德一致性的严格工程学科。
在本指南中,我们将智能 Agent 的构建定义为在技术画布上实践的艺术形式。这些 Agentic 设计模式是您的调色板和笔触——使您能够超越简单的提示词并创建动态的、响应式的和目标导向的实体的基础元素。它们提供了将大型语言模型的原始认知能力转变为可靠且有目的的系统所需的架构规范。
真正的技艺不在于掌握单一模式,而在于理解它们的相互作用——将画布视为一个整体,并组合一个系统,其中规划、工具使用、反思和协作和谐地工作。Agentic 设计的原则是一种新的创造语言的语法,它允许我们不仅指导机器做什么,而且指导它们如何存在。
Agentic AI 领域是技术中最令人兴奋和快速发展的领域之一。这里详述的概念和模式不是最终的静态教条,而是一个起点——一个在其上构建、实验和创新的坚实基础。未来不是我们仅仅是 AI 的用户,而是我们是智能系统的架构师,这些系统将帮助我们解决世界上最复杂的问题。画布就在你面前,模式就在你手中。现在,是时候开始构建了。
tag:
缺失模块。
1、请确保node版本大于6.2
2、在博客根目录(注意不是yilia根目录)执行以下命令:
npm i hexo-generator-json-content --save
3、在根目录_config.yml里添加配置:
jsonContent:
meta: false
pages: false
posts:
title: true
date: true
path: true
text: false
raw: false
content: false
slug: false
updated: false
comments: false
link: false
permalink: false
excerpt: false
categories: false
tags: true