前言
你盼世界,我盼望你无 bug。Hello 大家好!我是霖呆呆。
目前各种 Agent 产品层出不穷。我自己也用了一段时间的 Claude Code,用着用着就产生了一个疑问:
这些 Agent 到底是怎么"思考"的?它凭什么知道该调哪个工具?它怎么记住我之前说的话?
带着这些问题,我系统地学习了 AI Agent 的 10 个核心概念,从最基础的"Agent 核心循环"一直学到"编排框架选型"。
这篇文章就是我整个学习过程的总结,会用大量实际场景来帮你理解这些概念。如果你也在用 Agent 工具但对背后的原理一头雾水,这篇文章应该能帮到你 👇

目录
- [一、Agent 核心循环:Perceive → Think → Act → Observe](#一、Agent 核心循环:Perceive → Think → Act → Observe "#%E4%B8%80agent-%E6%A0%B8%E5%BF%83%E5%BE%AA%E7%8E%AFperceive--think--act--observe")
- [二、工具调用与函数调用:LLM 是怎么"动手"的](#二、工具调用与函数调用:LLM 是怎么"动手"的 "#%E4%BA%8C%E5%B7%A5%E5%85%B7%E8%B0%83%E7%94%A8%E4%B8%8E%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8llm-%E6%98%AF%E6%80%8E%E4%B9%88%E5%8A%A8%E6%89%8B%E7%9A%84")
- [三、规划与任务分解:Agent 怎么把大任务拆小](#三、规划与任务分解:Agent 怎么把大任务拆小 "#%E4%B8%89%E8%A7%84%E5%88%92%E4%B8%8E%E4%BB%BB%E5%8A%A1%E5%88%86%E8%A7%A3agent-%E6%80%8E%E4%B9%88%E6%8A%8A%E5%A4%A7%E4%BB%BB%E5%8A%A1%E6%8B%86%E5%B0%8F")
- 四、记忆系统:短期、长期、工作记忆
- [五、上下文窗口管理:Agent 的"内存管理"](#五、上下文窗口管理:Agent 的"内存管理" "#%E4%BA%94%E4%B8%8A%E4%B8%8B%E6%96%87%E7%AA%97%E5%8F%A3%E7%AE%A1%E7%90%86agent-%E7%9A%84%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86")
- [六、ReAct 范式:边想边做的艺术](#六、ReAct 范式:边想边做的艺术 "#%E5%85%ADreact-%E8%8C%83%E5%BC%8F%E8%BE%B9%E6%83%B3%E8%BE%B9%E5%81%9A%E7%9A%84%E8%89%BA%E6%9C%AF")
- [七、多 Agent 协作:一个人干不完就叫帮手](#七、多 Agent 协作:一个人干不完就叫帮手 "#%E4%B8%83%E5%A4%9A-agent-%E5%8D%8F%E4%BD%9C%E4%B8%80%E4%B8%AA%E4%BA%BA%E5%B9%B2%E4%B8%8D%E5%AE%8C%E5%B0%B1%E5%8F%AB%E5%B8%AE%E6%89%8B")
- [八、错误处理与自我纠正:Agent 犯错了怎么办](#八、错误处理与自我纠正:Agent 犯错了怎么办 "#%E5%85%AB%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86%E4%B8%8E%E8%87%AA%E6%88%91%E7%BA%A0%E6%AD%A3agent-%E7%8A%AF%E9%94%99%E4%BA%86%E6%80%8E%E4%B9%88%E5%8A%9E")
- [九、安全与对齐:给 Agent 装上"刹车"](#九、安全与对齐:给 Agent 装上"刹车" "#%E4%B9%9D%E5%AE%89%E5%85%A8%E4%B8%8E%E5%AF%B9%E9%BD%90%E7%BB%99-agent-%E8%A3%85%E4%B8%8A%E5%88%B9%E8%BD%A6")
- [十、编排框架与实战选型:用什么工具来造 Agent](#十、编排框架与实战选型:用什么工具来造 Agent "#%E5%8D%81%E7%BC%96%E6%8E%92%E6%A1%86%E6%9E%B6%E4%B8%8E%E5%AE%9E%E6%88%98%E9%80%89%E5%9E%8B%E7%94%A8%E4%BB%80%E4%B9%88%E5%B7%A5%E5%85%B7%E6%9D%A5%E9%80%A0-agent")
一、Agent 核心循环:Perceive → Think → Act → Observe
学 Agent 的第一步,就是搞清楚它到底在干嘛。
大家可能也知道,Agent 发展至今,已经不仅仅停留在"你问它答"了。一个真正的 Agent 在工作时,一直在跑一个四步循环:
markdown
Perceive(感知)→ Think(思考)→ Act(行动)→ Observe(观察)
↑ |
└──────────────────────────────────────────┘
来看个 🌰:
你让 Agent 帮你翻译一份 PDF 文档:
| 步骤 | Agent 做了什么 |
|---|---|
| Perceive | 接收到用户指令:"帮我翻译这个 PDF" |
| Think | 思考:我需要先读取 PDF 内容,然后翻译 |
| Act | 调用 PDF 读取工具,获取文本 |
| Observe | 拿到了 PDF 的文字内容 |
| Think | 思考:内容拿到了,开始翻译 |
| Act | 执行翻译 |
| Observe | 翻译完成 |
| Think | 思考:翻译结果是否符合用户预期?可以返回了 |
| Act | 将翻译结果返回给用户 |
看到没,Agent 不是一条线走到底的,而是在不断循环。每一次 Observe 之后都会回到 Think,重新审视当前状态。
最容易踩的坑:Think 缺失导致死循环 🚨
如果一个 Agent 陷入了死循环,第一反应不应该是"加个重试上限",而是要问:它的 Think 步骤是不是出了问题?
来看个反面案例:
Agent 在翻译完 PDF 后,没有经过 Think 步骤来判断"翻译结果是否可以返回给用户了",而是直接又回到 Perceive,把翻译结果当成新的输入,开始翻译"翻译后的内容"... 然后无限循环 😵
erlang
翻译 PDF → 拿到结果 → 没有思考"是否完成" → 又去翻译 → 又拿到结果 → ...
这不是"缺少重试上限"的问题------那只是工程层面的补救。根本原因是 Think 步骤缺失,Agent 没有在 Observe 之后停下来思考:"我到底做完了没有?"
这个区分很重要:Think 决定"做什么",重试上限决定"做多久"。两者缺一不可。
二、工具调用机制:Function Calling 与 MCP
搞清楚了核心循环,下一个问题来了:循环中的 Act 步骤,Agent 是怎么"动手"的?
这里涉及两个容易混淆的概念:Function Calling(函数调用) 和 MCP(Model Context Protocol)。
Function Calling:LLM 的"表达方式"
LLM 自己是不能执行代码的,它本质上只是在"生成文本"。那它怎么调工具呢?
答案是:LLM 输出一段结构化的 JSON,告诉宿主程序"我想调这个工具":
json
{
"tool": "get_weather",
"parameters": {
"city": "上海"
}
}
这就是 Function Calling------LLM 用结构化数据表达调用意图,但它自己不执行。
MCP:宿主侧的"连接协议"
MCP 是宿主程序(比如 Claude Code)用来管理和连接外部工具服务器的协议。它解决的是"工具从哪来、怎么调"的问题。
它们的关系
sql
LLM 输出 Function Call → Host 解析 → 通过 MCP(或其他方式)路由到具体工具 → 执行 → 结果返回给 LLM
这里有个关键理解:从 LLM 的角度看,所有工具长得都一样。无论这个工具是内置的还是通过 MCP 配置的,LLM 都是输出同样格式的 Function Call。至于工具到底是内置的还是 MCP 的,那是 Host 层面的事。
好吧,用人话说就是 😂:
- Function Calling = LLM 的"嘴"(表达意图)
- MCP = Host 的"手"(连接和执行工具)
工具描述的质量决定一切 💡
LLM 怎么知道该调哪个工具?答案是靠工具描述。对比一下:
vbnet
// ❌ 模糊的描述
name: "data_processor"
description: "处理数据"
// ✅ 精准的描述
name: "csv_to_json_converter"
description: "将 CSV 格式的文本转换为 JSON 数组,
每一行成为数组中的一个对象,首行作为字段名"
第一个描述太泛了------"处理数据"?处理什么数据?怎么处理?LLM 看到这种描述基本是蒙圈的。第二个描述就很明确,LLM 知道遇到 CSV 转 JSON 的需求时该调它。
💡 记住:工具描述不是写给人看的注释,而是写给 LLM 看的"使用说明书"。
三层安全设计
工具调用涉及到安全问题,比如"发邮件"这种不可逆操作。完整的安全设计有三层:
- 工具描述约束:在工具描述中写明"调用前必须和用户确认内容"
- LLM Think 评估:LLM 在 Think 步骤判断"这个操作是否需要确认"
- Host 拦截:宿主程序对高风险操作弹出确认提示
三层防线,缺一不可 🎯
三、规划与任务分解:Agent 怎么把大任务拆小
如果你用 Claude Code 帮你做一个博客项目,你会发现它不会上来就开始写代码。它会先做一件事:规划。
列出需求点、确定技术栈、规划页面结构、拆出任务清单------每一项都是具体要执行的步骤。
带依赖关系的拆解
关键不是简单列个 TODO list,而是要搞清楚任务之间的依赖:
yaml
任务 1: 初始化项目 → 无依赖
任务 2: 搭建页面布局 → 依赖任务 1
任务 3: 实现暗黑模式 → 依赖任务 2
任务 4: 写单元测试 → 依赖任务 2、3
为什么依赖关系这么重要?三个原因:
- Agent 知道执行顺序
- 保证依赖任务完成后才执行下游任务
- 在多 Agent 模式下,能知道哪些任务可以并行分配
两种执行策略
| 策略 | 说明 | 适用场景 |
|---|---|---|
| Plan-then-Execute | 先规划好所有步骤,然后逐步执行 | 需求明确、步骤可预见 |
| Interleaved(交替式) | 规划一步、执行一步、再根据结果规划下一步 | 不确定性高的任务 |
实际的 Agent 更偏向交替式。因为就算规划得再好,执行过程中也可能遇到突发情况------比如执行到第 3 步发现 Next.js 版本不支持某个暗黑模式方案,这时候 Agent 需要重新审视整个计划,调整方案再继续执行。
🚨 还有一个容易忽略的点:探索先于规划!
比如要重构一个认证模块,Agent 不应该上来就写计划。而是先审视一下项目现有的认证模块------看能不能改、改了影响多大------然后再做规划。
四、记忆系统:短期、长期、工作记忆
Agent 怎么"记住"东西?这里有三种截然不同的记忆类型 👇
三种记忆
| 类型 | 类比 | Agent 中的体现 | 生命周期 |
|---|---|---|---|
| 短期记忆 | 和朋友聊天时的对话内容 | 当前对话的上下文 | 本次对话 |
| 长期记忆 | 手机备忘录 | MEMORY.md、CLAUDE.md | 跨对话保留 |
| 工作记忆 | 做数学题时的草稿纸 | TodoWrite 任务清单、Plan | 任务结束就丢弃 |
这三者最容易搞混的是长期记忆和工作记忆。
来个场景帮你区分:
一个客服 Agent,用户打来电话说"耳机坏了要退货"。Agent 承诺 3 天内处理。
三天后用户又打来问进度。
这时候 Agent 需要知道"之前承诺了 3 天内处理"这个信息------它应该存在哪种记忆里?
答案是长期记忆 。因为这个信息需要跨对话保留。工作记忆不行,因为它在上一次对话结束时就被丢弃了。
💡 区分标准很简单:需要跨对话保留的 → 长期记忆。只在当前任务中有用的 → 工作记忆。
五、上下文窗口管理:Agent 的"内存管理"
LLM 的上下文窗口是有限的(就像你电脑的内存)。一个处理大型项目的 Agent,不可能把所有文件都塞进上下文里。
那怎么办?这里有几个核心策略:
策略一:按需加载
不一次性读所有文件,而是先搜索定位,再精确读取。
比如 Claude Code 修一个 bug,它的做法是:
- 先用
grep搜索关键词,找到 3 个相关文件 - 只读取这 3 个文件的内容
- 修改完成
而不是把整个项目的 50 个文件全部读一遍。
策略二:摘要压缩
对话太长时,把早期的对话内容压缩成摘要,保留关键信息,释放上下文空间。
策略三:子 Agent 分担
把任务拆给子 Agent 处理,每个子 Agent 有自己独立的上下文窗口。这样就把一个大的上下文需求分散到了多个小窗口里。
策略四:避免冗余
已经知道的信息不要重复加载。比如 Claude Code 编辑完一个文件后,不会重新读取这个文件------因为编辑的内容已经在上下文里了,再读一次就是加载重复信息。
💡 "避免冗余"和"摘要压缩"不是一回事!
- 避免冗余:不加载重复信息
- 摘要压缩:把已有信息压缩变短
前者是"不加",后者是"缩短"。我之前就搞混过 😅
六、ReAct 范式:边想边做的艺术
ReAct = Re ason + Act。它和核心循环是什么关系?
核心循环是通用的设计模式,ReAct 是具体的实现方法。
就像"组件化"是通用的前端思想,React 是实现组件化的具体框架。你不会说"组件化是 React 的改良版"对吧 😂
ReAct 之前的两种做法
| 做法 | 问题 |
|---|---|
| 只推理不行动(Chain-of-Thought) | LLM 一直在"想",但不调工具,容易产生幻觉 |
| 只行动不推理(Action-only) | 直接调工具,不说明为什么,遇到意外就懵了 |
ReAct 的创新就是把两者结合------Thought 和 Action 交替进行:
vbnet
Thought: 我需要先确认《三体》的作者,不能凭记忆猜
Action: search("三体 作者")
Observation: 刘慈欣
Thought: 确认是刘慈欣,接下来搜他的其他作品
Action: search("刘慈欣 其他作品")
Observation: 《球状闪电》《流浪地球》《超新星纪元》...
ReAct 的两大核心价值
1. 自我纠错
当搜索失败时,Thought 步骤让 Agent 能反思原因并调整策略:
vbnet
Thought: 我需要先确认作者
Action: search("三体 作者")
Observation: 没有找到相关结果
Thought: 搜索失败了,可能是关键词不对,换个方式试试
Action: search("《三体》 科幻小说 作者是谁")
Observation: 刘慈欣
如果是 Action-only 模式,搜索失败后 Agent 可能直接跳到下一步,或者傻乎乎地告诉你"找不到" 😬
2. 可追溯性(Traceability)
每一步推理都显式输出,开发者能看到 Agent "在想什么"。出了问题可以精确定位到哪一步的推理出了错。
其实你在 Claude Code 里已经见过了------Agent 在每次调用工具前输出的那些分析和推理文字(比如"让我先搜索一下相关文件"),就是 ReAct 中 Thought 的体现 💡
什么时候不需要 ReAct?
流程固定、没有不确定性的任务不需要。
比如"每天早上查天气 → 格式化 → 发通知",这种固定流水线甚至不需要 LLM 来编排,一个定时脚本就够了。ReAct 的价值在于应对不确定性,固定流程用它反而是浪费 token 🤷♂️
七、多 Agent 协作:一个人干不完就叫帮手
到目前为止我们聊的都是单个 Agent 的能力。但当任务变复杂了,一个 Agent 就不太够用了。
为什么需要多 Agent?
| 优势 | 说明 |
|---|---|
| 并行效率 | 没有依赖的任务可以同时跑 |
| 上下文隔离 | 每个 Agent 只加载自己需要的信息,不互相污染 |
| 专业化 | 每个 Agent 专注一个领域,配备针对性的工具和提示 |
两种协作架构
中心编排(Orchestrator):
css
[主 Agent]
/ | \
后端Agent 前端Agent 测试Agent
主 Agent 负责分配任务、收集结果、协调信息。子 Agent 之间不直接通信。
去中心化(Peer-to-peer):
markdown
后端Agent ←→ 前端Agent
↕ ↕
测试Agent ←→ ...
Agent 之间直接通信,通过共享状态来同步。
Claude Code 用的是哪种?
中心编排。 Claude Code 有一个主 Agent 做全局把控,spawn 出子 Agent 来并行处理任务。子 Agent 之间不直接通信,所有信息流经主 Agent。
为什么选这种?因为主 Agent 能统一调度------当后端 Agent 改了 API 字段名,主 Agent 可以通知前端 Agent 和测试 Agent 同步修改。如果是去中心化的,这个信息同步就会很混乱。
中心编排的代价
主 Agent 会成为瓶颈 ------所有信息都要经过它,带来额外的 token 消耗和延迟。所以实际使用中,主 Agent 不会让子 Agent 汇报每一个细节,而是只收集关键结果和变更 🎯
八、错误处理与自我纠正:Agent 犯错了怎么办
Agent 不是万能的,它会犯错。关键是怎么发现错误 和怎么处理错误。
三类错误信号来源
| 来源 | 说明 | 可靠性 |
|---|---|---|
| 环境反馈 | 执行结果直接告诉你错了(测试失败、命令报错、API 404) | ⭐⭐⭐ 最高 |
| 人类反馈 | 用户主动指出问题("你改错文件了") | ⭐⭐ |
| 自我反思 | Agent 在 Thought 中自己发现不对("这个文档版本不匹配") | ⭐ 可能反思错 |
需要注意的是,这里的可靠性指的是信号的确定性 ------环境反馈是程序化的确定结果, 而人类反馈可能存在表述模糊的情况。但在意图判断层面,人类反馈的权威性是最高的。
四种应对策略(从轻到重)
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 换方式重试 | 换关键词、换思路,不是重复同样的操作 | 第一次失败,可能是方法不对 |
| 回退重来 | 撤销修改,从头用完全不同的方案 | 连续修补越改越乱 |
| 升级求助 | 请求用户介入,或调用更强的模型 | 自身能力不足 |
| 优雅失败 | 承认失败,报告已尝试的方案 | 所有策略都用尽 |
🚨 还记得核心循环里的 Think 吗?这里又用上了:
Think 决定"做什么",重试上限决定"做多久"。 没有 Think,Agent 会盲目重试同样的操作;没有重试上限,即使有 Think 也可能无限尝试。两者缺一不可!
实际中,一个错误可能需要组合使用 多种策略。比如执行 npm install 报磁盘空间不足,Agent 可能需要先清理缓存(换方式重试),但清理磁盘属于有风险的操作,又需要先问用户(升级求助)。
九、安全与对齐:给 Agent 装上"刹车"
Agent 能力越强,越需要安全约束。这不是可选的,是必须的 🚨
风险分级权限模型
| 风险等级 | 操作类型 | 处理方式 |
|---|---|---|
| 无风险 | 读取文件、搜索 | 直接执行,不问 |
| 中等风险 | 编辑文件 | 可配置(严格模式要问,宽松模式自动执行) |
| 高风险 | Bash 命令、删除文件、推送代码 | 默认必须确认 |
| 禁止 | 恶意代码、攻击系统 | 无论如何都不执行 |
如果你用过 Claude Code,应该对此很熟悉------读文件不问你,执行 Bash 命令会弹确认。
四层防御(Defense in Depth)
这是整个安全设计中最重要的概念 👇
| 层级 | 机制 | 说明 |
|---|---|---|
| 第 1 层:模型层 | LLM 训练时内置的对齐 | 拒绝明显有害的请求 |
| 第 2 层:工具层 | 工具描述中的约束规则 | "发邮件前必须确认" |
| 第 3 层:系统层 | 权限分级、沙箱隔离 | 限制可访问的目录范围 |
| 第 4 层:人类层 | Human-in-the-Loop | 关键操作让用户确认 |
核心原则是:每一层都不能完全信任上一层。
即使模型层没拦住(被 prompt injection 绕过了),工具层可以拦;工具层也没拦住,系统层可以拦;系统层也漏了,还有人类做最后把关。
如果你做过前端,这个思路你一定不陌生------输入校验就是一样的:
sql
用户输入 → 前端表单校验 → API 参数校验 → 数据库约束(NOT NULL、UNIQUE)
每一层都不信任上一层已经校验过了。这就是多层防御的精髓 🎯
十、编排框架与实战选型:用什么工具来造 Agent
学完了 9 个核心概念,理论上你完全可以从零写一个 Agent 了。但正如你不会用原生 JS 从头撸一个大型应用一样------有框架帮你封装好了通用的能力,何必自己造轮子 😁
三个层级
| 层级 | Agent 领域 | 前端类比 | 特点 |
|---|---|---|---|
| 底层 SDK | Claude Agent SDK | 原生 JS | 最大灵活性,什么都能控制 |
| 编排框架 | LangGraph、CrewAI | React、Vue | 核心抽象开箱即用,有约定模式 |
| 低代码平台 | Dify、Coze | Webflow | 可视化搭建,上手快但灵活性低 |
选型指南
选底层 SDK: 需要极致控制力,团队技术能力强。比如 Anthropic 的 Claude Code,它的核心循环、上下文管理、权限系统、hook 机制都是从底层直接构建的------这种高度定制的场景,就适合在 SDK 层级或更底层去实现。
选编排框架: 有开发能力的团队,想利用框架的核心抽象(Agent、Tool、Memory)快速搭建,同时保留一定的灵活性和可扩展性。
选低代码平台: 不懂开发的人员也能用可视化方式搭工作流,或者需要快速验证想法。比如一个运营同学想搭个"每天自动总结新闻发到飞书群"的工作流,用 Dify 拖拖拽拽就行了。
💡 一个有趣的趋势:
当前 Agent 领域还在快速演化,底层 SDK 的使用率在上升。因为很多编排框架的抽象层反而成了限制------Agent 的行为很难被预定义的流程图完全覆盖。Anthropic 官方推荐的做法就是用轻量 SDK + 简单代码编排,而不是引入重型框架。
这就像前端早期------很多人觉得必须用框架,后来发现对于很多场景,原生 JS + 轻量库反而更合适 🤷♂️
后语
知识无价,支持原创!这篇文章就介绍到这里。
整篇文章下来,我们从 Agent 最基础的核心循环一路学到编排框架选型,10 个概念环环相扣:
- 核心循环是 Agent 的"心跳"
- 工具调用让它能"动手"
- 规划让它能"拆解问题"
- 记忆让它能"记住你"
- 上下文管理让它能"高效工作"
- ReAct让它能"边想边做"
- 多 Agent让它能"叫帮手"
- 错误处理让它能"从失败中恢复"
- 安全与对齐给它装上"刹车"
- 编排框架提供"开箱即用的工具箱"
如果你之前觉得 Agent 是个黑盒,希望看完这篇之后,你已经能透过现象看到本质了 🔥
喜欢霖呆呆的小伙伴还希望可以关注霖呆呆的公众号 LinDaiDai
我会不定时的更新一些前端方面的知识内容以及自己的原创文章 🎉。
你的鼓励就是我持续创作的主要动力 😊。