dsh-plugin-playbook:把成功任務沉澱成 SOP 與交付閘門

前言

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

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

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

小夜