dsh-think-chinese
让 DeepSeek Harness 的模型始终用中文思考和推理,并用中文回答的一个组合包(bundle)插件。
它向系统提示词注册两段语言要求,模型每一步都会读到它们。这是受支持的引导方式:Harness 没有单独的「推理语言」「输出语言」字段,能改的、也真正生效的就是系统提示词。
装好并重启后,渲染出的系统提示词会变成这样(... 处是 Harness 自己的第一方指导与工具说明):
You are an AI agent powered by DeepSeek Harness.
语言约束:内部推理与面向用户的全部输出都必须使用中文;代码、命令、文件路径、标识符和报错原文保持原样。除用户明确要求改用其他语言外,这条要求优先于任何语言、风格或格式上的默认习惯。
...
## 语言要求(思考使用中文)
### 思考
你的内部推理与思考过程(thinking / reasoning 内容)必须始终使用中文书写。
无论用户使用什么语言提问,也无论工具输出、报错信息、代码、日志或参考资料是什么语言,思考过程一律使用中文。
代码、命令、文件路径、标识符、API 名称和报错原文保持原样,不要为了让内容变成中文而改写或翻译它们。
### 输出(强制使用中文)
面向用户的全部可见文本都必须使用中文:正文、标题、列表、表格、总结、计划、进度说明、提问与确认,一个都不能例外。
不要先写其他语言的版本再补一段中文翻译,也不要双语对照;从第一个字起就用中文写。
专有名词、库名、协议名保留官方写法,可以夹在中文句子里,不要音译或自造译名。
即使工具输出、外部文档或上下文使用其他语言,回答仍然使用中文。
只有用户明确要求改用其他语言时才切换。
回答发出前自检:如果最终文本里出现成句的其他语言,先改写成中文再发出。
拿不准某个术语怎么译时,保留原文并在中文里附一句说明,不要整句改用其他语言。
为什么是这样实现的
- 新增独立段落,不占用 persona 槽位。
@deepseek-ai/dsh-system-prompt无条件注册deployment:persona-prefix与deployment:persona-suffix;本插件注册的是自己的deployment:reasoning-language与deployment:language-anchor,因此可以和部署人设共存,也可以单独启停。 - 一处要求,两个位置。 详细要求在最后(order
10250,位于所有第一方段落之后),一句话的锚点在开头(order10,紧跟 persona 前缀)。同一条语言约束在提示词首尾各出现一次,是让它真正被遵守的最省事办法;不想要锚点时设frontAnchor: false。 - 零依赖、零
peerDependencies。 整个插件只 import 自身,不解析任何其他包,因此不存在版本兼容门槛,也不会被启动器的模块回退(module fallback)机制影响。 - 不导出
Config。 Cordis 在插件没有 schema 时会把行上的config原样传入,所以本插件自己校验并补默认值,报错信息直接点名问题字段。 - 默认
interpolate: false。 段落文本默认不参与{{变量}}插值;否则文本里一个未注册的{{name}}会让整个系统提示词组装失败。本插件的文本是字面文案,选择退出插值最安全。 - 输出要求写得「啰嗦」是有意的。 模型漂移时最先失守的是标题、列表、表格、总结这类短文本,而不是正文,所以输出段落把这几个面逐个点名,并显式禁掉「先英文再补中文翻译」和「中英对照」这两种最常见的折中写法。
安装
方式一:应用内插件页(推荐,官方路径)
打开侧边栏的插件页,用「安装/添加组合包」输入本包的绝对路径:
D:\AI\deepseek-harness插件\dsh-think-chinese
由应用自己执行 pnpm 安装并同步 dsh.profile.bundles,profile 的 package.json、锁文件、node_modules 三者保持一致。安装完按提示重启应用。
方式二:install.ps1(离线、纯增量,不需要 pnpm)
powershell -ExecutionPolicy Bypass -File install.ps1 -WhatIfOnly # 先看计划
powershell -ExecutionPolicy Bypass -File install.ps1 # 装入 desktop profile
它做三件事,全部是增量的,不会删除 profile 里已有的任何东西:
- 把包复制到
<profile>\plugins\dsh-think-chinese - 建立
<profile>\node_modules\dsh-think-chinese目录联接(junction)指向它,等价于 pnpm 的link:依赖 - 在 profile 的
package.json中登记依赖"dsh-think-chinese": "link:./plugins/dsh-think-chinese",并把dsh-think-chinese追加到dsh.profile.bundles
改写 package.json 前会自动备份为 package.json.bak-<时间戳>。用 -Profile <名字> 可以装到别的 profile。重复执行是幂等的,也可以用它把改动同步到已装的副本。
方式三:官方 CLI(需要先完全退出桌面版)
& "D:\AI\deepseek-harness\resources\runtime\cli\bin\dsh.cmd" plugin --profile desktop add "D:\AI\deepseek-harness插件\dsh-think-chinese"
桌面版 profile 由应用托管,dsh plugin --profile desktop 要求应用已退出,否则可能在应用占用文件时改动 node_modules。
生效时机
- 新增或移除组合包 → 必须重启。桌面版在启动时读取
dsh.profile.bundles,ResolutionRouter.replace明确要求进程重启。当前会话可以在重启后用「恢复会话」继续。- 例外:插件页的启用/停用开关会顺手做一次 patch 重载,所以停用能立刻生效(系统提示词马上少掉这两段),重新启用同样立刻生效。
- 只改
config→ 不需要重启。base 组合包以root: []启用 HMR,只保留配置监听:改cordis.patch.yml(或组合包自己的cordis.patch.yml)会热生效(chokidar 默认 2 秒写入稳定窗口)。 - 改插件源码
lib/index.js→ 需要重启,或先按@deepseek-ai/dsh-hmr的说明把hmr条目的config.root配成["."]开启模块监听。
别在插件页里把它停用
插件页的开关对应 plugin_manager 服务的 setBundleEnabled:停用只会把名字从 dsh.profile.bundles 里删掉,依赖仍然保留("关闭保留依赖"),所以看起来"还装着"其实已经不生效了。停用后系统提示词会立刻恢复原样。想临时关掉、又不想动插件页,用 cordis.patch.yml 里的 disabled: true 更直观。重新启用直接用 install.ps1 再跑一次(幂等)或插件页的开关。
配置
行 id 是 think-chinese,组合包自带的 cordis.patch.yml 已经写入这份部署的默认值(reply: true + 自检补充)。要改就在 profile 自己的 cordis.patch.yml 里按 id 覆盖(注意:patch 里的 config 会整体替换组合包那一层的 config,缺的字段由插件补默认值):
- id: think-chinese
name: 'dsh-think-chinese'
config:
reply: true
extra: 先给结论,再给依据。
| 字段 | 默认值 | 含义 |
|---|---|---|
sectionName |
deployment:reasoning-language |
详细段落的段落名,也是注册表里的唯一键 |
order |
10250 |
详细段落的排序值;大于 10200(persona 后缀)即排在最后 |
language |
中文 |
要求的语言 |
reply |
false |
是否同时要求面向用户的全部可见输出也用该语言(本部署在组合包里设为 true) |
frontAnchor |
true |
是否注册开头的单行锚点段落 |
frontAnchorName |
deployment:language-anchor |
锚点段落名,不能与 sectionName 相同 |
frontOrder |
10 |
锚点排序值;大于 0(persona 前缀)、小于 500(plan 策略)即在最前面 |
interpolate |
false |
是否解析文本里的 {{变量}}。除非确实要用提示词变量,否则保持 false |
extra |
'' |
追加到详细段落末尾的补充指令(原样保留) |
只让模型「想中文」而不强制输出中文(回到插件包的默认行为):
- id: think-chinese
name: 'dsh-think-chinese'
config:
reply: false
只要临时整个关掉它:
- id: think-chinese
disabled: true
验证
# 1. 纯单元检查(任意 Node >= 20)
node test/unit.test.mjs
# 2. 对真实注册表做集成检查(读取桌面版安装目录,需要用 Electron 的 Node 运行)
$env:ELECTRON_RUN_AS_NODE = '1'
& "D:\AI\deepseek-harness\DeepSeek Harness.exe" --expose-internals test/integration.mjs
# 3. 对某个真实 profile 做接线检查:组合包能否解析、patch 是否插入该行、按 id 的
# config 覆盖是否生效、渲染出的系统提示词里是否真的出现这两段中文
& "D:\AI\deepseek-harness\DeepSeek Harness.exe" --expose-internals test/mount-profile.mjs desktop
第 3 个脚本会在终端里打印实际渲染出来的系统提示词,可以直接肉眼确认。想看正在运行的会话到底收到了什么,可以解开它的日志:
%USERPROFILE%\.dsh\sessions\<工作目录>\<会话 id>\session.v4.jsonl.zstd 里的 system/message 记录就是模型实际拿到的系统提示词(文件是追加式多帧 zstd,需要逐帧解压)。
卸载
powershell -ExecutionPolicy Bypass -File uninstall.ps1 # desktop
powershell -ExecutionPolicy Bypass -File uninstall.ps1 -Profile web
只删除本插件自己的东西:junction、plugins\dsh-think-chinese 目录、dsh-think-chinese 依赖项和 dsh.profile.bundles 中的选择项;同样会先备份 package.json。卸载后重启应用。
已知限制
- 它是「引导」而不是「强制」:模型偶尔仍可能漏掉某一句。锚点 + 末尾详细段已经是最省 token 的强化组合;还不够时可以再往
extra里追加指令,或把language之外的措辞按你的场景改写。 - 全局生效:插件挂在根作用域,因此主 agent 和所有子 agent(subagent)都会收到这两段指令。若只想影响某个 agent,应改用
@deepseek-ai/dsh-persona在 preset 作用域内挂载。 - 会占一点固定 token:锚点约 60 token,详细段落约 260 token(
reply: true时),每次请求都重复。 - 会影响 KV cache:改动文本会让系统提示词前缀失效一次,重启后第一次请求无法复用旧前缀;之后只要文本不变就保持稳定。
- 不要翻译代码与标识符:两段文本都写了这条豁免。如果你希望连报错、路径也译成中文,需要自己改
extra覆盖,但那通常会让模型开始改坏代码。
不装插件的等价方案
如果只想要效果、不想要一个包,也可以直接给 @deepseek-ai/dsh-system-prompt 这一行加 personaSuffix(它排在 10200,同样是最后一段)。在 profile 的 cordis.patch.yml 里:
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
personaPrefix: ''
personaSuffix: |
你的内部推理与思考过程(thinking / reasoning 内容)必须始终使用中文书写。
无论用户使用什么语言提问,也无论工具输出、报错信息、代码或日志是什么语言,思考过程一律使用中文。
面向用户的全部可见文本也必须使用中文:正文、标题、列表、表格、总结都要用中文,不要中英对照。
代码、命令、文件路径、标识符、API 名称和报错原文保持原样,不要翻译。
区别:这样会占用部署人设的后缀槽位(personaSuffix 只能有一份,patch 的 config 又是整体替换),而且没法在插件列表里单独开关;插件方案是独立段落、独立启停,并且可以同时在提示词开头放锚点。
目录结构
dsh-think-chinese/
├── package.json # npm 包 + dsh.manifestVersion / dsh.bundle.patch
├── cordis.patch.yml # 组合包 patch:insert 一行 id=think-chinese,并带本部署的 config
├── lib/index.js # 插件本体(零依赖 ESM)
├── install.ps1 # 装入 profile(增量、幂等、可回滚)
├── uninstall.ps1 # 从 profile 移除
└── test/
├── unit.test.mjs # 单元检查
├── integration.mjs # 对真实 dsh-system-prompt 注册表的集成检查
└── mount-profile.mjs # 对真实 profile 的接线检查
许可
MIT
No comments yet. Be the first to write one.