Skip to content

SkillOpt 自学习机制详解 ​

用费曼技巧讲清楚:SkillOpt 到底在做什么、为什么这样做、每一步发生了什么。

一句话概括 ​

SkillOpt 是一个「先考试、再补课、再考试」的闭环 —— 用旧 Skill 做一次模拟考试拿到基线分,分析答错的题总结补课方案,改完 Skill 后再考一次,只有新分数严格高于旧分数才采纳,否则保留旧 Skill 不动。

为什么需要 SkillOpt ​

想象一个场景:用户跟 AI 聊了很多轮,AI 的表现有好有坏。我们想知道:

"能不能从这些对话里学到东西,让 AI 下次表现得更好?"

最直觉的做法是让 AI 自己看历史对话、总结规则、写一份新的 Skill 文档。但这样做有一个致命问题 —— 你怎么知道新写的 Skill 真的比旧的好? 也许它改了一堆,结果反而变差了。

SkillOpt 的回答是:我不盲信改进,我用分数说话。 改完之后必须重新跑一遍,分数严格提升了才采纳,否则不动。

整体流程 ​

一步步拆解 ​

第一步:数据集构造 ​

做什么:把用户的聊天记录变成「考题」。

用户的对话是一问一答的形式。我们把每一对「用户提问 → AI 回答」配对起来,每对就是一道「考题」—— 题目是用户的话,参考答案是当时 AI 的回复。

然后把这些考题分成两份:

  • 训练集(train):用来「补课」,即分析答错的原因、提出改进方案
  • 验证集(selection):用来「考试」,即检验改完的 Skill 是否真的变好

分法很简单:最后 30% 的对话对作为验证集,前面的作为训练集。

为什么分两份? 如果用同一份题既补课又考试,就像「开卷考自己练过的题」—— 你永远不知道是真的学会了还是只是背了答案。分两份才能测出真正的提升。

代码位置:backend/services/review/pipeline/skillopt/dataset.py → DatasetProvider.build_split()

第二步:Baseline Rollout(旧 Skill 考试) ​

做什么:用旧 Skill 在验证集上做一次「模拟考试」,拿到基线分数。

具体来说,把旧 Skill 的内容作为系统提示词,把验证集里每道题的用户提问发给 LLM,让它生成回答。然后给每个回答打分。

这一步的意义:先知道现在有多好。后面所有改进都要跟这个分数比。

代码位置:backend/services/review/pipeline/skillopt/rollout.py → RolloutRunner.rollout()

沙箱模式 ​

Rollout 在「沙箱」中运行 —— LLM 被告知:

  • 你在沙箱里,不要调用真实工具
  • 不要写入用户会话或素材库
  • 只需要按 Skill 规则生成输出

这样 rollout 不会产生任何用户可见的副作用。

第三步:Train Rollout + 反思(分析错题) ​

做什么:用旧 Skill 在训练集上也跑一遍,然后让另一个 LLM(优化器)看结果,分析哪里做得不好,提出改进建议。

分两个子步骤:

3a. Train Rollout ​

和第二步一样,只是用的是训练集。这次跑的目的是收集「哪里答错了」的证据。

3b. 反思(Reflect) ​

把 rollout 结果(每道题的分数、失败原因、输出摘要)交给优化器 LLM,让它分析:

  • 哪些题答错了?错在哪?
  • Skill 里缺了什么规则?
  • 应该怎么补?

优化器返回一组「补丁」(patches),每个补丁包含:

  • reasoning:为什么要这样改(推理过程)
  • edits:具体的编辑操作列表

如果 LLM 反思失败怎么办? 系统有确定性回退:把所有答错题目的失败原因整理成列表,追加到 Skill 末尾。这样即使 LLM 挂了,也能留下「哪些题做错了」的记录。

代码位置:backend/services/review/pipeline/skillopt/reflect.py → LLMSkillPatchReflector.reflect()

编辑操作类型 ​

优化器可以提议 4 种编辑操作:

操作比喻说明
append在书末尾加一页在 Skill 末尾追加新内容
insert_after在某段后面插一句话在指定位置后面插入新内容
replace把某段话改写替换指定内容
delete删掉某段话删除指定内容(有长度限制,防止误删大片)

第四步:聚合 + 筛选 ​

做什么:多个 patch 中可能有重复的编辑建议。先合并,再取最重要的。

  1. 聚合:把相同操作(op、target、content 都一样)的编辑合并,每合并一次 support_count 加 1。然后按 support 从高到低排序。
  2. 筛选:只取 support 最高的前 N 条(N 由 REVIEW_SKILLOPT_EDIT_BUDGET 控制,默认 2)。

为什么要限制编辑数量? 一次改太多东西,万一改坏了很难定位问题。小步迭代更安全。

代码位置:backend/services/review/pipeline/skillopt/strategy.py → _aggregate_patches() + _select_by_budget()

第五步:应用编辑 ​

做什么:把筛选后的编辑逐一应用到当前 Skill 上。

每应用一条编辑后,系统会检查 Skill 的结构完整性 —— 必须包含 6 个必要章节:

  1. trigger — 触发条件
  2. workflow — 工作流程
  3. tool_policy — 工具使用策略
  4. output_schema — 输出格式
  5. quality_rubric — 质量标准
  6. failure_recovery — 失败恢复

如果某条编辑导致必要章节丢失,这条编辑会被回退(拒绝),跳过继续下一条。

如果当前 Skill 是空的,会用一份内置模板作为起始点。

代码位置:backend/services/review/pipeline/skillopt/update.py → MarkdownSkillUpdater.apply()

第六步:Gate 验证(新 Skill 再考试) ​

做什么:用候选 Skill 在验证集上重新跑一次 rollout,算出候选分数。只有候选分数严格大于基线分数,才算通过。

为什么要求严格大于? 等于意味着「改了跟没改一样」。既然没有改善,就不应该冒风险采纳新的。这是 SkillOpt 的核心安全机制 —— 宁可不变,也不变差。

代码位置:backend/services/review/pipeline/skillopt/strategy.py → _validate_candidate()

评分公式 ​

每道题的打分是确定性的(不依赖 LLM 评分),公式如下:

soft = token重叠率 × 0.55 + 质量关键词覆盖率 × 0.3 + 0.15
hard = 1(如果 soft ≥ 0.62),否则 0
  • token 重叠率:LLM 输出和参考答案的词语重叠比例。重叠越多越像「答对了」
  • 质量关键词覆盖率:输出中包含项目类型特定质量关键词的比例

不同项目类型的关键词:

聊天 (chat)图片 (image)视频 (video)
步骤、格式、检查、偏好、风险、结论主体、构图、光线、风格、参考图、水印、文字主体、动作、镜头、时长、比例、稳定、首帧

最终的混合分数 = hard通过率 × 0.5 + soft均值 × 0.5

为什么用弱评分而不是让 LLM 打分? 因为让 LLM 评估另一个 LLM 的输出,本身就不稳定。用确定性的公式,同样的输入永远得到同样的分数,才有可比性。

代码位置:backend/services/review/pipeline/skillopt/rollout.py → RolloutRunner._score_output()

完整时序图 ​

策略选择 ​

SkillOpt 是自学习的策略之一。每个用户的自学习策略由 user 表的 review_learning_strategy 字段控制:

字段值策略
distillation(默认)蒸馏:从历史对话中提炼规则
skillopt闭环 Skill 优化:本篇所述机制

运营人员通过直接修改数据库 user 表的 review_learning_strategy 字段切换用户策略。

支持的策略类型由 ReviewLearningStrategyType 枚举集中管理(backend/services/review/pipeline/contracts.py),新增策略只需扩展该枚举。

文件清单 ​

文件职责
backend/services/review/pipeline/skillopt/strategy.py主策略编排:数据集 → rollout → 反思 → 编辑 → 门控
backend/services/review/pipeline/skillopt/dataset.py数据集构造:消息配对 → train/selection 分片
backend/services/review/pipeline/skillopt/rollout.py沙箱 Rollout + 确定性弱评分
backend/services/review/pipeline/skillopt/reflect.pyLLM 反思 + JSON 解析 + 确定性回退
backend/services/review/pipeline/skillopt/update.pyMarkdown 编辑应用 + 结构校验
backend/services/review/pipeline/skillopt/types.py数据模型(DTO)
backend/services/review/pipeline/factory.py策略工厂(按用户策略类型缓存实例)
backend/services/review/pipeline/processor.py三阶段编排器(加载 → 策略执行 → 注册)
backend/services/review/pipeline/contracts.py策略 Protocol、枚举、上下文 DTO