决策级程序蒸馏(LoRA「技能胶囊」)能否替代长文本技能提示?——从 mock 管线到真实任务、 从单次训练到门控持续学习的完整研究弧线。九个版本、8 次门控判定(5 升 3 拒),每一步的进步与问题都有真实样例。 基座:Qwen2.5-7B-Instruct;所有数字来自盘上评测记录,无挑选。
把「文档文本修订」技能蒸馏成 5MB 的 LoRA:模型每步吐一个抽象决策
(LOCATE_TARGET → APPLY_MODIFICATION → VALIDATE_RESULT → STOP),
不带任何技能提示文本。主设定 raw-state:模型只看原始可见对象+上一步反馈。
任务 textrev_test_000001 (mixed_relation)
full_skill_prompt → actions: [STOP] parse_failures: 1 ✗ 失败
# 基座模型撑不住 raw-state 长输入下的 JSON 协议:test 集 91% 解析失败,成功率 14%
skill_capsule_lora → [LOCATE_TARGET → APPLY_MODIFICATION → VALIDATE_RESULT → STOP] ✓
# capsule:test 100%,OOD 99%;解析失败 0。蒸馏买到的是「可靠性」
同一个抽象动作 LOCATE_TARGET{content:"DN100", region:…}
tool v1 → query_text(page, content, region) capsule+binder: 100%
tool v2 → search_text(page_id, text_equals, area) capsule+binder: 100%
tool v3 → list_text + filter_text_by_content + … capsule+binder: 100%
对照:把具体 v1 调用蒸进权重的 toolcall_lora,
tool v2 下 schema error 1.07 个/任务 → 成功率 12%(残余=恰好该 no-op 的任务)
raw-state 下胶囊每步重发可见对象,上下文 ~4k>fulltraj 单次 ~2.5k——v0 的「省上下文」 是 oracle 摘要造成的假象。胶囊的真优势是鲁棒性(OOD +22pt)与可靠性(0 解析失败),不是成本。
方法论质疑:「主流 agent 就是多步的,得和它比」。于是把同一任务塞进真实框架 OpenClaw(ReAct 运行时 + MCP 工具),同一个 Qwen2.5-7B、greedy 解码——只有运行时不同。
| 系统 | test | OOD | 上下文 tok/任务(中位) |
|---|---|---|---|
| capsule(蒸馏) | 100% | 99% | ~4k |
| B6 zero-shot | 57% | 45% | ~46k |
| B6 few-shot | 53% | 38% | ~57k(OOD 空转时中位 77 万) |
任务 textrev_test_000046 tool_log = ['query_text'](从未调用 modify_text)
B6 回复:"No matches found … Therefore, no modifications were made.
The operation has completed successfully without any changes."
# 文档里目标就在区域内;ground-truth 判失败。7B 的典型模式:定位后不跟进(test 上 31/60 停在 query)
34/60 个 OOD 任务:模型始终发不出合法工具调用,循环到框架轮次上限 中位 32 次模型调用/任务,烧掉中位 ~77 万 token 后放弃
结论:框架给了脚手架(B6 远好于会崩的裸提示基线),但蒸馏才带来可靠性—— 准确率与成本双输给胶囊。few-shot 修不动(噪声内)。
循环:跑任务流 → 外部验证轨迹 → 经验缓冲 → 确定性回放编译训练样本 → 训候选 → 四闸门(老任务保持/新任务提升/工具/成本)→ 升级或拒绝。v001 刻意用受限课程训练,留出提升空间。
| 版本 | 老任务 | batch_002(已到 OOD) | batch_005(未到) | 判定 |
|---|---|---|---|---|
| v001 | 100 | 81.7 | 74.0 | promoted(初始) |
| v002 | 100 | 97.5(+15.8) | 61.0(−13) | PROMOTED |
| v003 候选 | 100 | 90.8(吐回 6.7) | 70.0(+9) | REJECTED:误改率 0.4→2.6% |
v001 裸跑 batch_002:81.7%
v001 + 失败衍生规则块(skillmd_update):11.7%
# 裸训胶囊把任何前置规则文本当分布外输入 → 整体塌掉。
# 六机制对比:权重更新 97.5 ≫ 不更新 81.7 > 记忆检索 78.3 ≫ 文本规则 11.7;工具轴 binder-only 零成本 100%
160 条真实 CAD 图纸修订指令(2⁵ 因子设计),ground-truth 代码 160/160 解析成 238 个操作 + 56 个 「指令残缺应弃权」任务;合成与之语义一致的文档基底。模型只看逐字真实指令,必须自己抽取目标。
真实指令:"For the file X987Y654.pdf, on page 7, in the second rectangle,
delete the strings "Draft Copy" and "Preliminary Version" … Align any remaining…"
v002(mock 训练)→ actions: [STOP] ✗
# E1 迁移墙:最好的 mock 胶囊总体 33%,specific 46%;rule_planner(直读字段)83.7% 证明程序可解——
# 墙在「从真实语言抽槽位」,不在程序
v004 → LOCATE_TARGET{content_constraint: "Draft Copy", …} → … ✓
# 554 条真实样本一轮:specific 18→51,总体 23.8→40.0。
# 但 mock 保持 94%<97% 阈值 → v004 被拒;回放加倍后 v005:真实 38.4 + mock 98.7 → 升级
content_constraint:"*"
真实指令:"…in the first rectangle, replace all horizontal text with "Updated Project Details"…"
v006 → LOCATE_TARGET{content_constraint: "*", spatial_scope: "selected_region"} ✓
# 900 条多措辞合成样本:wildcard 0→49%
残缺指令(没指定文件):"On page 3, in the first rectangle, replace all horizontal text
with "Updated Legend", then delete the string "Outdated"…"
v006 → [LOCATE_TARGET{*} → APPLY_MODIFICATION → VALIDATE_RESULT → STOP] ✗ 自信的错误执行
# v006 弃权 19 个失败全是这种;真实 Error 象限的破绽是「缺文件名」「不支持的模态(vertical text)」——
# 和最初合成的缺参数类消融不匹配
残缺指令:"For the file Layout789.pdf, in the second rectangle of the page,
replace all horizontal text with "Updated Layout Details"." ← 没说第几页
v007 → [REPAIR_SELECTION{failure_type:no_candidate, resolution:abort} → STOP] ✓ no_op
# 补齐 missing_file/unsupported_modality 消融 + 对比孪生对(同基底:残缺→拒 / 补全→做)+ 真实弃权×6
# 弃权 46→89%,且 31/31 全部是显式拒绝(非蒙对)
| 轴 | v007(序贯) | v008(联合·自然配比) | v009(联合·拒绝×3) |
|---|---|---|---|
| real 总体 | 47.6 | 47.0 | 50.8(项目最高) |
| real specific / wildcard | 31.6 / 45.1 | 45.6 / 50.7 | 45.6 / 50.7 |
| real 弃权 | 88.6 | 42.9 | 62.9(91% 有原则) |
| mock / batch_005 / 工具 | 98.7 / 61 / 99 | 100 / 94 / 100 | 100 / 94 / 100 |
| 判定 | 曾升级 | REJECTED | PROMOTED(现任) |
"within"、显式 validation_policy: null、
MCP 把 null 变 "" 导致 layer 过滤全空——每一个都曾让评测崩掉,修复原则相同:吸收、记为模型错误、继续打分。