Skill Miner
将过去编码助手会话中埋藏的信号转化为新的或现有的 "Agent Skills"。一个会话只有通过以下门控才能获得一个技能——可重复 AND (有改进空间 OR 重复请求):
- 可重复——任务或知识会重复出现,或者明显可能重复。过去的重复是最有力的证据,但合理可能重复的任务也算;真正的一次性任务永远不算。(必需。)
- 有改进空间——存在有意义的反馈,使得下次执行比第一次更好:
- 环境反馈——运行工作所揭示的内容:失败、该环境下反复出现的怪癖、曲折路径及其捷径、来之不易的启发式规则。这些本质上就是技能。
- 用户反馈——用户是专家,他们的反馈很宝贵;挖掘它以汲取用户的智慧(纠正、他们知道的更好方法、我们搞错的事实)。
- 重复请求——用户不断请求同一件事;一次提取出来,这样他们就不必再问了。
流程:发现 → 提炼(使用廉价 LLM,按会话处理)→ 分组、评判并生成。
0. 前提条件
必须能够访问一个小型 LLM。首先检查它:
python3 scripts/llm.py --check # 打印它将使用的后端,或者如何启用一个
设置 OPENAI_API_KEY / GEMINI_API_KEY / OPENROUTER_API_KEY 中的一个,或在 PATH 上有 claude / codex / gemini CLI。使用 SKILL_MINER_MODEL 覆盖模型,使用 SKILL_MINER_LLM 强制指定后端。
1–2. 运行流程(脚本完成繁重的、使用廉价 LLM 的工作)
保持工作目录为启动目录:所有产物都放在 ./out 下。
OUT=./out
python3 scripts/discover.py --since 35 --out $OUT/inventory.jsonl # 跨 agent 查找对话记录
python3 scripts/extract.py --inventory $OUT/inventory.jsonl --out $OUT/conversations.jsonl --workers 10
discover.py遍历common.py:ADAPTERS中的每个适配器(Claude Code、Codex、opencode;可以在此处添加更多),并保留最近--since天内的会话。除非用户要求更多,否则从最多 100 个对话开始。为extract.py添加--limit 15以快速抽样。extract.py解析每个对话并输出一行 JSONL:agent, session_id, path, main_dir, datetime, n_user_turns, topics[], tasks[], skills_used[], env_feedback[], user_feedback[]。main_dir= 完成大部分工作的最深文件夹(根据编辑/读取/提及的文件确定),而不是启动 cwd。topics是范围(通常是一个——兼作标题——用于分组)。tasks、env_feedback和user_feedback是简短数组,由廉价 LLM 从用户自己的话中复制而来(每个[]对应典型会话)——它们映射到门控的三个维度。廉价调用只看到用户轮次,因此env_feedback是用户关于运行情况的描述,而不是原始工具输出——在第 4 步中验证它。
3. 分组对话
读取 conversations.jsonl——每个会话一行。当行数 ≤ 100 时,整个文件可以放入上下文,因此直接读取。(如果挖掘了更多会话,先用 jq/grep 扫描具有非空 env_feedback / user_feedback 的行,然后读取感兴趣的部分。)忽略 topics 为 <error> 或琐碎/空的行。
按任务原型聚类——工作的种类,而不仅仅是目录(例如“CI 部署调试”、“设置 UI 迭代”、“依赖迁移”)——以判断维度 1(可重复):哪些任务重复出现或明显可能重复。然后,跨所有行收集另外两个维度:
- 维度 2 ——指向下次更好完成任务方法的
env_feedback和user_feedback(优先考虑环境反馈)。一个来之不易的教训即使没有聚类也是线索。 - 维度 3 ——在多个会话的
tasks中重复出现的细节(用户不断请求同一件事)。
将一次性设置步骤和孤立的随意评论放在一边。保留简短笔记:命名的组,每个组包含其会话数、主要的 main_dir、它携带的反馈/重复请求,以及几个示例 path 以便接下来作为证据打开。
4. 评判并生成
阅读 references/quality-bar.md 并应用其门控:可重复 AND (反馈 OR 重复请求)。
- 了解全局。 检查你现有的技能,了解哪些可以扩展——特别是那些反馈表明其表现不佳的技能;如果候选技能与它重叠,则打开该
SKILL.md并就地编辑。要查找技能文件路径:
仅用它来查找要编辑的文件;你的上下文仍然是全局真相的来源。如果候选技能专注于特定仓库,检查该仓库中已有的 Markdown 文档(python3 scripts/skills_inventory.pyREADME.md、设计文档、计划);如果重复出现的知识属于这些文档而不是技能,请在报告中向用户推荐。 - 根据原始记录确认。 对于每个线索,打开 1–3 个示例记录(
path字段)以确认信号是真实的,并捕获具体细节——确切的规则、确切的错误和解决方法、用户指出的更好路径、重复的请求。阅读用户在任何纠正附近以及[skill used: X]标记附近的语句。压缩的行只显示用户轮次,因此记录是你验证环境实际行为的地方。将反复出现的怪癖(记录下来)与一次性设置(最多一行注意事项)区分开来。 - 根据门控做决定。 一个线索只有在可重复且具有改进空间(反馈)或重复请求时才会成为技能。三个维度权重相同——不要因为任务只出现一次就放弃一个来之不易的教训,如果它明显会重复;也不要发布一个没有任何改进空间且没有重复请求的可重复任务。
- 生成/修改 ≤ 5 个技能。 每个技能都写成具体内容:规则、触发条件、步骤/命令、怪癖 + 解决方法——文件路径相对于仓库根目录(
src/pages/Run.tsx),绝不能是从记录中复制的机器特定绝对路径(/home/<user>/…)。它们放置的位置:- 扩展现有技能 → 在技能路径处就地编辑。不要分叉或复制它。
- 全新的技能 → 将其写入
~/.agents/skills/generated-skills/<name>/,暂存供用户审核和提升——不要将新技能直接放入实时的主目录。
- 报告。 列出你创建/修改的内容,以及每个内容来自哪个维度。对于每个值得注意的被拒绝的候选者,用一句话说明它错过了哪个维度。包括你认为应该更新以代替或补充技能更改的任何仓库文档。
扩展到其他 agent
每个 agent 存储记录的方式不同。要支持一个新的 agent(Gemini CLI、Cursor 等),向 common.py:ADAPTERS 添加一个 (discover_fn, parse_fn) 对,它产生标准化的记录(_norm(...))。流程的其余部分保持不变。Cursor(sqlite state.vscdb)尚未连接——opencode 的适配器是一个基于 DB(SQLite)的模板,可以作为参考。
注意事项
- 对记录只读;唯一的写入是
--out产物和你选择生成或改进的技能——新技能暂存在~/.agents/skills/generated-skills/,修改则就地写入现有技能。 - 子 agent/审查线程(Claude Code 侧链、Codex
thread_source: subagent)会被过滤掉——只挖掘真实的用户对话。
查看结果
独立运行时,结果是纯文本文件:./out 下的产物,以及你更改的技能(就地编辑,或暂存在 generated-skills/ 下)。此技能还附带 Skill Studio,一个桌面应用,用户可以在其中实时观看运行过程,审核每个暂存在 generated-skills/ 下的新技能(作为提议卡片,可接受或丢弃),并将就地编辑视为 git 跟踪的更改,可以保存为版本或恢复。