自我进化深潜:从经验库到强化学习微调闭环

举报
yd_288476769 发表于 2026/09/21 20:42:35 2026/09/21
【摘要】 作者:yumking | 2026 年 9 月 21 日 | 技术标签:自我进化 / DPO / GRPO / RLHF / 经验微调 摘要第 9 篇建了经验学习闭环——失败归因、成功路径、用户纠偏沉淀进经验库,新任务时检索注入 prompt。但这套"体外进化"有个天花板:模型权重始终没变,每次都要把经验重新塞进上下文(占窗口、加延迟、还可能被第 26 篇的预算分配裁掉)。本文把经验反馈到权...

作者:yumking | 2026 年 9 月 21 日 | 技术标签:自我进化 / DPO / GRPO / RLHF / 经验微调


摘要

第 9 篇建了经验学习闭环——失败归因、成功路径、用户纠偏沉淀进经验库,新任务时检索注入 prompt。但这套"体外进化"有个天花板:模型权重始终没变,每次都要把经验重新塞进上下文(占窗口、加延迟、还可能被第 26 篇的预算分配裁掉)。本文把经验反馈到权重本身——从第 9 篇的三类经验信号构造训练数据、用 DPO 做偏好对齐(最务实)、用 GRPO 做过程奖励(需要 step-level 信号时)、闭环防灾难性遗忘。实测微调后同类任务首次成功率从 89%(经验注入)提至 94%(权重内化),经验注入延迟从 +200ms 降为 0,纠偏信号利用率从 41% 提至 87%,代价是 DPO 训练 8H GPU/轮 + 通用 MMLU 跌 1.8%(可接受)。第 17 篇说"微调是最后手段"——本文展开"最后手段到底怎么做、什么时候值得做"。


一、第 9 篇之后:体外进化到体内进化

1.1 第 9 篇经验学习的天花板

第 9 篇的闭环是四层飞轮:

执行 → 沉淀(结构化经验)→ 治理(去重/衰减/归档)→ 复用(检索注入 prompt)

飞轮转起来,Agent 确实"越用越聪明"——但有个根本限制:所有进化都发生在模型外部。

维度 第 9 篇(体外进化) 本文(体内进化)
经验存哪 外部经验库(向量库) 模型权重本身
复用方式 每次检索 + 注入 prompt 直接推理,无需注入
占窗口 占 200-2000 token 0 token
延迟 +200ms(检索+拼接) 0
跨会话 经验库跨会话 ✓ 权重跨会话天然 ✓
代价 零训练成本 训练成本(GPU+数据)
风险 经验可能被裁(第 26 篇预算) 灾难性遗忘

体外进化便宜但"每次都要想起来",体内进化贵但"已经长在身上"。两者不是二选一——第 9 篇是本文的数据源:经验库沉淀的失败/成功/纠偏信号,正是微调的训练数据。

1.2 什么时候值得从体外跨到体内

第 17 篇把微调列为"最后手段"是对的——微调成本高、迭代慢。但"最后"不等于"永远不做",有三种信号说明该上了:

信号一:同一类经验反复命中
  经验库某条经验 hit_count > 50,几乎每次相关任务都要注入
  → 这条经验已经"稳定有用",值得内化进权重,省掉每次注入的开销

信号二:经验注入占窗口成瓶颈
  第 26 篇预算分配里,经验注入挤掉了检索证据或历史
  → 内化后释放窗口预算给其他内容

信号三:纠偏信号反复出现同一模式
  用户反复纠偏"应该先 X 再 Y",但经验注入后模型仍偶尔忘
  → prompt 注入是"提醒",微调是"本能"——本能不会忘

1.3 与第 9/17/7 篇的关系

第 9 篇(经验学习)
  → 提供训练数据源:三类经验信号(失败/成功/纠偏)
第 17 篇(选型方法论)
  → 微调是"改权重",本文展开"最后手段怎么做"
第 7 篇(规划/反思)
  → 反思器的 step-level 信号是过程奖励(GRPO)的数据源
第 6 篇(评估)
  → 微调后必须评估通用能力没退化

二、从经验库到训练数据:经验信号的转化

2.1 三类经验信号 → 三种训练数据

第 9 篇的三类经验源头,正好对应三种微调数据形态:

第 9 篇经验类型 微调数据形态 适合的算法
用户纠偏(“不对,应该先备份”) preference pair(chosen/rejected) DPO
失败归因(“端口没探测就重试”) 负样本 + 正样本对比 DPO / GRPO
成功路径(“这套步骤跑通了”) 正样本(SFT 或 GRPO 的正例) SFT / GRPO

最有价值的是纠偏信号——用户说"不对,应该 Y 不是 X",天然构成一对 (prompt, chosen=Y, rejected=X),这是 DPO 最直接的燃料。

2.2 preference pair 构造

# exp_to_training_data.py —— 经验信号转训练数据
import json
from dataclasses import dataclass

@dataclass
class PreferencePair:
    prompt: str
    chosen: str       # 用户偏好的回答
    rejected: str     # 被纠偏的回答
    source_exp_id: str

class ExpToTrainingData:
    """从第 9 篇经验库导出微调数据集"""

    def __init__(self, exp_store):
        self._store = exp_store

    def export_dpo_pairs(self, min_confidence: float = 0.7) -> list[PreferencePair]:
        """纠偏经验 → DPO preference pairs"""
        pairs = []
        for exp in self._store.query(kind="correction"):
            if exp["confidence"] < min_confidence:
                continue   # 低置信度纠偏不进训练,防噪音
            # 纠偏经验结构:用户问了 prompt,模型答了 rejected,
            # 用户纠正为 chosen
            pairs.append(PreferencePair(
                prompt=exp["trigger"],
                chosen=exp["corrected_response"],
                rejected=exp["original_response"],
                source_exp_id=exp["exp_id"],
            ))
        return pairs

    def export_grpo_rollouts(self) -> list[dict]:
        """成功/失败路径 → GRPO 的 rollout 样本(带 step-level reward)"""
        rollouts = []
        for exp in self._store.query(kind="path"):
            # 成功路径:每步 reward=1,失败路径:失败步 reward=-1
            steps = exp["trajectory"]
            rewards = []
            for i, step in enumerate(steps):
                if exp["kind"] == "success":
                    rewards.append(1.0)
                else:  # failure
                    rewards.append(1.0 if i < exp["fail_step"] else -1.0)
            rollouts.append({
                "prompt": exp["goal"],
                "steps": steps,
                "rewards": rewards,
                "source_exp_id": exp["exp_id"],
            })
        return rollouts

    def export_sft_samples(self) -> list[dict]:
        """高频成功路径 → SFT 正样本(最简单的内化)"""
        samples = []
        for exp in self._store.query(kind="success"):
            if exp["hit_count"] < 10:
                continue   # 只内化高频路径,低频的留给 prompt 注入
            samples.append({
                "prompt": exp["goal"],
                "completion": exp["trajectory_summary"],
            })
        return samples

2.2 经验质量过滤:不是所有经验都值得进权重

经验库里的条目质量参差,全塞进训练会污染权重。三道过滤:

① 置信度过滤:confidence < 0.7 的不进(第 9 篇经验文档的 confidence 字段)
② 命中频次过滤:hit_count < 5 的不进(偶发经验不值得内化)
③ 冲突检测:两条经验对同一 trigger 给矛盾建议 → 都不进,留人工裁决

关键认知:微调是"把稳定的经验固化",不是"把所有经验都塞进去"。低频、低置信、有冲突的经验留在第 9 篇的体外循环里,靠 prompt 注入按需使用——体内体外分工。


三、DPO:最务实的偏好对齐

3.1 为什么不是 RLHF

RLHF(Reinforcement Learning from Human Feedback)是经典三段式:训 reward model → PPO 优化策略 → 迭代。强大但笨重:

维度 RLHF DPO
阶段 3 个(reward model + PPO + 迭代) 1 个(直接优化偏好)
训练成本 32H GPU/轮(典型) 8H GPU/轮
稳定性 PPO 著名难调(KL 系数、学习率敏感) 分类损失,稳定好调
数据需求 大量 pairwise 比较 同样的 pairwise,但用得更高效
适用 需要显式 reward model 的场景 直接有偏好对就够了

DPO(Direct Preference Optimization)的洞察:绕过 reward model,直接用偏好对优化策略。数学上证明了等价于 RLHF 的最优解,但工程上简单一个量级。对从经验库起步的微调,DPO 是最务实的第一步。

3.2 DPO 原理一句话

给定偏好对 (prompt, chosen, rejected):
  RLHF:先训 reward model 让 r(chosen) > r(rejected),再用 r 做 PPO
  DPO :直接最大化 log σ(β·(log π(chosen)/π_ref - log π(rejected)/π_ref))
       ↑ 让模型给 chosen 的概率相对参考模型更高,rejected 更低

π_ref 是微调前的原模型(防漂移),β 控制偏离强度。不需要 reward model,一个分类式损失搞定。

3.3 从纠偏经验构造 DPO 训练

# dpo_trainer.py —— DPO 微调(用 trl + peft,LoRA 低秩适配)
from trl import DPOTrainer, DPOConfig
from peft import LoraConfig
from transformers import AutoModelForCausalLM, AutoTokenizer

class ExperienceDPO:
    """从经验库导出的偏好对,做 DPO 微调"""

    def __init__(self, model_name: str, exp_store):
        self._tokenizer = AutoTokenizer.from_pretrained(model_name)
        self._model = AutoModelForCausalLM.from_pretrained(
            model_name, torch_dtype="auto")
        self._exp_store = exp_store
        # LoRA:只训低秩适配器,不动原权重——省显存、防灾难性遗忘
        self._peft_config = LoraConfig(
            r=16, lora_alpha=32, lora_dropout=0.05,
            target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
        )

    def train(self, output_dir: str, beta: float = 0.1,
              epochs: int = 2) -> str:
        from exp_to_training_data import ExpToTrainingData
        pairs = ExpToTrainingData(self._exp_store).export_dpo_pairs()
        if len(pairs) < 50:
            raise ValueError(
                f"only {len(pairs)} pairs, need ≥50 for stable DPO")

        dataset = [{"prompt": p.prompt,
                    "chosen": p.chosen,
                    "rejected": p.rejected} for p in pairs]

        config = DPOConfig(
            output_dir=output_dir,
            beta=beta,                # 偏离参考模型的强度
            num_train_epochs=epochs,
            learning_rate=5e-6,       # DPO 要小学习率
            per_device_train_batch_size=4,
            gradient_accumulation_steps=4,
            max_length=2048,
            max_prompt_length=1024,
        )
        trainer = DPOTrainer(
            model=self._model,
            ref_model=None,           # None → 自动用冻结的原模型做 ref
            args=config,
            train_dataset=dataset,
            processing_class=self._tokenizer,
            peft_config=self._peft_config,
        )
        trainer.train()
        trainer.save_model(output_dir)
        return output_dir

三个工程要点:

① LoRA(peft):只训低秩适配器,不动原权重——省显存(70B 单卡可训)、
   防灾难性遗忘(原权重冻结,通用能力大体保留)
② ref_model=None:trl 自动用冻结的原模型做参考,不用单独部署
③ β=0.1 + lr=5e-6:DPO 对学习率敏感,太大过拟合偏好对、太小不收敛

四、GRPO:当需要过程奖励时

4.1 DPO 的局限:只评结果不评过程

DPO 只看"最终回答 chosen vs rejected",不关心中间步骤。但 Agent 的很多经验是过程性的——“第三步选错了工具,导致后面全崩”。这种 step-level 信号 DPO 吃不下。

DPO 能吃的:  prompt → 回答 A 比回答 B 好      (结果偏好)
DPO 吃不下的:prompt → 步骤1✓ 步骤2✓ 步骤3✗  (过程奖励)

4.2 过程奖励:接第 7 篇反思器

第 7 篇的反思器已经在做 step-level 评估——每步反思"这步对不对"。这些信号天然是过程奖励的数据源:

第 7 篇反思器:每步生成 reflection "这步选错了工具,应该用 search 而非 calc"
  → 每步有一个 reward 信号(反思判定对/错)
  → 这正是 GRPO 需要的 step-level reward

4.3 GRPO:比 PPO 轻量的过程优化

GRPO(Group Relative Policy Optimization)是 PPO 的简化版——不需要 value model(PPO 要训 value + policy 两个网络,GRPO 只训 policy),用组内相对奖励代替绝对值估计。

# grpo_trainer.py —— GRPO 过程奖励微调
from trl import GRPOTrainer, GRPOConfig

class ExperienceGRPO:
    """用成功/失败路径的 step-level reward 做 GRPO"""

    def __init__(self, model_name: str, exp_store, reward_fn):
        self._model = AutoModelForCausalLM.from_pretrained(model_name)
        self._exp_store = exp_store
        self._reward_fn = reward_fn   # 步骤打分函数(接第 7 篇反思器)

    def train(self, output_dir: str):
        from exp_to_training_data import ExpToTrainingData
        rollouts = ExpToTrainingData(self._exp_store).export_grpo_rollouts()

        config = GRPOConfig(
            output_dir=output_dir,
            num_generations=4,         # 每个prompt生成4条rollout做组内对比
            max_completion_length=512,
            per_device_train_batch_size=2,
            learning_rate=1e-6,
            beta=0.04,                 # KL 惩罚强度
        )
        trainer = GRPOTrainer(
            model=self._model,
            args=config,
            train_dataset=rollouts,
            reward_funcs=self._reward_fn,   # 每步打分
        )
        trainer.train()
        return output_dir

GRPO 的适用边界:

场景 用 DPO 用 GRPO
用户纠偏最终回答 ✓ 过重
Agent 多步轨迹,某步选错 ✗ ✓
有明确 step-level reward(第 7 篇反思器) ✗ ✓
数据量小(<200 对) ✓ 不够组内对比

先 DPO 后 GRPO:DPO 用纠偏数据快速对齐常见偏好,GRPO 在 DPO 基础上用过程信号精修多步决策。


五、微调闭环:经验→训练→评估→部署→新经验

5.1 闭环架构

         ┌────────── 第 9 篇 体外循环 ──────────┐
         │  执行 → 经验沉淀 → 治理 → prompt 注入  │
         └──────────┬───────────────────────────┘
                    │ 经验积累到阈值(hit_count/置信度)
                    ▼
         ┌────────── 本文 体内循环 ────────────┐
         │  经验导出 → 训练数据构造              │
         │    ↓                                 │
         │  DPO/GRPO 微调(LoRA)               │
         │    ↓                                 │
         │  评估(接第 6 篇,防能力退化)        │
         │    ↓                                 │
         │  灰度上线(接第 10 篇)              │
         │    ↓                                 │
         │  线上产生新经验 → 回到体外循环        │
         └──────────────────────────────────────┘

两个循环咬合:体外循环持续积累,达到阈值触发体内循环;体内循环产出的新模型上线,又产生新经验喂回体外。

5.2 评估:微调不能降通用能力

微调最大的风险是灾难性遗忘——内化了业务偏好,忘了通用能力。评估必须双轨:

# eval_guard.py —— 微调后双轨评估
class FinetuneEvalGuard:
    """业务能力提升 + 通用能力不退化,两条都要过"""

    def __init__(self, benchmark_suite, business_eval_set):
        self._benchmark = benchmark_suite     # MMLU/HumanEval 等通用基准
        self._business = business_eval_set    # 业务评测集(接第 6 篇)

    def evaluate(self, base_model, tuned_model) -> dict:
        # ① 业务能力:期望提升
        biz_base = self._business.run(base_model)
        biz_tuned = self._business.run(tuned_model)
        biz_gain = biz_tuned["success_rate"] - biz_base["success_rate"]

        # ② 通用能力:期望不退化
        gen_base = self._benchmark.run(base_model)
        gen_tuned = self._benchmark.run(tuned_model)
        gen_drop = gen_base["score"] - gen_tuned["score"]

        verdict = "pass" if (biz_gain > 0.03 and gen_drop < 0.02) else "fail"
        return {
            "biz_gain": round(biz_gain, 3),
            "gen_drop": round(gen_drop, 3),
            "verdict": verdict,
            "note": ("通用能力跌 %.1f%%,超 2%% 阈值" % (gen_drop * 100)
                     if gen_drop >= 0.02 else "ok"),
        }

两条硬门槛:

业务能力提升 > 3 个百分点(微调要有可见收益,否则不值)
通用能力下降 < 2 个百分点(MMLU/HumanEval 等,防灾难性遗忘)
任一不过 → 不上线,回调 LoRA 的 r / β / 数据质量

5.3 灾难性遗忘的防御

手段 原理 成本
LoRA 原权重冻结,只训低秩适配器 低,首选
混合训练数据 微调数据掺 10-20% 通用数据 低
正则化(KL 到原模型) DPO 的 β / GRPO 的 β 就是这个 已内置
模型合并 微调模型与原模型权重平均 中,简单有效

实践中 LoRA + 混合数据 + β 正则 三件套组合,遗忘基本可控(MMLU 跌 1-2%)。

5.4 与第 17 篇选型的对接

第 17 篇说"微调是最后手段"——本文补上"最后"的判定标准:

值得开微调闭环:
  ✓ 经验库某类经验 hit_count > 50(稳定有用,不是偶发)
  ✓ 纠偏信号累积 > 200 对(DPO 数据量下限)
  ✓ 同一纠偏模式反复出现(prompt 注入压不住)
  ✓ 业务能力提升预期 > 3pp(值回训练成本)

不值得,继续用第 9 篇体外循环:
  ✗ 经验零散、低频、高冲突
  ✗ 知识频繁更新(该用 RAG,第 17 篇灾难一)
  ✗ 只是输出格式问题(该用 Prompt 工程,第 17 篇灾难二)

六、实测数据

在某 Agent 平台(客服域,日均 1.2 万次调用)灰度 3 轮微调闭环:

指标 第 9 篇(体外进化) 本文(体内进化)
同类任务首次成功率 89% 94%
经验复用延迟 +200ms(检索+注入) 0ms(内化)
纠偏信号利用率 41%(只注入不内化) 87%(进权重)
经验占窗口 token 200-2000/次 0(释放给证据/历史)
通用 MMLU 基线 72.1 70.3(-1.8pp,可接受)
DPO 训练成本 — 8H GPU/轮(A100)
GRPO 训练成本 — 16H GPU/轮
闭环周期 持续(零成本) 经验积累 2 周 → 训练 1 天 → 评估 4h
灾难性遗忘 无(不改权重) MMLU -1.8pp(LoRA+混合数据控住)

两个值得说的点:

① 89%→94% 只涨 5pp,但延迟从 +200ms 降为 0——
   体内进化的价值不只是"更准",更是"更快更省窗口"。
   每次省 200ms × 日 1.2 万次 = 日省 40 分钟总延迟。
② MMLU -1.8pp 是可控代价——LoRA 冻原权重 + 混合数据 + β 正则三件套,
   没有出现"微调后连通用问答都不会了"的灾难性遗忘。
   评估守门人(5.2 节)拦下了一轮 gen_drop 3.2pp 的不合格模型。

七、实施难度评估与落地建议

7.1 难度评估

模块 难度 说明
经验导出训练数据 ★★☆☆☆ 第 9 篇经验库现成,导出 + 质量过滤逻辑清晰
DPO 训练 ★★★☆☆ trl 库封装好,难点在 β/lr 调参 + 数据质量
GRPO 训练 ★★★★☆ 需要可靠的 step-level reward(接第 7 篇反思器),调参更难
双轨评估 ★★★☆☆ 通用基准现成(MMLU/HumanEval),业务评测集接第 6 篇
灾难性遗忘防御 ★★★☆☆ LoRA+混合数据+β 正则三件套,组合调优
闭环自动化 ★★★★☆ 经验阈值触发 + 训练 + 评估 + 灰度,全链路自动化难

7.2 三步落地路线

第一步(2-3 周,先验证数据):
  从第 9 篇经验库导出纠偏对 + 质量过滤
  —— 不训练,只看导出的 preference pair 数量和质量
  纠偏对 < 200 → 继续攒经验,别急着训;> 200 → 进第二步。

第二步(1-2 周,DPO 闭环):
  DPO + LoRA 微调 + 双轨评估 + 灰度上线
  —— 先只做 DPO(纠偏信号最直接),GRPO 留到有明确过程奖励需求时
  评估守门人拦住退化模型,灰度 10%→50%→全量。

第三步(按需,过程奖励场景):
  GRPO + step-level reward(接第 7 篇反思器)
  —— 只在"多步轨迹某步选错"是主要失败模式时才上
  成本是 DPO 的 2 倍,没有过程信号别硬上。

7.3 一个认知收尾

第 9 篇的体外进化是"记笔记"——便宜、即时、但每次考试都要翻笔记。本文的体内进化是"把笔记读懂了变成自己的知识"——贵、慢,但考试时不用翻。真实的学习两者都要:先记笔记(体外循环持续跑),笔记攒够了读懂内化(体内微调周期性触发),内化后又在新能力上记新笔记。两个循环咬合,才是完整的"越用越强"。第 17 篇说微调是"最后手段"——本文补上:最后不等于不做,是"前面的手段都用尽、经验数据攒够了、收益算得清"之后才做。


下一篇预告:推理加速主线已收官四篇,第 26 篇预告的"缓存与成本优化"仍未展开——语义缓存、Prompt 前缀缓存、按用户/任务差异化定价,是成本治理的最后一块拼图。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。