最近在折腾 AI Agent 项目时,我发现自己绕不开一个问题:很多 Agent 跑起来之后,同一个错误会反复出现,换一种问法就翻车,甚至完全依赖人工调 Prompt 才能稳定一点。如果 Agent 只能“执行指令”,不能从失败中总结、更新自己的经验,那它和一段硬编码的流程几乎没有本质区别。这篇文章我会围绕 Prime Agent 这个“自我改进型 RLM Agent”展开,拆解它的核心思路、架构设计、奖励机制和反思流程,并给出一个可以直接运行的教学原型。无论你是刚接触 Agent 开发,还是已经在用 LangChain、自研 Agent 框架,都能从里面拿到一套相对完整的落地思路。
1. 什么是 Prime Agent:从普通 Agent 到自我改进
1.1 为什么普通 Agent 不够用
在进入 Prime Agent 之前,我们先对齐一下“普通 Agent”的定义。
一个典型的 LLM Agent,通常包含四部分:
- 大语言模型,作为“大脑”。
- 工具集,例如搜索、计算器、代码执行器、数据库查询接口。
- Prompt 模板,告诉模型当前任务、工具用法和输出格式。
- 执行循环:推理 -> 选择工具 -> 执行工具 -> 观察结果 -> 再次推理。
这套流程已经能解决很多问题,比如根据自然语言查询数据库、自动生成报告、调用 API 完成业务操作。但它有个明显的短板:模型不会因为“上次失败了”而自动调整自身行为。
举一个非常常见的例子:
用户让 Agent 写一段 Python 代码,Agent 生成后代码报错,报错原因是KeyError: 'name'。Agent 马上重新生成一次,结果还是访问了不存在的字段。重复三次之后,它可能仍然没有意识到“需要先检查字典中是否存在 name 字段”。
为什么?因为大多数 Agent 在每轮对话之间是“无状态”的。你的 Prompt 没变,Few-shot 示例没变,模型参数没变,模型怎么可能突然就学会规避KeyError?
这就是普通 Agent 的天花板:它擅长生成,但不擅长从错误中学习。而 Prime Agent 这类“自我改进型 Agent”想解决的问题,正是这个。
1.2 RLM Agent 的关键词拆解
标题里有一个组合词:RLM Agent。
在 Agent 相关的论文和技术文章中,RLM 并没有一个全世界统一的定义。不同语境下,它可能指:
- Reinforcement Learning + Language Model:通过强化学习方式训练语言模型,让模型在多次交互中根据奖励信号调整策略。
- Reasoning Language Model:具备更强推理能力的语言模型,能根据任务拆解中间步骤。
- Robot Learning Model:在具身智能领域使用的基础模型。
在 Prime Agent 的语境下,我更愿意把 RLM 理解为“通过强化学习反馈闭环来持续优化语言模型决策的 Agent”。也就是说,它不再是“单次调用 LLM 完成任务”,而是把每次任务执行都变成一个“尝试 -> 得到奖励 -> 更新策略”的强化学习过程。
和传统 Agent 相比,RLM Agent 有几个明显特征:
| 维度 | 传统 Agent | RLM Agent |
|---|---|---|
| 行为更新 | 靠修改 Prompt | 靠奖励信号和策略更新 |
| 失败处理 | 随机重新生成 | 反思错误并沉淀经验 |
| 记忆使用 | 单轮上下文 | 长期经验库 |
| 演进能力 | 无 | 可以持续改进 |
| 可靠评估 | 人工观察 | 奖励函数 + 评估集 |
这里要注意,RLM Agent 并非一定要微调模型。它可以通过 Prompt 动态组装、Few-shot 示例动态选择、工具调用策略调整等方式实现“自我改进”,微调只是更重的一种方式。
1.3 理解“Self-Improving”
“自我改进”这个词看起来很有吸引力,但在工程实现上要足够克制。
一个真正可落地的自我改进 Agent,通常具备以下能力:
- 能感知失败:任务执行失败时,能拿到具体错误信息,而不是只拿到一个“失败”的状态码。
- 能定位原因:知道错误发生在规划阶段、工具调用阶段还是结果解析阶段。
- 能沉淀经验:把失败案例、正确做法、反思过程写入经验库,后续可以检索。
- 能影响后续决策:新任务到来时,会优先参考历史相似经验,避免重复踩坑。
- 能在足够样本下更新策略:当某一类错误反复出现时,能从 Prompt 模板、示例选择或模型参数层面做出调整。
当然,自我改进也存在风险。如果 Agent 从错误经验中学习了错误结论,那改进就变成了“稳定地犯错”。所以后面我又补了一节“安全边界与人工审核”,这是生产环境必须考虑的部分。
现在,我们把 Prime Agent 定位成一个“以 RLM 为内核、带自我改进闭环的 Agent 原型”。
2. Prime Agent 整体架构与运行循环
2.1 架构模块
从工程实现角度,我把 Prime Agent 拆成六个模块:
- 感知模块:接收用户任务,解析目标,提取约束条件。
- 规划模块:把任务拆解成执行步骤,决定调用哪些工具。
- 执行模块:真正运行工具、执行代码、请求外部 API。
- 记忆模块:保存短期上下文和长期经验,支持相似度检索。
- 反思模块:对失败结果进行归因分析,生成改进建议。
- 策略更新模块:根据反思结果,更新 Prompt、Few-shot 示例或模型参数。
整体关系可以用下面的 ASCII 图表示:
用户任务 | v 感知模块 -> 规划模块 -> 执行模块 | | | | v v | 工具调用 执行结果 | | | | +----> 反思模块 <----+ | | | | v | | 经验库/记忆模块 | | | | +-------------------+------------+ | v 策略更新模块 | v 下一次任务执行从图中可以看到,反思模块是整个闭环的关键。没有反思,失败只会停留在“这次没成功”,而无法变成“下次不失败”的资产。
2.2 Agent Loop 的完整流程
Prime Agent 的单次任务执行,会走完下面这个循环:
- 接收任务,感知模块提取意图。
- 规划模块根据任务类型,选择执行模板和工具列表。
- 执行模块开始调用工具。
- 判断执行结果是否满足预期。
- 如果满足,任务结束,并把成功经验写入经验库。
- 如果不满足,反思模块分析错误类型,生成修复建议。
- 把修复建议作为上下文,再次进入规划阶段。
- 如果超过最大步数仍然失败,则记录失败案例,等待人工分析。
这里的“判断执行结果是否满足预期”会用到奖励信号。简单任务中,奖励信号可以是代码是否编译通过、单元测试是否通过、返回 JSON 是否合法;复杂任务中,可能需要借助一个独立的评估模型来打分。
2.3 与传统 Agent 框架的差异
很多 Agent 框架已经提供了“Agent Loop”的能力,比如 ReAct 模式:Reason + Act。但它们的循环和 Prime Agent 的循环有一个关键区别:
- ReAct 的循环:Reason -> Act -> Observe -> Reason,Observe 结果仍然只存在于当前上下文窗口,不会沉淀成跨任务经验。
- Prime Agent 的循环:Reason -> Act -> Observe -> Reflect -> Update Policy,Observe 结果会经过反思,并更新策略。
所以,你甚至可以在 LangChain 这类框架的基础上构建 Prime Agent,关键在于补上“反思”和“策略更新”两个环节,而不是重新发明轮子。
3. 环境准备与项目结构
由于本文的实战案例是一个偏教学性质的原型,我不会把版本号写死,因为不同模型的 API、不同 Agent 框架的依赖差异很大。下面以常见的 Python 环境为例进行说明。
3.1 运行环境建议
- 操作系统:Windows / Linux / macOS 均可。
- Python:建议 3.10 及以上。
- 模型获取方式:本地推理或云端 API 均可。
- 代码执行:需要安装 Python 环境,建议在虚拟环境中运行。
如果你想接大模型 API,常见的做法是使用 OpenAI 兼容接口的 SDK,或者通过 vLLM、Ollama 等工具启动本地模型服务。例如:
# 本地模型服务示例(按实际模型调整) ollama pull qwen2.5:7b ollama run qwen2.5:7b# 云端 API 示例(仅示意,不同平台不同) export OPENAI_API_KEY="your-api-key"请注意,这些命令只是环境准备的一种方式。实际项目中,你需要根据自己可用的模型服务调整。
3.2 项目目录规划
我们用一个固定的项目目录来组织代码:
prime_agent/ ├── agent/ │ ├── __init__.py │ ├── environment.py # 环境:代码执行器、结果判断 │ ├── memory.py # 经验库:写入、检索 │ ├── reflector.py # 反思模块 │ ├── policy.py # 策略更新模块 │ └── loop.py # Agent 主循环 ├── tasks/ │ └── sample_tasks.json # 测试任务集 ├── experience/ │ └── .gitkeep # 经验库持久化目录 └── main.py # 入口脚本这个小项目没有引入复杂框架,主要依赖 Python 标准库,方便你理解核心逻辑。如果你后面需要接入 LangChain 或自研框架,可以按模块迁移。
3.3 依赖选择说明
以下库不是硬性要求,只是为了演示:
json:标准库,用于经验数据持久化。subprocess:标准库,用于隔离执行 Python 代码。diff_match_patch:可选依赖,用于生成代码差异,你可以直接用字符串对比代替。openai或requests:可选,用于调用大模型 API。
在最小版本里,我会把“大模型生成”做成一个可替换函数,默认给出一个基于规则的实现,确保代码在没有外部 API 时也能直接跑通。
4. 核心机制拆解:奖励、记忆、反思与策略更新
4.1 奖励信号设计
奖励信号是 RLM Agent 的“指挥棒”。设计得好不好,直接决定 Agent 往哪个方向自我改进。
在设计奖励信号时,我通常遵循三个原则:
- 可计算:奖励必须能从任务结果中自动提取,不能依赖人工主观打分。
- 可解释:拿到奖励后,能知道 Agent 因为什么被奖励、因为什么被惩罚。
- 可分级:不要只给 0 和 1,要尽量提供中间档位,比如“部分成功”“超时但输出正确”。
以一个“写代码并运行得到结果”的 Agent 为例,奖励可以这样设计:
| 情况 | 奖励 | 说明 |
|---|---|---|
| 代码执行报错 | -1.0 | 越早报错,说明方案越不可行 |
| 执行成功但没有输出 | 0.0 | 代码可运行,但任务未完成 |
| 执行成功且输出非空 | 0.5 | 基本完成任务 |
| 输出与预期完全一致 | 1.0 | 完美完成任务 |
| 超过最大重试次数 | -2.0 | 消耗大量资源,需人工介入 |
在实际项目中,建议把奖励函数单独提取成一个类,方便后面做回归测试。
4.2 记忆系统与经验库
自我改进 Agent 的记忆系统和普通聊天记忆不一样。
普通聊天记忆是“上一轮说了什么”,而 Prime Agent 需要的是“结构化经验”。一条经验通常包含:
- 任务描述
- 失败步骤
- 错误信息
- 反思结论
- 修复后的解决方案
- 对应的奖励分数
经验库不只是一个 JSON 列表,它还需要支持检索。最朴素的检索方式是关键词匹配,进阶方案是向量检索。在本文的示例中,我会用简单的标签匹配和关键词匹配来演示,这样无需额外依赖向量数据库。
4.3 反思机制
反思是“从失败中学习”的核心实现。
一个常见的误区是:把错误信息和正确答案直接拼在 Prompt 里,让模型重新生成。这种方式只能解决“当前这一次”,不能让 Agent 在下一次任务中主动避免同类问题。
真正的反思,应该输出结构化结论,例如:
{ "task": "统计列表中的偶数个数并返回", "error_type": "TypeError", "root_cause": "对列表中的非整数元素直接取余", "fix_suggestion": "先检查元素类型,或者使用 isinstance(ele, int) 过滤", "improved_rule": "对列表元素做数学运算前,需要先确认元素类型" }其中improved_rule是策略更新的关键。它不是一个临时补救,而是一条通用规则,可以写入经验库,后续任务开始时作为参考。
4.4 策略更新方式
Prime Agent 的策略更新,从轻到重有四档:
- Prompt 模板更新:把根据错误总结出的通用规则,追加到系统 Prompt 里。
- Few-shot 示例更新:从经验库中挑选高奖励的“成功轨迹”作为示例。
- 工具描述更新:如果 Agent 经常选错工具,就优化工具描述,让模型更容易理解每个工具的适用场景。
- 模型微调:当经验数据积累到一定规模(比如上千条高质量轨迹),可以对模型做 LoRA 微调。
在原型阶段,我们通常只做前两档。因为它们成本低、立竿见影,也更容易解释。
5. 完整实战:实现一个能自我修复代码的 RLM Agent
接下来,我会构建一个简化但完整的 Prime Agent 原型。它的任务是:根据自然语言描述生成 Python 代码,运行代码,若报错则反思并修复,若成功后则提取经验规则。
5.1 案例目标
我们要让 Agent 完成这样一个任务:
输入:一个包含数字和字符串的列表,返回所有数字的和。
正确输出可能是:
6例如["a", 1, 2, 3],数字之和为 6。
这个任务很简单,但足够体现“代码报错 -> 反思 -> 修复 -> 沉淀规则”的完整闭环。
5.2 环境模块:执行代码并计算奖励
先看环境模块的代码。
# 文件路径:prime_agent/agent/environment.py import subprocess import sys import json class CodeEnvironment: """代码执行环境,负责运行 Agent 生成的 Python 代码并计算奖励。""" def __init__(self, timeout: int = 10): self.timeout = timeout def execute(self, code: str, expected_output: str = None): """执行代码,返回执行结果、输出和奖励分数。""" # 注意:subprocess 只是用于教学演示,生产环境请使用 Docker 等沙箱 try: result = subprocess.run( [sys.executable, "-c", code], capture_output=True, text=True, timeout=self.timeout, ) except subprocess.TimeoutExpired: return { "success": False, "error": "TimeoutError: code execution timed out", "output": "", "reward": -1.0, } if result.returncode != 0: return { "success": False, "error": result.stderr.strip(), "output": "", "reward": -1.0, } output = result.stdout.strip() reward = self._calculate_reward(output, expected_output) return { "success": reward >= 0.5, "error": "", "output": output, "reward": reward, } def _calculate_reward(self, output: str, expected_output: str) -> float: """根据输出和预期结果计算奖励分数。""" if output: if expected_output and output == expected_output: return 1.0 return 0.5 return 0.0这段代码用subprocess新建子进程运行 Python 代码,避免当前进程被死循环卡死。需要说明的是,subprocess只是隔离级别最低的一种方式,生产环境务必使用 Docker 沙箱或无网络权限的隔离容器,避免 Agent 生成的恶意代码造成破坏。
5.3 反思模块:从错误中提取规则
反思模块是本案例里最有价值的模块。这里我提供了一个纯规则版本的反思器,方便离线演示。如果接大模型,可以把reflect函数中的“规则匹配”替换为“LLM 调用”,让模型输出更复杂的归因结论。
# 文件路径:prime_agent/agent/reflector.py import re import json class RuleReflector: """规则反思器:根据错误信息提取修复建议。""" ERROR_PATTERNS = [ { "pattern": re.compile(r"KeyError"), "error_type": "KeyError", "fix_suggestion": "访问字典前先检查 key 是否存在,可以使用 dict.get()", "improved_rule": "当访问字典字段时,优先使用 .get() 并处理默认值", }, { "pattern": re.compile(r"TypeError"), "error_type": "TypeError", "fix_suggestion": "检查变量类型,必要时使用 isinstance 或 type() 做类型判断", "improved_rule": "对数据做数学运算前,务必先确认元素类型", }, { "pattern": re.compile(r"IndexError"), "error_type": "IndexError", "fix_suggestion": "访问列表前检查索引范围,或使用边界判断", "improved_rule": "访问列表或元组时,先确认索引不超过长度减一", }, { "pattern": re.compile(r"NameError"), "error_type": "NameError", "fix_suggestion": "检查变量是否已定义,避免使用拼写错误的变量名", "improved_rule": "使用任何变量前,先确认该变量已经赋值", }, ] def reflect(self, task: str, code: str, error: str) -> dict: """输入任务、失败代码和错误信息,输出反思结构。""" if not error: return { "task": task, "error_type": "", "root_cause": "", "fix_suggestion": "", "improved_rule": "", } for item in self.ERROR_PATTERNS: if item["pattern"].search(error): return { "task": task, "error_type": item["error_type"], "root_cause": error, "fix_suggestion": item["fix_suggestion"], "improved_rule": item["improved_rule"], } # 未匹配到规则的情况,建议交给 LLM 处理 return { "task": task, "error_type": "Unknown", "root_cause": error, "fix_suggestion": "建议人工分析错误日志", "improved_rule": "", }在这个反思器里,我把错误类型分成了 KeyError、TypeError、IndexError、NameError 四类,并给出了通用的改进规则。真实项目中,这些规则应该来自历史失败案例的统计分析,而不是人工臆测。
5.4 记忆模块:经验库的写入与检索
为了让经验能跨任务复用,我们需要一个简单的经验库。
# 文件路径:prime_agent/agent/memory.py import json import os import re class ExperienceMemory: """基于 JSON 文件的经验库,支持关键词检索。""" def __init__(self, storage_path: str = "experience/exp.json"): self.storage_path = storage_path self._ensure_file() def _ensure_file(self): os.makedirs(os.path.dirname(self.storage_path), exist_ok=True) if not os.path.exists(self.storage_path): with open(self.storage_path, "w", encoding="utf-8") as f: json.dump([], f, ensure_ascii=False, indent=2) def save(self, experience: dict): """保存一条经验。""" records = self.load_all() records.append(experience) with open(self.storage_path, "w", encoding="utf-8") as f: json.dump(records, f, ensure_ascii=False, indent=2) def load_all(self): """加载全部经验记录。""" with open(self.storage_path, "r", encoding="utf-8") as f: return json.load(f) def search_by_keyword(self, keyword: str, top_k: int = 3): """根据关键词检索经验记录。""" records = self.load_all() matched = [] for rec in records: text = json.dumps(rec, ensure_ascii=False) if keyword and keyword in text: matched.append(rec) return matched[:top_k] def get_successful_rules(self): """获取所有成功案例中沉淀的改进规则。""" records = self.load_all() rules = [] for rec in records: if rec.get("reward", 0) >= 0.5 and rec.get("improved_rule"): rules.append(rec["improved_rule"]) return rules检索能力这里故意做得很简单,只是为了让你理解“经验库复用”的思路。如果要支撑更大的规模,建议升级为向量检索,把任务描述和错误信息做 embedding,然后计算相似度取出最相关的案例。
5.5 Agent 主循环:生成 -> 执行 -> 反思 -> 修复
下面是最核心的 Agent Loop。为了不依赖外部大模型,示例里的generate_code用了一个规则模板加关键词替换的方式生成初始代码,实际项目应替换为大模型调用。
# 文件路径:prime_agent/agent/loop.py from .environment import CodeEnvironment from .reflector import RuleReflector from .memory import ExperienceMemory class PrimeAgentLoop: """Prime Agent 主循环。""" def __init__(self, max_steps: int = 3): self.env = CodeEnvironment() self.reflector = RuleReflector() self.memory = ExperienceMemory() self.max_steps = max_steps def generate_code(self, task: str) -> str: """ 根据任务生成代码。 教学演示中使用规则模板生成,实际项目请替换为 LLM 调用。 """ # 非常粗糙的模板:如果任务提到“数字和”,就生成求和的代码 if "数字" in task and "和" in task: return ( "data = ['a', 1, 2, 3]\n" "result = sum(data)\n" "print(result)" ) return "print('task not supported')" def reflect_and_fix(self, task: str, code: str, error: str) -> str: """根据错误信息生成修复后的代码。""" reflection = self.reflector.reflect(task, code, error) if reflection["error_type"] == "TypeError": return ( "data = ['a', 1, 2, 3]\n" "total = 0\n" "for item in data:\n" " if isinstance(item, int):\n" " total += item\n" "print(total)" ) if reflection["error_type"] == "KeyError": return ( "data = {'name': 'Tom'}\n" "print(data.get('name'))" ) # 其余情况简化处理:原样返回 return code def run(self, task: str, expected_output: str = None) -> dict: """执行整个 Agent Loop,返回最终结果。""" code = self.generate_code(task) experience = { "task": task, "steps": [], "reward": 0.0, "improved_rule": "", } for step in range(1, self.max_steps + 1): print(f"Step {step}: 执行代码") result = self.env.execute(code, expected_output) if result["success"]: experience["reward"] = result["reward"] experience["improved_rule"] = "成功,无需额外规则" experience["steps"].append({ "step": step, "code": code, "error": "", "output": result["output"], }) self.memory.save(experience) return { "success": True, "output": result["output"], "steps": experience["steps"], } # 执行失败,进入反思修复环节 reflection = self.reflector.reflect(task, code, result["error"]) print(f"Step {step}: 反思 -> {reflection['error_type']}") experience["steps"].append({ "step": step, "code": code, "error": result["error"], "output": result["output"], }) if reflection["improved_rule"]: experience["improved_rule"] = reflection["improved_rule"] self.memory.save(experience) # 根据反思结果生成修复代码 code = self.reflect_and_fix(task, code, result["error"]) experience["reward"] = -2.0 self.memory.save(experience) return { "success": False, "output": "", "steps": experience["steps"], }这段代码虽然简单,但已经具备闭环:如果第一次生成的sum(data)因为字符串参与求和而报TypeError,Agent 会反思出错类型,然后修复成“先判断isinstance(item, int)再累加”的版本,彻底解决问题。
5.6 运行与验证
写一个入口脚本:
# 文件路径:prime_agent/main.py from agent.loop import PrimeAgentLoop def main(): agent = PrimeAgentLoop(max_steps=3) task = "给定一个包含数字和字符串的列表,返回所有数字的和" result = agent.run(task, expected_output="6") print("\n===== Agent 执行结果 =====") for step in result["steps"]: print(f"第 {step['step']} 步代码:\n{step['code']}") if step.get("error"): print(f"错误信息:{step['error']}") print("最终成功:", result["success"]) print("最终输出:", result["output"]) if __name__ == "__main__": main()运行命令:
cd prime_agent python main.py预期输出大致如下:
Step 1: 执行代码 Step 1: 反思 -> TypeError Step 2: 执行代码 ===== Agent 执行结果 ===== 第 1 步代码: data = ['a', 1, 2, 3] result = sum(data) print(result) 错误信息:TypeError: unsupported operand type(s) for +: 'int' and 'str' 第 2 步代码: data = ['a', 1, 2, 3] total = 0 for item in data: if isinstance(item, int): total += item print(total) 最终成功: True 最终输出: 6可以看到,Agent 经历了从“失败”到“反思”再到“修复成功”的过程。任务完成后,经验库experience/exp.json中会写入一条包含任务描述、错误类型和改进规则的经验记录。后续遇到同类任务时,就可以从经验库中检索这条规则,指导生成阶段直接绕过TypeError陷阱。
6. 常见问题与排查思路
在尝试编写类似自我改进 Agent 的过程中,你可能会遇到下面这些问题,我把高频现象和解决思路整理成了一个表格。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| Agent 反复生成同一段错误代码 | 反思模块没有真正影响下一轮生成,错误没有作为上下文传入 | 检查循环里是否把reflection的修复建议拼到下一轮 Prompt 中 |
| 任务成功了但奖励永远为 0.5 | 奖励判断只检查了“有输出”,没有和期望结果比对 | 完善expected_output的比对逻辑,支持数值、字符串、JSON 等多格式 |
| 经验库越来越大,检索越来越慢 | 全量加载 + 关键词匹配导致效率低 | 升级为向量检索,或对经验按错误类型建索引 |
| Agent 在找不到工具时报错且无法恢复 | Agent 的工具选择策略缺少“兜底方案” | 增加默认工具,或让 Agent 明确返回“无法完成”,避免死循环 |
| 反思结论经常是错的 | 规则型反思器覆盖场景有限,或 LLM 反思时上下文不足 | 给反思模块提供更多执行信息:代码、错误堆栈、输入数据样例、历史经验 |
| 代码执行环境可能被恶意代码破坏 | 直接在宿主进程执行 Agent 生成的代码 | 强制使用 Docker、Firejail 等沙箱;限制网络、文件系统、CPU 和内存 |
| Agent 学到了“错误规则”并稳定复现 | 经验库缺少人工审核,低质量经验被当作真理 | 对经验增加置信度分数,只有多轮验证通过后才自动生效 |
排查这类问题,我建议按下面顺序来:
- 先看 Agent Loop 是否完整,有没有漏掉“反思”环节。
- 再看反思结果是否真的写入了下一轮 Prompt 或经验库。
- 然后看奖励函数能不能区分“成功”和“看起来成功”。
- 最后看经验库是否存在脏数据。
7. 工程化落地建议与安全边界
7.1 安全边界:代码执行与沙箱
如果你要让 Agent 生成代码并执行,安全是最高优先级。
即使你的 Agent 只是内部工具,也强烈建议:
- 使用 Docker 容器执行代码,设置网络禁用、文件系统只读。
- 限制 CPU 核数和内存大小,防止死循环和内存溢出。
- 设置单次执行超时时间,例如 5 到 10 秒。
- 禁止执行包含敏感路径、环境变量读取、socket 连接等特征的代码。
- 记录所有执行日志,便于事后审计。
下面是一个 Docker 沙箱的简化思路:
docker run --rm \ --network none \ --memory 256m \ --cpus 1 \ --read-only \ -v /tmp/agent_workspace:/workspace \ python:3.10-slim \ python /workspace/main.py在生产环境中,任何由 Agent 生成的代码都应该被当作“不可信输入”来处理。
7.2 可观测性与日志
自我改进 Agent 的调试难度比普通脚本高很多,因为它的行为会随经验变化。建议从一开始就做好日志:
- 每一轮执行的代码。
- 完整的错误栈。
- 反思模块的输出。
- 奖励分数。
- 经验库的读写操作。
日志格式建议使用 JSON,方便后续做离线分析。
{"event": "execution_start", "task": "任务描述", "step": 1} {"event": "execution_error", "error_type": "TypeError", "error": "..."} {"event": "reflection", "error_type": "TypeError", "improved_rule": "..."} {"event": "execution_success", "reward": 1.0, "output": "6"}有了这些日志,你才能回答“Agent 为什么突然变好了/变差了”这类问题。
7.3 评估与回归
当 Agent 具备自我改进能力后,一个很重要的事情是:如何确保改进不破坏已有能力。
因此,我建议维护一个固定的回归测试集。每次策略更新后,都跑一遍回归测试集,比较整体奖励分数的变化。如果某个旧任务因为新规则的引入而失败,说明策略更新过于激进,需要回滚。
回归测试集不需要很大,20 到 50 个覆盖不同错误类型的任务通常就够用。重点是要包含那些曾经失败并沉淀过经验的任务。
7.4 策略更新与人工审核
自我改进不是“全自动放任不管”。一个合理的流程是:
- 反思模块生成改进规则。
- 改进规则先进入“待审核队列”。
- 开发者在预览环境验证规则效果。
- 规则通过后,才写入线上经验库。
特别是当 Agent 用于生产环境、涉及数据库操作或外部 API 调用时,必须设置人工确认环节。从输入材料中的热词可以看到,“agent 安全”被反复提及,这提示我们,自我改进能力越强,越需要把“安全护栏”放在架构层面去考虑。
8. 总结与后续学习路线
8.1 本文要点回顾
这篇文章围绕 Prime Agent 展开,核心内容可以归纳成几条:
- 普通 Agent 和 RLM Agent 的本质区别在于“是否能从失败中学习”。
- 自我改进闭环至少包含:执行、奖励、反思、记忆、策略更新。
- 奖励信号要可计算、可解释、可分级。
- 反思模块必须输出结构化结论,而不是简单地把错误信息拼进 Prompt。
- 经验库要支持检索和沉淀,不能只存不取。
- 代码执行类 Agent 必须做沙箱隔离。
文中给出的原型代码虽然简单,但已经形成了一条完整的 Agent Loop,你可以直接复制到本地运行,再逐步替换成真实的大模型调用和更强的反思策略。
8.2 下一步学习方向
如果你打算继续深入,可以按下面的路线走:
- 把
generate_code替换为真实 LLM 调用,让 Agent 真正根据任务动态生成代码。 - 把规则反思器升级为“LLM 反思 + 历史经验注入”的混合反射器。
- 调研 LangChain 的 AgentExecutor、ReAct 模式,理解它们与自研 Agent 的关系。
- 学习向量检索(如 Chroma、FAISS),把经验库从关键词匹配升级为语义检索。
- 有条件的话,可以用强化学习框架(如 RLlib、TRL)做小规模策略微调实验。
- 阅读 Agent 安全相关论文和项目,把安全设计纳入 Agent 评估体系。
在训练集里放 20 个左右的小任务,跑通“失败 -> 反思 -> 修复 -> 回归测试”这个最小闭环,你会比直接去研究复杂框架收获更多。祝开发顺利。