deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
一个 DeepSeek Harness(dsh)插件:把 Ponytail 搬进 dsh, 并加一个「需求配方召回」能力,让它记住每个项目里"这类需求上次是怎么做的",下次同类需求直接照做。
包名
dsh-spec-ponytail,运行时身份仍是ponytail:命令(ponytail lite/full/ultra、ponytail recipes)、 技能名(ponytail-review等)、常驻段(ponytail:ruleset)与数据目录(<cwd>/.dsh-ponytail/)全部保持不变, 避免破坏已安装版本与既有文档。只有插件包/仓库名改成了dsh-spec-ponytail。
它给每一轮请求装上一套懒惰阶梯:最好的代码是你从没写过的代码。
实测于
@deepseek-ai/dsh0.1.2-alpha.4(Windows + Web profile)。dsh 仍是 developer preview, 插件已锁定其 API 面(systemPrompt.section/skills.register/agent/pre-step);升级 dsh 后如失效,先看 CHANGELOG。
| 痛点 | 这个插件的做法 |
|---|---|
| Agent 装个日期选择器要引一个库、写两遍包装 | 阶梯第 4 级:<input type="date">,原生就有 |
| 「以后可能要扩展」的抽象没人用 | 阶梯第 1/2 级:先问要不要存在,再问能不能复用 |
| 需求是 10 行,回来是 200 行 | 最短可用 diff + 「skipped: X, add when Y」三行交代 |
| 为了少写代码把校验和安全一起砍了 | 安全底线写死在规则里:信任边界校验、防数据丢失、安全、无障碍永不在砍的范围内 |
| 刻意走的捷径过一阵就没人记得 | ponytail: 注释写明上限与升级触发条件,ponytail-debt 可随时收割成台账 |
① 常驻系统提示段 systemPrompt.section(text 是函数 → 每 step 重新渲染,随档位变化)
规则集一直在上下文里,且**一次都不用重复发送**
② 切档注入 agent/pre-step(只在用户真的切档那一步注入一次)
系统提示段在 pre-step 之前就组装完了,不补这一次,切档当步读到的还是旧档位
③ 八个 Skill skills.register(review / audit / debt / gain / verdicts / recall / help 按需加载)
完整说明不占常驻 token
为什么不用上游那套每轮推送:Claude Code 只有 UserPromptSubmit 一个注入口,所以上游每轮
把规则集重发一遍;dsh 有常驻段(且每 step 重新 assemble),一次注册就一直在,还能吃到
供应商侧的前缀缓存。这是阶梯第 4 级「原生功能优先」的直接应用。
| 档位 | 行为 |
|---|---|
| lite | 按需求做,但用一行点出更懒的替代方案,由你选 |
| full(默认) | 阶梯强制执行:标准库与原生优先,最短 diff、最短解释 |
| ultra | YAGNI 极端派:删除优先,先把一行版交出来,再在同一段话里质疑其余需求 |
| off | 常驻段整段消失,零注入 |
dsh 没有斜杠命令面,所以切换就是发一条独立成句的消息 —— 插件在请求发出前就解析并生效, 不经过模型理解,也不会被模型漏读:
| 你发 | 效果 |
|---|---|
ponytail lite / ponytail full / ponytail ultra |
切档 |
ponytail |
报告当前档位(若已 off,则按默认档位重新启用) |
ponytail off · stop ponytail · normal mode · 关闭 ponytail |
关掉 |
判据是整句锚定:ponytail ultra 是切档,帮我按 ponytail 的风格改一下 是普通正文,
ponytail-review(技能名)也不会被吞成指令 —— 三种情况都有单测守着。
默认档位解析顺序:持久化档位 > PONYTAIL_DEFAULT_MODE 环境变量 > 插件 defaultMode 配置 > full。
切过的档会记住。 每次切档都会把档位写进 <dsh 启动目录>/.dsh-ponytail/mode(一行档位名),所以:
process.cwd(),本机实测 = C:\Users\wen13\.qbot-dsh\home
—— 那是侧栏启动 dsh 的目录,不是会话工作区。所以它实际是跨工作区共享的:
在 A 项目切 ultra,B 项目也跟着 ultra。(0.2.0 文档里一度写成"按工作区隔离",是错的,已更正。)| Skill | 做什么 |
|---|---|
ponytail |
懒模式本体:完整阶梯、Rules、Output、Intensity、安全底线 |
ponytail-review |
只审「过度设计」:一行一条 L42: yagni: factory, one product. Inline.,结尾给 net: -N lines |
ponytail-audit |
全仓版的 review,按可删体量排序 |
ponytail-debt |
把全仓 ponytail: 注释收成债务台账,标出没有升级触发的那些(会静默腐烂的那批) |
ponytail-gain |
上游 agentic 基准的记分板(明确禁止编造「你这个仓库省了多少」) |
ponytail-verdicts |
项目的简化裁决台账:什么不能砍 + 为什么;评审前读、评审后记 |
ponytail-recall |
需求配方召回:把「这类需求上次怎么做的」(做法 + 禁区)沉淀为配方,同类需求自动召回 |
ponytail-help |
速查卡:档位、技能、怎么切、怎么配默认档 |
让相似需求快速响应:把「这类需求上次怎么做的」沉淀成一份三要素配方(触发 / 做法 / 禁区), 下次同类需求由插件自动召回注入,实现就从已验证的改法开头,而不是从零推导。
<会话工作目录>/.dsh-ponytail/recipes.md(每个项目一份,与 verdicts.md 同构):## Spring 分页查询接口
触发:分页 查询接口 列表翻页
做法:
- 四层:Controller → Service → ServiceImpl → Mapper
禁区:
- common/Result.java 是全局契约,别改
ponytail recipes 注入整个配方库(空库也会说明格式)。recipes.md 追加一条
(沿用 ## 名称 + 触发:… 结构)。见 ponytail-recall Skill。npm run token-audit 实测)| 项 | 字符 | 粗估 token |
|---|---|---|
| 常驻段 · full | 2103 | ≈ 526 |
| 常驻段 · ultra | 2143 | ≈ 536 |
| 常驻段 · off | 0 | 0 |
| 切档注入(只在切档那一步,一次) | 2203 | ≈ 551 |
| 报告档位注入 | 79 | ≈ 20 |
诚实边界:526 token/step 是每个 step 的固定税,会叠加在宿主自身已有的系统提示上。三点缓解:
off 档下常驻段整段消失,是真正的 0;觉得太贵就 ponytail lite 或 /ponytail off;要改规则集文本,见 lib/ruleset.js(上限由
tests/ruleset.test.js 守着,超 2200 字符直接测试失败)。
前置:dsh 可用、Node 22+。
dsh plugin --profile web add github:winston-hoo/dsh-spec-ponytail
dsh web # 必须重启,插件才会组合进插件树
本地源码调试(--patch 加载,注意 Windows 要 file:/// 形式):
node apps/cli/lib/bin.js --profile headless \
--patch D:/HBuilderProjects/DSH/dsh-spec-ponytail/dev/ponytail.patch.yml "你的任务"
验证装上了(--dump-config 只合成插件树、不启动服务,是排障第一招):
pnpm dsh --profile web --dump-config | Select-String ponytail
出现 # == dsh-spec-ponytail 段即成功。
skipped: … 三行交代ponytail ultra → 当步就收到 Level → **ultra**,之后行为更激进ponytail → 回一句 [ponytail] Current level: **full**(这句话只可能由本插件的 pre-step 处理器产生,是最省事的一键验收)—— ✅ 已实测通过关闭 ponytail → 常驻段消失(行为回到常规)# ponytail: <上限>, <升级触发>ponytail-debt → 上面那个标记被收进台账<dsh 启动目录>/.dsh-ponytail/mode(本机 = C:\Users\wen13\.qbot-dsh\home\.dsh-ponytail\mode)→ 里面就是刚才那个档位名;重启 dsh 后档位不变pnpm add 返回 layers added: dsh-spec-ponytail / activation: applied,profile 的
dsh.profile.bundles 里出现 dsh-spec-ponytail;patchReload: live —— skill 目录当场就变(八个 ponytail 技能出现在会话里,无需重启);PONYTAIL MODE ACTIVE — level: full 段,措辞与本插件
lib/ruleset.js 一致;已排查 app 包、agent presets、DSH home、其它工程,全机器没有第二个
PONYTAIL MODE ACTIVE 注入源 —— 这一段只能来自本插件。⚠️
file:安装是复制一份到 profile(不是软链)。改了源码要重新刷新才生效: 在 profile 目录执行pnpm update dsh-spec-ponytail(或再走一次dsh plugin add)。 日常开发用dev/ponytail.patch.yml走--patch加载,那条路径才是直接读源码。
npm test # node --test,85 条
npm run token-audit
本地跑测试需要能解析 @deepseek-ai/schemastery(宿主在运行时提供)。仓库里用一条
junction 指向 harness checkout 的 vendor/schemastery 即可(node_modules/ 已 gitignore):
New-Item -ItemType Junction -Path node_modules\@deepseek-ai\schemastery `
-Target D:\HBuilderProjects\DSH\deepseek-harness\vendor\schemastery
沙箱内注意:
node --test会 spawn 子进程(管道 stdio 会被拒为 EPERM),逐文件跑即可:node tests/mode.test.js; node tests/ruleset.test.js; node tests/store.test.js; node tests/verdicts.test.js; node tests/plugin.test.js; node tests/recipes.test.js。
systemPrompt.section / skills.register / agent/pre-step;升级 dsh 后失效先 --dump-config。process.cwd(),本机实测为 C:\Users\wen13\.qbot-dsh\home(侧栏启动 dsh 的目录),不是会话工作区 —— 因此跨工作区共享,同一 dsh 进程里的多个会话也共享一个档位。要真按工作区隔离,得改用 agent.session.cwd 并在常驻段渲染时按会话解析(多一次磁盘读或一层缓存);没做。写入失败(目录不可写)只告警,本轮切档照常生效,只是重启后不保留。ponytail 一律当正文,不会被吞 —— 这是刻意的取舍(宁可漏切,不可误吞需求)。tests/ruleset.test.js 守着压缩版的七级阶梯与安全底线不丢项,但守不住措辞分叉。PONYTAIL_SUBAGENT_MATCHER 在我们的机制下没有存在必要(阶梯第 1 级)。ponytail-gain 的数字是上游基准,不是本仓库实测;该 Skill 明确禁止把基准说成「你这个仓库省了多少」。skills/ 目录、不联网、不执行 shell、不读写你的项目文件。源码公开,装前可自行审查。dsh plugin --profile web remove dsh-spec-ponytail
# 若声明了 dsh.bundle.patch,还需清理 profile 的 cordis.patch.yml 对应行
dsh web # 重启生效
卸载会移除插件与常驻段;<dsh 启动目录>/.dsh-ponytail/mode 与各项目
<会话工作目录>/.dsh-ponytail/(verdicts / recipes)是你自己的记忆文件,留着不影响、删了干净。
Q:这个插件会不会像「开票催办」事故那样,把文档标可选但承担功能的参数偷偷砍掉,或点击直接调接口、连二次确认都没有?
A:上游 ponytail 只声明「别砍校验 / 防数据丢失 / 安全 / 无障碍」这一类安全底线,并不覆盖「功能性的可选参数」和「不可逆 / 对外的写操作须确认」,所以这类"曲解偷懒"它兜不住。本插件 0.3.2 把这两条写死进常驻段(每回合都生效,见 lib/ruleset.js 的 ## Never lazy about):
optional,只要当前流程用它就必须传(remark / reason 不是装饰),不得因为 schema 允许空值就把唯一业务参数当装饰砍掉。@click 直连接口。判据 = "能撤吗?会波及第三方吗?"——沾一条就确认。完整来龙去脉见 CHANGELOG.md 的 0.3.2 条目。
本插件是 Ponytail 的 DeepSeek Harness 插件化改造,遵循上游的 MIT 开源协议:
ponytail / -review / -audit / -debt / -gain / -help)移植自上游;
逐项差异见 NOTICE。ponytail-verdicts / ponytail-recall 为本插件自有能力,未移植。LICENSE;MIT 许可文本随 LICENSE 一并保留。CHANGELOG.md —— 逐版本变更记录docs/design.md —— 三层注入契约、档位模型、改动规则集时要同步的四处lib/ruleset.js —— 模型看到的全部规则文本(唯一事实来源)CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。