技能礦工
將隱藏在過去編碼代理對話中的信號,轉化為新的或現有的「代理技能」。一個對話記錄只有在通過以下三道閘門時,才值得被提煉成技能:可重複 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 # 在各代理中尋找對話記錄
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是完成大部分工作的最深層資料夾(根據編輯/讀取/提及的檔案判斷),而非啟動時的目錄。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>/下,讓使用者可以審閱並提升 — 不要將新技能直接放到使用中的主目錄。
- 報告。 列出你建立或修改了哪些技能,以及每個技能來自哪個維度。對於每個值得注意但被否決的候選技能,用一句話說明它缺少了哪個維度。包含你認為應該更新(以代替技能修改或作為補充)的任何倉庫文件。
擴展到其他代理
每個代理儲存對話記錄的方式不同。要支援新的代理(Gemini CLI、Cursor 等),請在 common.py:ADAPTERS 中新增一個 (discover_fn, parse_fn) 配對,該配對應產生標準化的記錄(_norm(...))。管道的其餘部分保持不變。Cursor(使用 sqlite state.vscdb)尚未接入 — opencode 的配接器是一個基於資料庫(SQLite)的範本,可供參考。
注意事項
- 對你的對話記錄僅有讀取權限;唯一會進行的寫入是
--out產出物以及你選擇生成或改善的技能 — 新技能會暫存在~/.agents/skills/generated-skills/下,編輯則直接對現有技能進行。 - 子代理/審查執行緒(Claude Code 的 sidechain、Codex 的
thread_source: subagent)會被過濾掉 — 只會挖掘真正的使用者對話。
檢視結果
獨立執行時,結果是純文字檔案:./out 下的產出物,以及你修改的技能(就地編輯,或暫存在 generated-skills/ 下)。此技能也附帶 Skill Studio,這是一個桌面應用程式,使用者可以在其中即時觀看執行過程、審閱每個暫存在 generated-skills/ 下的新技能(以提議卡片形式顯示,可選擇接受或丟棄),並將就地編輯視為 git 追蹤的變更,以便儲存為版本或還原。