Agent 设计三阶段:ReAct → Memory → Reflection
你用过 ChatGPT------一问一答。你还用过 LangGraph 的 Supervisor 模式------多个 Agent 协作完成任务。但你知道怎么从前者升级到后者吗?这篇文章把 Agent 设计拆成三个阶段,每阶段加一个核心能力,最终从零构建一个能自主研究、有记忆、会反思的智能体。

Agent 到底是什么
Agent = LLM + 工具 + 记忆 + 自主决策循环
别被"智能体"这个名字吓到。Chat 和 Agent 的区别,一句话就能说清楚:
Chat: 用户 → LLM → 回复 → 结束
Agent: 用户 → LLM → 思考 → 选工具 → 执行 → 观察结果 → 再思考 → ... → 完成任务
Chat 是"一问一答",Agent 是"自主完成一个目标"。你告诉 Agent "帮我调研 LangGraph 和 CrewAI 的差异",它不会一次回答你,而是会自己搜索、自己整理、自己写报告。
Agent 的四个核心要素:
| 要素 | 角色 | 类比 |
|---|---|---|
| LLM(大脑) | 理解任务、推理、决策 | 大脑皮层 |
| Planning(策略) | 拆解任务、规划步骤 | 前额叶 |
| Tools(工具) | 执行具体操作 | 手脚 |
| Memory(记忆) | 记住上下文和经验 | 海马体 |
阶段一:ReAct ------ 让 LLM 学会"边想边做"
ReAct 是什么
ReAct = Reasoning(推理)+ Acting(行动)交替进行。
这是 Google DeepMind 2022 年提出的范式,如今是所有 Agent 的基础架构。流程极其简单:
┌──────────┐ ┌──────────┐ ┌──────────────┐
│ Thought │───►│ Action │───►│ Observation │
│ (推理) │ │ (行动) │ │ (观察) │
└──────────┘ └──────────┘ └──────────────┘
▲ │
└──────────────────────────────┘
循环直到 Final Answer
一个完整的 ReAct 过程
任务:LangGraph 最新版本是多少?支持哪些 Python 版本?
Step 1:
Thought: 我需要搜索 LangGraph 的最新版本信息。
Action: search("LangGraph latest version 2026")
Observation: LangGraph 1.2.0 已发布,支持 Python 3.10-3.13
Step 2:
Thought: 已获取版本号和 Python 支持范围,信息齐全。
Final Answer: LangGraph 最新版为 1.2.0,支持 Python 3.10 到 3.13。
最简 ReAct Agent 实现
python
# 30 行代码的 ReAct Agent
def react_agent(task: str, max_steps: int = 10) -> str:
history = [{"role": "user", "content": task}]
for step in range(max_steps):
response = llm.chat(history) # LLM 输出 Thought + Action 或 Final Answer
if "Final Answer:" in response:
return response.split("Final Answer:")[-1].strip()
if "Action:" in response:
action = parse_action(response) # 解析:Action: search("query")
result = execute_tool(action) # 执行工具
history.append({"role": "user", "content": f"Observation: {result}"})
return "达到最大步数限制"
三个关键点:
- 循环:不是调用一次 LLM,而是一直循环直到完成任务
- 工具调用:LLM 通过特定格式声明要调什么工具、传什么参数
- 观察反馈:工具结果注入对话历史,LLM 据此调整下一步
ReAct 的 Prompt 模板
这是让 LLM 进入 ReAct 模式的关键------一个精心设计的 Prompt:
你是一个研究助手。按以下格式回答:
Question: 用户的问题
Thought: 你当前的思考
Action: 要执行的动作,格式:tool_name(tool_input)
Observation: 工具返回的结果
... (Thought/Action/Observation 可重复)
Thought: 最终思考
Final Answer: 最终答案
可用工具:
- search(query: str): 搜索互联网
- calculator(expression: str): 计算数学表达式
Question: {question}
ReAct 为什么有效? 四个原因:
- 思考链可见------每一步推理都可追溯,调试不靠猜
- 工具与推理解耦------推理归 LLM,执行归工具,各司其职
- 自我纠正------观察到意外结果,LLM 可以调整下一步
- 可中断可恢复------任何一步都可以检查、修改后继续
阶段二:Memory ------ 让 Agent 不再"失忆"
为什么需要记忆
阶段一的问题:Agent 只能在一次调用内保持连贯。跨调用?完全不记得。
用户第 1 次:「帮我研究一下 ReAct 范式」
Agent 搜了一堆资料 → 生成报告 → 结束(所有中间结果丢失)
用户第 2 次:「再研究一下 Reflection」
Agent 从头开始,不知道你刚研究过 ReAct → 重复搜索
记忆系统解决的就是这个问题------让 Agent 记住"之前干了什么"和"之前学了什么"。
两层记忆
┌──────────────────────────────────────────────┐
│ 短期记忆(Short-term Memory) │
│ 当前对话的完整历史 │
│ 作用:理解上下文、追踪多轮对话 │
│ 实现:对话历史列表(memory.short_term) │
│ 类比:会议中的白板 │
├──────────────────────────────────────────────┤
│ 长期记忆(Long-term Memory) │
│ 跨会话保留的知识和总结 │
│ 作用:积累经验、避免重复搜索 │
│ 实现:向量数据库或简单 dict 存储 │
│ 类比:会议纪要存档 │
└──────────────────────────────────────────────┘
记忆系统实现
python
class MemorySystem:
def __init__(self):
self.short_term: list[dict] = [] # 短期:对话历史
self.long_term: dict[str, str] = {} # 长期:topic → summary
self.index: dict[str, list[str]] = {} # 索引:topic → keywords
def remember(self, topic: str, summary: str):
"""存入长期记忆"""
self.long_term[topic] = summary
self.index[topic] = [w for w in topic.lower().split() if len(w) > 1]
def recall(self, query: str) -> list[dict]:
"""从长期记忆中检索相关知识"""
query_words = set(query.lower().split())
matches = []
for topic, summary in self.long_term.items():
index_words = set(self.index.get(topic, []))
if query_words & index_words: # 有交集 → 相关
matches.append({"topic": topic, "summary": summary})
return sorted(matches, key=lambda m: len(query_words & set(m["topic"].split())), reverse=True)
def summarize_context(self, max_tokens: int = 500) -> str:
"""压缩短期记忆,避免 token 爆炸"""
if len(self.short_term) <= 3:
return "\n".join(str(m) for m in self.short_term)
# 保留最近 2 条完整,更早的做摘要
recent = self.short_term[-2:]
older_summary = f"[前{len(self.short_term)-2}步] " + " → ".join(
m["thought"][:50] for m in self.short_term[-5:-2]
)
return older_summary + "\n" + "\n".join(str(m) for m in recent)
Token 预算管理
ReAct 循环中,每一步的 Thought/Action/Observation 都会加入对话历史。10 步之后,历史可能膨胀到 5000+ tokens。解决方案:上下文压缩------超过阈值时,将早期步骤压缩为摘要,只保留最近几轮的完整信息。
阶段三:Reflection ------ 让 Agent 学会"自我纠错"
反思是什么
阶段二的 Agent 能搜索、能记忆、能生成报告------但它从不检查自己的输出质量。
Reflection(反思)= Agent 审视自己的输出,发现不足并自我改进。
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Generate │───►│ Review │───►│ Revise │
│ (生成) │ │ (审视) │ │ (修改) │
└──────────┘ └──────────┘ └──────────┘
│ │
检查通过? 不通过
│ │
▼ │
┌──────────┐ │
│ Output │◄───────┘
└──────────┘
两阶段架构:生成 + 反思
第一阶段(生成 Agent)------用 ReAct 循环生成初始报告。
第二阶段(反思 Agent)------用另一个视角审视报告。注意,反思可以用同一个 LLM(内省式),也可以用另一个 LLM(对抗式,效果更好)。
python
REFLECTION_PROMPT = """请审视以下报告,按以下维度检查:
1. 事实准确性:所有数据是否有来源支撑?
2. 完整性:是否覆盖了问题的所有方面?
3. 逻辑性:论证链条是否有漏洞?
4. 清晰度:表述是否容易理解?
给出:
- 评分(1-10)
- 具体问题清单
- 改进建议
如果评分 >= 8,输出 "PASS"。
报告内容:
{report}
"""
防止无限反思
反思机制一个必须处理的问题:Agent 可能反复修改,没完没了。
python
MAX_REFLECTION_ROUNDS = 3
PASS_THRESHOLD = 7 # 评分 >= 7 就通过
for round in range(MAX_REFLECTION_ROUNDS):
review = reflector.review(report, task)
if review["score"] >= PASS_THRESHOLD:
break # 达标,结束
report = reflector.revise(report, review) # 修改后继续
if round == MAX_REFLECTION_ROUNDS - 1:
print(f"达到最大修改轮次,停止反思")
两条硬规则:最大轮次 + 质量阈值。 少一条都可能出问题。
三种设计模式全景对比
ReAct 不是唯一的 Agent 模式。这里是一张完整的对比表:
| 模式 | 核心循环 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| ReAct | Think→Act→Observe | 简单可靠,可追溯 | 复杂任务容易迷路 | 搜索、问答 |
| Plan-Execute | Plan→Execute | 路线清晰 | 计划可能过时 | 多步工作流 |
| ReWOO | Plan→Tool use→Solve | 减少 LLM 调用 | 缺少中间纠正 | Token 敏感任务 |
| LLMCompiler | 并行执行 DAG | 速度快 | 依赖需明确 | 可并行的多工具 |
| Reflexion | ReAct + 反思 | 质量高 | 延迟和成本翻倍 | 需要高质量输出 |
| Multi-Agent | 多角色协作 | 专业化 | 协调开销大 | 复杂项目 |
选择决策树:
任务复杂度?
│
├── 简单(1-2步)→ 直接 ReAct
│
├── 中等(3-5步)→ ReAct + Reflection
│
└── 复杂(>5步或含子任务)
│
├── 子任务独立 → Multi-Agent(Supervisor 模式)
└── 子任务有依赖 → Plan-Execute + Reflection
生产环境避坑指南
1. Token 成本
ReAct 每步都要调 LLM。一个 10 步的 Agent 任务可能消耗 10 次 × 2000 tokens = 20000 tokens。缓解方案:上下文压缩、中间结果摘要、选择更便宜的模型做简单推理。
2. 死循环
Agent 可能在同一个工具上反复调用。必须设置 max_steps 和循环检测------如果连续 3 步都在调同一个工具且结果相同,强制终止。
3. 幻觉
LLM 可能编造工具调用结果。反思阶段的"事实检查"就是针对这个------强制要求每个结论标注来源。
4. 工具失败
搜索超时、API 限流、参数错误......每个工具都需要异常处理和降级策略。
5. 可观测性
你不知道 Agent 中间干了什么?打印每一步的 Thought/Action/Observation,或接入 LangSmith 做全链路追踪。
总结
Agent 设计的过程,本质上是把"人类完成任务的流程"逐步赋给 LLM:
- ReAct(阶段一)------让 LLM 进入"边想边做"的循环,不再是单次问答
- Memory(阶段二)------加上短期和长期记忆,让 Agent 记住经验、跨对话关联
- Reflection(阶段三)------加上自我审视机制,让 Agent 从"做完"升级到"做好"
三个阶段的代码都在 github.com/barryness/cc-ai-learning 的 009-agent-learning/agent_demo.py,按 --phase 1/2/3 分别运行,每个阶段都是独立的可跑 Demo。