文章总结: 本文主要介绍了AIAgent的三种主流工作范式,特别是ReAct。它解释了ReAct如何将思考与行动交织进行,通过Thought、Action、Observation的循环来完成任务,并分析了其相比纯思考或纯行动模式的优势,最后还提供了一个使用SerpApi实现ReAct智能体的代码示例。 综合评分: 85 文章分类: AI安全,技术标准,解决方案,安全开发,其他
从零玩转 AI Agent —— 4:Agent 到底是怎么”思考”和”行动”的?
原创
Claude Code Claude Code
Crush Sec
2026年3月21日 10:30 广东
上一期我们搞清楚了 LLM 的工作原理,知道了它本质上是一个”预测下一个词”的机器。 但光有一个会说话的大脑还不够——Agent 怎么把这个大脑和外部世界连起来?当任务变复杂,它又是怎么组织自己的思考和行动的?
引子:同一个任务,三种不同的”做法”
给 Agent 一个任务:“帮我找一下最新款的华为手机,总结一下卖点。”
这个问题 LLM 凭自己的知识库回答不了(信息太新),必须借助工具。但怎么用工具,不同的 Agent 范式差异巨大:
ounter(lineounter(lineounter(lineReAct: 边想边搜 → 看到结果 → 再想下一步 → 循环到有答案为止Plan-and-Solve:先列步骤 → 拆成子任务 → 逐步执行 → 汇总结果Reflection:生成初稿 → 自我审查 → 发现不足 → 修改优化 → 再审查
这三种范式,是今天几乎所有主流 Agent 框架(LangChain、AutoGen、Dify)的设计原型。搞清楚它们,你就能看懂那些框架在背后做了什么。
一、ReAct:边想边做
核心思想
ReAct(Reasoning + Acting)的核心只有一句话:
把”思考”和”行动”显式地交织在一起,每次行动之后看结果、再思考、再行动。
每一步都遵循固定的轨迹:
ounter(lineounter(lineounter(lineounter(lineThought → Action → Observation ↑ | └──────────────────────┘ (循环直到完成)
| 角色 | 含义 | 例子 |
| — | — | — |
| Thought | 内心独白,分析当前情况 | “我需要搜索最新信息” |
| Action | 调用工具 | Search[华为最新手机] |
| Observation | 工具返回的结果 | 搜索结果摘要 |
为什么这样设计有效?
- 纯思考(Chain-of-Thought):会推理,但和外部世界完全隔离,容易产生幻觉
- 纯行动:直接调用工具,但没有规划,遇到复杂问题会乱套
- ReAct:推理指导行动,行动结果修正推理——两者相辅相成
完整实现
下面是一个完整的 ReAct 智能体,使用 SerpApi 做实时搜索:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineimport osimport refrom openai import OpenAIfrom dotenv import load_dotenvfrom typing import List, Dict, Any
load_dotenv()
# ============================================================# 第一部分:LLM 客户端# ============================================================class HelloAgentsLLM: def __init__(self): self.model = os.getenv("LLM_MODEL_ID") api_key = os.getenv("LLM_API_KEY") base_url = os.getenv("LLM_BASE_URL") self.client = OpenAI(api_key=api_key, base_url=base_url)
def think(self, messages: List[Dict], temperature: float = 0) -> str: response = self.client.chat.completions.create( model=self.model, messages=messages, temperature=temperature, stream=True ) chunks = [] for chunk in response: content = chunk.choices[0].delta.content or "" print(content, end="", flush=True) chunks.append(content) print() return "".join(chunks)
# ============================================================# 第二部分:工具定义与管理器# ============================================================def search(query: str) -> str: """调用 SerpApi 执行 Google 搜索,返回结构化结果""" from serpapi import SerpApiClient params = { "engine": "google", "q": query, "api_key": os.getenv("SERPAPI_API_KEY"), "gl": "cn", "hl": "zh-cn" } results = SerpApiClient(params).get_dict() if "answer_box" in results and "answer" in results["answer_box"]: return results["answer_box"]["answer"] if "organic_results" in results: snippets = [ f"[{i+1}] {r.get('title','')}\n{r.get('snippet','')}" for i, r in enumerate(results["organic_results"][:3]) ] return "\n\n".join(snippets) return f"未找到关于 '{query}' 的信息。"
class ToolExecutor: def __init__(self): self.tools: Dict[str, Dict[str, Any]] = {}
def register(self, name: str, description: str, func: callable): self.tools[name] = {"description": description, "func": func}
def get_func(self, name: str): return self.tools.get(name, {}).get("func")
def list_tools(self) -> str: return "\n".join( f"- {n}: {info['description']}" for n, info in self.tools.items() )
# ============================================================# 第三部分:ReAct 提示词模板# ============================================================REACT_PROMPT = """你是一个可以调用外部工具的智能助手。
可用工具:{tools}
请严格按照以下格式回应:Thought: 你的思考过程Action: 工具名[工具输入] 或 Finish[最终答案]
当你已有足够信息时,使用 Finish[答案] 结束。
Question: {question}History: {history}"""
# ============================================================# 第四部分:ReAct 智能体核心循环# ============================================================class ReActAgent: def __init__(self, llm: HelloAgentsLLM, tools: ToolExecutor, max_steps: int = 5): self.llm = llm self.tools = tools self.max_steps = max_steps
def run(self, question: str) -> str: history = [] for step in range(1, self.max_steps + 1): print(f"\n--- 第 {step} 步 ---") prompt = REACT_PROMPT.format( tools=self.tools.list_tools(), question=question, history="\n".join(history) or "(无)" ) response = self.llm.think([{"role": "user", "content": prompt}])
# 解析 Thought 和 Action thought_m = re.search(r"Thought:\s*(.*?)(?=\nAction:|$)", response, re.DOTALL) action_m = re.search(r"Action:\s*(.*?)$", response, re.DOTALL) thought = thought_m.group(1).strip() if thought_m else "" action = action_m.group(1).strip() if action_m else ""
if thought: print(f"思考: {thought}") if not action: break
# 检查是否完成 if action.startswith("Finish"): match = re.match(r"Finish\[(.*)\]", action, re.DOTALL) final = match.group(1) if match else action print(f"\n最终答案: {final}") return final
# 执行工具 tool_match = re.match(r"(\w+)\[(.*)\]", action, re.DOTALL) if not tool_match: continue tool_name, tool_input = tool_match.group(1), tool_match.group(2) print(f"行动: {tool_name}[{tool_input}]") func = self.tools.get_func(tool_name) observation = func(tool_input) if func else f"未找到工具 '{tool_name}'" print(f"观察: {observation}")
history.append(f"Action: {action}") history.append(f"Observation: {observation}")
print("已达到最大步数,流程终止。") return ""
# ============================================================# 运行入口# ============================================================if __name__ == "__main__": llm = HelloAgentsLLM() tools = ToolExecutor() tools.register( "Search", "网页搜索引擎。回答时事、实时信息时使用此工具。", search ) agent = ReActAgent(llm, tools, max_steps=5) agent.run("华为最新的手机是哪一款?它的主要卖点是什么?")
运行效果:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line--- 第 1 步 ---Thought: 用户询问华为最新的手机型号及其主要卖点,这属于时事信息,需要使用搜索工具获取最新数据。Action: Search[华为最新手机 发布]思考: 用户询问华为最新的手机型号及其主要卖点,这属于时事信息,需要使用搜索工具获取最新数据。行动: Search[华为最新手机 发布]观察: [1] 华为手机- 华为官网智能手机 ; Mate 系列. 非凡旗舰. HUAWEI Mate 80 Pro Max. ¥7999 起 ; Pura 系列. 先锋影像. HUAWEI Pura 80 Pro+. ¥7999 起 ; Pocket 系列. 美学新篇. HUAWEI Pocket 2 优享 ...
[2] 华为发布会2025.11.25华为Mate 80 系列| Mate X7 及全场景新品发布会华为全新发布Mate 80 系列、Mate X7、MatePad Edge、WATCH Ultimate 2、华为智慧屏MateTV Max、华为路由X3 Pro ...
[3] 2026年华为手机各系列介绍及选购指南(3月份更新) ...华为今年新机都只有纯血鸿蒙系统版本可选,介意者可以考虑荣耀等其他品牌。 近期更新:已更新12月22日发布的华为nova15系列。已更新11月25日发布的华为Mate80系列。
--- 第 2 步 ---Thought: 从之前的搜索结果可以看出,华为最新的手机是 Mate 80 系列,于2025年11月25日发布。但目前的信息只显示了价格和简单的宣传语("非凡旗舰"),我需要搜索更多关于这款手机的详细配置和卖点信息。
Action: Search[华为Mate 80 Pro 配置 卖点]思考: 从之前的搜索结果可以看出,华为最新的手机是 Mate 80 系列,于2025年11月25日发布。但目前的信息只显示了价格和简单的宣传语("非凡旗舰"),我需要搜索更多关于这款手机的详细配置和卖点信息。行动: Search[华为Mate 80 Pro 配置 卖点]观察: [1] 华为Mate 80系曝光汇总王炸升级全系配备硬件规格方面,Mate 80 系列几乎确定将首发新旗舰处理器,电池则是6000mAh 的硅碳负极方案,系统预装鸿蒙OS 6,并且继续支持卫星通信,这些核心卖点基本是稳了 ...
[2] HUAWEI Mate 80 Pro 参数规格- 华为官网HUAWEI Mate 80 Pro 参数规格 · 屏幕. 尺寸. 6.75 英寸 · 处理器. 麒麟9030 Pro(16 GB RAM 版本). 麒麟9030(12 GB RAM 版本) · 操作系统. HarmonyOS 6.0 · 存储. 运行内存(RAM).
[3] 华为Mate 80 Pro Max 为什么值得买?看完这一篇就够了!近期价格降至7761元左右,性价比凸显。 · 搭载旗舰级多摄组合,长焦和微距能力突出。 · 6.9英寸双层OLED直屏,8000nit峰值亮度是核心亮点。 · 麒麟9030 Pro芯片 ...
--- 第 3 步 ---Thought: 根据搜索结果,华为最新发布的手机系列是 Mate 80 系列,于 2025 年 11 月 25 日发布。其中顶级型号为 Mate 80 Pro 和 Mate 80 Pro Max。主要卖点包括最新的麒麟 9030 系列芯片、HarmonyOS 6.0 系统、高亮度的双层 OLED 屏幕、大容量硅碳负极电池以及旗舰级影像系统和卫星通信功能。
Action: Finish[华为最新的手机是 **HUAWEI Mate 80 系列**(含 Mate 80 Pro 和 Mate 80 Pro Max 等),该系列于 2025 年 11 月 25 日发布。
其主要卖点如下:1. **旗舰性能**:首发搭载新一代麒麟 9030 及 9030 Pro 处理器。2. **最新系统**:预装 HarmonyOS 6.0(纯血鸿蒙系统)。3. **顶级屏幕**:Mate 80 Pro Max 配备 6.9 英寸双层 OLED 直屏,峰值亮度高达 8000nit。4. **超长续航**:全系配备 6000mAh 硅碳负极大电池。5. **影像能力**:采用旗舰级多摄组合,长焦和微距拍摄能力突出。6. **通信功能**:支持卫星通信功能。7. **价格**:起售价为 7999 元。]思考: 根据搜索结果,华为最新发布的手机系列是 Mate 80 系列,于 2025 年 11 月 25 日发布。其中顶级型号为 Mate 80 Pro 和 Mate 80 Pro Max。主要卖点包括最新的麒麟 9030 系列芯片、HarmonyOS 6.0 系统、高亮度的双层 OLED 屏幕、大容量硅碳负极电池以及旗舰级影像系统和卫星通信功能。
最终答案: 华为最新的手机是 **HUAWEI Mate 80 系列**(含 Mate 80 Pro 和 Mate 80 Pro Max 等),该系列于 2025 年 11 月 25 日发布。
其主要卖点如下:1. **旗舰性能**:首发搭载新一代麒麟 9030 及 9030 Pro 处理器。2. **最新系统**:预装 HarmonyOS 6.0(纯血鸿蒙系统)。3. **顶级屏幕**:Mate 80 Pro Max 配备 6.9 英寸双层 OLED 直屏,峰值亮度高达 8000nit。4. **超长续航**:全系配备 6000mAh 硅碳负极大电池。5. **影像能力**:采用旗舰级多摄组合,长焦和微距拍摄能力突出。6. **通信功能**:支持卫星通信功能。7. **价格**:起售价为 7999 元。
这段代码的三个核心:
① 提示词定义了整个交互规范REACT_PROMPT 告诉 LLM 用什么格式输出——这是让机器理解指令的”合同”。格式越清晰,解析越稳定。
② 正则表达式解析 Thought/ActionLLM 输出是纯文本,re.search 负责从中提取结构化信息。这是 ReAct 实现中最脆弱的环节——模型不遵守格式时就会出错。
③ history 列表是 Agent 的”短期记忆”每一步的 Action 和 Observation 都被追加进去,下一步的 LLM 调用能”看到”所有历史——这就是 ReAct 能动态纠错的根本原因。
二、Plan-and-Solve:先规划,再执行
核心思想
ReAct 是”走一步看一步”,适合探索性任务。但有些任务结构清晰、路径确定——比如一道多步数学题——这时候更好的策略是:
先把整个解题路径规划出来,再严格按步骤执行。
两阶段工作流:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line第一阶段(规划) 第二阶段(执行)───────────────── ────────────────────────────接收问题 步骤 1 → 结果 1 ↓ ↓LLM 拆解成 [步骤1, 步骤2, ...] 步骤 2 + 结果1 → 结果 2 ↓ 步骤 3 + 结果2 → 最终答案
每个执行步骤都能”看到”前面的结果,保证信息在链条中顺畅传递。
核心实现
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineimport astimport osfrom openai import OpenAIfrom dotenv import load_dotenv
load_dotenv()
# ============================================================# 第一部分:规划器 —— 把问题拆成步骤列表# ============================================================PLANNER_PROMPT = """你是一个顶级的 AI 规划专家。将以下问题分解成逻辑清晰的步骤。输出必须是 Python 列表格式,用 ```python ... ``` 包裹,例如:["步骤1", "步骤2", ...]
问题: {question}"""
class Planner: def __init__(self, llm): self.llm = llm
def plan(self, question: str) -> list: prompt = PLANNER_PROMPT.format(question=question) response = self.llm.think([{"role": "user", "content": prompt}]) try: plan_str = response.split("```python")[1].split("```")[0].strip() return ast.literal_eval(plan_str) except Exception as e: print(f"解析计划失败: {e}") return []
# ============================================================# 第二部分:执行器 —— 逐步执行,传递中间结果# ============================================================EXECUTOR_PROMPT = """你是一位顶级的 AI 执行专家。严格按照计划逐步解决问题。
原始问题: {question}完整计划: {plan}历史步骤与结果: {history}当前步骤: {current_step}
请仅输出当前步骤的答案,不要额外解释。"""
class Executor: def __init__(self, llm): self.llm = llm
def execute(self, question: str, plan: list) -> str: history = "" last_result = "" for i, step in enumerate(plan): print(f"\n→ 步骤 {i+1}/{len(plan)}: {step}") prompt = EXECUTOR_PROMPT.format( question=question, plan=plan, history=history or "无", current_step=step ) last_result = self.llm.think([{"role": "user", "content": prompt}]) history += f"步骤 {i+1}: {step}\n结果: {last_result}\n\n" return last_result
# ============================================================# 第三部分:整合——先规划,后执行# ============================================================class PlanAndSolveAgent: def __init__(self, llm): self.planner = Planner(llm) self.executor = Executor(llm)
def run(self, question: str): print(f"\n问题: {question}") plan = self.planner.plan(question) if not plan: print("无法生成计划,终止。") return print(f"\n生成计划: {plan}") final = self.executor.execute(question, plan) print(f"\n最终答案: {final}")
# ============================================================# 运行入口# ============================================================if __name__ == "__main__": from chapter4_llm import HelloAgentsLLM # 复用第一部分的 LLM 客户端 llm = HelloAgentsLLM() agent = PlanAndSolveAgent(llm) agent.run( "一个水果店周一卖了15个苹果,周二卖了周一的两倍," "周三比周二少5个。三天总共卖了多少个?" )
运行效果:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line问题: 一个水果店周一卖了15个苹果...
生成计划: [ "计算周一销量:15个", "计算周二销量:15 × 2 = 30个", "计算周三销量:30 - 5 = 25个", "计算总销量:15 + 30 + 25 = 70个"]
→ 步骤 1/4: 计算周一销量:15个15→ 步骤 2/4: 计算周二销量:15 × 2 = 30个30→ 步骤 3/4: 计算周三销量:30 - 5 = 25个25→ 步骤 4/4: 计算总销量:15 + 30 + 25 = 70个70
最终答案: 70
这段代码的三个核心:
① 规划器强制输出 Python 列表用代码块格式包裹输出,然后用 ast.literal_eval 安全解析——比解析自然语言稳定得多。
② 执行器的 history 传递中间结果每执行完一步,把”步骤+结果”追加进 history,下一步的 LLM 调用能直接用上——这就是多步推理不出错的关键。
③ Planner 和 Executor 职责分离规划器只管”拆问题”,执行器只管”跑步骤”。职责分离让代码更清晰,也更容易替换其中一个组件。
三、Reflection:生成 → 反思 → 优化
核心思想
前两种范式完成任务就结束了。但初次生成的结果不一定是最好的——正如我们写完代码会 code review,写完文章会修改。
Reflection 范式引入了一个”内部评审员”:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line执行(生成初稿) ↓反思(评审员找问题)──→ "无需改进" → 结束 ↓优化(根据反馈修改) ↓再次反思 …(循环直到满意或达到上限)
完整实现
以”生成素数查找函数并持续优化”为例:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linefrom typing import Optional, List, Dict, Any
# ============================================================# 第一部分:短期记忆模块 —— 存储执行轨迹# ============================================================class Memory: def __init__(self): self.records: List[Dict[str, str]] = []
def add(self, record_type: str, content: str): self.records.append({"type": record_type, "content": content}) print(f"记忆已更新 [{record_type}]")
def get_trajectory(self) -> str: parts = [] for r in self.records: label = "上一轮代码" if r["type"] == "execution" else "评审反馈" parts.append(f"--- {label} ---\n{r['content']}") return "\n\n".join(parts)
def last_execution(self) -> Optional[str]: for r in reversed(self.records): if r["type"] == "execution": return r["content"] return None
# ============================================================# 第二部分:三套提示词(初始执行 / 反思 / 优化)# ============================================================INITIAL_PROMPT = """你是一位资深 Python 程序员。根据以下要求编写函数,包含完整签名、文档字符串,遵循 PEP 8。
要求: {task}
直接输出代码,不要额外解释。"""
REFLECT_PROMPT = """你是一位极其严格的代码评审专家,专注于算法效率。
原始任务: {task}待审查代码:{code}
分析时间复杂度,指出算法瓶颈,给出具体改进建议。如果已经最优,回复"无需改进"。
直接输出反馈,不要额外解释。"""
REFINE_PROMPT = """你是一位资深 Python 程序员,正在根据评审意见优化代码。
原始任务: {task}上一版代码: {last_code}评审意见: {feedback}
根据评审意见生成优化后的代码,直接输出,不要额外解释。"""
# ============================================================# 第三部分:Reflection 智能体核心循环# ============================================================class ReflectionAgent: def __init__(self, llm, max_iterations: int = 3): self.llm = llm self.memory = Memory() self.max_iterations = max_iterations
def _call(self, prompt: str) -> str: return self.llm.think([{"role": "user", "content": prompt}]) or ""
def run(self, task: str) -> str: print(f"\n任务: {task}")
# 初始执行 print("\n--- 初始执行 ---") initial_code = self._call(INITIAL_PROMPT.format(task=task)) self.memory.add("execution", initial_code)
# 迭代循环:反思 → 优化 for i in range(self.max_iterations): print(f"\n--- 第 {i+1}/{self.max_iterations} 轮迭代 ---")
last_code = self.memory.last_execution() feedback = self._call(REFLECT_PROMPT.format(task=task, code=last_code)) self.memory.add("reflection", feedback)
if "无需改进" in feedback: print("反思认为代码已足够好,停止迭代。") break
refined = self._call(REFINE_PROMPT.format( task=task, last_code=last_code, feedback=feedback )) self.memory.add("execution", refined)
final = self.memory.last_execution() print(f"\n最终代码:\n{final}") return final
# ============================================================# 运行入口# ============================================================if __name__ == "__main__": from chapter4_llm import HelloAgentsLLM llm = HelloAgentsLLM() agent = ReflectionAgent(llm, max_iterations=2) agent.run("编写一个 Python 函数,找出 1 到 n 之间所有的素数。")
运行效果:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line任务: 编写一个 Python 函数,找出 1 到 n 之间所有的素数。
--- 初始执行 ---(生成了基于试除法的初版,时间复杂度 O(n√n))记忆已更新 [execution]
--- 第 1/2 轮迭代 ---评审反馈: 当前 O(n√n) 时间复杂度过高,建议改用埃拉托斯特尼筛法, 复杂度降至 O(n log log n)。记忆已更新 [reflection](生成了基于筛法的优化版本)记忆已更新 [execution]
--- 第 2/2 轮迭代 ---评审反馈: 当前筛法已足够高效,在一般情况下无需改进。记忆已更新 [reflection]反思认为代码已足够好,停止迭代。
最终代码:def find_primes(n): """使用埃拉托斯特尼筛法找出 1 到 n 的所有素数。""" if n < 2: return [] is_prime = [True] * (n + 1) is_prime[0] = is_prime[1] = False p = 2 while p * p <= n: if is_prime[p]: for i in range(p * p, n + 1, p): is_prime[i] = False p += 1 return [num for num in range(2, n + 1) if is_prime[num]]
这段代码的三个核心:
① 三套提示词对应三个”角色”初始执行是”程序员”,反思是”严苛的评审员”,优化是”听取意见的程序员”——角色设定的差异决定了 LLM 输出的风格和侧重点。
② Memory 存储完整轨迹add_record 把每次”执行”和”反思”都存起来,get_trajectory 可以把整个历史序列化成文本——这就是模型能”知道自己试过什么”的原因。
③ "无需改进" 作为终止信号让 LLM 自己决定何时停止,而不是死等到最大轮数——这比固定迭代次数更智能,也防止了”优化过度”。
四、三种范式怎么选?
ounter(lineounter(lineounter(lineounter(lineounter(line场景描述 推荐范式────────────────────────────── ──────────────────需要实时搜索、调用 API 获取信息 ReAct(动态探索)任务可以被清晰分解为多个步骤 Plan-and-Solve(结构化执行)对结果质量要求极高,可以接受慢一点 Reflection(迭代优化)
| 维度 | ReAct | Plan-and-Solve | Reflection | | — | — | — | — | | 决策模式 | 走一步看一步 | 先规划后执行 | 生成后自我修正 | | 最适合 | 探索性任务 | 结构化推理 | 质量敏感任务 | | 主要成本 | 多次 LLM 调用 | 多次 LLM 调用 | 成本最高 | | 可解释性 | 高(Thought 可见) | 高(计划可见) | 高(反馈可见) |
这三种范式并不互斥——在实际项目里,你可能用 Plan-and-Solve 把大任务拆成子任务,每个子任务用 ReAct 去执行,最后用 Reflection 对整体结果做一轮审查。这就是今天主流框架的实际做法。
五、下一步
亲手实现了三种范式之后,你会发现一个共同的痛点:从零搭这些东西,工程量不小——提示词模板、解析器、错误处理、重试逻辑……每次都要重写。
那有没有一种方式,不用写这么多代码,也能快速搭出这些 Agent 流程?
下一期,我们走进低代码平台:Coze、Dify、n8n——用拖拽代替代码,验证一个 Agent 想法只需要几分钟,而不是几天。这对于快速迭代、非技术背景的同学,以及需要把 Agent 接入现有业务系统的场景,价值巨大。
本系列基于 Hello-Agents 开源课程,结合实践整理而成。代码已在 Python 3.10+ 环境验证。本文由 AI 辅助生成。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:Crush Sec Claude Code Claude Code《从零玩转 AI Agent —— 4:Agent 到底是怎么”思考”和”行动”的?》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。







评论