dsh-quality-guard:用第二個模型給助手回覆做質檢

前言

DSH 的插件生態裏,一類需求很實際:助手說完話之前,先讓別人看一眼。wdj20050927 維護、分類爲工作流的 dsh-quality-guard 就是幹這件事的——助手的回覆在真正發給你之前,會被第二個模型當裁判判一次;不合判據就打回重寫。

先說它和已有做法的區別在於判據從哪來。機械判據(字數、正則、格式)管不住偏題、鋪墊、術語堆砌:一段完全答非所問的回覆,只要夠短、帶個鏈接,就能合規。這個插件把判據交給獨立的一次模型調用,README 給出的依據是「同一條上下文裏的自檢基本無效」(Huang et al., Large Language Models Cannot Self-Correct Reasoning Yet, arXiv:2310.01798),而獨立輪次的驗證纔有效(CoVe, arXiv:2309.11495)。代價是每輪多一次模型調用。

下面介紹這個插件。它由 engine/(鉤子本體)和 panel/(可視化面板,可選)兩半組成,當前版本 1.6.1,許可證 MIT,倉庫在 https://github.com/wdj20050927/dsh-quality-guard 。

兩半分別是什麼

目錄 角色 幹什麼
engine/ selfcheck-guard 掛在 agent/turn-stopping 上。輪次要結束時往 next-step 投一條消息,輪次就不結束,模型接着改;判官是另起的一次模型調用。
panel/ dsh-quality-guard Web 面板:側邊欄一行「質檢」+ 主欄一頁編輯器。讀寫 ~/.dsh/quality-guard/settings.json。

面板改完即時生效,不靠熱重載:引擎在每次判決前重新 stat + 讀一遍 settings.json,用 mtime:size 做緩存 key,文件一變,下一輪就用新值。

一次檢查是怎麼走的

1、輪次將結束時,引擎讀到 turn-stopping,先讀 settings.json。
2、把判據 + 原問題 + 草稿發給判官,判官返回逐條 0-10 打分(壓在輸出第一行)和 FIX: 建議。
3、引擎把分數折算成 0-100:分母恆爲「條數 × 10」,漏答按 0 壓着;任一條 <6 分就把總分上限壓到 59,並列爲 fail。
4、不及格且重寫次數沒超 maxReworks,就通過 steer 讓模型按 FIX 重寫;否則放行。

判官拿不到 llm、超時、報錯、沒有路由,一律走放行分支(fail-open)。但已經開始輸出的分數不會被丟掉:斷流、max-tokens、半截 JSON 都先搶救分數,拿不到分數才補判一次,兩次都沒有才進 unknown 出口,此時看 onUnknown 決定放行還是打回。

任一條判據低於 6 分即不合格(v1.5.0 起)。低於 6 的條目把滿分折算到 59,必然低於任何 ≥60 的及格線;6 分本身不觸發否決(6 分等於做到一半),只有 0/2/4 才折算。也就是說每條判據都能一票否決。

安裝與啓用

先裝面板,再裝引擎。面板一條命令即可:

dsh plugin --profile web add github:wdj20050927/dsh-quality-guard

倉庫根的 package.json 聲明瞭 dsh.bundle.patch: ./panel/cordis.patch.yml,裝完 dsh 會自動把 quality-guard 這一行插進 profile 層。想確認插進去了,跑:

dsh --profile web --dump-config

輸出裏應當出現:

# == dsh-quality-guard
- id: quality-guard
  name: dsh-quality-guard

引擎不能像這樣安裝,它要按絕對路徑掛、要指自己的配置路徑。把 engine/ 整個拷到插件目錄:

~/.dsh/plugins/selfcheck-guard/

然後在 ~/.dsh/profiles/<profile>/cordis.patch.yml 末尾追加一段 insert,把路徑換成你自己的絕對路徑(Windows 用正斜槓):

- insert:
    - id: selfcheck-guard
      name: 'C:/Users/YOUR_NAME/.dsh/plugins/selfcheck-guard/index.mjs'
      config:
        settingsFile: 'C:/Users/YOUR_NAME/.dsh/quality-guard/settings.json'
        criteriaFile: 'C:/Users/YOUR_NAME/.dsh/plugins/selfcheck-guard/criteria.example.md'
        auditFile: 'C:/Users/YOUR_NAME/.dsh/quality-guard/audit.jsonl'
        dryRun: true
        maxReworks: 3
        timeoutMs: 60000

改完重啓 dsh(或重載 patch)。settings.json 不存在也沒關係,引擎會用 patch 裏的靜態配置 + criteriaFile 開跑。注意別在 patch 裏填 maxTokens,輸出預算由引擎按檔位自動算,填了數字等於關掉自動預算。

面板也可以手動裝:拷到 ~/.dsh/plugins/dsh-quality-guard/,在 profile 的 node_modules 裏建目錄聯接(Windows),再往 patch 加一條按包名掛的 - id: quality-guard / name: dsh-quality-guard。面板需要 react ^18.2 和 @deepseek-ai/dsh-client-locale、@deepseek-ai/dsh-client-ui-layout,後兩個 dsh 自帶。只裝面板不裝引擎也能跑,只是沒有東西去讀它寫的設置。

配置

配置有兩個來源,活設置優先:

1、settingsFile(~/.dsh/quality-guard/settings.json)——面板寫的就是它,人也能手改,引擎每輪現讀。
2、patch 裏的靜態 config——只在①讀不到或讀不懂時兜底。

常用字段(完整表見 README):

字段 含義 範圍 patch 默認 面板默認
enabled 總閘 bool true true
dryRun 演習:只判斷、記日誌、不打回 bool true true
triggers.minReplyChars 回覆短於這個字數就跳過 0–20000 0 0
triggers.maxReworks 同一輪最多打回幾次 0–10 3 3
triggers.scoreThreshold 判官打分的及格線 0–100 70 80
judge.timeoutMs 判官超時就放棄本條 1000–120000 60000 60000
judge.model 指定判官模型,留空沿用當前路由 — null null
reasoningEffort 判官思考檔位,v1.3.0 起只填 auto auto auto auto
onUnknown 判官兩次都沒裁定時放行還是打回 pass / rework rework rework
auditFile 審計日誌落點,空字符串=不寫 — — ~/.dsh/quality-guard/audit.jsonl

超出範圍的數值會被夾回默認值(引擎側 readLive()),面板側直接報人話錯誤。判官的檔位和輸出預算不用你填:引擎先用最省的那檔(low,off 會被上游拒),判不出來才升一檔重判,預算隨檔位一起漲。手寫 settings.json 裏塞舊值還能跑,但面板一保存就歸一成 auto。

判據怎麼寫

兩種寫法二選一。文本文件(criteriaFile)原樣餵給判官,不解析;面板裏用 settings.json 的 criteria 數組,每條 {id, label, enabled, text},勾掉的跳過,exceptions 一行一條。兩者最終拼成同一段文本:

判據(任一條不滿足即不合格):
1. ……
2. ……

例外:
- ……

全部勾掉或全空,退回代碼內置判據——寧可判得嚴,也不要靜悄悄變成不查。

典型用法

先用 dryRun: true 跑一輪,只記日誌不打回,看判官給的分數和 worst / fix 是否合理,再決定要不要開打回。確認判據有效後,把 dryRun 改成 false,maxReworks 按實際需要設 1–3 之間,scoreThreshold 默認 patch 是 70、面板是 80。

自測不聯網、不花錢,用假 llm:

node engine/selftest.mjs
# → 220 passed, 0 failed

覆蓋判據拼裝、超時/報錯放行、maxReworks 上限、dryRun、外部判據文件、活動設置覆蓋 patch,以及判官輸出塞進 reasoning、aborted、max-tokens 三種異常的搶救路徑。

適用場景與注意

適合需要把「回覆質量」變成可執行閘門的場景:偏題、鋪墊、術語堆砌這些機械判據管不住的問題,有獨立一輪語義判定才抓得住。對延遲敏感、不想每輪多一次模型調用的場景,這個代價要先想清楚。

幾點使用注意:打回走 agent.steer(),舊回覆已經按 append 落盤,界面上會多留一條舊回覆,這是設計取捨,方便對照長版短版。判官偏嚴不一定是判官錯了,README 記錄過一次實測:判官按「不旁生枝節」「數值必帶出處」判 no,實際是那段回覆多給了地點、還帶沒有出處的數值,測判官之前先確認語料本身無歧義。判官系統提示裏「寧可判不合格」在 v1.2.0 已被移除,發現誤傷應及時調整判據而不是調嚴格度。

隱私上要注意:audit.jsonl 每一行都是真實對話的複述,worst / fix 是判官寫的原話,等於把對話摘要留在磁盤上。倉庫的 .gitignore 已擋掉 *.jsonl、settings.json 和備份,不要強行 git add -f;分享截圖前先看判據裏有沒有混進私人設定。想不留痕,把 auditFile 置空即可,質檢照常工作。

這個插件以當前 dsh 進程的權限運行,能讀到你的對話和本地配置。安裝前建議通讀源碼與許可證(MIT)再啓用,尤其是判官路由到哪個模型。

目錄頁:https://www.skillhub.cn/plugins/wdj20050927/dsh-quality-guard
GitHub:https://github.com/wdj20050927/dsh-quality-guard

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

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

小夜