目录
Agentic design patterns
智能体工作流的核心思想是将复杂的任务分解为一系列基础“构建模块”(building blocks),然后通过特定的设计模式将这些模块组合、串联起来,从而构建出能够处理复杂问题的系统。
多智能体协作 (Multi-agent collaboration)
使用多个具有不同专长的角色(智能体)协同工作,共同完成一个复杂项目。
- 角色分配: 为不同的智能体分配特定角色
- 分工合作: 各个智能体根据自己的角色和能力,执行相应的子任务。
- 沟通协调: 智能体之间相互沟通、传递信息,共同推进项目。
反思设计模式 Reflection Design Pattern
反思如何改进任务输出 Reflection to improve outputs of a task
- 硬编码的“提示-反思”工作流:工程师预先设计好整个步骤,而不是让模型自主决定何时反思。这是一种可靠且易于实现的工程化方法
- 结合外部反馈的反思:仅仅让模型“内省”是有限的,而引入来自模型之外的新信息,则能带来质的飞跃。
例:反思与改进: 将 code V1、Output 和 Errors 一起作为输入,交给 LLM 进行反思(提供了额外信息),要求其根据这些具体的、客观的反馈来重写代码
迭代
-
直接生成(Zero-shot Prompting):不提供任何中间反馈或修正的机会;“零样本提示”中的“零样本”指的是在提示中没有提供任何输入-输出示例
编写反思提示的两大黄金法则:
-
明确指示反思动作(Clearly indicate the reflection action):
-
不要含糊地说"请改进",而要说"请审查"、"请检查"、"请验证"。
-
明确告诉模型你要它做什么,例如"审核电子邮件初稿"或"验证HTML代码"。
具体指定检查标准(Specify criteria to check):
-
不要只说"让它更好",而要列出具体的评判标准。引导模型围绕你最关心的维度进行深入思考和改进。
图表生成流程示例
将生成的图像作为输入,交由一个多模态语言模型(Multi-modal LLM)进行反思。
- 输入准备: 将 V1 版本的代码 (V1 code) 和它生成的图表 (plot.png) 一同打包,作为新的输入。
- 反思指令: 提示多模态 LLM 扮演“专家数据分析师”的角色,对图表进行批判性评估。
- 视觉推理: 多模态模型能够“真正地看”这张图,分析其可读性、清晰度和完整性,并提出具体的改进建议。
- 生成新代码: 根据反思反馈,模型更新代码,生成第二版(V2 code)。
最终成果: 运行 V2 代码,生成了 plot_v2.png
评估反思的影响
反思(Reflection)作为一种设计模式,能有效提升agent性能,但其代价是会略微拖慢agent速度。因此,关键在于如何科学地评估反思带来的实际收益,从而在“性能提升”与“效率损耗”之间做出明智取舍。
客观任务:用“真实答案”数据集 + 代码自动化评估
使用外部反馈
外部反馈工具:开发一个简单的字数统计工具。
- 反思流程:
模型生成初稿。
工具统计字数,发现“超过字数限制”。
将“当前字数”和“字数限制”等信息作为反馈,传回给模型。
模型基于此反馈,压缩或精简内容,重新生成符合字数要求的版本。
基于任务特性,设计定制的外部反馈工具,输出特定 m e t r i c 作为外部反思工具 {\color{red}基于任务特性,设计定制的 外部反馈工具,输出特定metric作为外部反思工具} 基于任务特性,设计定制的外部反馈工具,输出特定metric作为外部反思工具
实验示例
工具使用 Tool Use
-
工具即函数,模型自主决策 关键在于,模型拥有自主决策权。它不再是被动地根据内部知识库生成答案,而是能主动判断:在当前情境下,是否需要、以及应该调用哪个工具来完成任务。
-
语言模型通过调用“函数工具”,也能突破自身训练数据和能力的限制,变得无比强大。
-
LLM能区分哪些信息是静态的(可内化),哪些是动态的(需外求)
创建工具 Creating a Tool
现代方法:
- 当前主流的 LLM 都经过了直接训练,能够原生地理解何时以及如何请求调用工具。
- 开发者不再需要像过去那样在提示词中硬编码特定的触发语法(如全大写的 “FUNCTION”),而是只需向 LLM 提供工具的描述和可用性,模型会自行决定何时调用。
实现工具使用: \color{red}实现工具使用: 实现工具使用:
- 提供工具 (Provide the Tool):开发者编写好功能函数。
- 告知模型 (Tell the LLM):通过系统提示词,明确告诉模型有哪些工具可用,以及如何“请求”调用它们(即输出什么格式的文本)。
- 解析并执行 (Parse and Execute):开发者编写代码,监听模型的输出,识别其“请求”,并实际执行对应的函数。
- 反馈结果 (Feed Back Result):将函数执行的结果作为新的上下文,送回给模型,让它继续推理或生成最终答案。 这个流程的关键在于,
开发者扮演了“翻译官”和“执行者”的角色,弥合了语言模型的“文本生成”能力与现实世界“函数执行”能力之间的鸿沟( 挑战之一 \color{red}挑战之一 挑战之一)。
示例

- 编写含参函数
get_current_time(timezone) - 使用如下提示词,使LLM进行相关决策时,输出带有具体参数的文本,如
FUNCTION: get_current_time("Pacific/Auckland") - 用户提问 相应问题(即某时刻Agentic AI的输入),LLM决策输出
FUNCTION: get_current_time("Pacific/Auckland") - 通过设定好的代码,对LLM的输出决策get_current_time(“Pacific/Auckland”)
进行解析,随后调用编写好的 get_current_time("Pacific/Auckland") - 将代码执行结果(如"04:00:00")返给LLM,LLM再输出回复:
“It's 4am in New Zealand.”
工具调用语法 Tool Use Syntax (AISuite)
LLM 本质上是一个“文本生成器”,它既没有手指去点击按钮,也没有网络权限去直接访问 API 数据库。因此:
-
LLM(大语言模型)本身不会直接调用工具。
-
LLM 会“请求”开发者去调用某个工具,开发者负责执行该工具并将其结果返回给 LLM。
-
在开发社区中,人们常简化说“LLM 调用了工具”,但这在技术上并不准确,仅是一种便捷的说法。
核心机制:从-生成内容-到-生成意图-
开发者教会模型结构化输出(Structured Output):开发者通过 System Prompt(系统提示词) 或 微调(Fine-tuning),教会模型:当用户的问题需要外部信息(如天气、股价、计算)时,不要直接回答,而是输出一段符合特定格式的代码(通常是 JSON:get_current_time(“Pacific/Auckland”))。
运作流程:ReAct 模式(Reasoning and Acting)/ 标准工具调用流
-
模型决策(Model Decision)
LLM 接收到用户的提问。它比对用户提供的工具描述(Tool Definition)。如果它判断需要外部工具,它会进入“待定”状态,并生成一个包含函数名和参数的字符串。注意: 此时模型停止生成,将控制权交回给代码。
-
代码捕获与解析(Orchestration)
开发者的后端代码(如 Python 的 LangChain 或 OpenAI SDK)一直在监听模型的输出。一旦发现输出符合 JSON 格式且命中工具规则,代码会:
截断模型的输出 & 解析 JSON,提取出函数名和参数 -
真实执行(Real Execution)
后端代码拿着模型提供的参数,真正在服务器上发起 HTTP 请求、查询数据库或运行本地 Python 脚本。隔离性: LLM 对这一步完全不知情,它只是在“等待”回复。
-
上下文注入(Context Injection)
代码获取工具返回的结果(例如:{“temp”: “25C”, “condition”: “Sunny”})后,会将这个结果包装成一条新的 “Tool Role Message” 或 “System Message”,重新发送给 LLM。提示词重构: “模型你好,刚才你要求的工具返回了以下结果:25度,晴。请你根据这个结果回答用户最初的问题。”
-
最终生成(Final Response)
LLM 阅读了工具返回的数据,再次发挥其语言组织能力,给用户一个自然的回复:“上海今天天气晴朗,气温约25度。”
为什么 LLM 能写出正确的 JSON?
LLM得以 “调用”工具,是因为它在底层具备了两种关键能力:
-
模式识别(Schema Adherence): 现代模型(如 GPT-4, Claude 3.5)经过了海量 JSON 和代码数据的训练。通过 Constrained Beam Search(约束性束搜索) 等技术,可以强制模型在特定时刻只从符合 JSON 语法的 Token 中进行选择。
-
推理与参数抽取: 模型必须理解“上海”是一个地点参数(city),“今天”需要转换成标准日期格式。这涉及到 NLP 中的 命名实体识别(NER) 能力的进化。
传统程序: 逻辑由程序员通过 if-else 写死。如果用户问天气,程序必须去查天气。
LLM 代理(Agent): 程序员只提供“工具箱”。至于什么时候用工具、用哪个工具、参数怎么填,完全由 LLM 根据语义实时判断。
AI Suite 库
- 提供了一种统一、简便的语法来调用多个不同的 LLM 提供商(如 OpenAI)。
- 该库的核心功能之一是自动处理工具描述,极大简化了开发流程。
- get_current_time()
import aisuite as ai
client = ai.Client()
response = client.chat.completions.create(
model="openai:gpt-4o", # 指定使用的模型
messages=messages, # 传递给 LLM 的消息数组
tools=[get_current_time], # 定义 LLM 可以访问的工具列表
max_turns=5 # 设置工具调用的最大轮次,防止无限循环
)
AI Suite 能将 Python 函数转换为 LLM 可理解的格式。 当你将 get_current_time 函数传入 tools 参数后,AI Suite 会在后台自动为其生成一个 JSON Schema。这个 Schema 是传递给 LLM 的真实数据结构。
{
"type": "function",
"function": {
"name": "get_current_time",
"description": "Returns the current time as a string",
"parameters": {}
}
基于AI Suite的Agentic AI开发流程:
- 开发者定义函数: 编写一个带有清晰 docstring 的 Python 函数。
- AI Suite 自动化封装: 在调用 client.chat.completions.create 时,AI Suite 自动读取函数信息,生成标准的 JSON Schema。
- LLM 接收并决策: LLM 接收到包含所有可用工具描述的 Schema。它会根据当前的对话上下文和用户需求,决定是否需要调用某个工具。
- LLM 发出请求: 如果需要,LLM 会生成一个包含工具名称和所需参数的请求。
- 开发者执行工具: AI Suite 的客户端接收到 LLM 的请求后,会自动调用开发者定义的对应函数,并传入指定的参数。
- 结果返回与迭代: 函数执行的结果会被送回 LLM,LLM 可以基于此新信息继续思考,甚至发起下一次工具调用。整个过程最多可重复 max_turns 次。
- 最终响应: 当所有轮次结束或 LLM 决定不再调用工具时,它会生成最终的文本响应返回给用户。
AI Suite 实验示例 - 邮件助理工作流
在为邮件助理智能体分配任务之前,将创建一个名为 build_prompt() 的小型辅助函数。 该函数会用系统风格的前言包装自然语言请求,使 LLM:
- 认识到自己充当邮件助理智能体
- 知晓自己有权限使用可用工具
- 直接执行动作,无需人工确认
def build_prompt(request_: str) -> str:
return f"""
- 你是一名专注于邮件管理的 AI 助理。
- 你可以执行诸如列出、搜索、过滤与操作邮件等动作。
- 使用提供的工具与邮件系统交互。
- 在执行动作前不要向用户请求确认。
- 如有需要,我的邮箱地址是 "you@email.com",你可以用它来发送邮件或执行与我账户相关的操作。
{request_.strip()}
"""
- 可用工具的集合决定了智能体能与不能做的事(例如没有 delete_email 就无法删除消息)
工具使用 - 代码执行
- 让模型自己写代码,扩展了模型的能力边界,使其能处理任何可以通过编程解决的问题

工具使用 - MCP Model Context Protocol
- 旨在为大型语言模型(LLM)提供一种标准化的方式来访问外部工具和数据源
- 不再是每个应用都创建自己的工具封装。
- 只需要开发 n 个 MCP 服务器(每个对应一个工具),然后让 m 个应用去连接这些服务器。
MCP 核心组件
- 客户端 (Clients)
角色:希望访问外部工具或数据的应用程序。
示例:Cursor, Claude Desktop, Windsurf。
功能:向 MCP 服务器发送请求,获取数据或执行操作。 - 服务器 (Servers)
角色:提供工具和数据源的软件服务。
示例:Slack, Google Drive, GitHub, PostgreSQL。
功能:作为“包装器”,接收来自客户端的请求,并将其转换为对原始工具 API 的调用,然后将结果返回给客户端。
来源:部分服务器由服务提供商开发,但也有大量第三方开发者贡献。
场景示例:
用户在 Claude Desktop 中输入查询:“总结该 GitHub 仓库的 README 文件内容”,并附上 URL。
- 流程:
Claude Desktop 作为 MCP 客户端,识别到这是一个需要访问 GitHub 的请求。
它向已连接的 GitHub MCP 服务器发送一个请求,参数包含文件路径 (README.md)、仓库名 (aisuite) 和所有者 (andrewng)。
GitHub MCP 服务器执行请求,从仓库下载文件内容。
服务器将长文本响应返回给 Claude Desktop。
Claude Desktop 将接收到的内容反馈给 LLM,LLM 生成一份简洁、格式良好的摘要。 - 第二次查询:用户询问“有哪些最新的 Pull Request?”。
同样,客户端向服务器发送“List pull requests”的请求。
服务器返回 JSON 格式的拉取请求列表。
LLM 将其整理成清晰易读的列表,包括标题、状态、作者和描述等信息。
构建Agentic AI技巧
基于基本事实进行客观/主观评估
错误分析
-
检查追踪 (Traces) 和中间输出
定义: 代理在运行过程中,每一步产生的中间输出的整体集合被称为追踪 (trace)。单个步骤的输出有时被称为 span。
方法: 查看追踪,观察每个步骤的输出质量,先笼统了解哪个组件出了问题 -
聚焦错误: 将精力集中在最终输出不令人满意的少数案例上,而不是那些运行良好的案例。
-
建立电子表格进行量化: 为了更严谨地分析,可以建立一个电子表格,明确地统计每个组件出现“错误”的频率。
组件级评估
- 组件级评估更高效, 信号更清晰,避免了整体系统的复杂性带来的噪声。还适用于团队分工: 如果有多个团队分别负责不同组件,每个团队可以自行维护指标。
示例:
- 创建测试样例: 针对少数几个查询,请人类专家提供一份黄金标准网页资源列表,即最权威、最应该找到的网页。
- 编写评估代码: 使用信息检索领域的标准指标(如 F1 分数),编写代码来衡量网页搜索的输出列表与黄金标准列表之间的重叠程度。
- 利用这个指标,开发者可以快速高效地调整网页搜索组件的参数或超参数,如更换搜索引擎、更改结果数量、调整日期范围。
- 快速实现增量改进:在调优过程中,可以快速判断网页搜索质量是否提高。
解决识别到的问题
对于LLM 组件,改进主要围绕输入、模型本身和工作流程结构展开。
- 改进提示词:增加明确指令(在提示词中指明一些资源和任务应有的规划路径,而不是让LLM自己猜);使用少样本提示 (添加具体的输入和期望输出示例)
- 尝试不同的 LLM: 不要嫌麻烦,多测试几款 LLM,并使用评估 (Evals) 来选择最适合特定应用的最佳模型。
- 任务分解:如果单个步骤的指令过于复杂,导致 LLM 难以准确执行,考虑将任务分解为更小的、更易于管理的步骤,比如拆成生成步骤 + 反思步骤,或连续多次调用。
- 微调模型:这是最复杂、成本最高的选项。只有在穷尽所有其他方法后,仍需要挤出最后几个百分点的性能改进时才考虑。它适用于更成熟且性能要求极高的应用。
高度自治智能体模式 - Patterns for Highly Autonomous Agents
规划设计模式
规划模式的Agent系统高度自主,能够自行决定执行复杂任务所需的工具调用序列,而无需事先硬编码。
方法抽象:
-
提供工具集: 给 LLM 提供一套功能工具
-
LLM 编写计划: 要求LLM根据用户请求返回一个逐步的执行计划,说明应按什么顺序调用哪些工具
-
逐步执行: 按照计划,将每一步的指令和上一步的输出/上下文依次喂给 LLM,让它调用相应的工具并执行
-
最终输出: 将所有步骤的结果反馈给 LLM,生成最终的用户答案
-
目前,规划模式在AI Coding应用中非常成功,但在其他领域仍然处在尝试阶段。
-
这种规划模式灵活度高,代码量小,难点在于工具设计与流程设计
规划设计模式细节 - 结构化输出
- 在规划模式中,如何利用结构化输出来保证 LLM 生成的计划能够被下游代码可靠地执行,是非常重要的
- 让LLM直接讲出自己的任务规划,但自然语言不够清晰和明确,难以被下游代码稳定地解析和执行。故可以进一步要求 LLM 以结构化格式(如 JSON 或 XML)输出计划。
规划设计模式进阶 - 使用代码作为行动
-
相较于让 LLM 输出 JSON 等结构化数据来表示计划,可进一步让 LLM 直接编写软件代码来的,直接用代码来表达计划的多个步骤和工具调用。
-
若允许LLM直接执行代码,就能获得下列优势:
1.利用大型库: LLM 得以利用像 Pandas 这样的数据处理库中数百甚至数千个内置函数。
2.高表达能力: LLM 能够编写简洁的代码来表达一个涉及多步骤、复杂逻辑的计划,例如解析日期、按日期排序、过滤、去重、计数。
3.性能更优: 研究表明,在许多任务中,让 LLM 编写代码来采取行动的性能优于让它编写 JSON 或纯文本计划。
多智能体系统 - Multi-agentic workflows
把一个Agent拆成很多次级Agent,并构成一个多Agent系统,即Multi-Agent系统,就十分有必要了。多个承担不同任务的Agent可以靠互相协作来解决复杂的任务,提高系统的效率和模块化。
示例:市场Agent 分为 调研 生成报表 创建文件 三个 子Agent

- 突破上下文限制。现在绝大多数模型都具有128k的上下文,对于一些需要多轮规划执行的调研类任务或业务分析任务来说是完全不够的。但如果让每个Agent只负责自己的部分,最终只返回自己部分的调研结果,让一个总结Agent总结各个子Agent的调研结果,生成最终报告,就能规避上下文的限制
- 节约成本;在时间成本上,上下文越短,LLM回复速度越快,延迟越低
多智能体的 各种协作模式
线性模式(Linear communication pattern)
线性模式按顺序执行任务,信息单向流动;
优点:结构简单、易于理解;
缺点:不灵活,出错时难以反馈或修正。
双层模式(Hierarchical communication pattern)
有一个“管理员(Manager Agent)”负责协调所有下属Agent。
优点 :清晰、易于控制、任务协调性强;
缺点 :可能成为瓶颈(manager负担重)。
多层模式(Deep Hierarchy)
一些高级系统会让子Agent自己也拥有下属Agent。 例如“研究员”下面有“网页研究员”和“事实核查员”,“作家”下面有“风格写手”和“引用校对员”。
优点:可扩展、模块化、可分层调度;
缺点:通信复杂、难以调试、出错难追踪。
去中心模式(All-to-all communication)
在这种模式下,每个Agent都能随时与其他Agent交流,没有中心,也没有固定顺序。
实际生产中,线性模式与双层模式会更常用一些,因为至少对于当前LLM的能力而言,信息会在层级之间传递时丢失部分信息,层级越多,信息越匮乏/失真。
在常见的Agent框架中,langchain是忠实的线性结构,smolagents更青睐于双层/多层结构,而metagpt、camelai则致力于做去中心结构。当然,大部分框架都可以同时实现这些不同的结构,只是代码风格不同
1369

被折叠的 条评论
为什么被折叠?



