做LLM应用开发的团队,大概率都经历过这样的循环:同一个系统提示词,在上一批数据上跑得很好,换了一组真实请求后效果就明显下滑。于是又开始人工改prompt、调工具描述、加few-shot示例,一轮下来大半天就没了。这种"人肉调优"的路径依赖很强,因为你调出来的prompt,本质上是"你对任务分布的理解"的编码。一旦真实输入偏离预设的模板,Agent的表现就会回落。
人工跟进还有一个更隐蔽的问题:反馈周期太长。线上数据回流到可用的改进依据,往往需要几天甚至几周;同一个Agent在不同任务类型上的失败模式还可能完全不同,人工很难在有限时间内覆盖所有场景。这正是"自我改进型智能体"(Self-Improving Agent)值得关注的原因。它想解决的问题很朴素:既然模型能生成文本、能调用工具、能写代码,那能不能让它基于运行过程中沉淀的经验,自动调整自己的策略,形成"运行—评估—改进"的闭环?
标题里的Prime Agent,可以看作这个方向的一个具体实践:一个以RLM(Recursive/Reasoning Language Model,具备递归推理能力的大语言模型)为核心的自我改进Agent。这篇文章不会停在概念讨论,我会从工程视角拆解"自我改进Agent"最少需要哪几个模块,并给出一个可以跑通的最小闭环示例。读完你会理解:为什么"经验"正在成为LLM应用开发的重要资产;self-improving、self-evolving、meta-evolution这几个层次的真实区别;如何用最小的代码实现"经验驱动prompt自动迭代";以及真正容易踩坑的地方在哪里。
1. 这篇文章真正要解决的问题
先给一个比较直接的判断:自我改进Agent的核心价值,不是"模型自己会写prompt"这个噱头,而是把LLM应用开发的调优成本,从"人肉加运气"变成"数据加闭环"。
传统LLM应用开发有一个很典型的流程:
- 人工设计system prompt,设定角色、任务规则、输出格式;
- 招少量测试样本,人工跑一遍,看输出质量;
- 发现问题,修改prompt,再跑;
- 上线后靠用户反馈继续迭代。
这个流程最大的问题在于反馈链路太长。线上日志、用户反馈、失败案例没有回流到策略层,下一次改进仍然依赖人重新分析。而且,一旦Agent接入的工具变多、任务类型变多,人工就很难判断"当前效果差到底是prompt问题、工具选择问题,还是任务拆解问题"。
自我改进Agent的思路,是把"经验"当作一等公民沉淀下来。每次任务执行的结果、评分、上下文、错误信息,都变成结构化的记录。系统在一个批次运行结束后,自动分析这些经验,找出失败共性,生成新的策略候选,再通过回归验证决定是否替换当前策略。这个闭环让"调优"从人工手艺变成可以自动运转的工程系统。
这篇文章的读者,不是只想要一个新概念的人,而是真正想把Agent调到更好用的工程师。最适合的场景包括:
- 你有一个稳定运行的Agent服务,但效果总差口气,又不想频繁人工调prompt;
- 你需要Agent在多个任务类型上持续工作,人工跟进不过来了;
- 你已经积累了运行日志,但不知道怎么把这些日志变成模型能力;
- 你在设计Agent框架,想提前把"自我改进"能力留出扩展位。
如果只是想了解概念,看综述就够了。但这篇文章更希望推动你动手做一个最小版本。看完之后,你可以在自己的项目里先落地一个简单的"运行—评估—改进"循环,再逐步扩展。
2. 核心概念:RLM、自我改进与经验闭环
2.1 RLM到底是什么
RLM这个缩写在近期的论文和项目中出现过多种含义:Recursive Language Model(递归语言模型)、Reasoning Language Model(推理语言模型)、Reward Language Model(奖励语言模型)。不同的团队在用词上有自己的偏好。
在"Self-Improving RLM Agent"这个组合里,理解成"具备递归/推理能力的大语言模型"更符合直觉。它强调的不是单纯的文本生成,而是模型在执行任务时可以反复推理、审视中间结果、修正路径。你可以把它类比为一个"边做边想"的Agent:先推理,再行动,看结果,再调整。
之所以要强调RLM而不是普通LLM,是因为自我改进的前提是对错误有感知。如果模型只能一次性输出,而不能回看自己的推理过程,那改进就无从谈起。具备递归推理能力的模型,可以把一次失败拆解成"哪一步决策出了问题",为后续改进提供更精准的信号。
2.2 自我改进的三个层次
社区里讨论的"自我改进",实际上包含几个递进层次,很容易混淆:
- Self-execution:模型自己执行任务,这是基础能力,不算改进;
- Self-improvement:模型基于执行结果反馈,在固定任务上改进自己的策略;
- Self-evolution:模型在一个分布不断变化的任务流上,持续调整自身能力,而不是只优化某一个静态任务;
- Meta-evolution:模型开始改进"改进过程"本身,比如学会如何选择经验、如何设计评估指标、如何决定更新时机。
从self-improvement到meta-evolution,本质上是控制权从"人"逐步让渡给"系统"。第一层仍然依赖人来设计反馈信号,第二层开始由系统自动从经验中学习,第三层则把学习策略本身也纳入优化对象。
2.3 经验为什么成为关键资产
在传统机器学习里,数据通常是"标注好的静态样本"。但Agent的运行经验不是这样,它天然带有时序性、场景性和上下文性。一条经验通常包含:任务描述、输入上下文、Agent采取的步骤、最终输出、评估结果、错误信息、耗时等。
这些经验的价值在于,它们是模型在真实运行环境中踩坑后留下的痕迹。相比人工构造的测试集,运行经验更贴近真实分布;相比静态benchmark,它能持续反映线上场景的变化。后面我们会看到,一个自我改进系统,本质上就是"经验采集—经验分析—策略更新—回归验证"的闭环。
3. 自我改进Agent的技术架构拆解
这一节很重要。理解了架构,你才知道一个能自我改进的Agent系统最少需要哪些组件,也才能分辨哪些项目是概念包装,哪些是真能力。
一个最小闭环系统至少包含四层:执行层、经验层、评估层、改进层。
执行层是Agent本体,负责接收任务、调用工具、生成输出,这一层就是我们熟悉的LLM加工具调用框架。经验层负责记录每次执行产生的结构化经验,包括成功的、失败的、异常的。评估层负责对执行结果打分,评估器可以是规则、独立模型、人工反馈,或多个混合。改进层负责基于经验池中的失败样本生成策略改进候选,并通过回归验证决定是否更新。
整体流程是:执行层产生输出,评估层打分,经验层存储;改进层定期分析失败样本,生成新的prompt或few-shot示例,再回到执行层做回归验证。这里的关键不是某个单点能力,而是四层之间的数据协议是否稳定。
3.1 执行层的关键是"可观测"
执行层最大的坑是只记录最终输出,不记录过程。Agent每执行一步,都应该留下日志:当前任务、当前步骤、调用的工具、输入的参数、输出内容、引发的异常。没有这些过程数据,后面的评估和改进都无法定位具体问题。
3.2 经验层不只是数据库
经验层承担"经验检索"的作用。改进层分析失败时,需要按任务类型、错误类型、时间范围等维度检索经验。建议按任务类型分桶存储,避免不同任务的失败样本混在一起。如果经验量很大,还需要去重、过滤和生命周期管理。
3.3 评估层决定上限
评估器是自我改进系统里最容易被低估的组件。如果分数不可靠,后面的改进都是错误方向的强化。评估器的设计决定了整个闭环的上限,它必须和生成器解耦,避免"自己评价自己"的偏差。
3.4 改进层要支持版本回溯
改进层负责把经验转化为策略。常见策略包括:优化system prompt、增加few-shot示例、调整工具描述、修改任务拆解方式、改变模型参数。每一次改进都应该生成一个新的"策略版本",并绑定评估结果,方便回滚。
4. 环境准备与最小系统搭建
在动手之前,先说清楚本文示例所需的环境。这里不写死具体版本,以你实际项目为准:
- Python 3.9以上,建议3.10或3.11;
- 一个可调用的LLM服务,可以是OpenAI兼容的API,也可以是本地部署的模型服务;
- 一个简单的文件系统或SQLite,用于存储经验记录;
- git,用于对策略版本做代码级管理。
为了演示,我会模拟一个典型场景:有一个Agent负责"从日志中判断异常原因并给出修复建议"。我们希望这个Agent能随着经验积累,自动改进自己的prompt,提高修复建议的准确率。
本文的代码是教学型的最小实现,重点不是工程完备性,而是把闭环思路跑通。你在生产环境中可以直接复用这套设计,再替换成自己的评估器和存储方案。
4.1 初始化项目结构
建议把项目拆成下面几个文件:
agent/ ├── experience.py # 经验数据结构与存储 ├── evaluator.py # 评估器 ├── improve_loop.py # 改进闭环 ├── runner.py # Agent执行入口 ├── client.py # LLM客户端封装 ├── experiments/ │ └── prompts/ │ ├── prompt_v1.txt │ └── prompt_v2.txt └── experience_store/ └── records.jsonl这样做的目的是让每个模块职责单一:执行、评估、存储、改进互相解耦。后续如果要替换存储方案或评估模型,只需要改对应模块。
4.2 初始化LLM客户端
不管你是用OpenAI SDK还是其他兼容服务,都可以按下面方式封装一个简单的客户端:
# 文件路径:client.py from openai import OpenAI client = OpenAI( api_key="your-api-key", base_url="your-base-url" # 自建服务或兼容接口 ) def chat(system_prompt: str, user_message: str, model: str = "your-model") -> str: resp = client.chat.completions.create( model=model, messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_message} ], temperature=0.2 ) return resp.choices[0].message.content注意,这里的模型名和API地址要根据你的部署环境替换。如果是自建模型,重点确认服务是否兼容OpenAI的chat completions接口,这是目前最通用的协议。
5. 完整示例:从经验池驱动Agent自我改进
这一节会给出一个能跑起来的完整最小闭环。我们分三部分来实现:经验记录、评估器、改进循环。
5.1 定义经验数据结构
经验记录是整个系统的数据基础。我们用dataclass定义一个结构,保证每条经验都有统一的字段,方便后续聚合分析。
# 文件路径:experience.py import json import time from dataclasses import dataclass, field, asdict from typing import Any, Dict, Optional @dataclass class ExperienceRecord: task_id: str task_desc: str prompt_version: str input_payload: Dict[str, Any] output: Optional[str] = None score: Optional[float] = None error: Optional[str] = None created_at: float = field(default_factory=time.time) def to_json(self) -> str: return json.dumps(asdict(self), ensure_ascii=False) @staticmethod def from_json(line: str) -> "ExperienceRecord": data = json.loads(line) return ExperienceRecord(**data)这段代码里值得注意的地方是task_desc和prompt_version两个字段。task_desc用于区分任务类型,改进时按任务聚合失败样本;prompt_version用于把经验和当时的策略版本关联起来,这是回滚和版本追溯的关键。
5.2 实现一个可组合的评估器
评估器决定了"什么算好"。这里的示例混合了规则和LLM判断两种方式。规则评估稳定、免费、即时,适合硬性校验;LLM评估灵活,适合开放性任务,但成本和随机性更高。生产环境通常组合使用。
# 文件路径:evaluator.py import json from experience import ExperienceRecord def rule_based_score(record: ExperienceRecord) -> float: if record.error: return 0.0 if not record.output: return 0.0 try: data = json.loads(record.output) if data.get("status") == "ok" and "suggestion" in data: return 1.0 return 0.5 except json.JSONDecodeError: return 0.3 def llm_judge_score(record: ExperienceRecord, judge_client) -> float: prompt = f""" 你是一个严格的评估员。请根据以下任务和模型输出,从正确性、完整性和可执行性三个维度评分。 任务:{record.task_desc} 输入:{json.dumps(record.input_payload, ensure_ascii=False)} 模型输出:{record.output or "无输出"} 请只返回 0 到 1 之间的小数,不要输出其他内容。 """ resp = judge_client.chat.completions.create( model="judge-model", messages=[{"role": "user", "content": prompt}], temperature=0 ) try: return float(resp.choices[0].message.content.strip()) except ValueError: return 0.0评估器使用独立的模型进行判断,而不是让执行模型自己评价自己。实际项目中可以采用"规则预筛 + LLM精判"的组合,先过滤掉明显不合格的输出,再对边界样本做深度评估,这样能明显降低成本和延迟。
5.3 实现经验驱动的改进循环
改进循环是整个系统的核心。它读取经验池中的失败样本,交给LLM进行"诊断加生成新prompt",然后触发回归验证。注意,这里没有自动替换prompt,而是先产出候选版本,再由人工或回归测试决定是否上线。
# 文件路径:improve_loop.py import json from collections import defaultdict from experience import ExperienceRecord def load_records(path: str): records = [] with open(path, "r", encoding="utf-8") as f: for line in f: line = line.strip() if line: records.append(ExperienceRecord.from_json(line)) return records def find_failed_records(records, threshold=0.6): failed = [] for r in records: if r.score is not None and r.score < threshold: failed.append(r) return failed def analyze_failures(failed_records): """按任务描述聚合失败样本,找出集中失败的任务类型""" task_buckets = defaultdict(list) for r in failed_records: task_buckets[r.task_desc].append(r) return task_buckets def generate_new_prompt(client, task_desc, failed_records): examples = "\n".join([ "任务:{0}\n输入:{1}\n输出:{2}\n评分:{3}".format( r.task_desc, json.dumps(r.input_payload, ensure_ascii=False), r.output, r.score ) for r in failed_records[:5] ]) prompt = f""" 你是一名提示词工程专家。下面是当前 Agent 在任务「{task_desc}」上的失败案例。 请分析失败原因,并生成一个新的 system prompt。 新 prompt 要解决这些失败案例暴露的问题,同时保持原有能力。 只输出新的 system prompt 本身,不要输出解释。 """ resp = client.chat.completions.create( model="improve-model", messages=[{"role": "user", "content": prompt}], temperature=0.5 ) return resp.choices[0].message.content.strip() def improve_once(client, current_prompt, records, threshold=0.6, min_failed=3): failed = find_failed_records(records, threshold) if len(failed) < min_failed: return current_prompt, False, {} buckets = analyze_failures(failed) # 只改进失败任务最集中的那个任务类型 top_task = max(buckets.items(), key=lambda x: len(x[1])) new_prompt = generate_new_prompt(client, top_task[0], top_task[1]) return new_prompt, True, {"task_desc": top_task[0], "failed_count": len(top_task[1])}这里的关键点是min_failed阈值。它的作用是防止系统在失败样本太少时就盲目改prompt。从实际经验看,一次改进只针对一个失败最集中的任务类型,比一次性改所有任务类型更可控,也更容易验证归因。
5.4 用一个Runner串起整个流程
最后,需要一个Runner把"执行任务—记录经验—触发改进"串起来。
# 文件路径:runner.py import json import uuid from client import chat from experience import ExperienceRecord from evaluator import rule_based_score SYSTEM_PROMPT = open("experiments/prompts/prompt_v1.txt", encoding="utf-8").read() def run_task(task_desc: str, payload: dict, record_path: str): task_id = str(uuid.uuid4()) record = ExperienceRecord( task_id=task_id, task_desc=task_desc, prompt_version="v1", input_payload=payload ) try: output = chat(SYSTEM_PROMPT, json.dumps(payload, ensure_ascii=False)) record.output = output except Exception as e: record.error = str(e) record.score = rule_based_score(record) with open(record_path, "a", encoding="utf-8") as f: f.write(record.to_json() + "\n") return record这样,一个最小的自我改进系统就成型了。当前版本里改进是离线触发的:先积累一批经验,再调用improve_once生成新prompt,验证通过后再替换SYSTEM_PROMPT。
6. 运行效果与验证方法
6.1 如何运行
先用一个脚本批量执行若干任务,生成经验:
python -c " from runner import run_task tasks = [ ('日志异常诊断', {'log': '2024-06-01 10:32:11 ERROR OrderService NPE at line 42'}), ('日志异常诊断', {'log': '2024-06-01 10:35:29 ERROR PaymentService timeout after 3000ms'}), ('日志异常诊断', {'log': '2024-06-01 10:36:01 ERROR CacheService connection refused'}), ] for task, payload in tasks: record = run_task(task, payload, 'experience_store/records.jsonl') print(record.task_id, record.score) "一条经验记录写入文件后,看起来是这样:
{ "task_id": "4f2e0b12-9a0c-4b7e-8f6d-3a1d9e2c5b00", "task_desc": "日志异常诊断", "prompt_version": "v1", "input_payload": { "log": "2024-06-01 10:32:11 ERROR OrderService NPE at line 42" }, "output": "{\"status\": \"ok\", \"suggestion\": \"检查OrderService第42行空指针\"}", "score": 1.0, "error": null, "created_at": 1717234330.123 }6.2 如何判断改进是否有效
当失败样本累计到一定数量后,调用改进循环:
python -c " from client import client from improve_loop import load_records, improve_once records = load_records('experience_store/records.jsonl') old_prompt = open('experiments/prompts/prompt_v1.txt', encoding='utf-8').read() new_prompt, changed, info = improve_once(client, old_prompt, records) print('changed:', changed) print('info:', info) if changed: with open('experiments/prompts/prompt_v2.txt', 'w', encoding='utf-8') as f: f.write(new_prompt) "判断改进有效,不能只看生成的新prompt是否"看起来更有道理"。更稳妥的做法是保留一个固定回归测试集,这个测试集不参与改进,只用于前后对比:
- 用旧prompt在回归集上跑一遍,记录分数分布;
- 用新prompt在回归集上跑一遍,记录分数分布;
- 比较平均分、失败样本数、任务完成率等指标;
- 只有当新prompt在回归集上整体不劣于旧prompt,且失败任务上明显提升时,才替换。
如果失败,第一步应该检查评估器是否稳定。LLM评估的随机性、JSON解析失败、超时未记录,都会导致经验池里出现噪声样本。一个噪声严重的经验池,会把改进方向带偏。
7. 常见问题与排查思路
自我改进Agent看起来只有三四个模块,但真正跑起来后,问题往往出在数据质量、评估稳定性和版本管理上。下面整理了一些高频问题:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 新prompt在旧任务上能力下降 | 没有做回归验证就替换 | 对比新旧prompt在固定回归集上的分数 | 增加不可变的回归集,验证通过后才替换 |
| 评分忽高忽低,改进方向不稳定 | 评估模型temperature设置过高 | 检查评估调用参数和日志 | 评估时temperature置0,多次采样取均值 |
| 经验池增长过快,分析越来越慢 | 缺少去重、过滤和分桶 | 查看records文件中的重复任务 | 按任务类型分桶,定期清理重复和低质量记录 |
| 改进过拟合到失败样本 | 训练分布和测试分布不一致 | 对比改进前后在回归集上的表现 | 将经验池拆分为改进集和验证集 |
| 循环不收敛,每次都在改不同方向 | 失败样本噪声大或改进信号弱 | 人工抽查失败样本和评分 | 调高min_failed阈值,降低改进频率,增加人类审核 |
| API调用成本持续上升 | 每次改进都调用多个大模型 | 查看日志中LLM调用次数 | 增加缓存,用小模型预筛,批量评估代替逐条评估 |
这里还想多说一句:很多自我改进项目做不出来效果,不是因为模型能力不够,而是因为经验池本身就是脏的。如果采集阶段没有把输入、步骤、输出、异常完整记录,后面的分析就是空中楼阁。所以经验采集接口比改进算法更值得优先投入。
8. 工程落地的最佳实践与安全边界
如果看到这里,你已经对自我改进Agent有了基本动手能力。接下来的内容,是你在把它推向生产环境之前必须想清楚的事情。
8.1 经验是资产,要用资产管理的方式对待它
经验数据一旦积累起来,价值不亚于标注数据集。建议做三件事:
- 结构化:每条经验都必须有统一schema,字段尽量细分,不要把所有内容塞进一个自由文本字段;
- 版本化:经验记录里要带上prompt_version、模型版本、Agent代码版本,方便追溯;
- 生命周期管理:定期对经验池做清洗、去重、归档,避免脏数据长期污染改进过程。
8.2 评估器要与生成器解耦
在架构上,评估模型、执行模型、改进模型可以共用同一个底座,但在逻辑上必须解耦。不要让执行模型来评价自己的输出。更稳的方案是"规则预筛 + 独立评估模型精判 + 关键样本人工抽检"三级结构。规则负责拦截硬错误,独立评估模型负责质量打分,人工抽检负责发现系统性问题。
8.3 自动修改Prompt必须设置安全边界
自我改进意味着系统可以自动修改自己的行为策略。在开放环境中,这存在风险。生产环境建议采用以下控制方式:
- human-in-the-loop:自动生成策略候选,人工确认后再发布;
- 灰度与回滚:新prompt先在少量流量上灰度,观察指标后再全量;上线后保留历史版本,随时回滚;
- 变更审计:每次策略改动都生成一条审计日志,记录修改时间、触发原因、涉及的任务类型和通过的回归结果;
- 权限最小化:自动更新prompt的能力只授予信任的进程,不放在公共调用链上。
8.4 关注成本与延迟
每轮改进都会产生额外的大模型调用。如果是高频Agent服务,建议:
- 只在批量离线阶段执行改进,不在线上同步链路中执行;
- 对评估结果做缓存,同一输入在评估器里不要重复计费;
- 对改进频率做限制,比如"累计失败样本超过50条且时间超过24小时才触发一次改进"。
8.5 先做垂直,再做通用
最容易成功的落地方式,是选择一两个任务类型的Agent先跑通闭环,比如日志诊断、工单分类、代码审查。垂直场景里任务边界清晰、评估标准相对明确,自我改进的效果容易量化。等积累了成熟的经验管道,再扩展到通用场景。
9. 从Self到Meta:下一阶段的演进方向
最后,我们回到"self-improving agents in the era of experience"这个更大的背景。从近期的综述和项目来看,关注点正在从"模型能不能自我改进"转向"如何设计一种能持续演进的经验机制"。这个演进趋势可以概括为从self到meta的上升。
第一代自我改进系统,关注的是一个固定任务上能否用失败样本反哺策略,这是经验驱动的单点优化。第二代系统开始考虑任务分布漂移:经验不只是用来修bug,还用来发现新任务类型、新工具需求,Agent会主动感知"当前能力覆盖不了哪些输入",并决定是否扩展工具或重写流程。第三代系统,也就是meta-evolution阶段,优化对象变成了改进过程本身:系统会学习哪些经验对改进最有价值,评估标准应该偏向精确率还是召回率,什么情况下应该停止改进以避免过拟合。改进策略本身成为可学习的对象。
从工程角度看,现阶段更值得投入的是第一代和第二代能力。建议你把本文的最小闭环跑通,沉淀自己的经验数据和评估体系。这块基础设施越扎实,未来引入更复杂的meta层时就越容易。
如果回到文章开头那个"人肉调prompt"的问题,我的建议是:不要急着构建一个大而全的自我改进平台。先选一个任务、定一个评估指标、攒一个经验池,跑通最小闭环。自我改进的价值不在于"模型自己会写prompt"这个噱头,而在于它把经验变成了可沉淀、可复用、可自动化的工程资产。方向是确定的,但路径需要一点点验证。先从一个最小闭环开始,你会对这套系统里的每一个环节都有更实在的体感。