用 distill 把 DSH 對話經驗蒸餾成可複用技能

前言

用 DeepSeek Harness(dsh)寫代碼、改倉庫、走評審,同一個團隊習慣經常要反覆講:提交信息怎麼寫、測試怎麼跑、哪些文件不能動。會話一換,智能體又回到「請再說明一下你們的規範」。記憶插件可以存事實,但不一定把「怎麼做這類事」沉澱成後續會話能直接調用的技能。

社區插件 distill 走另一條路:主對話不額外註冊工具,只在回合結束時於後臺派發反省子代理,把值得複用的流程寫成 SKILL.md。它不替代圖譜記憶或長期記憶,而是把「做過什麼」收成「以後怎麼做」。

本文按社區目錄頁、GitHub 倉庫 README、package.jsonsrc/index.ts 交叉覈對後整理。社區目錄站點 https://deepseek-harness-plugin.com/zh-CN/plugins/ 是獨立收錄頁,與 DeepSeek / 幻方沒有官方從屬關係;官方運行時仍以 https://github.com/deepseek-ai/deepseek-harness 爲準,其核心理念是「一切皆插件」。

這是什麼

distill 是一款 DeepSeek Harness 的「記憶」類插件,由 GitHub 用戶 LoserFox 維護,倉庫爲 LoserFox/distill。npm 包名是 @loserfox/distill,當前版本 0.1.0,主要語言 TypeScript。目錄頁收錄於 2026-08-03;GitHub 倉庫在 2026-08-17 顯示 19 星(目錄頁當時顯示 16,星標以 GitHub 爲準)。

目錄頁的定位可以概括成一句話:每個回合結束後,後臺 subagent 對對話做反省,把經驗沉澱爲技能的創建或更新;只掛接 agent/turn-stopping,不註冊任何面向模型的工具或技能。

package.json 把許可證寫成 BSD-3-Clause,但倉庫根目錄沒有 LICENSE 文件,GitHub 也未識別出 SPDX 許可證。安裝前應自己打開源碼覈對許可聲明。

核心功能

主對話保持原樣

插件插入行 id 是 distill(見倉庫 cordis.patch.yml)。它不往主 agent 的工具表或技能表裏加任何東西,因此對話表面不會多出「蒸餾」按鈕或新工具名。README 寫明:唯一對模型可見的間接效果,是後臺反省子代理帶有 skill 查看器,寫進去的技能會在後續輪次出現在 dsh-tool-skill 目錄裏。

反省派發本身記在日誌裏,對話循環不可見,也不會和用戶當前任務搶工具調用。

回合結束後再蒸餾

觸發點是 agent/turn-stopping。一次反省的大致流程如下:

  1. 收集自上次蒸餾檢查點以來新增的人類 user/message
  2. 數量達到 minUserMessages(默認 3)後,派發後臺反省子代理。
  3. 子代理工具白名單隻保留 skill 查看器;結果走結構化輸出契約,而不是自由文本。
  4. 無論 skip / create / update,檢查點都會推進到最後一條已反思消息,下一輪只覆蓋新消息。

每個會話同時只允許一次進行中的反省;反省尚未結束時到達的已結束回合會被跳過,下次結算再評估。

反省子代理的目標路由優先使用配置裏成對出現的 provider / model;都沒配則沿用剛結束的 agent 自己的 agent.options。兩者都不存在時本輪跳過並打警告。子代理提供方默認名是 spawnproviderName)。提供方缺失、運行失敗、被取消或沒有捕獲結果時只記警告,不會把主循環打崩。

三種提議,寫入本地技能包

子代理只能給出下面三種結構化結果之一:

  • {"action": "skip"}:沒有值得保存的內容。
  • {"action": "create", "skill": {"name", "description", "whenToUse?", "content"}}:新建技能,寫成帶 frontmatter 的 SKILL.md 包,由本地技能提供方像發現手寫技能一樣發現它。源碼註釋裏對應的發現插件是 dsh-skill-filesystem
  • {"action": "update", "skill": {...}}:對某個先前蒸餾出的技能做整文件替換。

落地前會做校驗:技能名必須通過 isSkillName(kebab-case),描述和內容不能爲空。create 時若目標文件已存在則跳過。update 只作用於已經帶有插件所有權標記的文件:

distilled-by: dsh-distill

缺少該標記、或不是本插件蒸餾出來的技能,update 會被跳過並記警告。因此手寫技能、內置技能和運行時註冊的技能不會被重寫。只有帶該標記的技能會出現在子代理的可更新列表裏。

默認寫入位置由 targetRoot 決定:

  • project(默認):倉庫 git 根下的 .agents/skills;找不到 .git 祖先時回退到會話 cwd。
  • user~/.agents/skills。源碼裏可用 agentsHome 或環境變量 DSH_AGENTS_HOME 覆蓋用戶根目錄。

提示詞來源

反省提示詞改編自 Nous Research hermes-agent_SKILL_REVIEW_PROMPT(MIT,Copyright (c) 2025 Nous Research),針對 DSH 界面改了工具引用和輸出契約。完整署名寫在 src/index.ts 文件頭。提示詞要求產出的是「類級別」技能(一類任務怎麼做),而不是一次會話一條的碎片條目。

安裝與啓用

目錄頁給出的安裝命令如下,在 DeepSeek Harness 終端裏運行即可:

dsh plugin add github:LoserFox/distill

需要裝到指定 profile(例如 web)時,以倉庫 README 爲準:

dsh plugin --profile web add github:LoserFox/distill
dsh --profile web --dump-config | grep distill

如需可復現安裝,目錄頁建議固定 commit 哈希。當前 main 最新提交是 2026-08-13d2aaa395adeffe88e429be796c12d829752cbad1(提交說明爲遷移到官方 0.1.0-rc.5,並以 @loserfox/distill 發佈):

dsh plugin add github:LoserFox/distill#d2aaa395adeffe88e429be796c12d829752cbad1

卸載:

dsh plugin --profile web remove distill

安裝後必須重啓目標 profile 的 DSH 進程。README 寫明組合層變更不參與 HMR 熱更新。

宿主前提(base bundle 裏默認存在):

  • subagent-spawn-in-process:註冊反省子代理使用的 spawn 提供方
  • tool-skill:子代理可調用的 skill 查看器

插件還要求 ctx.subagentsinject: ['subagents'])。沒有 tool-skill 的部署仍會跑反省,但子代理在提議前無法查看已有技能。package.json 的 peerDependencies 把 @deepseek-ai/dsh-agent 標到 ^0.1.0-rc.6

配置項

配置字段以倉庫 README 爲準,並與 src/index.ts 中的 Config 對照過:

字段 默認值 含義
enabled true 總開關
minUserMessages 3 觸發一次反省所需的新增人類用戶消息數
provider / model 未設置 顯式輔助路由,必須同時提供;默認用 agent 自身路由
maxTokens 2048 反省子代理輸出 token 上限
timeoutMs 30000 反省的端到端截止時間(毫秒)
targetRoot project project 寫入項目 .agents/skillsuser 寫入用戶級技能目錄
providerName spawn 反省子代理使用的子代理提供方註冊名
allowUpdate true 是否允許更新先前蒸餾出的技能;false 時只提供 create

providermodel 必須成對出現,只配其中一個會在校驗階段報錯。源碼裏還有可選字段 agentsHome,用於覆蓋 user 目標的根目錄。

適用場景與注意事項

目錄頁給出的使用方向包括:從真實會話裏抽出工作方式(提交約定、評審偏好、項目習慣),讓新會話或新人的智能體從已有規範起步;把反覆口頭解釋的流程收成技能。目錄頁也提醒:偶爾審查蒸餾結果,刪掉過時條目、合併重疊技能、改措辭讓它們讀起來像團隊標準。蒸餾質量取決於會話質量,不是裝上就會自動變「更懂你」。

使用前需要知道當前實現的邊界:

  • 只做整文件更新。update 會重寫整個 SKILL.md,不支持局部補丁,也不能寫入 references/templates/scripts/ 這類支持文件。
  • 所有權標記按來源選擇。加標記之前蒸餾出的技能沒有 distilled-by: dsh-distill,會被當作用戶所有,永遠不會被自動更新,除非重新創建或手動補上標記。
  • 檢查點從日誌推導。README 寫的是:檢查點來自最近一條已記錄的 session/distill-review-request;從未反省過的會話從第一條用戶消息開始。
  • 項目目標依賴 git 根。沒有 .git 祖先時回退到會話 cwd。

更需要單獨說明的是會話事件兼容性。當前 main0.1.0,commit d2aaa395)會把僅用於診斷的 session/distill-review-request 寫進會話日誌。GitHub Issue #6#9 以及官方倉庫討論 #1584 都報告:在 dsh 0.1.0-rc.6 上,該自定義事件類型不在 harness 的已知會話事件列表裏,也無法通過現有 session.append API 標成可忽略,導致觸發過蒸餾的會話在重啓或恢復時出現 SessionFormatUnsupportedError,整段歷史無法加載。截至 2026-08-17,倉庫裏已有未合入的修復 PR(#8#10)。在修復進入你實際安裝的 commit 之前,不建議把它接到還需要保留歷史的生產會話上;安裝前請先覈對 Issue 與當前提交。

插件以當前 dsh 進程的權限運行,安裝時可能執行代碼。安裝前應檢查源代碼倉庫和許可證;需要可復現安裝時請固定 commit 哈希。

小結

distill 把「回合結束」變成一次後臺技能策展:不改主對話表面,只在積累了足夠的新用戶消息後,用受限工具集的子代理決定 skip、create 或 update,並把結果寫成帶所有權標記的本地 SKILL.md。它適合想把團隊習慣從口頭說明變成可發現技能的人,但當前 0.1.0 與 dsh 0.1.0-rc.6 的會話事件兼容性仍是硬限制,裝之前要先看倉庫狀態。

目錄頁:https://deepseek-harness-plugin.com/zh-CN/plugins/distill/

GitHub:https://github.com/LoserFox/distill

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜