DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

huang2005-hj /

huang2005-hj/dsh-plugin-grill-me

Verified

Interview users one frontier at a time: a grill-me skill plugin for DeepSeek Harness (MIT, independent implementation of mattpocock/skills grill-me)

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@6bf79164

dsh-plugin-grill-me

DSH 插件:把 mattpocock/skills 里的 grill-me / grilling 技能做成能装、能跑、而且确定性生效的 DSH 插件,并把同一份上游里的 grill-with-docs / domain-modeling 一起移植进来 —— 后两个额外加了一条文档通道:访谈过程中答应的 ADR / 术语表只要没落盘,就不算谈完。

上游 grill-me 是一段提示词:它要求模型把计划当成一棵设计树来审问,一轮把整个 frontier(前提已落定、现在就能问的决策)一次问完,每题给出推荐答案,然后等用户回答;只有 frontier 为空、并且用户确认达成共识之后,才允许动手。

提示词会被模型忘记。这个插件在提示词之外加了一层确定性的状态机:它从会话记录(transcript)里推导当前处于第几轮、哪些问题还没答、frontier 是否为空,然后

  • 在模型每一步之前注入当前 frontier 的状态指令(并且每一步只保留一份,不重复堆叠);
  • 在模型违反协议时(比如刚问完一轮就跑去调工具、装依赖、动手改文件)用一次纠偏消息把它拉回来;
  • grill-with-docs 模式下另记一本文档账:模型用 📄 ADR: <标题> / 📄 术语: <词> 承诺要写的文件,没写就不给「访谈完成」;
  • 提供 /grill-me、/grill-with-docs 两条命令和 grill_status 工具,让你随时查看面试进度。

状态机是纯函数、只读转录、无副作用;所有判断都能用会话记录复现。

安装(从 GitHub)

插件本体零依赖,装的是一个真正的 bundle 包(package.json 里声明了 dsh.bundle,挂载行写在自带的 cordis.patch.yml 里,不需要手改 profile 任何文件)。

# 把 <profile> 换成你的 profile 名(桌面版通常就是 desktop)
dsh plugin --profile <profile> add https://github.com/huang2005-hj/dsh-plugin-grill-me/releases/download/v0.4.0/dsh-plugin-grill-me-0.4.0.tgz

装完重启 DSH,然后在插件管理里确认 dsh-plugin-grill-me 处于启用状态。装好后 skills 目录里会出现 grill-me、grilling、grill-with-docs、domain-modeling 四个技能,/grill-me、/grill-with-docs 两条命令与 grill_status 工具随即可用。

  • 想核对拿到的东西没被改过:同一页 release 里的 SHA256SUMS.txt 列出了两个资产的 SHA256,装之前对一下即可。
  • 想连源码一起拿:同一页 release 里的 grill-me-dsh-src-0.4.0.zip(13 个文件,解压后 node test/state.test.mjs 即可复跑测试,零依赖、不需要 npm install)。
  • 也可直接从仓库安装(拉源码):dsh plugin --profile <profile> add github:huang2005-hj/dsh-plugin-grill-me。

装法(本机开发用)

# 1) 打包(插件本体零依赖,直接就是可安装目录)
cd <仓库根目录>

# 2) 用 DSH 的 plugin_manager 装进当前 profile(本地目录)
#    在 DSH 会话里让模型调用 plugin_manager:
#      action=install_bundle, target=<本地目录或 npm 包名>

装好后 desktop profile 的 patchReload: "live" 会让它立即生效;skills 目录里出现 grill-me、grilling、grill-with-docs、domain-modeling 四个技能。

用法

入口 谁触发 说明
/grill-me 用户 上游的 wrapper:只负责加载 grilling。模型不会自己调用它(modelInvocable: false,等价于上游的 disable-model-invocation: true)。
/grill-with-docs 用户 上游的 wrapper:先 grilling 再 domain-modeling,也就是「拷问 + 把定下来的东西当场写成 ADR / 术语表」。同样 modelInvocable: false。
/grilling、/domain-modeling、skill 工具、触发词 用户 / 模型 两个协议本体:grilling 是访谈,domain-modeling 是文档纪律(术语表 + ADR)。
grill_status 模型 只读工具:返回当前轮次、未答问题、文档欠账、已记录到的违规。
/grill-me、/grill-with-docs 命令 用户 打印当前面试状态(后者多一行文档通道)。

典型过程:

你: /grill-me 帮我审一下「把本地缓存换成 SQLite」这个计划

模型: ❓ **Q1** - **<问题标题>**:<正文>
      ➡️ <推荐答案>
      ---
      ❓ **Q2** - **<问题标题>**:<正文>
      ➡️ <推荐答案>
      (一轮问完,停下等你回答)

你: 1 是,2 选 B,3 你看着办
(插件记为:这一轮已回答)
模型: ❓ **Q3** ...(下一轮 frontier)
...
frontier 为空 → 你说一句「确认」(`可以了`/`没问题`/`开始吧`/`确认理解,开始吧` 之类都行,光秃秃一个 `确认` 也算)→ 此时才允许动手;这句确认**认下就不会被撤回**,之后你再说别的话也不会把它顶掉

文档通道(grill-with-docs)

上游把这条链拆成两个技能:grill-with-docs 只是「先 grilling、再 domain-modeling」,domain-modeling 才是文档纪律本身。上游自己的长文里记着一个已知故障:文件写入静默不发生 —— 访谈谈完了,答应要写的 ADR 和术语表一个字都没落盘。这个插件把那一半也变成确定性的:

  • 模型在正文里用 📄 ADR: <标题> / 📄 术语: <词> 声明要写的东西。引用不算承诺:代码块和引用块里的标记不记账。
  • 声明即欠账。只有真的调了写文件类工具、且目标路径命中 docs/adr/** 或 **/GLOSSARY.md,这笔账才算还清。GLOSSARY-MAP.md(多上下文索引)算文档、写它不会被纠偏,但它不是术语表,顶不了任何一笔账。连「哪个标题对应哪个文件」都按文件自己的名字(去掉目录和 NNNN- 前缀)做 slug 匹配:标题完全一致优先,否则取最长的那个能被文件名包含的标题 —— 所以「Use JSON」抢不走「Use JSON for storage」的那次写入。写得对不对、值不值得写,插件不判断:那是 domain-modeling 三条判据(难回退 / 没上下文会让人困惑 / 是真实取舍)的事,机器只保证「你说要写的,最后必须写出来」。
  • 欠账未清时,就算 frontier 空了、你也确认了,模型也拿不到「访谈完成、可以动手」:指令改成列出这些欠账,模型跑去做别的(纯文档写之外的动作)会被纠偏一次。同一步里既写了文档又写了代码算这笔账还清(文件在步骤结束时确实存在),不纠偏;读不出目标路径的写操作既不算还账也不判违规 —— 拿不准时宁可不纠,也不要冤枉一个已经把文档写出来的模型。
  • 只有 grill-with-docs 模式有这本账;/grill-me 与 grilling 完全不谈文档,与上游一致。
  • 上游 ADR 模板本体只有「标题 + 1–3 句」,Status / Considered Options / Consequences 都是可选段 —— 它也明说多数决策不配 ADR,一次访谈零 ADR 也是正常结果。

它到底“确定性”在哪里

  • 轮次记账:src/state.js 解析助手消息里的 ❓ **Qn** 与 ➡️,得出每一轮的问题清单。只有带上协议自己的题头(❓ 或 Qn - **标题**)才算是「问了一轮」:普通行文里写 Q1: … Q5: …(季度、清单、复述刚才的问题)不算,否则模型会把自己的正文当真问题、再被指令喂回来,变成没有用户输入也会无限自转的假面试。
  • 逐题记账:一轮之后的第一条真实用户消息按题号逐题结算 —— 1 是 记成「接受推荐」、3 选 B 记成「改选」、回答复述了该题自己的推荐答案(3 no auth 对 ➡️ No auth yet)也算接受、没提到的题仍然开放,所以一轮里 Q2 没答不会被 Q1/Q3 带走。题号识别有三条通路:Q2: … 这种显式标签、1 a 2 b 3 c 这种严格递增 run,以及 1是2两边都发3同意 这种数字直接粘在答案上的写法(每个数字都必须真的是本轮还在开放的问题)。不做语义猜测:题号对不上本轮问题就整轮不动;而只有「纯肯定」(都可以 / yes to all three)或本轮只剩 1 题还开放时,才会整轮一次性结清,其他没有题号的回复保持本轮开放、绝不替用户做决定。
  • 确认要认账:frontier 清空之后,CONFIRM_RE(确认理解/全部确认/没问题/开始吧…)算确认;整条消息就是一个接受词(确认/同意/好的/ok…)也算,不需要模型先写出「共享理解」那种仪式措辞(GRILL-28:用户打了一句光秃秃的 确认,插件却继续让模型等着)。更关键的是这句确认属于说出它的那条消息:0.3.2 每步都按「最新一条人话」重算,于是你确认完随手说一句无关的话(哪怕只是「重启了」),状态就退回 awaiting-confirmation,插件又开始劝模型「别动手,等确认」——正好和你的意思相反(GRILL-30)。0.3.3 把确认闩在它自己的 seq 上,只有在它之后又有新一轮问题被回答(或你给了更新的确认)时才失效;grill_status 会额外报出 confirmedAtSeq,你能看到这条确认是哪句话给的。
  • 注入:agent/pre-step 里若面试处于活动状态,插件追加一条 source.kind = 'grill-me' 的指令消息;同一步里已存在则原地替换,绝不重复堆叠。
  • 纠偏:agent/turn-stopping 里若检测到「问完一轮却去执行动作」,插件 agent.steer(...) 一条纠偏消息,强制同一轮内再走一步。纠偏预算按违规本身记账(violationKey:同一次动作、同一轮缺推荐都只纠 1 次)—— 0.2.0 按 (agent, turn) 记账,而每次 steer 都会开出新的 turn,于是同一条旧违规会不停把自己再喂一遍,没有用户输入也会无限自转;0.3.0 修掉了这个自转。0.3.1 修掉了让纠偏形同虚设的那一步(GRILL-27):纠偏消息本身也是 source.kind = 'grill-me',会被 agent/pre-step 的「原地替换」逻辑当成旧指令吞掉、换成一条全新的指令 —— 模型因此永远读不到自己刚违反了哪条规则,转录里连一条 form = 'correction' 的消息都不存在。现在只有 form = 'directive' 的插件消息会被替换,纠偏消息原样送进模型,旁边仍只有一条新指令。
  • 不误伤:普通英文里出现的 “grill / grilling” 不会激活面试,插件自己的名字也不再算激活词(光是提到 grill-me 这个插件、队友复述它的指令、转录里引用一段文档,都不该把人拖进面试)。只有人自己写的 /grill-me、/grilling、/grill-with-docs、中文触发词(拷问/盘问/质询/逼问/压力测试/grill 我),或者宿主明确标记的技能调用(skill 工具加载 grilling / grill-with-docs)才会激活;domain-modeling 单独加载不激活访谈(它只是文档纪律,不是访谈模式)。激活后一直有效,直到 /grill-stop、stop grilling、不用问了 之类的收尾词。

文件

路径 作用
src/state.js 纯状态机:projectEvents / analyze / renderDirective / renderStatus / describeViolation,以及文档账(parseDocDeclarations / classifyDocPath / isWriteTool)。零依赖。
src/skill.js 四个技能的正文与描述(两个 wrapper + grilling、domain-modeling 两个协议本体)。
lib/index.js Cordis 插件入口:注册四个技能、grill_status 工具、两条命令,挂 agent/pre-step 与 agent/turn-stopping。
cordis.patch.yml bundle patch:把这个包挂进 loader 树。
test/ 状态机对抗测试 + 冒烟测试。

设计约束(踩过的坑)

  • 插件不能 import '@deepseek-ai/*':profile 的 node_modules 里没有这个 scope,宿主包都打包在 app.asar 内。所以消息构造用 src/state.js 里自带的 makeUserMessage(形状与宿主 createUserMessage 一致)。
  • agent/pre-step 的 {kind:'reject'} 会让整个 turn 以 blocked 结束,可能把已经产生的工具结果悬空 —— 插件因此只用 enter 注入,从不 reject,纠偏交给 turn-stopping + steer。
  • 技能名必须匹配 /^[a-z0-9]+(?:-[a-z0-9]+)*$/,所以中文只出现在 description / 正文里。

卸载

plugin_manager 里 disable/remove 这个 bundle 即可;插件在 apply 里注册的 disposer 会随 Cordis 卸载自动回收。

—/ 5

No ratings yet

Verified DSH bundle

Commit 6bf791641674

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout