1. 先搞清楚:从零学 Agent,到底在学什么
很多人一上来就问“该先学 LangChain 还是先学 AutoGPT”,这个问题本身就问错了。Agent 不是一个框架,也不是一个库,它是一套让大模型自主决策、调用工具、循环执行直到完成任务的系统设计模式。框架只是这套模式的某一种实现载体,换一个框架,底层逻辑是不变的。
我见过太多人花了两个月把某个框架的 API 背得滚瓜烂熟,结果面试官问一句“你的 Agent 怎么做错误恢复的”,直接卡住。原因很简单:他学的是框架的使用方法,不是 Agent 的设计方法。
所以这篇文章的核心思路是:先建立 Agent 的思维模型,再动手写最小可运行系统,然后逐步叠加记忆、规划、多工具编排、安全防护等能力,最后才去对比和选型框架。这个顺序不能反。反过来学,你会被框架的抽象层遮住眼睛,永远看不清里面到底发生了什么。
这篇文章适合谁看?如果你是大模型应用开发者、后端工程师想转型 AI 方向、或者产品经理需要理解 Agent 的能力边界,都可以按这个路线走。不需要你先精通深度学习,但需要你能写 Python,理解 HTTP 请求和 JSON 的基本概念。整个学习周期,如果每天投入两小时,大概六到八周可以从零到能独立搭建一个可用的 Agent 项目。
下面我把整个学习路径拆成五个阶段,每个阶段说清楚:学什么、为什么这么学、怎么验证自己学会了、以及最容易踩的坑在哪里。
2. 第一阶段:建立 Agent 的思维模型(第 1 周)
2.1 先理解 Agent 和普通 LLM 调用的本质区别
普通 LLM 调用是什么?你给它一段 prompt,它给你一段回复,结束。一次输入,一次输出,没有循环,没有工具,没有状态。
Agent 是什么?你给它一个目标,它自己决定下一步做什么,执行一个动作,观察结果,再决定下一步,直到它认为任务完成或者触发终止条件。核心区别就三个字:循环体。
用伪代码表示,一个最原始的 Agent 循环长这样:
while not done: thought = llm.think(context) # 思考下一步 action = llm.decide(thought) # 决定用什么工具 result = execute(action) # 执行工具 context.append(result) # 把结果放回上下文 done = llm.check(goal, context) # 判断是否完成这个循环就是 Agent 的心脏。后面你要学的所有东西——记忆管理、多工具编排、错误恢复、并发控制——都是在给这个循环加装备。所以第一周的任务不是写代码,是把这张图刻在脑子里。
2.2 必读的几份材料,按顺序来
市面上的教程很多,但质量参差不齐。我建议按这个顺序读:
- 吴恩达的 Agent 系列教程:他的讲法最大的好处是把 Agent 拆成了四个模块——规划、工具、记忆、执行。这个四分法不一定完美,但作为入门框架非常好用,能让你快速建立分类意识。
- ReAct 论文:Reasoning + Acting 的原始论文,不用全读,重点看它怎么把“思考”和“行动”交替进行的。手写 ReAct Agent 是检验你是否理解 Agent 循环的最好方式。
- 一篇关于 Agent 架构的综述:找一篇 2024 年之后的综述文章,快速扫一遍,知道学术界把 Agent 分成了哪些类型、有哪些开放问题。这一步的目的是建立全局视野,不是深入细节。
注意:不要在这一周就去碰 LangChain 或任何框架的文档。框架文档会给你大量“怎么做”的细节,但你还没有“为什么”的判断力,很容易被带偏。
2.3 这一周的验证标准
学完第一周,你应该能回答这几个问题:
- Agent 的循环体包含哪几个基本步骤?
- ReAct 和普通 Chain 的区别是什么?
- 为什么 Agent 需要工具调用?不用工具行不行?
- 一个 Agent 如果没有终止条件,会发生什么?
如果你能用自己的话把前三个问题讲清楚,第四题能说出“会无限循环、消耗 token、可能产生副作用”,那这一周就过关了。讲不清楚就回去重读,不要急着往下走。
3. 第二阶段:手写一个最小可运行 Agent(第 2-3 周)
3.1 为什么必须手写,不能直接上框架
这是整个学习路线里最关键的一个决定。我强烈建议你至少手写一个完整的 ReAct Agent,不依赖任何 Agent 框架,只用最基础的 LLM API 和 Python 标准库。
原因有三个。第一,框架帮你隐藏了 prompt 拼接、输出解析、循环控制这些细节,但这些细节恰恰是 Agent 最容易出问题的地方。第二,手写一遍之后,你再看框架的源码,会有“原来它就是这么干的”的顿悟感,学习效率反而更高。第三,面试和实际工作中遇到 Agent 行为异常时,你需要有能力从底层排查,而不是只会调框架参数。
3.2 最小 Agent 的四个组成部分
一个能跑的最小 Agent,需要这四个东西:
第一,一个 LLM 调用接口。用你熟悉的任何一家 API 都行,关键是封装成一个函数,输入 messages 列表,输出文本。
第二,一套工具定义。从最简单的开始,比如一个计算器工具、一个获取当前时间的工具。工具的定义要包含名称、描述、参数 schema。描述非常重要,LLM 就是靠描述来决定什么时候调用哪个工具的。
第三,一个输出解析器。LLM 输出的文本需要被解析成结构化的“思考”和“行动”。最简单的做法是约定输出格式,比如用Thought:和Action:作为标记,然后用正则提取。
第四,一个循环控制器。控制最大迭代次数、处理工具执行异常、判断终止条件。
3.3 实操:手写 ReAct Agent 的关键代码结构
下面是我自己手写时用的结构,你可以参考:
import re import json def react_agent(goal, tools, max_steps=10): context = f"目标:{goal}\n" for step in range(max_steps): # 1. 让 LLM 思考并决定行动 prompt = build_react_prompt(context, tools) output = call_llm(prompt) # 2. 解析输出 thought = extract_thought(output) action, action_input = extract_action(output) # 3. 判断是否终止 if action == "finish": return action_input # 4. 执行工具 try: result = tools[action](**action_input) except Exception as e: result = f"工具执行失败:{e}" # 5. 把结果追加到上下文 context += f"Thought: {thought}\nAction: {action}\nObservation: {result}\n" return "达到最大步数,任务未完成"这段代码不到三十行,但它包含了 Agent 的所有核心要素。你把它跑通,改一改 prompt,加几个工具,观察 LLM 的行为变化,比看十篇教程都有用。
3.4 这一阶段的常见坑
坑一:输出格式不稳定。LLM 有时候不按你约定的格式输出,导致解析失败。解决办法是在 prompt 里给 few-shot 示例,并且在解析失败时做一次重试。
坑二:工具描述写得太模糊。比如你写“计算器工具”,LLM 不知道它能算什么、参数是什么格式。要写成“计算数学表达式,输入是一个字符串形式的算式,如 '2+3*4'”。
坑三:没有最大步数限制。我早期写的一个 Agent 因为工具一直返回错误,LLM 一直重试,跑了四十多步才停,烧了不少 token。永远要设 max_steps。
实操心得:手写阶段不要追求功能完整,追求的是“我能解释每一行代码为什么这么写”。这个阶段慢就是快。
4. 第三阶段:给 Agent 加上记忆和规划能力(第 3-4 周)
4.1 短期记忆和长期记忆,解决的是不同问题
手写的 Agent 有一个明显缺陷:上下文窗口有限,对话一长就装不下了。这就引出了记忆系统。
短期记忆解决的是“当前任务执行过程中的信息保留”。最简单的做法就是维护一个 messages 列表,但要做窗口管理——超出 token 限制时,要么截断最早的,要么做摘要压缩。
长期记忆解决的是“跨会话的信息保留”。比如用户上周告诉过 Agent 他的偏好,这周再对话时 Agent 应该记得。这就需要一个外部存储,通常是向量数据库,把历史信息做 embedding 存进去,需要时检索出来。
这里有个容易混淆的点:很多人把 RAG 和 Agent 记忆混为一谈。RAG 是检索外部知识,记忆是保留交互历史,两者技术上有重叠,但目的不同。做 Agent 记忆时,你要考虑的是:存什么、什么时候存、什么时候取、取了怎么用。
4.2 规划能力的三个层次
规划是 Agent 从“被动响应”到“主动执行”的关键。我把它分成三个层次:
第一层:隐式规划。就是 ReAct 那种,LLM 在每一步的 Thought 里自己想做啥,没有显式的计划。优点是简单,缺点是长任务容易跑偏。
第二层:显式计划。先让 LLM 生成一个任务分解列表,然后逐步执行。比如 Plan-and-Execute 模式,先规划再执行,执行过程中可以根据结果调整计划。
第三层:层次化规划。大任务拆成子任务,子任务再拆,形成树状结构。这个复杂度最高,一般项目用不到,但你要知道有这个东西。
我的建议是:先把第一层做扎实,再尝试第二层。很多实际项目用 ReAct 加一个好的 prompt 就够了,不需要上来就搞复杂的规划器。
4.3 记忆系统的实操要点
如果你要做一个带记忆的 Agent,这几个设计决策要想清楚:
| 决策点 | 选项 | 建议 |
|---|---|---|
| 存储介质 | 内存 / Redis / 向量库 | 原型用内存,生产用向量库+Redis |
| 写入时机 | 每轮写 / 任务结束写 | 任务结束写,避免噪音 |
| 检索方式 | 相似度 / 时间衰减 / 混合 | 混合检索效果最好 |
| 压缩策略 | 截断 / 摘要 / 分层 | 摘要+分层,保留关键信息 |
注意:记忆系统最容易出的问题是“存了太多没用的东西,检索时反而干扰判断”。宁可少存精存,不要什么都往里塞。
5. 第四阶段:多工具编排与工程化(第 4-6 周)
5.1 从单工具到多工具,难点在哪里
单工具 Agent 很简单,LLM 只需要判断“用不用这个工具”。多工具就不一样了,LLM 要判断“用哪个工具、按什么顺序用、工具之间怎么传递数据”。
工具数量超过十个之后,你会发现 LLM 的选择准确率明显下降。这时候需要做几件事:
- 工具分组:把相关工具归到一类,先让 LLM 选类别,再选具体工具。
- 工具描述优化:描述要包含“什么时候用”和“什么时候不用”,负向描述往往比正向描述更有用。
- 动态工具加载:不是所有工具都一次性给 LLM,根据当前上下文只加载相关的几个。
5.2 错误处理和重试机制
Agent 执行过程中出错是常态,不是异常。工具可能超时、可能返回格式不对、可能参数传错。一个健壮的 Agent 必须有错误处理。
我的做法是三层防护:
- 工具层:每个工具内部做参数校验和异常捕获,返回结构化的错误信息而不是抛异常。
- Agent 层:LLM 看到错误信息后,决定是重试、换工具还是放弃。prompt 里要明确告诉它“遇到错误时可以重试,但同一工具连续失败三次就换方案”。
- 系统层:设置全局的最大步数和超时时间,防止失控。
5.3 并发场景下的 Agent 设计
这是很多人忽略的一块。当你的 Agent 要同时服务多个用户请求时,问题就来了:上下文怎么隔离?工具调用怎么限流?状态怎么管理?
基本思路是:每个请求一个独立的 Agent 实例,共享底层 LLM 客户端和工具注册表,但上下文和状态完全隔离。如果工具调用有外部依赖(比如数据库),需要加连接池和限流。
至于“AI Agent 怎么扛并发”这个问题,核心不在 Agent 本身,在于你的 LLM 调用层和工具执行层能不能水平扩展。Agent 的逻辑层通常是无状态的,把状态外置到 Redis 或数据库,就可以横向扩展。
5.4 安全防护不能等到最后才做
Agent 安全是一个独立的话题,但你在工程化阶段就要开始考虑。主要风险包括:
- Prompt 注入:用户输入里藏指令,让 Agent 执行非预期操作。
- 工具滥用:Agent 调用了不该调用的工具,或者传了危险参数。
- 数据泄露:Agent 把敏感信息写到了日志或外部存储。
防护手段包括:输入过滤、工具权限分级、敏感操作二次确认、输出审查。这些不是可选项,是必选项。
6. 第五阶段:框架选型与项目实战(第 6-8 周)
6.1 主流 Agent 框架的定位差异
到了这个阶段,你已经有了足够的手写经验,可以去看框架了。这时候你看框架的视角会完全不同——你不再是被框架牵着走,而是带着判断力去评估。
目前主流的几类框架:
| 框架类型 | 代表 | 适合场景 | 学习成本 |
|---|---|---|---|
| 通用编排 | LangChain / LlamaIndex | 快速原型、多工具编排 | 中 |
| 多智能体 | AutoGen / CrewAI | 角色协作、复杂任务分解 | 中高 |
| 轻量级 | 各厂商 SDK 自带 Agent | 单一场景、快速集成 | 低 |
| 企业级 | 各云厂商 Agent 平台 | 生产部署、监控运维 | 高 |
选型的核心原则是:先看你的场景需要什么,再看框架能提供什么。不要因为某个框架火就用它,也不要因为某个框架简单就轻视它。
6.2 一个完整的 Agent 项目应该包含什么
如果你要做一个能拿得出手的 Agent 项目,至少包含这些模块:
- Agent 核心:循环控制、prompt 管理、输出解析
- 工具系统:工具注册、参数校验、执行隔离
- 记忆系统:短期上下文管理、长期存储检索
- 可观测性:日志、追踪、token 消耗统计
- 评测体系:任务成功率、工具调用准确率、响应时间
- 安全层:输入过滤、权限控制、输出审查
6.3 评测:怎么知道你的 Agent 好不好
Agent 评测比普通 LLM 评测难得多,因为它是多步的、有状态的。我常用的几个指标:
- 任务完成率:给定一组任务,Agent 能独立完成的比例。
- 平均步数:完成同类任务平均需要多少步,越少越好。
- 工具调用准确率:选对工具、传对参数的比例。
- 错误恢复率:遇到错误后能自行恢复的比例。
做评测时要注意:测试集要覆盖正常路径和异常路径,只测正常情况没有意义。
6.4 面试中常被问到的 Agent 问题
如果你是为了面试准备,这几个问题出现频率极高:
- ReAct 的原理是什么?和 Function Calling 有什么区别?
- Agent 的记忆系统怎么设计?短期和长期怎么配合?
- 多工具场景下怎么提高工具选择准确率?
- Agent 陷入循环怎么办?怎么检测和打断?
- 怎么评测一个 Agent 的好坏?
- Prompt 注入怎么防?
这些问题的答案,如果你按前面的路线手写过、踩过坑,都能用自己的实践经验回答,而不是背八股。
7. 几个我踩过的坑和对应的解法
7.1 不要过早追求多智能体
我刚开始学的时候,看到 AutoGen 的多智能体演示觉得很酷,花了两周去搭一个“产品经理+程序员+测试”的多 Agent 系统。结果发现,大部分任务单 Agent 加好工具就能做,多智能体反而引入了通信开销和协调复杂度。多智能体是解决特定问题的工具,不是 Agent 的终极形态。先把单 Agent 做扎实。
7.2 上下文管理比你想的重要
Agent 跑长任务时,上下文会迅速膨胀。我遇到过一个任务跑了十五步,上下文到了八千 token,LLM 开始“忘记”前面的关键信息。后来加了摘要压缩和关键信息提取,才稳定下来。上下文不是越多越好,是要让 LLM 在每一步都能看到它真正需要的信息。
7.3 工具设计要“防呆”
我写过一个数据库查询工具,参数是 SQL 语句。结果 LLM 生成了一条 DELETE 语句,差点出事。后来改成只允许 SELECT,并且在工具层做了 SQL 解析校验。永远不要相信 LLM 会按你期望的方式使用工具,要在工具层做硬约束。
7.4 日志和追踪要提前做
Agent 出问题时,如果没有详细的执行日志,排查起来非常痛苦。我现在的习惯是:每一步的输入、输出、工具调用、耗时、token 消耗全部记录。这样出问题时能快速定位是哪一步、哪个环节出的错。
8. 学习路线速查表
把上面的内容压缩成一张表,方便你对照执行:
| 阶段 | 时间 | 核心任务 | 验证标准 |
|---|---|---|---|
| 建立思维模型 | 第 1 周 | 读教程和论文,理解 Agent 循环 | 能讲清 ReAct 原理 |
| 手写最小 Agent | 第 2-3 周 | 不依赖框架写 ReAct Agent | 能跑通并解释每行代码 |
| 记忆与规划 | 第 3-4 周 | 加短期记忆、尝试显式规划 | 长任务不丢关键信息 |
| 多工具与工程化 | 第 4-6 周 | 多工具编排、错误处理、并发 | 能处理工具失败和并发请求 |
| 框架与实战 | 第 6-8 周 | 选型、做完整项目、评测 | 有可演示的项目和评测数据 |
这个路线不是死的,你可以根据自己的基础调整节奏。但顺序不要变:先懂原理,再手写,再加能力,最后用框架。反过来走,你会花更多时间在调试框架的抽象泄漏上,而不是在理解 Agent 本身。
最后分享一个我自己的判断标准:当你看到一个 Agent 框架的文档时,如果能在脑子里把它翻译成“哦,这就是在循环体里加了个记忆检索”,说明你真的学明白了。如果还是觉得它很神秘,那就回去再手写一遍。