自我改进 Agent 统一拆解:θ / Σ 双路线

自我改进 Agent 统一拆解:θ / Σ 双路线

基于三篇综述的整合:Schmidhuber 团队《Self-Improvements in Modern Agentic Systems》、厦门大学《Self-Evolving Agents: From Model-Centric to Environment-Driven Co-Evolution》,以及 STAIR(作为反例参照)。

总框架

自我改进 = 把学到的东西存下来。能存的地方只有两个:

  • θ(模型权重):靠梯度更新写入。慢,但一劳永逸——之后每次生成自动生效。
  • Σ(模型外面的一切):prompt、记忆库、工具集、控制代码。靠直接编辑写入,快、可读、可回滚。

判断标准就一条:改动是否跨任务保留。推理时多采样几次、反思一下,这些行为随任务结束就消失,不算自我改进。

所有方法都跑同一个三步循环:

  1. 产生信号:让模型干活,产出轨迹、答案、对比。
  2. 验证信号:判断哪些是好的——这是最关键的一步。
  3. 写入介质:把验证过的东西存进 θ 或 Σ。

一、改 θ 的路线

1. 信号从哪来:可靠性分四档

(a) 自评(最弱)

同一题采样多次,多数投票,留下多数派答案对应的轨迹。问题在于:模型自信地错时,采样越多错得越整齐,投票反而把错误固定下来。它测的是「收敛程度」,不是「对错」。

(b) 可执行验证(可靠)

用程序判对错:单元测试 pass/fail、代码跑不跑得通、数学答案对不对。模型不用会判断好坏,执行器替它判。Absolute Zero 全靠这一条——Challenger 出题自带验证程序,Solver 对错由执行器裁决,所以能零人工数据训练。

(c) 自我对弈(解决冷启动)

把模型拆成两个角色:Challenger 出题,Solver 解题。Solver 解出来,Solver 得分;解不出来,Challenger 得分。效果是 Challenger 自动去出「刚好比 Solver 当前水平难一点」的题——难度自适应,不需要人排课程表。两个角色共享同一套权重,用 GRPO 更新。

(d) 轨迹级信号(信息最全,也最贵)

整条交互过程都是训练数据,监督分三种粒度:

  • 结果监督:只对最终成败给分。简单,但 20 步的轨迹错了,不知道错在哪一步。
  • 过程监督:每步打分。精细,但标注贵。
  • 步骤对比:拿成功和失败轨迹对比,找到分歧步骤构造训练对。好处是失败轨迹不是垃圾,而是可以反向修评估器——策略和评估器一起进化。

2. 目标函数三种写法

SFT(模仿验证过的自己)

就是交叉熵,细节在过滤:硬过滤(只留全对的)信号干净,但剩不下难题;软加权(按置信度给样本加权)能留住难例。这个方法的硬伤是:它只会在「已经被验证对的区域」里加概率,不会产生新行为——这就是 offline 合成路线天花板低的机制原因。

DPO 系(用好坏对比)

构造「改前 vs 改后」或「本轮 vs 上一轮」的偏好对,闭式求解不用跑 RL。一个关键选择:reference model 用固定的还是滚动的。固定的稳但保守,滚动能逃离当前分布但容易失控。

GRPO(当前主流)

同一题采样 G 条,用组内通过率当基线,按相对表现算优势。好处有两个:不需要单独训价值网络;二元对错这种稀疏奖励,经组内对比变成了排序信号,正好配自对弈。

3. 写入粒度和防翻车

  • 全参数更新:表达力最强,但改错了难追溯。
  • LoRA:可以多个补丁并存、热切换、单独回滚。TT-SI 的玩法是推理时发现模型在某个输入上不确定,现场造几个针对性样本、快速训一个 LoRA 补丁、用完就扔——这是 θ 路线能做到的最快速度。
  • 回滚机制:保留历史 checkpoint,任何一代在测试集上退化就退回去。

θ 路线特有的三个坑:

  1. 坍缩:递归用自生成数据训练,输出分布越来越窄,先丢多样性再丢正确性,而且可能要几代之后才暴露。
  2. 钻判据空子:验证器本身是用语言写的(LLM judge、任务描述),模型可以学会满足判据的字面意思而不是真实意图。
  3. 能力磨损:在窄任务上 RL 太多,预训练带来的通用能力会掉。

二、改 Σ 的路线

θ 不动,编辑四个部件。

1. Prompt:改「怎么指示模型」

按反馈信号的信息量,四种做法:

  1. 标量搜索:只告诉模型「这个 prompt 得了 0.6 分」,让它提议下一个。没有方向信息,靠试(APE / OPRO)。
  2. 文本批评:失败后让模型写一段诊断(「你没处理空输入」),按诊断改 prompt。MAPS 的做法是:从失败案例归纳出规则,验证规则有效,再注入 prompt。
  3. 群体进化:维护一堆 prompt,用 LLM 当遗传算子——crossover 是「融合两个 prompt 的优点」,mutation 是「换个说法」。Promptbreeder 进一步把「怎么变异」的指令也放进进化池,算子自己也被进化。
  4. 文本梯度:把 agent 系统看成计算图,失败后用 LLM 反向推出一段诊断文本(相当于梯度),再逐节点回传修正(TextGrad)。

2. Memory:改「存什么经验」

三个独立的设计选择。

存什么

  • 原始轨迹:保真但吃 context。
  • 蒸馏后的规则 / 教训 / 工作流:省空间,迁移性看蒸馏质量。
  • 代码技能:把成功操作固化成函数,迁移性最好——代码的语义由执行器保证,不靠语言理解。
  • 隐式向量:latent token 直接注进 KV cache,最省空间但不可读、不可审计。

怎么组织

  • 向量索引:语义相似检索,强在找类似案例,弱在处理不了「用户换新工作了」这种需要覆盖旧事实的情况。
  • 时序知识图(Zep):带时间戳的实体关系,支持事实修正。
  • 卡片互链(A-MEM)、层级结构(H-MEM)。

怎么增删改查

最新的趋势是把记忆操作本身变成可学习的:用 RL 学「这条信息值不值得写」(Mem-α)、学「这轮该不该查记忆」、学遗忘时机(MemEvolve 直接进化记忆系统的结构)。

本质一句话:记忆只有被检索出来塞进 context 才起作用,所以记忆优化最终都收敛成 context 工程——context 从被动容器变成被设计、被评测的对象。

3. Tool:改「能做什么动作」

三个动作。

路由(从现有工具里选),四种实现:

  • embedding 匹配:工具多了噪声大。
  • 依赖图(ToolNet):把工具间前置条件建成 DAG,路由变成带约束的路径搜索,选第一步时就能预判多步组合可不可行。
  • 学出来的路由策略:多轮场景能纠错,但分布变了会脆。
  • 生成式(ToolGen):工具 ID 变成特殊 token,选择 + 填参统一进生成过程,代价是工具集更新要重训。

精炼(修工具)

固定闭环:生成代码 → 沙箱执行 → 抓错误栈 → 反馈修订 → 验证通过才入库。三个改进方向:请专门的 critic 模型做诊断;把修好的轨迹蒸馏成可复用子程序(修「这一类问题」而不是「这一次调用」);DRAFT 发现很多失败其实是文档和行为对不上——修文档比修代码便宜。

创造(造新工具)

完整流程:写代码 → 装依赖 → 沙箱调试 → 写文档 → 标准化注册 → 进池。铁律:没验证过的工具不允许被路由到——坏工具入库后会被反复调用,错误按复利放大。

4. 控制代码:改「系统本身」

写入对象从部件升级为代码。谱系:

  • AFlow:把 agent 编排写成代码,用 MCTS 搜索更好的版本。
  • ADAS:meta-agent 自己写系统代码、跑、看结果、重写。
  • Gödel Agent / DGM:直接改自己的运行时代码,DGM 还维护一棵 agent 后代树。

这一层必须有验证门控:改完的代码跑一遍测试,通过才替换,不通过就回滚。没有这道门,自我修改的期望结果就是自我损坏——一次 prompt injection 会从临时攻击变成永久漏洞。


三、两条路的关系

1. 改进内容其实和存储位置无关

「学会处理 API 超时」这件事,可以存成:

存哪 读取成本 能看懂吗 跨任务迁移
θ(行为倾向) 零 看不懂 强
prompt(一段指令) 每轮费 token 能 中
记忆库(一条规则) 检索时费 token 能 中
工具集(一个重试封装函数) 调用时 能 强,还能给别人用

所以很多「方法属于哪一类」的争执只是表象——同一个改进,换个介质而已。

2. 真正的安全分界线:判据在不在自己的控制回路里

比 θ/Σ 更本质的区分:

  • 间接自改:模型产出数据和任务,由外部规则(梯度、选择压力)决定采纳。判据在回路外。
  • 直接自改:模型输出本身就是对自己的修改(改 prompt、注册工具、patch 代码)。判据在回路内。

风险不来自「改了哪里」,而来自「谁说了算」。判据在自己手里 → 必然会学着讨好判据(reward hacking、坍缩);判据在外面且可验证 → 有锚。三篇综述关于安全的所有讨论,都是这一条的具体展开。

3. 最终形态是嵌套循环

Σ 快循环(试错、反思、累积经验)
        ↓ 验证稳定后
θ 慢循环(蒸馏进权重,摊销到所有未来任务)
        ↓ 更好的先验
Σ 快循环

中间那步转换(scaffold → 参数蒸馏)还是开放问题:失败的时候,系统要自动判断该改 prompt、改工具还是走梯度——三个介质的验证周期和回滚成本差着量级,目前没有统一的决策机制。


四、一张表收束

每个方法 = 在表里选一个格子,再决定验证做得多硬:

  信号靠自评 信号靠执行器 信号靠交互/同伴
写 θ 自蒸馏 SFT、SPIN STaR、Absolute Zero WebRL、SWE-RL
写 prompt Self-Refine GEPA、MAPS 多智能体辩论
写记忆 自反思入库 按执行结果过滤的经验库 多 agent 共享记忆
写工具 自生成+自评 沙箱验证后注册 技能社区共享
写代码 裸改自己(危险) 测试门控的代码进化 去中心化共同进化

三条结论:

  1. 信号来源比介质选择更重要——同样是写 θ,有没有执行器验证,是进化和坍缩的分水岭。
  2. 自改每深入一层,验证就必须硬一档——改输出 < 改组件 < 改元规则 < 改运行时。
  3. offline/online、θ/Σ、快/慢是三对独立的轴——比较方法之前先说清在哪根轴上比。

附录:核心公式速查

1. 自我改进的通用算子形式(Schmidhuber 综述 §3.2)

A_{t+1} = U( A_{1:t}, E( π_{θ_t,Σ_t}; Σ_t, C_t ) )

agent 配置 A = (θ, Σ),Σ = (p, m, T, g)。E 是执行过程(产出轨迹/批评/编辑建议),U 是把信号写回介质的更新算子。

2. 两条路线的分解

θ 路线:θ_{t+1} = IMPROVE_θ(θ_{1:t}; S_t),   Σ_{t+1} = Σ_t
Σ 路线:Σ_{t+1} = IMPROVE_Σ(Σ_{1:t}; S_t),   θ_{t+1} = θ_t

3. 自生成数据 + SFT 的训练目标(厦大综述 §5.1)

θ_{t+1} = argmin_θ  L(θ; D_t) + λ·Ω(θ, θ_0)
D_t = D_base ∪ Filter(D_gen)

Ω 是相对初始点的正则项,用来防遗忘;Filter 是质量门控(多数投票 / 执行器 / 过程奖励)。

4. GRPO 的组内优势(Absolute Zero / R-Zero 等自对弈的训练核心)

A_i = r_i − mean( r_1 … r_G )        (同一 prompt 采 G 条轨迹,组内相对表现)

二元对错奖励经组内对比变成排序信号,不需要价值网络。

5. Prompt 精修的迭代形式(§6.1.2)

p_{t+1} = Refine( p_t, c_t ),   c_t = Critique( Output(p_t) )

6. 文本梯度的更新规则(§6.1.4)

p_{t+1} = p_t ⊕ g(p_t)

g 是由 LLM 从失败案例反推出的结构化诊断文本,⊕ 表示由 LLM 语义化地执行修正。

7. 全脚手架自改的验证门控(§6.4,安全的关键式)

Σ_{t+1} =  Σ̃_{t+1}   若 V(Σ̃_{t+1}) = 1   (测试/安全校验通过)
         =  Σ_t       否则               (回滚)

8. 环境的形式化(厦大综述 §2.B)

E = ⟨S, V⟩

S 是状态空间(任务上下文 + 可交互的外部知识),V 是验证反馈机制(执行器、单元测试、证明器等确定性判据)。V 的质量决定自进化系统的上限。

9. 自对弈的 Challenger–Solver 奖励结构(Absolute Zero)

Solver 解出题   →  Solver +r,  Challenger −r   (题太简单)
Solver 失败    →  Challenger +r              (题有区分度)

双向压力自动把题目难度推向 Solver 能力的边缘(自适应课程)。




Enjoy Reading This Article?

Here are some more articles you might like to read next: