前言¶
DSH 裏跑過一次成功的任務之後,經驗往往只留在會話裏。下次遇到同質任務,模型還是從零摸索,上次踩過的坑可能再踩一遍。已有的做法要麼靠人工寫 README,要麼靠人記住教訓,都沒法在下次執行前自動浮出來。
yangyiqun747/dsh-plugin-playbook 是 DSH 的「經驗複用 + 交付閘門」插件,維護者是 yangyiqun747,分類爲工作流。思路是:一次任務成功後,把「可複用的 SOP + 踩過的坑」沉澱成一條 playbook;下次遇到同質任務時,它作爲原生 Skill 出現在技能目錄裏,模型按需加載並照着做。同一個任務族累計到足夠樣本後,SOP 可以升級成交付閘門:執行前必須讓用戶 review,交付前必須逐項拿到客觀證據,否則寫文件的動作會被硬攔截。
下面介紹這個插件的實際做法。
核心功能¶
插件一共提供了三組能力。
經驗庫工具:5 個¶
1、playbook_save:保存一條經驗。
2、playbook_search:按相關性檢索。
3、playbook_get:取全文。
4、playbook_promote:把條目轉正爲 active。
5、playbook_feedback:回寫本次使用結果(ok 或 fail)。
閘門工具:6 個¶
1、gate_status:看本會話與工作區裏有哪些閘門、歷史通過率。
2、gate_propose:提議一條閘門(寫入時是「未確認」,不攔截任何動作)。
3、gate_confirm:通過原生提問通道詢問用戶,用戶同意後才落庫。
4、gate_start:先通過原生提問通道把本次方案交給用戶 review,用戶點「開始執行」後才啓用閘門。
5、gate_check ×N:每項記錄客觀證據(命令 + 退出碼 + 輸出摘要)。
6、gate_finish:全部必過項就緒後放行交付,並寫回統計。
外加一個硬攔截守衛(在 tools/pre-execute 上攔住 write / edit / present,直到已確認的 L2+ 閘門逐項通過)、一個 Skill Provider(active 狀態的每條 playbook 以 playbook-<id> 出現在技能目錄,用內置 skill 工具加載)、一條斜槓命令 /playbook,以及兩段系統提示(playbook:usage 經驗庫用法、playbook:gates 當前閘門狀態播報)。
存儲:純 Markdown,可 git 可手改¶
數據落在工作區內:
<workspace>/.dsh/playbooks/<id>.md # 經驗
<workspace>/.dsh/gates/<id>.md # 閘門
frontmatter 裏帶 id、title、status(draft / active / deprecated)、scope、tags、whenToUse,以及 stats(uses、ok、fail、lastUsed、lastOutcome)。正文按「何時使用 / 前置條件 / SOP / 坑 / 驗證 / 證據」分段。
文件名 <id> 會被規整成 ASCII kebab-case。原因很實際:active 條目要變成原生 Skill,而 skill 名(playbook-<id>)必須是 ASCII。規則是抽掉標題裏的 ASCII 字母數字拼成 kebab(「爲 DSH 開發…Host 插件」→ dsh-host);標題裏完全沒有 ASCII 時退回 pb-<8位內容哈希>。中文標題本身不受影響,完整保留在 frontmatter 的 title 字段裏。
召回方式¶
1、Skill 目錄:active 條目以 playbook-<id> 出現,description 用 whenToUse,模型自行判斷相關性後加載。
2、主動檢索:playbook_search 按 tags(權重 6/4)加關鍵詞(標題 5、標籤 4、何時使用 3、正文 1)打分,並按 stats.ok/fail 微調,已驗證有效的排在前面。
3、全文:playbook_get。
生命週期與自動降級¶
playbook_save -> draft 只有用戶確認後才轉正
playbook_promote -> active active 纔會作爲 Skill 暴露、纔會被召回
↓ 複用
playbook_feedback(ok|fail) 寫回 stats
↓ 連續失敗
自動降級 -> draft / deprecated
自動降級只在 active 上觸發,規則如下:
fail >= 2且ok === 0→deprecated(從來沒成功過,直接淘汰)。fail >= 3且fail > ok * 2→deprecated(成功過但基本不靈)。fail >= 2且fail > ok→ 退回draft(需要修訂)。
原文特別指出順序不能反:draft 分支必須排在最後,否則條目在第 2 次失敗時就離開 active,後面那些 active 專屬的 deprecated 判斷會變成永遠夠不到的死代碼。
交付閘門:先 review,再放行¶
經驗庫解決「怎麼做」,閘門解決「做完敢不敢交」。閘門的定義只能由用戶確認,插件只能提議。
風險分把一個任務族量化成 R,再由 R 決定門有多硬。簡化地說,D 由改動面、鏈路長度、認知密度等因子算出(有客觀驗證手段會打折,不可逆動作會加分),P 由歷史通過率與用戶返工次數算出,兩者按 R = 0.5 × D + 0.5 × (1 − P) 合成。用戶返工(reworks)在 P 裏的權重是普通成功/失敗的 2 倍。
R |
等級 | 行爲 |
|---|---|---|
| < 0.25 | L0 |
不設閘門 |
| 0.25 – 0.5 | L1 |
逐條自檢並列證據(軟提醒,不攔截) |
| 0.5 – 0.75 | L2 |
客觀驗證,write / edit / present 被硬攔截 |
| ≥ 0.75 | L3 |
同 L2,另要求獨立驗證者:至少一個必過項由別的 agent 自己調 gate_check 記錄 |
一套完整流程是:
1. gate_status 看本會話與工作區裏有哪些閘門、歷史通過率
2. gate_propose 提議一條閘門(未確認,不攔截)
3. gate_confirm 通過原生提問通道直接問用戶;同意後才落庫
4. gate_start 先通過原生提問通道把方案交給用戶 review;
用戶點「開始執行」後才啓用閘門
5. gate_check ×N 每項記錄客觀證據(命令 + 退出碼 + 輸出摘要)
6. gate_finish(pass) 全部必過項就緒 -> 放行交付,寫回統計
(L3 時另要求第 5 步裏至少一項由別的 agent 記錄)
不想經過模型時可以直接看:/playbook gates 列出工作區裏的閘門(等級、是否已被用戶確認、通過率、按當前數據建議的等級),/playbook gates <id> 看單個閘門的檢查項與歷史。
四條不變量¶
1、不許自證放行:gate_confirm 與 gate_start 都通過 ctx.userQuestions.ask 直接問用戶,答案由人在界面上給出。模型只能在原生通道不可用時用 user_confirmed 兜底,且兜底會記進 history / 工具輸出。
2、L2 以上必須有客觀證據:gate_check 要求命令 + 退出碼 + 輸出摘要,自評不算證據;L3 還要求至少一條證據的記錄人不是開啓閘門的那個 agent。
3、閘門定義只能由用戶確認後變更:gate_propose 寫出的永遠是 confirmed_by_user: false,連等級被改動都要重新確認。
4、必須有熔斷與逃生艙:同一個閘門連攔 2 次(MAX_BOUNCES)後自動打開熔斷、放行並把判斷權交回用戶;用戶說「這次不用閘門」時用 gate_finish(exempt) 出閘,豁免不計入統計。
閘門狀態按工作區存放,不按 agent¶
gate_start 把會話建在工作區的閘門目錄上,所以同一個工作區裏的所有 agent共用一條閘門。用原生 subagent 派出去的子 agent 落地在同一個會話,它自己調 gate_check 記的證據會被標記 verifier: <子 agent id> 並計入 independent;子 agent 的 write / edit / present 一樣會被硬攔截;gate_finish 只有開啓閘門的那個 agent 能調。
這是 L3「獨立驗證者」的實現方式:不是讓模型聲明「我找了人複覈」,而是讓另一個 agent 自己調用工具、由宿主填上它的身份。模型無法僞造。
失敗時的降級與既有機制的關係¶
守衛自己出錯時不會靜默放行:它會把錯誤寫進閘門狀態段落、警告用戶,然後按「未通過但放行 + 警告」處理。
插件不造輪子:執行前 review 用原生 ctx.userQuestions.ask,動作級阻斷用原生 tools/pre-execute,閘門狀態播報用原生 ctx.systemPrompt.section,插件不 import 任何 @deepseek-ai/*。plan mode 只是盡力而爲——首次真實運行裏 ctx.get('planMode') 在插件上下文返回空,所以 gate_start 不再依賴它,用戶 review 走提問通道,plan mode 能拿到就順帶切,拿不到就把原因寫進 plan_mode 字段。任務已經跑在 AgentTeams 團隊裏時不疊門禁,用它的 requirements/review verdict,閘門只負責把 verdict 回寫成 gate_check 的證據。
README 裏附了一組真實宿主裏的實測記錄:tools/pre-execute 硬攔截生效(閘門激活時 write 被拒,錯誤原文含缺證據清單,探針文件未被創建);ctx.userQuestions.ask 確認閘門生效;ctx.get('planMode') 在插件上下文取不到;gate_propose 的 factors 落盤曾有 bug(已修);提示段落對 failed 項的播報曾有 bug(已修);重複 install_bundle 會返回 application: failed。每條都對應了迴歸測試或具體輸出原文。
安裝與啓用¶
dsh plugin --profile desktop add <本目錄的絕對路徑>
卸載:
dsh plugin --profile desktop remove dsh-plugin-playbook
從本地目錄路徑安裝,不從 GitHub 拉取。安裝包是 ESM,main 爲 lib/index.js,並聲明瞭 cordis.patch.yml 補丁文件;Node 版本要求 >=22。
啓用後配置寫在 cordis.patch.yml 的 config:
- insert:
- id: playbook
name: dsh-plugin-playbook
config:
dir: .dsh/playbooks # 經驗庫,相對工作區
gateDir: .dsh/gates # 閘門庫,相對工作區
promptSectionOrder: 140 # 系統提示段落排序
slashCommand: true
安裝期如果 install_bundle 報的錯跟本插件無關(例如 ENOENT ... dsh-plugin-whale-maid-1.0.0.tgz),那是 profile 的 pnpm-lock.yaml 裏某條 file: 依賴指向了已刪除的本地壓縮包,pnpm 每次 install 都會去讀它。修法是在對應源目錄執行 pnpm pack --pack-destination <lockfile 期望的目錄>,再用 SHA512 重算並更新 lockfile 裏該條目的 integrity。
測試:
npm test
# 等價於 node --test "tests/*.test.mjs"
注意別寫成 node --test tests/,Node 會把它當模塊路徑而報 MODULE_NOT_FOUND。
典型用法¶
完整走一遍的流程如下。
1、任務成功後沉澱經驗:調 playbook_save 寫入 SOP 與「坑」段落。
---
id: "windows-sandbox-build"
title: "Windows 沙箱裏跑構建"
status: "active"
scope: "project"
tags: ["windows", "sandbox", "build"]
whenToUse: "需要在沙箱內執行 pnpm/node 構建時"
stats:
uses: 3
ok: 2
fail: 1
---
# Windows 沙箱裏跑構建
## 何時使用
## 前置條件
## SOP
## 坑
## 驗證
## 證據
2、確認轉正:用 playbook_promote 升到 active,之後它以 playbook-windows-sandbox-build 出現在技能目錄。
3、下次同類任務先檢索:playbook_search 按 tags 與關鍵詞打分召回,或直接 playbook_get 取全文。
4、任務族樣本夠了,提議閘門:gate_propose 給出檢查項與等級建議,此時不攔截。gate_confirm 走原生提問通道請用戶確認。
5、執行前 review 並開閘:gate_start 把方案交給用戶 review,用戶點「開始執行」後閘門生效。
6、逐項取證:每做完一項檢查,調 gate_check 記錄命令、退出碼、輸出摘要。
7、交付判定:全部必過項就緒後調 gate_finish(pass) 放行並寫回統計;否則只能 gate_finish(fail)。failedEvidence 只統計 required 項,optional 項失敗不阻塞 pass。
適用場景與注意¶
適合用在:同一類任務反覆出現、上次的成功做法值得固化的場合,尤其是出現頻率高、改動面大、或者「做完不敢直接交」的任務族。對個人練手、一次性腳本,L0 不設閘門,插件的經驗庫也只有在願意寫 SOP 時纔有收益。
注意幾點:
- 插件以當前 dsh 進程的權限運行,裝的代碼會在你的工作區讀寫文件,安裝前應檢查源碼與許可證(
MIT)。 - 星標與下載量在目錄頁上並不高,屬於社區裏的個人維護項目,長期維護需要自行判斷。
- 閘門行爲依賴原生
tools/pre-execute與ctx.userQuestions.ask可用;庇護通道不可用時的兜底會被記錄,且默認走「未通過但放行 + 警告」而不是靜默放行。 - 存儲是工作區內的純 Markdown,可以直接 git 管理,但也意味着沒有額外的權限隔離或加密。
結語¶
一句話概括這個插件的價值:成功經驗 → 結構化 playbook → 同質任務自動召回 → 用戶確認成閘門 → 交付前強制達標。它解決的不是模型能力問題,而是經驗留不下來、交付缺客觀證據這兩件事。
目錄頁:https://www.skillhub.cn/plugins/yangyiqun747/dsh-plugin-playbook
GitHub:https://github.com/yangyiqun747/dsh-plugin-playbook