DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

winston-hoo /

winston-hoo/dsh-spec-forge

Verified

This plugin has no description yet.

★ 2 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@112acc20

dsh-spec-forge · 需求锻造

一个 DeepSeek Harness(dsh)插件。它管两件事:在你动手前,把模糊需求问清楚;在你做完后,把这次的经验存下来,下次再遇到同类需求时自动顶上来。

实测于 @deepseek-ai/dsh 0.1.2-alpha.4(Windows + Web profile)。 dsh 仍是 developer preview,API 会有破坏性变更;插件已锁定其 API 面,升级 dsh 后如失效请看 CHANGELOG。


它解决的是什么

编程对话里最磨人的不是写代码,而是这几件事反复发生:

  • 需求说不清就开工。 "帮我优化一下那个查询"——哪个查询?优化成什么样?做完才发现理解错了。
  • 同一套规矩每次都重新交代。 "common/Result.java 别动""Controller 别写业务逻辑"——换了个会话,模型又踩一次。
  • 同一个套路,每次都从零描述。 你第 N 次让模型"加个分页查询接口",它还是第 1 次见到这个需求的样子。
  • 好用的提示词用完就丢。 你花半小时调教出来的一段标准改法,关掉对话就没了。

这个插件把这些经验沉淀成明文 Markdown 模板库,存在 ~/.dsh/spec-forge/ 下。你看得见、改得动、能进 Git——它不是黑盒。


装好之后,一次任务是这样走的

整条链路是五个工具串起来的闭环:

收到需求 → spec_recall(翻历史模板与禁区)→ spec_triage(体检+定复杂度)
                                              ↓
                    L1 直接动手 / L2 最多问 3 个 / L3 完整 Grill-me
                                              ↓
          spec_distill(把需求+澄清+禁区 压成实现提示词)→ 动手写代码
                                              ↓
                    spec_retro(做完沉淀成模板)→ 下次同类需求被召回

举一个真实触发过 L1 的例子。用户只发了这么一句:

"index.vue 这个物业管理员管理页面的新增/修改接口增加一个主管管员字段 isMainAdmin,值为1是,0否,默认为否,这个字段用开关来显示,请帮我完成这个需求"

spec_triage 把它判成 L1 原子操作,报告直接给出执行清单,一个问题都不问:

  • 改动文件:index.vue
  • 字段名:isMainAdmin
  • UI 组件:按"开关"推断为 el-switch
  • 默认值:否
  • 列表展示:默认不展示(保守方案,没说就不加)
  • 风格自举:先扫 index.vue 最近的表单代码,沿用现有写法

在 v0.1.0 里,同样是这条需求,模型会一口气连问 5 个问题——哪怕每个问题它自己都能推断出答案。这就是 L1 通道要治的病:该闭嘴干活时别装严谨。

L2、L3 则反过来:需求一句话说不清时(比如"帮我优化一下那个查询"),模型会先体检再有限追问——模块级改动最多 3 个问题、每题附带它推断的默认值(不答复就按默认执行);架构级重构才放开 Grill-me。追问前有硬性急停:不允许预扫工作区去"更懂业务",省 token 也省时间。

三个等级判据与响应的速查:

等级 什么算这类 插件怎么做
L1 原子操作 单文件 CRUD,字段/组件/默认值都明确;或消息含"直接做/速做/不用问/别问/不要问/极速模式" 不许追问,直接给执行清单 + 扫描目标文件风格自举,疑虑标 // TODO: [待确认]
L2 模块变更 模块级新增/调整,一句话推不全 最多 3 问,每题附推断默认值;不答复按默认执行
L3 架构重构 含架构/重构/拆分/迁移/升级/建表/跨文件/多模块 完整 Grill-me,问透为止

L1 还有一张"保守默认表"兜底:列表默认不展示新列、默认不加业务校验、默认后端接口已就绪——只有用户明确说要才会放开,宁可少做不瞎猜。


沉淀:不是每轮对话都要存

一开始我们担心两个方向:存太勤,模板库会被琐碎对话灌水;存太懒,真正值钱的套路又漏掉。现在沉淀由三层漏斗把关:

  1. 代码层硬门槛。 插件自己判断这个会话有没有"资格"沉淀:必须真实改过代码(有 edit/write 类工具调用),且工具调用次数达标。纯问答、只读诊断、一次性咨询——直接拦下,不提示、不打扰。
  2. 价值三问(留给模型自检)。 调用沉淀工具前过一遍:这做法下次还会用吗?结论跨项目成立吗?用户会反复提同类需求吗?任一为否就跳过。
  3. 任务链合并。 一条任务链只沉淀一次,中途的小修小补(改个编译错、修个警告)并进最终那份模板,不产生碎片。

模型判断失误漏了沉淀?兜底在 spec_recall:下次这个会话又提出编程需求时,插件会检查"上一轮明明改过代码却没沉淀",随召回结果提醒一句。你也可以随时主动说——"把这次沉淀成模板" 会无条件触发。

沉淀出来的模板是同名幂等的:同一类需求再次沉淀会覆盖更新旧模板而不是无限堆积。每份模板长这样(六个段落,沉淀和复用共用一套结构):

# Spring Boot 新增分页查询接口

分类:`feature/api` 标签:`java` `spring-boot`

## 触发场景
当用户要求新增支持分页的查询接口时适用。

## 需求澄清清单
- 分页参数用 pageNum/pageSize 还是 offset/limit?
- 返回 VO 是否包含关联表字段?

## 标准改法
1. XxxController 新增方法
2. XxxService 与 XxxServiceImpl 实现
3. Mapper XML 写查询 SQL

## 禁区
- 不要修改 common/Result.java 的返回结构

## 提示词模板
```text
按 Controller → Service → ServiceImpl → Mapper 四层实现……
```

## 验收标准
- [ ] mvn -q test 通过

完整示例见 templates/example-spring-pagination.md。

禁区会写进项目档案,不只是跟着模板走:每次会话识别到的"不能改",会累积到该仓库的 profile.md,此后所有同类需求自动注入,不用你反复交代。

存储是双层明文目录,项目层优先于全局层:

$DSH_HOME/spec-forge/
├── global/                      # 全局层:跨仓库通用的习惯
│   ├── templates/<id>.md
│   └── profile.md
└── projects/<repo-hash>/        # 项目层:按仓库路径哈希隔离
    ├── templates/<id>.md
    └── profile.md               # 该项目的禁区与约定

仓库哈希 = 工作目录路径归一化后的 sha256 前 12 位(Windows 路径同样适用)。所有落盘都是原子写(先 .tmp 再 rename),崩溃不会留下半个文件。

模板库也会旧。 spec_library 会统计超过 90 天未被命中的过期模板并列出名字——模板不是越多越好,旧模板会稀释召回精度。但它只报告不擅自动手,只有你明确说"清理过期模板"才会物理删除(删了不可恢复)。


召回:它怎么认出"这是同类需求"

spec_recall 收到需求后做三件事:把需求原文拆成加权指纹 → 和模板库里每一份比对打分 → 超过阈值就把最像的(默认最多 2 份,可配)连同项目禁区一起注入上下文。

打分是透明的,六个维度:

总分 = 0.62×词汇相似度 + 0.14×同分类 + 0.08×标签重叠
      + 0.08×同仓库 + 0.05×新鲜度 + 0.03×使用热度
词汇相似度 = 0.6×加权余弦 + 0.4×覆盖率
  • 词汇相似度是主项。 指纹按 token 加权:路径(4) > 技术词(3) > 标识符(2) > 中文 2-gram(1),"改 index.vue"比"有个页面"值钱得多。
  • 查询侧先聚焦再比。 用户需求常常很长(带路径、叙述、寒暄),fingerprint 默认取 24 个 token 里一多半是权重 1 的 2-gram,会稀释余弦与覆盖率。0.3.2 起查询指纹先削掉低信号尾巴(强 token 全保留 + 最多 8 个 2-gram)再进打分——同一条真实需求,聚焦前后词汇分差约 0.03~0.1,跨仓库(无同仓库加分)时这点余量就是命中与否的分界线。落盘模板的指纹保持完整不动。
  • 同分类按一级比。 模板的二级分类(如 feature/api 里的 api)由模型沉淀时自由填写、不可控,所以 feature/api 与 feature/pagination 视为同类。查询侧的分类和标签是插件从需求原文现推断的,不依赖模型自觉。
  • 标签重叠做了别名归一。 模板里存的是 a-switch,需求里写的是"开关",两边要能对得上——组件别名(a-switch→switch、element-plus→elementplus)、中英技术词("分页"→pagination)都会归一到同一把钥匙上;重叠率按"模板标签被查询覆盖的比例"算,模板标签都能在需求里找到说法就算高重叠。
  • 同仓库 + 新鲜度 + 热度是调节项。 本仓库沉淀过的模板优先;90 天半衰期衰减;命中越多越可信但用对数压平,避免马太效应。

阈值默认 0.35,matchThreshold 可调:调低更易命中(会引入误召回),调高更严格。实测分离度(用真实模板,非构造数据):

需求 得分 结果
同类:Vue 管理页加 isMainAdmin 开关字段 0.63 ✅ 命中
无关:node_modules 加 .gitignore + 写 README 0.11 ❌ 不命中

召回侧还有一处工程优化:模板列表在进程内带读缓存(写盘版本号 + 文件名集合双重失效),模板库到几百份时也不会每次召回都全量读盘解析。

诚实边界:这不是向量检索,是零依赖、零成本、可解释的关键词指纹。对"说法完全不同但语义相同"的需求召回有限——这是刻意取舍,调阈值只能缓解不能根治。


五个工具

工具 什么时候被调用 干什么
spec_recall 收到编程需求的第一件事 翻模板库,把命中模板的澄清清单/标准改法/验收标准 + 项目禁区注入上下文
spec_triage 召回之后 四维体检 + 定 L1/L2/L3。L1 出执行清单,L2 出≤3 问,L3 出完整 Grill-me
spec_distill 澄清完毕、动手之前 把需求 + 澄清答案 + 禁区蒸馏成一份实现提示词;禁区为空会拦下
spec_retro 任务收尾 把这次经验沉淀/更新成模板;digest 留空时自动从会话事件流提取摘要
spec_library 用户问"模板库里有什么" 展示数据目录、模板清单、命中统计、项目禁区、过期模板(可显式清理)

注入分三层,成本不同:

层次 机制 内容 成本
常驻 系统提示词 section 路由规则 + 等级响应 + 急停规则,约 400 token(0.3.2 精简自 600) 始终占用
按需 运行时 Skill 完整流程说明书(含三层漏斗决策) 用到才加载
执行 五个工具 上面这张表 调用才产生

安装

前置:dsh 可用、Node 22+、pnpm 在 PATH 上(dsh plugin 内部转发 pnpm,没装就 npm i -g pnpm)。

方式一(推荐,装正式发布):

dsh plugin --profile web add github:<你的账号>/dsh-spec-forge
dsh web   # 必须重启,插件才会组合进插件树

方式二(本地源码调试):插件里的裸导入(@deepseek-ai/dsh-tools 等)会从插件目录向上找 node_modules。已装过 dsh + pnpm 就直接用方式一;源码调试则把 node_modules/@deepseek-ai 指到 profile 的公共依赖目录(Windows 用 junction、macOS/Linux 用 ln -s),或用 --patch 叠加启动(Windows 下 patch 里的 name 必须写成 file:/// URL,裸盘符会报 ERR_UNSUPPORTED_ESM_URL_SCHEME)。本仓库 dev/ 下的 patch 含本机绝对路径、已被 .gitignore 排除,仅供本地调试。

验证装没装上:

dsh --profile web --dump-config | grep spec-forge

配置

在 profile 的 cordis.patch.yml 中调整,均有默认值:

配置 默认 说明
autoRecall true 是否注入常驻路由提示
autoRetro true 是否在任务完成后提示沉淀
matchThreshold 0.35 命中阈值,低更易命中、高更严格
maxInjectTemplates 2 单次最多注入几份模板
injectMaxChars 4000 注入上下文上限字符数
defaultScope project 沉淀默认落项目层还是全局层
retroMinToolCalls 2 自动复盘要求的最少工具调用数
retroRequireCodeChange true 沉淀提醒要求真实改过代码,纯问答/只读不提醒
strictDistill true 提炼时强制要求禁区,空则报错
storageHome 空 自定义数据目录,留空用 $DSH_HOME/spec-forge

验证

npm test          # 单元测试:138 个,覆盖指纹/匹配/会话提取/存储/渲染/分类器/沉淀门槛/读缓存/查询聚焦
npm run smoke     # 端到端冒烟:沉淀→召回→注入→体检→完成判定→幂等 整条链路
npm run verify    # 加载验证:mock ctx 执行 apply(),确认工具都能注册、schema 合规
npm run token-audit # 静态 token 预算审计:常驻/工具定义/SKILL/单次调用产出/真实库命中注入

冒烟的真实输出(可作验收基线):

1. 沉淀:一次任务结束后写入模板          [PASS] 模板已落盘
2. 召回:同类需求命中                    [PASS] 得分 0.499,命中次数已累加
3. 召回:异类需求不命中                  [PASS] 得分 0.136
4. 注入:禁区/澄清清单/标准改法进上下文  [PASS]
5. 体检:模糊需求被拦下要求澄清          [PASS] 缺失 要实现什么/哪些不能改/上下文
6. 完成判定:不做完的活不误判为完成      [PASS]
7. 幂等:同类需求再次沉淀是覆盖非堆积    [PASS] 仍 1 份

真实环境验收,装完之后可以照着试:

  1. 发一条简单 CRUD 需求(如"index.vue 加 isMainAdmin 字段,开关,默认 0"),观察是否直接动手不追问;
  2. 发一条含糊需求("帮我优化一下那个查询"),观察是否先体检再限问(≤3 问而非 5 问);
  3. 发一条完整需求(文件路径 + 禁区 + 验收命令),观察是否走完 召回→体检→提炼→实现→沉淀;
  4. 发一条带"直接做"的需求,观察是否无条件进 L1 快通道;
  5. 检查模板落盘:ls ~/.dsh/spec-forge/projects/<hash>/templates/;
  6. 再发一条同类需求,确认 spec_recall 召回刚沉淀的模板(模型会引用其中的澄清清单)。

它不做什么(已知边界)

  1. dsh 还是开发者预览版。 插件锁定的 API 面是 ctx.tools.register / systemPrompt / skills / exec.agent.session;0.3.0 起不再依赖 turn/end 事件(它不含会话事件流)。升级 dsh 后失效,先 --dump-config 排查再看 CHANGELOG。
  2. 匹配不是向量检索。 关键词指纹对"说法完全不同但语义相同"的需求召回有限,这是刻意的零依赖取舍。
  3. 沉淀时机有三层保障但非绝对。 代码层硬门槛 + 模型价值三问 + 任务链合并,理论上仍可能漏——漏了 spec_recall 会提醒,或直接说"把这次沉淀成模板"。
  4. "任务完整结束"是启发式判定,依据事件流结构判断,准但不敢说绝对可靠。
  5. 急停规则是提示词约束,不是硬拦截。 "提问前不许扫工作区"写死在模型可见的四层文本里,实测有效,但模型仍可能违背——等 dsh 出工具级前置钩子才能根治。
  6. 复杂度分级是启发式。 写得太短的需求("加个字段")会保守判 L2 而非 L1;生僻表述可能漏检,漏了回退 L2,不会默认 L1 瞎干。
  7. 插件与宿主同进程同权限。 它只读写 $DSH_HOME/spec-forge,不联网、不执行 shell、不读凭据;源码公开,装前可自行审查。

卸载

dsh plugin --profile web remove dsh-spec-forge
# 若声明了 dsh.bundle.patch,还需清理 profile 的 cordis.patch.yml 对应行
dsh web   # 重启生效

模板数据在插件目录之外,卸载不删沉淀。要彻底清空:rm -rf ~/.dsh/spec-forge

开发与发布

变更记录见 CHANGELOG.md。发布流程:改代码 → npm test → 升 package.json 版本 → CHANGELOG 顶部加条目 → 同步 README → commit & push → 在 profile 目录 env -u NODE_OPTIONS pnpm update dsh-spec-forge 刷新锁文件(pnpm-lock 会钉住 GitHub 依赖的提交 SHA,不改锁文件重装仍是旧代码)。

许可证

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 112acc209986

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