opencode-skill-distiller
v0.2.0
Published
OpenCode plugin: automatically distills reusable engineering skills from coding sessions
Maintainers
Readme
opencode-skill-distiller
OpenCode 插件:Skill Evolution — 自动从编码 session 中提取可复用工程经验,形成结构化 skill 并按需注入。
工作原理
插件监听 OpenCode session 生命周期,提供两条核心管线:
┌─── Retrieval 管线 ───────────────────────────────────────────┐
│ 用户发消息 → 开启 episode → 检索相关 skill → 注入 system │
└──────────────────────────────────────────────────────────────┘
┌─── Distillation 管线 ───────────────────────────────────────┐
│ 工具调用追踪 → session idle → 蒸馏 → 决策 → 持久化 │
│ (CREATE / UPDATE / REJECT) │
└──────────────────────────────────────────────────────────────┘Retrieval 管线
- 用户发送第一条消息时,插件从 skill 库中检索最相关的 skill
- 通过
system.transform注入到 agent 的 system prompt - 默认只注入最相关的 1 个 skill(最多 2 个)
Distillation 管线
- 追踪 session 中的工具调用、错误信号、成功信号
- Session idle 后触发蒸馏流程(启发式分类 + 验证评分)
- 决策引擎判断 CREATE(新 skill)、UPDATE(更新已有 skill)或 REJECT(丢弃)
启发式分类:
| 决策 | 条件 | 置信度 |
|---|---|---|
| definite_distill | 有重试后成功(验证闭环),或 ≥3 次成功调用无失败 | 0.8 × cap |
| maybe | ≥3 次工具调用 | 0.6 × cap |
| hard_skip | 活动不足 | 跳过 |
验证闭环:如果 session 中出现了 "失败 → 同工具重试成功" 的模式,置信度上限为 1.0;否则上限为 0.5。
安装
OpenCode 通过 ~/.opencode/node_modules/ 发现插件,使用 --prefix 安装:
npm install --prefix ~/.opencode opencode-skill-distillerpostinstall 自动将插件添加到 opencode.json 的 plugin 列表,无需手动配置。
从 tarball 安装
npm install --prefix ~/.opencode ./opencode-skill-distiller-0.1.0.tgz卸载
opencode-skill-distiller cleanup && npm uninstall --prefix ~/.opencode opencode-skill-distiller本地开发
在 .opencode/plugins/ 中创建桥接文件:
# .opencode/plugins/skill-distiller.ts
export { default } from "../../src/index.ts";使用
自动运行
安装后无需配置。插件自动工作:
- Retrieval:你在 OpenCode 中提问时,插件自动检索并注入相关经验
- Distillation:session idle 后(默认 60 秒),插件评估该 session 是否值得沉淀
- Decision:根据相似度判断是创建新 skill 还是更新已有 skill
产物位置
your-project/
├── .claude/
│ └── skills/ # 跨平台 skill(OpenCode + Claude Code + Cursor)
│ └── fix-build-errors/
│ └── SKILL.md
└── .opencode/
└── memory/
├── skills/ # JSON skill 存储(插件内部元数据)
│ └── fix-build-errors.json
└── governance-log.jsonl # 所有蒸馏决策日志Skill 文件格式
JSON(skills/*.json)— 规范存储,包含完整的 skill 元数据:
{
"skillId": "fix-build-errors",
"name": "fix-build-errors",
"intent": "Fix TypeScript build errors in the project",
"signalsMatch": ["edit", "bash", "write"],
"strategy": ["Edit type definitions", "Run typecheck to verify"],
"antiPatterns": ["Error: ENOENT"],
"confidence": 0.8,
"version": 1,
"status": "active",
"validation": ["Error was resolved during session"]
}Markdown(.claude/skills/*/SKILL.md)— 跨平台可读投影:
---
name: fix-build-errors
description: Fix TypeScript build errors
metadata:
source: "skill-distiller"
confidence: "0.80"
version: "1"
---
# fix-build-errors
## When to use
- edit
- bash
## Strategy
1. Edit type definitions
2. Run typecheck to verify
## Anti-patterns
- Error: ENOENT
## Validation
- Error was resolved during session查看蒸馏日志
cat .opencode/memory/governance-log.jsonl每行一条 JSON 记录,包含 action(CREATE/UPDATE/REJECT)、skillId、reason、confidence。
配置
| 配置项 | 默认值 | 说明 |
|---|---|---|
| maxRetrievedSkills | 2 | 每次注入最多检索几个 skill |
| idleDebounceMs | 60_000 | session 空闲多久后触发蒸馏(毫秒) |
| injectionMode | system-transform | 注入方式(system-transform / silent-prompt / both) |
| confidenceCapWithoutValidation | 0.5 | 无验证闭环时的置信度上限 |
| skillStorePath | .opencode/memory/skills | JSON skill 存储路径 |
| governanceLogPath | .opencode/memory/governance-log.jsonl | 治理日志路径 |
| markdownProjectionEnabled | true | 是否生成 SKILL.md 投影 |
| maxToolCallsPerEpisode | 100 | 单 episode 最大追踪工具调用数 |
架构
src/index.ts — 插件入口 (4 hooks + idle pipeline)
│
├── runtime/ — 事件处理
│ ├── event-normalizer 多源 payload → 统一 NormalizedEvent
│ └── episode-tracker TaskEpisode 生命周期 (open → active → finalized → cleaned)
│
├── trace/ — 追踪层
│ ├── trace-recorder NormalizedEvent → EpisodeTracker 调用
│ └── trace-finalizer TaskEpisode → SessionTrace (不可变快照)
│
├── retrieval/ — 检索层
│ ├── context-builder TaskEpisode → RetrievalContext
│ ├── scorer 4 轴评分 (信号/环境/关键词/工具名)
│ ├── retrieve-skills 编排: 评分 → 排序 → 截断
│ └── injector system-transform / silent-prompt 注入
│
├── distill/ — 蒸馏层
│ ├── validation-scorer 验证闭环检测 + confidence cap
│ ├── candidate-normalizer SessionTrace → CandidateGene
│ └── distill-session 启发式分类 + 编排
│
├── decision/ — 决策层
│ ├── similarity 4 轴相似度 (name/signal/intent/env)
│ └── decide-skill-action CREATE / UPDATE / REJECT
│
├── storage/ — 持久层
│ ├── skill-store JSON 文件 CRUD
│ ├── governance-log JSONL 审计日志
│ └── markdown-projector JSON → SKILL.md 投影
│
└── types/ — 类型定义
├── skill.ts Skill, CandidateGene, DecisionResult
├── trace.ts TaskEpisode, SessionTrace, ToolRecord
└── config.ts SkillEvolutionConfigHook 接线
| Hook | 触发时机 | 插件行为 |
|---|---|---|
| chat.message | 用户发消息 | 开启 episode + 检索 + 注入 |
| experimental.chat.system.transform | system prompt 构建 | 追加检索到的 skill 文本 |
| tool.execute.after | 工具执行后 | 记录工具结果(成功/失败) |
| event (session.idle) | session 空闲 | 触发蒸馏管线 |
| event (session.deleted) | session 删除 | 清理内存状态 |
| event (command.executed) | 命令执行 | 记录命令计数 |
安全设计
- 自递归防护:SelfFilter 防止插件自身写入事件触发蒸馏循环
- 治理去重:同一 session 不会重复蒸馏
- 置信度上限:无验证闭环的经验不高于 0.5 置信度入库
- 决策门槛:0.7 相似度 → UPDATE,0.3-0.5 区间 → REJECT(重叠但不够接近)
测试
bun test # 运行全部 293 个测试
bun run typecheck # 类型检查
bun run build # 构建 dist/
npm pack --dry-run # 验证打包许可证
MIT
