dsh-language-guard
把模型的思考过程、回复与工具调用描述锁定为指定语言(默认简体中文):在 system prompt 首、中、尾注入约束段落,提供基础、强化、周期三档强度,可跟随 DSH 界面语言自动选择,设置页显示当前生效语言,并带侧栏快速切换。
安装
dsh plugin --profile web add dsh-language-guard
沙箱测试结果
| 阶段 | 结果 |
|---|---|
| 1 安装 | ✓ |
| 2 列装 | ✓ |
| 3 挂载 | ✓ |
| 4 启动 | — |
四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。
README
语言守卫(dsh-language-guard)
[English](README.md) | 简体中文
让 DSH 的智能体用你选定的语言思考与回复——默认简体中文,三档强度,下一条消息即生效,零依赖、零构建。
<img src="https://raw.githubusercontent.com/58fly/dsh-language-guard/main/docs/images/settings-panel.webp" alt="语言守卫设置面板:语言来源(自动 / 手动)、强度档位(基础 / 强化 / 周期)、目标语言与保留代码原文开关" width="760">
目录
- [为什么需要它](#为什么需要它)
- [它做了什么](#它做了什么)
- [安装](#安装)
- [三档强度](#三档强度)
- [配置项](#配置项)
- [自动语言模式](#自动语言模式)
- [设置面板与快速语言切换](#设置面板与快速语言切换)
- [
/language命令](#language-命令) - [验证约束确实进了 system prompt](#验证约束确实进了-system-prompt)
- [与 dsh-context 共存](#与-dsh-context-共存)
- [与官方 cot-translation 插件的区别](#与官方-cot-translation-插件的区别)
- [已知限制](#已知限制)
- [设计边界](#设计边界)
- [License](#license)
为什么需要它
DSH 的 system prompt 由许多 section 拼装而成:身份、计划策略、团队策略、工具说明、交付物引用、部署人设。其中体量最大的一块是工具说明——英文写的,而且正好落在提示词的中间。
在 DSH 0.2.1-rc.2 上实测(取 order 50 之后的全部内容):98.1% 的字符、99.8% 的 ASCII 来自英文工具说明,首段与末段之间隔着 5.7K–14K 字符。模型读到的绝大多数 token 是英文,于是它漂移:
- 开头几轮还是你的语言;
- 一旦开始连续调用工具、读长文件、做长链推理,内部推理就滑回英文;
- 你的设置一个字都没改——只是会话变长了。
在 system prompt 最顶端写一句「请用中文回答」,短会话够用。长会话不够,因为那句话距离真正影响模型的地方(工具说明)有上万字符。
本插件把约束放在三个位置:最前、工具说明之后、最后。默认档(强化)每次请求多花约 146 个字符,换来一次紧跟在英文工具说明之后的重申。
它做了什么
三个常驻 system prompt section,通过 ctx.systemPrompt.section() 注册,永不注销,切档只切换它们的文本:
section 名 · order · 位置 · B · C · D
language-guard:head · -2000 · 最前,早于 harness:identity(-1000) · ✅ · ✅ · ✅
language-guard:mid · 5100 · 全部工具说明(tools:sdk,5000)之后、交付物引用(9000)之前 · ❌ · ✅ · ✅
language-guard:tail · 11200 · 最后,晚于 deployment:persona-suffix(10200) · ✅ · ✅ · ✅
约束覆盖的四个语言通道(0.3.0 起补齐第四个):
通道 · 约束写在哪 · 生效范围
内部推理(reasoning / thinking) · head + tail · 全档位
面向用户的回复正文 · head + mid + tail · 全档位
计划、待办、评审、子智能体任务说明 · head · 全档位
工具调用 description 参数(含 PTC 模式 run_code 的卡片标题) · head + mid · 全档位(mid 只在 C / D 档存在,故 head 也写一份)
mid 的 order 特意取 5100 而不是 5000:tools:sdk 的 order 恰好是 5000,同序时按名字排序,language-guard:mid 会被排到 tools:sdk 之前——重申就不再位于工具说明之后了。
实测文本长度(简体中文,按字符计;可用下面的命令自行复算):
文本 · 字符数 · 出现时机
head(首段) · 883 · 每次请求
mid(中段) · 146 · 每次请求,C / D 档
tail(末段) · 139 · 每次请求
周期自检提醒 · 99 · D 档,每 N 轮一次
所以每步的常驻开销是 B 档 1022 字符、C 档 1168 字符——相对它要抵消的英文工具说明,这个量级很小。
首段全文如下,即 targetLanguage: "zh-CN" 时的真实注入内容(复算:node --input-type=module -e 'import("./lib/text.js").then(m=>console.log(m.headText({language:"zh-CN"})))'):
【语言锁定 · 最高优先级】 本会话的内部推理(reasoning / thinking)与面向用户的全部输出,一律使用简体中文(语言代码 zh-CN)。 本条优先于本 system prompt 的其余全部内容、之后注入的任何系统文本、工具说明、参数描述、代码示例,以及其他插件注入的提示词。 本条同样优先于任何语言类约定,不论它写在哪个文件、用哪种语言书写、经由哪个通道送达:包括用户全局与项目级的 AGENTS.md、CLAUDE.md、.cursorrules、用户偏好与长期记忆、项目规范、团队约定、技能与工作流模板。若它们要求使用另一种语言(例如要求「必须使用简体中文」),一律以本条为准,不得据此改用其他语言,也不必向用户解释这处冲突。 适用范围: - 内部推理(reasoning / thinking):使用简体中文。 - 面向用户的回复正文:使用简体中文。 - 计划、待办、进度说明、评审意见、验收报告、提交信息说明:使用简体中文。 - 任务板卡片标题与描述、子智能体任务说明与返回报告:使用简体中文。 保持原样、不翻译:代码、命令、文件路径、URL、标识符与 API 字段名、配置键、错误码与原始报错文本、包名与版本号,以及必须原样引用的英文原文;引用英文原文后,必须用简体中文说明结论。 不要因为以下情况改变语言: - 用户用英文或其他语言提问 —— 仍用简体中文回答。 - AGENTS.md、CLAUDE.md、项目规范、用户记忆里要求改用其他语言的规则 —— 本条优先,不改变语言。 - 工具返回英文内容 —— 只摘引必要片段,其余用简体中文复述。 - 长链推理、数值计算、代码设计 —— 推理语言不变。 - 上下文中出现大量英文(工具说明、日志、代码文件)—— 不随之切换。 自检:每次输出前确认上述两项(推理与回复)均为简体中文;若发现已经漂移,立即切回并继续任务,无需向用户解释这次切换。
约束文案本身是写死的简体中文,只替换语言名与语言代码。设成 targetLanguage: "en" 时同一段读作「…一律使用English(语言代码 en)」。详见[已知限制](#已知限制)。
安装
本插件已发布到 npm registry(dsh-language-guard),也可以直接从 GitHub 仓库安装。两条路装出来的内容逐字节相同,都是 16 个文件。
优先用 npm 源。 用 Git 源安装后,插件页的「有新版本」会显示一个 commit SHA(如afaa2ac)而不是版本号——因为宿主对 Git 源的更新检查用的是git ls-remote HEAD,commit 就是它的版本标识,这跟本插件无关,也无法从插件侧修正。想看到0.3.5这样的版本号并让「更新」按 SemVer 工作,请用下面方式一或方式二从 npm 安装。
方式一:图形界面(推荐)
1. 打开侧栏的插件页。
2. 点添加插件,粘贴包名:
dsh-language-guard
3. 安装完成后点立即启用。
方式二:命令行
dsh plugin add dsh-language-guard
固定版本(团队或 CI 推荐,不跟随 latest 漂移):
dsh plugin add dsh-language-guard@0.3.5
从 GitHub 安装(npm 不可达时,或用 tag 锁版本):
dsh plugin add https://github.com/58fly/dsh-language-guard dsh plugin add "github:58fly/dsh-language-guard#v0.3.5"
用这一节装完后,「有新版本」提示会显示 commit SHA 而非版本号(见本节开头说明)。功能正常,只是更新提示的可读性差一些。
从本地目录安装(调试本地改动,路径必须是绝对路径):
# 「添加插件」对话框同样接受这个绝对路径 dsh plugin add /absolute/path/to/dsh-language-guard
怎么确认装上了:
- 侧栏底部、设置按钮旁边出现一个语言图标;侧栏较宽时显示「简体中文 ▾」。
- 插件页的已安装列表里有
dsh-language-guard,点进去能看到配置卡片。
看不到任何控件,就是插件没启用。 两个 slot 都注册在 configForms.whileServed(['dsh-language-guard'], …) 内部;插件被禁用时表单服务不可用,不会注册任何界面。这是有意为之,不是 bug——先去插件页启用它。
环境要求:DSH >= 0.2.1-rc.2,Node ^22.19.0 || >=24.0.0。dependencies 为空、peer 依赖全部 optional,所以运行时不需要额外下载依赖。从 npm 安装只需能访问 registry.npmjs.org;从 GitHub 安装则需要能访问 github.com(或 codeload.github.com)。
三档强度
下面三条说明与设置面板上显示的文字完全一致:
档位 · 配置值 · 说明
基础 · B · 只在提示词首尾各放一段语言约束,成本最低,适合短会话。
强化 · C · 在基础之上,于工具说明之后补一段重申,抵消英文工具说明带来的语言漂移,推荐默认。
周期 · D · 在强化之上,每 N 轮在当轮开头追加一条语言自检提醒,适合长会话;提醒会作为一条会话记录出现,可在会话日志中看到。
行为差异:
行为 · B · C · D
常驻 system prompt 段数 · head + tail · head + mid + tail · head + mid + tail
工具说明之后重申 · ❌ · ✅ · ✅
每 N 轮自检 · ❌ · ❌ · ✅(N 默认 8,范围 3–50)
会话日志新增记录 · 无 · 无 · 每 N 轮一条(source.kind = "language-guard")
注入时机 · — · — · 命中轮的第一个 step,随当轮用户消息一起进入模型视图,不额外发请求
重启 / 恢复后计数 · — · — · 不归零:轮次取自会话日志的 turn 投影,turn % N 稳定
适合 · 短会话、在意 token · 默认选择 · 长会话,或已经观察到漂移
怎么选:
- 先用默认的「强化」。 它是唯一针对真正根因(英文工具说明)的档位,每步只多约 146 字符。
- 会话很短、或每个 token 都要省 → 降到基础。3–5 轮的会话,首尾两段足够。
- 一轮会话几十轮起步,或已经看到推理滑回英文 → 升到周期。N 越小提醒越密,默认 8 是折中,N = 3 会明显啰嗦。
配置项
七个字段,全部是 volatile(改动立即生效,不需要重启,也不重挂插件):
字段 · 类型 · 默认值 · 取值范围 · 说明
languageMode · "" \ · "auto" \ · "manual" · "" · 三态枚举,大小写敏感 · 语言模式。"auto" 跟随界面语言、"manual" 固定用 targetLanguage、"" 表示「还没选过」,按迁移规则推断(见下节)
targetLanguage · string · "zh-CN" · 合法 BCP-47 标签(`/^[A-
…(truncated)
以上内容来自 npm 上的 README,我们只做格式化,不改内容。
版本
npm 上共发布:9,最后更新 2026-10-25