本文记录了AI Agent开发过程中的探索和实践,本文作者是鹅厂架构师 hardyqliu

什么是 AI Agent

第一步是去了解什么是 AI Agent。 AI Agent 的定义在这篇文章中总结的很好:lilianweng.github.io… 下面这个图也比较经典:

简单讲,目前的 AI Agent 是使用 LLM 作为大脑(决策器)的智能体。基于 LLM 的逻辑推理能力理解并规划任务执行,结合工具调用和记忆系统完成任务。

设计一个 Agent

要实现一个 AI Agent,就是将上面讲的 LLM、工具、检索以某种形式组合在一起。 关于如何构建 Agent,Anthropic 的几篇文章写的很好:

OpenAI的Agent白皮书也可以参考下:

大体上目前的开发模式可以分为WorkFlow 和 Agent 两种方式

WorkFlow

WorkFlow 并不是 Agent 的专属,WorkFlow 只是做任务编排和自动化的一种方式。如果你在一个任务流的过程中引入了LLM,就可以说是WorkFLow模式了。WorkFLow最大的好处是确定性,In/Out的运行逻辑完全在我们的if-else,swatch-case的控制内。

Agent

WorkFlow 也有一个明显的缺点,随着Agent 的能力(功能)逐渐变多,workflow 的复杂度直线上升,可维护性变差。随着模型复杂指令的理解能力、推理和规划能力的提升,以LLM为中心的Agent模式正被越来越多的使用。目前核心的实现还是tool-calling loop,即在一个while循环中LLM通过自主选择工具解决需求。一种实现方式是ReAct模式,在后面的Prompt部分中有示例。

这两个方式其实并不是非 A 即 B,这只是不同的实现逻辑,在构造我们具体Agent 的时候,需要根据我们需求合理组合各种方式,主要能满足需求即可。大家提的Multi-Agent,目前阶段完全就是这两种方式的结合。

下面介绍几个我认为比较重要的模式。

Router模式

Router模式本身就是一种问题解耦的方式。AI Agent 应用中,要解决的用户问题复杂多样,有的需要超强推理模型才能处理,有的问题小模型就能回答,就没必要上推理模型了,这时候就需要Router进行分类处理。Router 模式还有一个 好处是提高Agent的可控制性。在开发,测试过程中,Router 模式避免了“牵一发,动全身”的问题。大大提高了我们开发调试的难度,可以针对不同的分支针对性的优化。OpenAI 的 GPT-5 里就包含了一个实时路由器能够根据对话类型、复杂度、工具需求以及我们的明确意图 快速决定使用哪个模型。

Router作为 AI Agent 的入口,分类准确度影响着整个系统的能力。准确度的提升首先需要合理的意图分类,一个意图要尽可能独立,和其他意图要有明确的区分点,最开始设计的时候也需要考虑如果后续新增意图,尽量不要影响之前已有的意图分类。

Router的分类方式也有不同的选择,常见的分类方式有:1、基于关键字/词典规则的路由 2、基于向量检索的路由 3、基于大模型的路由 4、混合路由(比如将Bert + LLM组合在一起)。基于大模型的意图识别效果和泛化上肯定是最好的,我们构建原型的时候可以完全基于大模型路由构建,后续再通过切小模型、构建混合路由来优化速度和成本。

大模型的控制参数之一Temperature可以控制模型输出的随机性,在调用模型时,我们最好把 Temperautre 设置的很低 或者设置为0,提升确定性。 Prompt也显著影响着意图分类的准确性,后面我们会介绍一些 Prompt 的填写方式。如果为了进一步提升准确率,就需要构建数据集,自己进行一些模型的微调了。如果需求需要的意图太多,也可以构造两层意图识别器,比如可以在第一层进行语义识别,第二层使用进行意图识别,例如第一层先识别是法律问题,第二层识别刑法 还是 教育法。

Orchestrator-Worker模式

对于一个复杂任务,Orchestrator(编排者)会将任务分解成各个子任务,并委派给Worker开始执行任务,每个Worker完成自己的工作后将结果交给Synthesizer(总结者),总结者将Worker的输出综合生成报告。目前的DeepResearch系统很多使用的是这种模式。

LangChain也开源了一个deep_research的架构,代码很简单:

Plan-and-Execute模式

如上图所示,Planer会根据需求将任务分解成一系列Task List,然后由Worker执行,Planer会根据Worker的执行结果,重新分解任务继续执行,直到Planer认为任务完成。编程助手会使用这种方式,Cursor提供了Plan Mode 来让助手完成更加复杂的任务。

实现一个Agent

框架

最开始要介绍的是 coze 或者 dify 这类低/零代码平台,这类平台提供的可视化设计与编排工具,使用者”拖拖拽拽”就可以构建自己的 Agent。混元上的元器平台提供类似的能力: ()

要快速实现原型可以使用上面讲的那些平台,但是要实现更加灵活的控制,最好还是写代码。目前市面上有很多 Agent 的构建框架,这些框架从不同程度上对 Agent 的各个概念和模式进行了封装。使用框架最大的好处是可以更快速的进行原型构建,各种模式的抽象化封装组合起来也更加方便。但是使用框架也意味着引入了框架的复杂度,出现问题不好排查。 下面是一些使用量比较多的框架的对比(来源于GPT-5):

框架名 LangChain / LangGraph CrewAI Semantic Kernel (SK) AutoGen LlamaIndex
主要语言 Python / JS Python C# Python Java Python Python / JS
核心定位 通用 LLM 应用开发框架(LangGraph 是 LangChain 的有状态工作流扩展) 多 Agent 协作框架 微软推出的 AI 应用编排框架 多 Agent 对话与任务协作 LLM 数据接入与检索增强(RAG)框架
特点 模块化(Prompt、Chain、Tool、Memory)、生态丰富、多模型支持,LangGraph 支持有状态 Agent 流程 以“团队”概念组织多个 Agent,支持角色分工、任务分配、协作对话 插件化(Skills)、Planner 自动任务分解、与 Azure/OpenAI 深度集成 强调多 Agent 自主对话、任务分解、代码执行,适合研究和原型 专注于构建知识库、索引、检索,支持多种数据源和向量数据库,易与 LangChain 集成

就我个人用的比较多的是 LangChain 和 LangGraph,应该是目前使用最多的框架(据说在Agent市场占有率达到了 60%)。LangChain对 AI Agent 的各个模块如Model、Prompt、Tool、Memary等进行了封装,抽象层次没有那么高,我们构建起来自由度会比较高,LangChain还提供了例如文档分割、文档加载、代码沙盒执行等工具。LangGraph 是一个对编排工作的低层次的抽象,可以帮忙我们实现持久执行、流式处理、人机交互等编排任务。

在 10 月份 LangChain 发布了 LangChain 1.0版本。提供了create_agent接口,对 tool-calling loop 的工作流进行抽象,可以更快的构建 Agent。还提出了dynamic model middleware,以 Hook 的方式支持在 Agent 执行的各个环节执行额外的工作。

Prompt

如果AI应用是一台电脑,LLM就是这台电脑的CPU,LLM的上下文窗口就是内存,Prompt就是加载到内存的数据,CPU型号不变的情况下,计算出什么样的结果,取决我们输入了怎么样的内容。 Prompt内容格式:OpenAI建议以markdown格式 或者XML 格式 或者两者结合的方式输入构建Prompt。Anthropic 建议使用XML格式构建Prompt。 Prompt的编写原则是明确和具体,大模型最怕的就是模棱两可的输入。不同场景Prompt的内容也不太一样,一般主要包含4个元素:

  • 角色:给大模型安排一个角色来执行任务
  • 上下文信息:提供必要的外部信息和背景资料
  • 指令:明确告诉LLM你需要让他完成什么任务
  • 输出要求:你希望得到LLM怎么样的输出,比如字数限制、格式限制等

基于上面的四个部分 出现了很多Prompt的”框架”,比如CARE,Prompt包含4部分:Context、Action、Result、Example。下面是一个满足CARE模式的Prompt示例(示例由GPT-5生成):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ontext(背景)
你是一位资深的市场营销顾问,擅长为中小企业制定线上推广策略。客户是一家刚成立的手工咖啡品牌,希望提升在社交媒体上的曝光度。

Action(行动)
请为该品牌制定一份为期一个月的社交媒体内容计划,包括每周的主题、发布频率、内容形式(图片、视频、文字)、以及互动方式。

Result(结果)
输出一份结构清晰的表格,包含每周的主题、具体内容创意、发布渠道(如微博、抖音、小红书)、以及预期的互动目标(点赞数、评论数、分享数)。

Example(示例)
第1周主题:品牌故事与创始人介绍

内容形式:短视频 + 文字说明
发布渠道:抖音、小红书
互动目标:点赞 500+,评论 50+
创意:拍摄创始人手冲咖啡的过程,配上品牌理念介绍

TRACE,包含Task、Requirements、Audience、Context、Example 5个部分,下面是一个满足TRACE的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Task(任务)
撰写一条微博,宣传即将举行的城市马拉松比赛。

Requirements(要求)
字数不超过 140 字
语气积极、鼓舞人心
包含比赛日期和报名链接

Audience(受众)
20–40 岁
喜欢运动、跑步的城市居民

Context(背景)
比赛由市体育局主办,今年是第十届,预计有 5000 名跑者参加。

Example(示例)
“第十届城市马拉松来了!🏃‍♂️10月15日,和5000名跑者一起奔跑在最美赛道!立即报名👉[链接]”

ROSES,包含Role、Objective、Style、Example、Scenario 5个部分,下面是一个满足ROSES的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Role(角色)
你是一位资深旅行规划师。

Objective(目标)
为一对情侣设计 3 天的厦门浪漫旅行行程。

Style(风格)
温暖、细腻、富有画面感。

Example(示例)
例如:第一天安排鼓浪屿漫步 + 海边日落晚餐。

Scenario(情境)
情侣希望在周年纪念日旅行,预算中等,偏好安静、文艺的活动。

还有很多种Prompt的内容组织方式,详细内容可以参考这个网站:AiPromptsX | Advanced AI Prompt Engineering Platform
还有一些其他的提升词技术,比如思维树(ToT)、方向性刺激等等,可以参考下面的教程:提示工程指南 | Prompt Engineering Guide
这个仓库有一些prompts可以参考:github.com/x1xhlol/s…github.com/f/awesome…
上面的角度是从内容组织的方式,怎么写Prompt让模型更全面的理解需求/指令。下面的ReAct(Reason + Act)方式是站在AI Agent的角度,教模型怎么完成任务。 ReAct包含下面5个部分:

  • Reason(推理):模型先根据用户需求进行思考,分析任务、制定计划。
  • Act(行动):模型在推理中决定调用哪个工具,并执行工具操作。
  • Observation(观察):接收工具返回的结果。
  • 继续 Reason + Act:根据结果继续推理或调用其他工具,直到完成任务。
  • Final Answer(最终回答):给出完整的答复。

下面是一个ReAct的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
你是一个智能旅行助理,能够根据用户的需求,结合推理和工具调用,提供完整的旅行信息。
你拥有以下工具:
1. get_weather(location: str) —— 查询指定地点的天气
2. get_hotels(location: str) —— 查询指定地点的酒店信息
3. get_attractions(location: str) —— 查询指定地点的景点信息

工作流程(ReAct 模型):
- 你会先进行推理(Reason),分析用户的需求,制定计划。
- 在推理过程中,如果需要外部信息,调用相应的工具(Act)。
- 工具返回结果后,你会观察(Observation)并继续推理。
- 重复 Reason + Act,直到获得所有必要信息。
- 最终给出完整的、结构化的回答(Final Answer)。

输出格式要求:
- 推理过程用 `Reason:` 表示
- 工具调用用 `Action:` 表示,并写明调用的工具及参数
- 工具返回结果用 `Observation:` 表示
- 最终回答用 `Final Answer:` 表示

示例:
用户:我想去北京旅游,帮我看看天气、推荐酒店和景点。

Reason: 用户想去北京,需要查询天气、酒店和景点信息。
Action: get_weather("北京")
Observation: 北京天气晴,气温25°C。
Reason: 已获得天气信息,接下来查询酒店。
Action: get_hotels("北京")
Observation: 返回北京酒店列表。
Reason: 已获得酒店信息,接下来查询景点。
Action: get_attractions("北京")
Observation: 返回北京景点列表。
Reason: 已获得全部信息,可以生成最终回答。
Final Answer: 北京天气晴,气温25°C。推荐酒店有…… 推荐景点有……

注意事项:
- 不要编造工具返回的结果,必须使用工具的真实输出。
- 如果用户需求不明确,先通过推理提出澄清问题。
- 在最终回答中,整合所有工具信息,确保内容完整、易读。

我们将Observation设置为模型的 Stop Word,当模型输出Observation时,表示模型需要获取到工具的结果,我们执行对应的工具,拿到工具输出后继续下一次的模型请求,让模型继续作答,直到模型输出了Final Answer,标志本次任务完成。

工具

上面的ReAct示例中已经涉及到工具的调用,我们需要自己去实现 get_weather、get_hotels、get_attractions这些工具,并且通过合适的描述让大模型认识这些工具即可,和我们提供给别人API没什么区别。但是站在AI Agent开发的角度,就会出现工具和Agent耦合太深,工具的复用性差的问题。 目前的解决方式是MCP(Model Context Protocol),从它的名字也可以看出,MCP协议统一了LLM获取额外上下文信息的方式,包括不限于工具、Prompt、资源等内容。

RAG(检索增强生成)

构建AI Agent应用,尤其是特定领域、特定应用的应用,肯定会包含一些额外的私有知识数据、实时更新内容、长期使用记忆等。RAG技术就是将这些内容也可以添加到模型上下文中的方式。最普遍的应用场景就是问答场景+向量知识库。下面介绍一下向量知识库的制作:

首先我们需要从各个地方收集到我们的知识,原始数据可能是markdown文档,iwiki知识库,word文档,网站(网页)、视频、音频等等格式。第一步就是文档的解析,对于这些文档解析目前的工具有很多,LangChian也提供了解析文档的功能:,或者参考llamahub里提供的工具: ,公司内部的trag平台也提供了对应的工具使用: 。 视频/图片可以使用视频/图片理解大模型转换成文本,音频可以使用ASR模型转换成文本,这一步我们也需要把文档进行清洗,比如去除一些无用、冗余信息。

第二步是文档切分,原始数据中单个文件可能很长,超过了模型上下文处理,太长的内容也会导致模型抓不到重点。这里要采用合适的规则把文档整理成一个一个的知识块,简单的方式是按标题进行分割、按特定字符切割,或者使用固定大小的重叠块进行分割。复杂的可以使用支持长文本的模型进行语义分割,利用LLM进行内容总结+知识提取。

第三步就是Embedding,将原始文本转换为固定长度的数字向量,然后通过与问题的相似度匹配进行检索,这里Embedding的模型也有很多种,中文比较好的有bge-large-zh、qwen3-8B等,具体可以参考CMTEB:,这是一个关于Embedding的评测榜单。

除了向量知识库,还有一种基于图的GraphRAG,最早是微软开源出来的: 。GraphRAG会使用LLM将文本块中的实体和实体的关系和主张提取出来,基于社区的方式构造成知识图谱,GraphRAG的优势在于对知识的相关度关联比较大,基于GraphRAG的检索可以让LLM理解知识整体内容,对于总结、概括大意等领域效果很好,在一些关系性问题,比如腾讯和微信是什么关系等问题上效果也优于之前的向量检索方式。