如果你让同一个 Agent 连续执行同一类任务 100 次结果会怎样很多人的第一反应是“它会越做越熟练”。但现实很残酷绝大多数 LLM Agent 是“无记忆执行体”第 100 次执行和第 1 次执行几乎没有本质区别——该走的弯路还会走该犯的错还会犯。这就是当前 Agent 开发最尴尬的瓶颈。工具调用、任务规划、上下文管理这些外围能力已经趋于成熟唯独“从经验中学习”这一环几乎是空的。Prime Agent 这类自改进 RLM Agent 想改变的正是这一点让 Agent 不再只是“执行一次任务”而是成为一个能评估自己、沉淀经验、在下一次执行中真正用上这些经验的系统。读完本文你会得到三样东西第一理解 RLM 在自改进 Agent 中的定位以及从 Self-Evolution 到 Meta-Evolution 的完整演进逻辑第二一套可以直接运行的 Python 最小实现包含执行、评估、经验记忆、重试四个核心模块第三一份工程化落地清单告诉你哪些场景适合自改进、哪些场景千万不要用。如果你正在做 Agent 应用开发或者准备把 Agent 接入生产环境这篇文章值得看完后收藏。1. 这篇文章真正要解决的问题1.1 一次性 Agent 的瓶颈先看一个常见场景。你基于某个大模型写了一个 Agent给它配好了工具写好了 system prompt测试一轮效果不错于是上线。跑了一周之后你发现它在某些边界场景下反复出错比如用户输入格式不规范、工具返回了异常数据、任务描述有歧义。这时候你要做什么大概率是继续改 prompt、加 few-shot 示例、或者临时在代码里写 if-else 兜底。改完之后重新上线继续跑。下个问题出现再改再上线。这种开发模式本质上是“人工在循环里”。Agent 本身的执行链路没有任何自我纠错能力它不知道上一次为什么失败不知道哪一步浪费了多次工具调用也不知道历史上哪些策略对同类任务更有效。每个任务都是零起点每次失败都需要人去诊断。这里真正容易踩坑的地方是很多人误以为 Agent 已经具备学习能力。模型的参数确实是训练出来的但推理时它是静态的。你给 Agent 的上下文里如果没有历史经验它就不可能“越用越聪明”。1.2 为什么“经验”突然变得重要近期的研究趋势把当前阶段称为 Agent 的“经验时代”Era of Experience。一个核心判断是Agent 的进步不应该只依赖模型本身的能力跃迁还应该依赖运行过程中不断积累的轨迹经验。类比一下人类的工作方式。新员工进公司要看手册遇到问题要翻文档、问同事老员工则不一样他脑子里存了大量“这个场景上次是怎么处理的”的经验遇到类似任务时可以直接套用效率和质量都高得多。现在的 LLM Agent 大多数处于“新员工状态”虽然模型里装了海量常识但它对自己执行过的任务没有任何记忆。Prime Agent 这类自改进 RLM Agent 要解决的就是这个问题。它的核心不是把模型做得更大而是把 Agent 的架构改造成一个“带反馈回路的学习系统”执行任务、评估结果、沉淀经验、在下一次任务中召回经验。这四步循环起来Agent 才真正开始积累属于自己的运行经验。1.3 本文的问题边界需要提前说明的是不同团队的实现细节会有差异本文关注的是这类系统背后的通用设计模式。文章会从概念、架构、代码、验证、工程落地五个角度展开读者可以把它当作一套可复用的参考方案而不是某个固定产品的说明书。2. 基础概念Agent、Agent Loop 与 RLM2.1 Agent 到底是什么Agent 这个词在社区里被用得很泛这里先给一个可操作的定义Agent 是大模型与外部世界之间的执行闭环它由大模型、工具集合、循环控制、记忆四部分组成。大模型负责理解任务、生成计划和决策工具集合提供与外部世界交互的能力比如计算、搜索、读写文件、调用 API循环控制决定“推理—调用—观察—再推理”这个循环怎么走、什么时候终止记忆则负责保存上下文、历史轨迹和跨任务经验。可以这样类比大模型是大脑工具是手脚循环控制是神经系统记忆是经验库。只有大脑没有手脚模型只能回答问题不能完成任务只有手脚没有记忆Agent 每次执行都像失忆的人重新学习走路。2.2 Harness 与 Agent 的区别很多 Agent 框架里会出现两个容易混淆的词Harness 和 Agent。简单说Harness 是“壳”Agent 是“核”。Harness 负责 Agent 运行时的通用控制逻辑消息循环、工具解析、上下文组装、错误处理、执行中断恢复Agent 则专注于任务决策当前这一步该调用什么工具、下一步该怎么走。用一个操作系统类比Harness 是操作系统负责进程调度、资源管理和系统调用Agent 是运行在操作系统上的进程负责自己的业务决策。理解这个区别对实现自改进系统有帮助。经验沉淀、轨迹记录、重试机制这些能力应该放在 Harness 层让所有 Agent 共享而 RLM 评估、策略调整这类和任务强相关的能力则可以在 Agent 层做定制。2.3 Agent LoopAgent 的心脏LLM 本身就是一次性的给它 prompt它返回 completion交互结束。Agent 则不同它把多次 LLM 调用串成一个循环也就是常说的 Agent Loop。典型流程如下Agent 接收任务LLM 基于当前上下文生成下一步动作可能是调用工具也可能是直接给出最终回答如果是工具调用执行工具并观察结果把工具结果追加到上下文回到第 2 步如果 LLM 给出最终回答循环终止。用伪代码表示就是这样messages [system_prompt, user_task] while True: reply llm.chat(messages) messages.append(reply) if reply.is_tool_call(): result tools.execute(reply.tool_call) messages.append(result) elif reply.is_final(): break这个循环看起来简单真正容易出问题的地方在于循环什么时候停工具调用失败怎么处理上下文膨胀了怎么办自改进系统里的经验记忆、RLM 评估本质上都是在围绕这个循环做增强。2.4 RLMReward Language Model 还是 Reasoning Language ModelRLM 在技术资料里有两种常见理解需要先厘清。第一种是 Reasoning Language Model指“推理语言模型”强调模型在给出最终答案之前先产生一条推理链chain of thought典型代表是 o1 风格的推理模型。第二种是 Reward Language Model指“奖励语言模型”用模型输出自然语言形式的评估和反馈替代传统的标量奖励函数。在 Prime Agent 这类自改进 Agent 系统里这两种理解并不冲突反而指向同一个位置Agent 循环中的“评判者”。我们把 RLM 理解为“既能推理、又能给奖励信号的模型模块”更符合实际架构。传统强化学习里的 Reward Model 输出一个数字RLM 则输出结构化的自然语言反馈比如“结果正确但你绕了远路第 2 步调用了多余工具”。这种反馈有两个好处一是人类可读方便排查二是可以被 Agent 直接利用成为下一轮执行的策略提示。可以把 RLM 理解成“会写评语的裁判”。普通裁判只告诉你得了几分RLM 会告诉你为什么扣分、下一次应该怎么调整。下表对比了三类模型组件输出用途典型问题普通 LLM文本生成回复、执行任务无法判断执行质量Reward Model标量分数强化学习、排序分数不可解释RLM结构化文本 分数Agent 自评估、反馈、策略生成需要设计好评估 prompt2.5 Agent Skill 与 MCP 的关系顺带说一个常见混淆Agent Skill 和 MCPModel Context Protocol的区别。Skill 是 Agent 的能力单元描述“我能做什么、怎么做”比如一个 Python 代码执行技能包含提示词、工具函数和参数说明MCP 则是工具接入的协议标准解决“Agent 怎么发现和调用外部工具”的问题。在自改进系统里Skill 负责定义能力边界MCP 负责打通工具层。经验记忆应该保存成功轨迹中“用了哪个 Skill、按什么顺序调用工具”而不是只记住最终答案否则经验很难迁移到同类任务上。3. Prime Agent 核心设计自改进范式与架构拆解3.1 自改进的四个层次要理解 Prime Agent 的定位先看自改进 Agent 的能力分层。从研究社区对 Self-to-Meta Evolution 的讨论看可以分成四个层次L0 静态执行Agent 没有改进能力每次任务从零开始失败了靠人工介入L1 自我评估Self-EvaluationAgent 执行完后能给自己打分根据分数决定是否重试L2 经验积累Experience AccumulationAgent 把高分轨迹存入记忆后续任务能召回复用L3 元演化Meta-EvolutionAgent 不仅积累经验还能改进“积累经验”和“调整策略”的机制本身。绝大多数生产环境里的 Agent 停在 L0。加了 RLM 评估和重试逻辑后可以到 L1。Prime Agent 这类自改进 RLM Agent 努力的方向是 L2 到 L3不仅会用经验还会优化自己的改进方式。这里的关键判断是从 L1 到 L2 是架构分水岭。只顾打分和重试Agent 仍然没有记忆只有把评分结果沉淀成可召回的经验Agent 才真正开始“进化”。3.2 架构组件拆解自改进 Agent 的架构可以拆成五个核心模块。模块职责关键设计点Executor 执行器驱动 Agent Loop调用 LLM 与工具单次执行必须有步数上限避免死循环RLM Evaluator 评估器对执行轨迹打分并输出自然语言反馈与执行模型分离temperature 建议设为 0Experience Memory 经验记忆保存高分轨迹供后续任务召回先用 JSONL 起步再演进为向量检索Retry Policy 重试策略根据分数决定继续重试还是终止分数低时结合 RLM 反馈调整下一步Tools 工具层提供 Agent 的能力边界最小权限、沙箱执行、全量日志这个设计有两个容易被忽略的点。第一执行器和评估器要分离。如果让同一个模型既当运动员又当裁判评估结果很容易被“自我感觉良好”带偏。用独立的 RLM 模块评估分数更有参考价值。第二经验记忆的粒度要细致。不要只存“这个任务做成功了”要存“用什么策略、调用了哪些工具、中间经历了哪些步骤”否则经验无法推广到变体任务上。3.3 一次完整的数据流自改进 Agent 的一次完整执行数据流比普通 Agent 多出四个环节。第一步任务输入。用户提交任务可能是字符串、JSON 结构或结构化表单。第二步经验召回。Agent 从经验记忆里检索与当前任务相似的记录把历史策略拼进上下文。没有匹配经验时直接进入执行。第三步执行循环。Executor 驱动 Agent LoopLLM 生成计划、调用工具、观察结果直到产出最终回答。这一步和普通 Agent 没有区别只是会把完整轨迹记录下来。第四步RLM 评估。Evaluator 拿到任务描述、执行轨迹、最终答案输出分数和自然语言反馈。第五步策略决策。系统根据分数决定达到阈值就收下这个结果并沉淀经验没达到阈值就带着 RLM 反馈重试重试次数超限则返回当前最优结果。第六步经验沉淀。高分轨迹写入 Experience Memory形成可供未来任务召回的记录。这个流程里最容易做错的是第二步很多人把经验召回做成简单的“查缓存”直接复用旧答案。正确做法是召回“策略”而不是答案。历史答案可以给 Agent 做参考但真正有用的是“当时是怎么一步步做到这个答案的”。3.4 几个关键设计判断第一为什么不做模型微调而是做运行经验积累微调需要训练数据和算力而且在生产环境里每次业务变化都重新训练不现实。自改进是更轻的路径不动模型权重只改推理时的上下文。第二为什么用 RLM 而不是规则判断规则判断对简单任务有效但真实任务的评价标准常常是模糊的。RLM 可以理解任务语义输出细粒度反馈适应性更强。缺点是评估本身要消耗 token需要控制成本。第三为什么经验存储先不引入向量数据库对一个小型系统来说JSONL 文件足够支撑几千条经验的读写。向量检索、相似度计算可以后续再加一开始就让架构复杂化反而会增加排查难度。4. 环境准备与前置条件在动手写代码之前先准备好环境。本文的示例代码要求 Python 3.10 及以上版本并依赖一个兼容 OpenAI 接口的模型服务。版本细节请以你实际使用的服务为准本文重点演示通用思路。4.1 安装依赖建议先建一个虚拟环境避免污染系统 Python。python3 -m venv venv source venv/bin/activate # Windows 下使用 venv\Scripts\activate pip install openai python-dotenv这里只装了最少的依赖。openai 客户端库是通用接口封装只要你的模型服务提供 OpenAI 兼容的 HTTP 接口都可以用这个库调通。4.2 配置模型服务在项目根目录创建.env文件# .env LLM_API_KEY你的密钥 LLM_BASE_URLhttps://api.example.com/v1 LLM_MODELgpt-4o-mini使用.env文件时注意三点第一密钥绝对不能提交到 Git 仓库建议把.env加入.gitignore第二base_url 要指向你实际可用的模型服务网关服务方可能有合规要求请在企业允许的范围内使用第三模型名称以服务方提供的为准本文示例中的模型名需要按实际情况替换。4.3 项目目录结构self-improving-agent/ ├── llm.py # LLM 调用封装 ├── tools.py # Agent 工具集合 ├── rlm_evaluator.py # RLM 评估器 ├── experience_memory.py # 经验记忆 ├── agent.py # 自改进 Agent 主循环 ├── main.py # 示例入口 └── .env # 环境变量不入库下面每一个文件都会给出完整代码建议按顺序创建。5. 从零实现一个自改进 RLM Agent这一节是全文的核心。我们用一个计算任务作为示例场景完整跑通“执行—评估—重试—沉淀经验”的闭环。虽然示例很小但模块边界和真实项目保持一致后续替换成真实业务工具链不需要改架构。5.1 LLM 调用封装# llm.py 统一 LLM 调用封装兼容 OpenAI 格式的接口。 import os from openai import OpenAI _client OpenAI( api_keyos.getenv(LLM_API_KEY), base_urlos.getenv(LLM_BASE_URL), ) def chat(messages, modelNone, temperature0.7, max_tokens2048): 发送消息并返回文本结果。 model model or os.getenv(LLM_MODEL, gpt-4o-mini) resp _client.chat.completions.create( modelmodel, messagesmessages, temperaturetemperature, max_tokensmax_tokens, ) return resp.choices[0].message.content这个封装把模型调用收敛到一个函数里后续所有模块都通过chat()调用模型。如果你们的服务用的是国内模型网关只要接口兼容 OpenAI 格式替换LLM_BASE_URL和模型名即可。5.2 工具层为了让示例足够安全这里写一个支持四则运算的calculate工具。注意生产环境不要直接用字符串拼接执行任意代码下面用 AST 解析限制合法表达式。# tools.py Agent 工具集合。 import ast import operator _OPERATORS { ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv, } def _safe_eval(node): 只允许数字和四则运算的 AST 求值禁止执行任意代码。 if isinstance(node, ast.Expression): return _safe_eval(node.body) if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)): return node.value if isinstance(node, ast.BinOp) and type(node.op) in _OPERATORS: left _safe_eval(node.left) right _safe_eval(node.right) return _OPERATORS[type(node.op)](left, right) raise ValueError(f不支持的表达式节点: {type(node).__name__}) def calculate(expression: str) - str: 执行四则运算仅用于演示。 try: result _safe_eval(ast.parse(expression, modeeval)) return str(result) except Exception as exc: return fERROR: {exc}工具函数统一返回字符串这样 Agent 循环不需要处理复杂类型LLM 读起来也直观。工具出错时返回带ERROR:前缀的字符串RLM 评估器就能识别到执行异常。工具层在真实项目中往往是最需要谨慎的地方。工具意味着 Agent 获得了操作外部世界的能力必须遵循最小权限原则只开放任务必需的工具所有工具调用记录日志高危操作加人工审批。5.3 RLM 评估器RLM 评估器是自改进系统的“裁判”。它读取一次执行的完整轨迹输出分数和自然语言反馈。为了拿到稳定的分数评估调用使用 temperature0。# rlm_evaluator.py RLM 评估模块用语言模型对 Agent 执行结果打分并给出反馈。 import json from llm import chat SYSTEM_PROMPT 你是 RLMReward Language Model评估器。 你会收到一次 Agent 执行任务的完整记录包括目标任务、执行轨迹和最终答案。 请从三个维度评估正确性(correctness)、完整性(completeness)、效率(efficiency)。 输出必须是 JSON格式如下 { score: 0.0, dimensions: {correctness: 0.0, completeness: 0.0, efficiency: 0.0}, feedback: 对改进方向的自然语言建议要求具体 } score 取值 0 到 1严格打分不要因为语气友好就给高分。 class RLMEvaluator: def __init__(self, modelNone, temperature0.0): self.model model self.temperature temperature def evaluate(self, task: str, trace: list[dict], final_answer: str) - dict: messages [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: json.dumps( {task: task, trace: trace, final_answer: final_answer}, ensure_asciiFalse, indent2, )}, ] raw chat(messages, modelself.model, temperatureself.temperature) try: result json.loads(raw) result[score] float(result[score]) return result except (json.JSONDecodeError, KeyError, TypeError): return { score: 0.0, dimensions: {correctness: 0.0, completeness: 0.0, efficiency: 0.0}, feedback: f评估结果解析失败原始输出: {raw[:200]}, raw: raw, }这里有两个设计细节值得注意。第一评估器把完整轨迹传给 RLM而不是只传最终答案。因为自改进关注的是“过程”如果只评估最终答案Agent 就永远不会发现自己在过程中浪费了工具调用。第二JSON 解析失败时返回 0 分而不是抛异常这样 Agent 循环不会因为评估器问题而中断。5.4 经验记忆经验记忆模块负责保存高分轨迹并在新任务到来时召回相关经验。先做最简单的 JSONL 文件存储关键词匹配召回。真实项目中可以替换为向量库。# experience_memory.py 经验记忆把成功任务的轨迹沉淀下来供后续任务参考。 import json import os import time import uuid class ExperienceMemory: def __init__(self, store_pathexperience.jsonl, max_records500): self.store_path store_path self.max_records max_records self.records [] self._load() def _load(self): if not os.path.exists(self.store_path): return with open(self.store_path, r, encodingutf-8) as fp: for line in fp: line line.strip() if line: self.records.append(json.loads(line)) def save(self, task: str, strategy: str, score: float, trace: list[dict]): record { id: uuid.uuid4().hex, ts: time.time(), task: task, strategy: strategy, score: score, trace: trace, } self.records.append(record) if len(self.records) self.max_records: self.records self.records[-self.max_records:] with open(self.store_path, a, encodingutf-8) as fp: fp.write(json.dumps(record, ensure_asciiFalse) \n) def recall(self, task: str, top_k: int 3): 按任务关键词的简单匹配召回。实际项目中可替换为向量检索。 keywords set(task.lower().split()) scored [] for rec in self.records: overlap keywords set(rec[task].lower().split()) if overlap: scored.append((len(overlap), rec)) scored.sort(keylambda x: x[0], reverseTrue) return [rec for _, rec in scored[:top_k]] def stats(self): if not self.records: return {total: 0, avg_score: 0.0} avg sum(r[score] for r in self.records) / len(self.records) return {total: len(self.records), avg_score: round(avg, 3)}经验文件是自改进系统的“记忆资产”本质上就是数据。