限制单步思考字数,强制模型及时给出可见结论
29.7/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/9/29 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add superSizzzz/dsh-think-budget该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:待复验
是什么
dsh 原生插件 · skill
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 35 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件
查看扫描证据(共 2 处,展示前 2 条)
- 写入本地文件lib/index.js:221
mkdirSync(dirname(logPath), { recursive: true }); - 写入本地文件lib/index.js:224
appendFileSync(logPath, `${JSON.stringify(entry)}\n`, 'utf8');
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-llm@deepseek-ai/schemastery给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 限制单步思考字数
- 无结论时强制先给结论
DeepSeek Harness 插件:给单步思考一个字数预算,连续几步没有可见结论时强制先给结论再继续
README
由 DeepSeek 最新模型翻译生成dsh-think-budget —— 思考节拍器
管住 dsh「闷头想很久、屏幕上一直不出现正文」这件事:给单步思考一个字数预算,并且要求它在若干步之内必须写出一条可见结论,然后才能继续。
插件本身没有任何新工具、新服务、新 UI。它只做两件事:往系统提示里写一段规则,以及在模型越界时往会话里塞一条提醒。
装它
dsh plugin --profile web add github:superSizzzz/dsh-think-budget
一条命令,装完即生效 —— dsh 会读包里的 dsh.bundle.patch 自动并入 profile。
卸载:dsh plugin --profile web remove dsh-think-budget。
换 --profile 后面的名字就能装到别的 profile,每个 profile 各装一次。
| 项 | 要求 |
| dsh | ≥ 0.1.7-rc.2 |
| Node | ≥ 22.6 |
| profile | 不限 —— web / tui / headless 都能装,插件不碰任何 web 专属能力 |
| 模型 | 不限 —— 只有会产出 reasoning 的路由才会触发「思考超预算」那条规则 |
想改源码、让改动立刻热重载,见下面《装上》里的方式二。
展开完整文档(README 剩余 1 节)
dsh-think-budget —— 思考节拍器
管住 dsh「闷头想很久、屏幕上一直不出现正文」这件事:给单步思考一个字数预算,并且要求它在若干步之内必须写出一条可见结论,然后才能继续。
插件本身没有任何新工具、新服务、新 UI。它只做两件事:往系统提示里写一段规则,以及在模型越界时往会话里塞一条提醒。
装它
dsh plugin --profile web add github:superSizzzz/dsh-think-budget
一条命令,装完即生效 —— dsh 会读包里的 dsh.bundle.patch 自动并入 profile。
卸载:dsh plugin --profile web remove dsh-think-budget。
换 --profile 后面的名字就能装到别的 profile,每个 profile 各装一次。
| 项 | 要求 |
| dsh | ≥ 0.1.7-rc.2 |
| Node | ≥ 22.6 |
| profile | 不限 —— web / tui / headless 都能装,插件不碰任何 web 专属能力 |
| 模型 | 不限 —— 只有会产出 reasoning 的路由才会触发「思考超预算」那条规则 |
想改源码、让改动立刻热重载,见下面《装上》里的方式二。
它管的是什么
观察到的现象:一次提问之后,模型连着跑了十来步 —— 每一步都在思考、都在调工具 —— 但对话里一个字都没多出来。用户看不出它是在推进还是卡住了。
判据只有一条,都在明面上:
- 一次「回复」= 一步 = 一次成功的模型调用(一个提交进会话的 assistant/message)。失败的尝试、被取消的流不算。
- 「结论」= 这一步的可见正文,去掉空白后长度 ≥ minConclusionChars。
思考(reasoning)不算 —— 用户看不见它,它就不是交付物。
- 连续 maxStepsWithoutConclusion 步没有结论,或者单步思考超过 maxReasoningCharsPerStep 字且这一步没结论,就出手。
两层机制
预防层 —— 往系统提示注册一段「思考节拍」:
思考节拍
- 思考(reasoning)是内部草稿,用户看不到;正文才是交付物。不要把结论留在思考里。
- 每 3 次回复之内,至少写一次可见正文结论 —— 阶段判断也算,「目前还不确定,因为…」也算。
- 单次思考控制在约 4000 字以内。一件事推演到能下判断就够了,不要反复重推同一个问题。
- 先给结论,再继续调用工具;需要长任务时,用阶段结论代替沉默。
模型一开始就配合,比事后纠正省事得多。关掉它(systemPromptSection: false)就只剩补救层。
补救层 —— 越界时注入一条模型可见的提醒:
【思考节拍】你最近连续 3 次回复都没有写正文,只有思考和工具调用。
现在请立即用正文写出你目前的结论 —— 可以很短、可以不完整、可以是「还不确定,因为…」,但必须写出来。
写完之后如果还需要继续,再继续调用工具。
这条消息走 agent.inject(),是一等公民的 user 消息:有 id、有自己的来源 kind(think-budget)、会进会话日志、在 UI 里有折叠摘要。它不是注释、不是旁路 —— 模型像读任何一条用户消息那样读它。
文案刻意给退路:「还不确定」也算结论。只逼「必须写点什么」、不逼「必须想明白」,否则模型为了凑结论会编一个假答案 —— 那是这类插件最容易帮倒忙的地方。
能力边界
它拦不住正在生成的思考流。
reasoning 由模型端产出、经由流式协议送达 harness。harness 收的时候那些 token 已经产生了。所以「限制思考长度」在这里的落地方式是:
- 越界 → 下一轮施压(提醒注入);
- 可选硬手段:越界 → 该步请求换一个更低的推理强度(downgradeReasoningEffort,默认关闭)。
「到点掐断正在生成的思考」这件事,插件层做不到。唯一真正的硬开关是推理强度,而它是按请求设置的,只能在每一步开始前决定。
另外三点也如实说:
- 不取消轮次、不拒绝步骤、不改消息内容。 插件只往会话里加消息。想强制停止失控轮次是另一个插件的活(agent/turn-stopping 那条路)。
- 恢复的会话从零开始计数。 账本只在内存里,是从流里现数的。恢复一个压缩过的会话不会把历史 reasoning 重算一遍。
- 降档是唯一有副作用的开关。 填了模型不支持的档位,会让这次请求以 UNSUPPORTED_REASONING_EFFORT 失败。所以默认关,且只在连续无结论到阈值(模型明显陷进去了)时才用。
装上
有两种装法。二选一,不要同时用 —— 两种挂出来的补丁条目 id 相同,同时存在会让插件被加载两次,每条提醒发两遍。
方式一:用 dsh 的插件管理器(推荐)
dsh plugin --profile web add github:superSizzzz/dsh-think-budget
一条命令,不用手写任何配置。dsh 会从 GitHub 拉下这个包、读它在 package.json 里声明的 dsh.bundle.patch,把包自带的补丁并入 profile —— 插件当场生效。
卸载:
dsh plugin --profile web remove dsh-think-budget
要改配置,就往该 profile 的补丁文件里补一条覆盖(~/.dsh/profiles/web/cordis.patch.yml):
- id: think-budget
config:
maxStepsWithoutConclusion: 5
只写你想改的字段,没写的回落到插件默认值。
为什么它能这么装:包的 package.json 声明了 dsh.bundle.patch,且入口指向编译产物 lib/index.js。Node 的类型擦除明确拒绝 node_modules 里的 .ts (ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING),所以凡走包名加载的插件都必须提供 .js。
方式二:源码 checkout(想改代码用这个)挂的是 src/index.ts,靠 Node 的类型擦除,改完保存即热重载,不用编译。
插件不自己装依赖 —— @deepseek-ai/ 由 dsh 提供,这里只声明 peerDependencies。所以 clone 之后要把依赖接过去,再挂进 dsh 的补丁层。
1) 放到你想放的位置
git clone https://github.com/superSizzzz/dsh-think-budget.git D:\plugins\dsh-think-budget
2) 接依赖(在插件目录下建一个指向 dsh 依赖目录的 junction)
cd D:\plugins\dsh-think-budget
node scripts/link-deps.mjs
3) 挂载 —— 见下面的 patch 段
- insert:
- id: think-budget
name: 'file:///D:/plugins/dsh-think-budget/src/index.ts' # ← 上一步打印出来的那行 config: enabled: true maxReasoningCharsPerStep: 4000 maxStepsWithoutConclusion: 3
粘到哪个文件,决定管多大范围:
| 文件 | 作用范围 |
| ~/.dsh/profiles/web/cordis.patch.yml | 只管 web profile |
| ~/.dsh/cordis.patch.yml | home 层,对所有 profile 生效 |
追加到末尾即可,别覆盖文件里原有的条目 —— 这是个 insert 补丁,跟已有内容共存。
dsh 的 profile 默认开着 patchReload: live,保存即热重载,不用重启。
想先试一次、不碰任何 profile 文件,仓库里备了一份现成的补丁层(把里面的换成你的实际目录):
dsh web --patch /cordis.think-budget.yml
它要什么权限
没有网络请求,不执行命令,不加新工具,不改写你的消息。全部动作都落在 dsh 现有的事件面上:
| 动作 | 具体是什么 | 怎么关 |
| 读 | 数流里的分片长度(agent/assistant-stream 的 text / reasoning delta) | enabled: false |
| 写 | 往会话注入一条 user 消息(agent.inject) | enabled: false |
| 改 | 注册一段系统提示(systemPrompt.section) | systemPromptSection: false |
| 改 | 改写单步请求的推理强度(agent/request waterfall) | 默认就关(downgradeReasoningEffort 留空) |
| 文件 | 往 logPath 追加一行 JSONL | 默认就关(logPath 留空) |
会碰磁盘的只有 logPath 那一项,而且默认关闭。
它工作起来是什么样
下面这行是插件自己记的账(logPath 打开时写的那一行),来自一次真实对话:模型连续 3 步只思考和调工具、正文 0 字,插件随即注入了一条要求先给结论的提醒。
{"at":"2026-09-26T09:15:30.056Z","sessionId":"session-befa…","kind":"no-conclusion-streak","streak":3,"reasoningChars":1840,"visibleChars":0,"toolCalls":2}
同一场对话稍后触发了另一条规则(单步思考超预算)—— 这次它要的是「先写一句判断再继续」:
{"at":"2026-09-26T09:43:38.767Z","sessionId":"session-befa…","kind":"reasoning-over-budget","streak":1,"reasoningChars":4432,"visibleChars":0,"toolCalls":2}
两次都当场见效:模型的下一条回复就带上了正文。
让 AI agent 帮你装
下面这段可以直接粘给任何能操作你机器的 AI agent(Claude Code、Cursor,或者另一个
dsh 都行)。它是自包含的,不用再补上下文。
帮我把 dsh-think-budget 这个 dsh 插件装到本机。
仓库:https://github.com/superSizzzz/dsh-think-budget
它是什么:给 dsh 的单步思考一个字数预算,连续几步没有输出可见结论时,往会话里注入一条提醒,要求先给结论再继续。插件只做两件事 —— 往系统提示加一段规则、往会话注入提醒 —— 不加新工具、不改消息内容。
首选做法(一条命令,不用手写任何配置):
dsh plugin --profile web add github:superSizzzz/dsh-think-budget
dsh 会读包里的 dsh.bundle.patch 自动并入 profile。想确认装上了,就往
~/.dsh/profiles/web/cordis.patch.yml 末尾追加一段覆盖,加上 logPath: '/events.jsonl',再看那个文件有没有出现 {"event":"applied", ...} 这一行。卸载:dsh plugin --profile web remove dsh-think-budget。
上面那条走不通时(网络或 pnpm 问题),改用下面的源码方式。
步骤:
1. clone 到一个你选定的插件目录,例如 D:\plugins\dsh-think-budget。
2. 进那个目录跑 node scripts/link-deps.mjs --patch。它会在目录里建一个指向 dsh 依赖目录的 node_modules junction(不做这步,插件 import @deepseek-ai/ 会失败),然后把一份路径已经填好的 patch 片段打印出来。
3. 把打印出来的 - insert: 段追加到下面哪个文件的末尾,由你决定范围: ~/.dsh/cordis.patch.yml → home 层,所有 profile 生效 ~/.dsh/profiles/web/cordis.patch.yml → 只管 web profile 注意是追加到末尾那个 YAML 数组里,不要覆盖原有的插件条目。
4. 验证:dsh 的 profile 默认 patchReload: live,保存即热重载。想确认装载成功,在那段 config 里加一行 logPath: '/events.jsonl',再看那个文件里有
没有出现 {"event":"applied", ...} 这一行。
注意:
- 这是个 insert 补丁,跟补丁文件里已有的内容共存,别动别人的条目。
- 插件目录下必须存在 node_modules(第 2 步建的),否则加载会失败。
- 装完不需要重启 dsh;热重载没起来的话再重启。
- 想临时停手:把 config 里的 enabled 改成 false。彻底卸掉:删掉那个 insert 块。
- 默认阈值是「连续 3 步无结论」和「单步思考 4000 字」。嫌管得碎就调大到 5 / 8000。
卸掉
从 cordis.patch.yml 删掉那个 insert 块(或把 enabled 改成 false 保留代码但停手)。插件没写任何持久状态,删掉就是删掉。
配置
配置就写在那段 patch 的 config: 里 —— 没有独立配置文件,也没有设置界面。
改完保存即可:热重载会重新校验配置、重建监听器;字段填错会在重载时报清晰的错误,不会静默退回默认值。
- insert:
- id: think-budget
name: 'file:////src/index.ts'
config:
↓ 要调的就是这一段 enabled: true maxReasoningCharsPerStep: 4000 maxStepsWithoutConclusion: 3
| 字段 | 默认值 | 含义 |
| enabled | true | 总开关。false 时一个监听器都不装 |
| maxReasoningCharsPerStep | 4000 | 单步思考字符预算;只在「这一步没结论」时算数。0 关掉这一项 |
| maxStepsWithoutConclusion | 3 | 连续多少步没结论就强制要一条。0 关掉这一项 |
| minConclusionChars | 12 | 去空白后多长算「结论」。挡住「让我看看」这类过渡语 |
| cooldownSteps | 2 | 同一种提醒两次之间的最小步数间隔 |
| maxRemindersPerTurn | 5 | 单轮提醒条数上限;到顶就闭嘴等下一条用户消息 |
| includeSubagents | true | 是否也管子 agent。false 时只盯顶层 agent |
| systemPromptSection | true | 是否注册系统提示里的「思考节拍」段落 |
| downgradeReasoningEffort | '' | 越界时的推理强度降档值。空 = 不用(推荐保持空) |
| reminderTag | 思考节拍 | 提醒文案里方括号里的标签 |
| logPath | '' | 事件日志(JSONL)。空 = 不记 |
想更严:maxStepsWithoutConclusion: 2、maxReasoningCharsPerStep: 2500。
想更松:maxStepsWithoutConclusion: 5、maxReasoningCharsPerStep: 8000。
怎么确认它真的生效
配置里加一行 logPath: '/events.jsonl' 并保存。那个文件会立刻出现一行:
{"at":"2026-01-01T00:00:00.000Z","event":"applied","node":"v26.5.0","headless":false,"config":{"maxReasoningCharsPerStep":4000,...}}
config 里就是这次实际生效的值。有这一行 = 插件被加载了、配置也读进去了。
之后每次出手还会往同一个文件追加记录(格式见下面的《排查》)。
一行都没有 = 插件没被加载,回去检查 patch 里 name 那个路径。
开发
源码是 src/.ts,两种加载方式各取所需:
- src/index.ts 直接加载(方式二):零构建,改完保存即热重载。
- lib/.js 编译产物(方式一):给包名加载用 —— Node 拒绝擦除 node_modules 里的 .ts。产物随仓库提交,所以安装端不用装 TypeScript。
node scripts/link-deps.mjs # 首次 clone 后接一次依赖
npm test # 跑两个测试文件
npm run typecheck # 只做类型检查,不产出
npm run build # 改了 src/ 之后重建 lib/
tsconfig.json 开了 rewriteRelativeImportExtensions:源码里的相对导入必须带 .ts 扩展名(类型擦除的要求),编译时会被改写成 .js,一份源码同时服务两种加载方式。同样因为类型擦除,源码里要避开需要转译的语法(enum、参数属性、装饰器)。
改了 src/ 记得跑一次 npm run build 并提交 lib/ —— 否则
dsh plugin add 装出来的还是旧产物。
测试
两个测试都是直跑,不需要起 dsh、不花额度:
npm test # 两个一起跑
node test/tracker.test.mjs # 判定规则的 43 项断言
node test/plugin.smoke.mjs # 装配与注入链路的 34 项断言
tracker.test.mjs 钉的是智力:什么算结论、什么时候出声、冷却和配额怎么算、新一轮怎么清账、关掉的项真的不触发。
plugin.smoke.mjs 钉的是接线:apply 不抛错、事件名注册得上、流里的字数被正确累计、越界时真的调了 agent.inject()、注入的是一份 harness 收得下的完整 user 消息。用的是假 ctx 和假 agent。
想再验一层「dsh 的 loader 到底认不认它」,起一个不占 3080 的隔离实例:
dsh --profile web --patch \test\verify-load.yml --port 3199 --no-open
verify-load.yml 会先把飞书桥关掉(验证过程不该往真实飞书发消息),再把装载留痕写进 test/.verify-applied.jsonl。文件里出现带 "event":"applied" 的行,就说明 loader 解析了 file:// 路径、import 了 .ts、校过 config、调到了 apply。验证完把那个实例关掉即可。
排查
在配置里打开 logPath,每次注入提醒会追加一行 JSONL:
{"at":"2026-01-01T00:00:00.000Z","sessionId":"main-session-...","kind":"no-conclusion-streak","streak":3,"reasoningChars":1284,"visibleChars":0,"toolCalls":2}
有行 = 插件在管事、模型确实越界了。一行都没有 = 模型这段时间表现没问题,或者阈值太松(调小 maxStepsWithoutConclusion 试试)。
实现地图
| 文件 | 职责 |
| src/index.ts | 插件入口:装配监听器、累计流、投递提醒、注册系统提示 |
| src/tracker.ts | 账本与判定规则。纯逻辑,不碰任何服务 |
| src/policy.ts | 所有对模型说的话(系统提示段落、提醒正文、摘要) |
| src/config.ts | schemastery 配置 schema 与归一化 |
| scripts/link-deps.mjs | 把 node_modules 链到 dsh 的依赖目录 |
| cordis.patch.yml | 包自带的补丁层,dsh plugin add 装完自动应用 |
| cordis.think-budget.yml | 本地 checkout 用的补丁层,--patch 直接用 |
| tsconfig.json | 编译配置:src/.ts → lib/.js |
| lib/ | 编译产物(随仓库提交,安装端不用装构建工具链) |
| test/tracker.test.mjs | 判定规则测试 |
| test/plugin.smoke.mjs | 装配链路测试 |
| test/verify-load.yml | 隔离实例验证用的补丁层 |
它依赖的 harness 接口
全部来自 dsh 0.1.7-rc.2 的公开事件面,没有碰包内实现:
| 接口 | 用途 |
| agent/assistant-stream | 逐片读流的 text-delta / reasoning-delta,累积出「这一步思考多长、写了多少正文」 |
| agent.inject(UserMessage) | 把提醒投进模型看得见的地方 |
| agent/request waterfall | 可选:改写这一步的 reasoningEffort |
| systemPrompt.section() | 注册「思考节拍」系统提示段落 |
| createUserMessage() / MessageSourceMap | 造一条合法消息,并声明自己的来源 kind |
许可
MIT,见 LICENSE。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
superSizzzz/dsh-think-budget
限制单步思考字数,强制模型及时给出可见结论
相关插件 · 技能 / 提示词
人设统管ZiChuanLan/agent-purge
一份系统提示词,喂给多个 coding…
★ 931已汉化DSH
73.8
人物画像蒸馏titanwings/distilly
Distilly — 把他们的思考方式提炼成可复用的技能,供任何智能体或机器人使用。原名 Colleague Skill(原同事 Skill)。
★ 25,659已汉化DSH
71.3
推理工作空间套件Tiger3807861189/J-Space-Cognition-Suite
J-Space 是面向复杂推理、大型仓库工程、子代理协作与授权安全分析的推理时工作空间和控制套件。
★ 2,957已汉化DSH
70.5
两阶段工具锚定预设xiaobright/dsh-anchored-standard
实验性 DeepSeek Harness agent preset…
★ 3,742已汉化DSH
70.1
智能体工作流编排nrslib/takt
不再日夜盯着 AI 编码智能体。
★ 1,402已汉化DSH
70
Agent 运行时手册Electricitysheep/dsh-handbook
DeepSeek Harness dsh 从 0 到 1 深度手册:安装/插件开发/性能调优/实测案例/同模型多…
★ 827已汉化DSH
68.7