前言¶
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