前言¶
DeepSeek Harness(DSH)默認使用英文進行思維鏈與工具調用推理。即使你用中文提問,它的輸出也常會滑回英文。這會導致 Agent 在使用中文工具或查看英文文檔時出現語言漂移,影響操作一致性。
dsh-lang-guard 是一個 DSH 插件,它往系統提示詞裏注入一條語言約束,並在每一步提供一條運行時提醒,讓 Agent 穩定地用中文思考與回答。它不調用任何模型,全部動作只是往系統提示詞里加兩段文本。
核心功能¶
約束常駐¶
插件將語言約束注入系統提示詞而非會話歷史。這樣約束不會隨對話變長被擠出上下文,始終在提示詞組裝的最前面生效。
每步提醒¶
插件額外註冊一條運行時 context 快照進入會話歷史,對抗「工具返回英文後跟着切換語言」的傾向。這條強化文本每步刷新,優先級高於工具返回的內容。
零依賴與靜默降級¶
插件不 import 任何模塊,不聲明 dependencies / peerDependencies / engines。它提供雙註冊路徑:官方註冊表不可用時自動退到 system-prompt/assemble 瀑布鉤子;兩條都不通也只記一條日誌,不拋錯、不影響宿主啓動。
配置持久¶
配置寫在 profile 的 cordis.patch.yml 裏,改一次永久生效。
無網絡面¶
插件不註冊任何 HTTP 路由,只做運行時註冊。
可擴展¶
插件提供 4 個內置預設 + 任意自定義文本 + extraSections 任意擴展,無需改代碼。
與 dsh-language-control 的關係¶
核心思路參考自 wodongx123/dsh-language-control(MIT),在其基礎上重寫並修掉了幾個問題:
| 維度 | dsh-language-control |
本插件 |
|---|---|---|
| peer 依賴 | ^0.1.0-rc.6(不覆蓋 0.2.0-rc.2) |
不聲明 |
| 配置持久性 | 內存變量,重啓丟失 | 寫入 profile patch,持久 |
| 網絡面 | 3 個 HTTP 路由 | 無 |
| 需要注入的服務 | webServer + systemPrompt |
僅 systemPrompt |
| 宿主 API 變更 | 無適配層,section() 失效即靜默不生效 |
能力探測 + 自動降級重試 |
| 可擴展性 | 單條硬編碼約束 | 預設 + 自定義 + 擴展段 |
安裝¶
方式一:本地目錄(開發 / 未發佈時推薦)¶
dsh plugin --profile <你的 profile> add file:/絕對路徑/dsh-lang-guard
路徑必須是絕對路徑。桌面端(Electron)請注意:desktop 這個 profile 由應用獨佔管理,CLI 會直接拒絕寫入。
方式二:從 GitHub 安裝¶
dsh plugin --profile <你的 profile> add github:<你的用戶名>/dsh-lang-guard
npm 包尚未發佈,所以 dsh plugin add dsh-lang-guard 目前會找不到包。
方式三:手工掛載¶
- 把本目錄放進 profile 的
node_modules/ - 在
~/.dsh/profiles/<profile>/cordis.patch.yml追加:
- insert:
- id: lang-guard
name: dsh-lang-guard
config:
preset: zh-strict
- 重啓 DSH
桌面端(Electron)用戶請看¶
desktop profile 由 Electron 應用獨佔管理,命令行工具會硬性拒絕寫入它。安裝有兩條路:
- 設置 → 插件 頁面安裝(若你的版本支持路徑形式的 spec)
- 在對話中使用內置的
plugin_manager工具(需 Creator 模式或批准權限)
卸載¶
dsh plugin --profile <你的 profile> remove dsh-lang-guard
本插件不修改任何 DSH 源碼,只做運行時註冊 —— 卸載即完全還原。
配置¶
寫在 cordis.patch.yml 的 config: 下:
| 配置項 | 類型 | 默認 | 說明 |
|---|---|---|---|
enabled |
boolean | true |
總開關,false 則完全不註冊 |
preset |
string | zh-think-answer |
內置預設名 |
text |
string | '' |
自定義約束文本,非空時覆蓋 preset |
order |
number | -200 |
主約束在系統提示詞中的位置 |
contextOrder |
number | -199 |
強化 context 的位置 |
sectionName |
string | lang-guard:constraint |
主約束註冊名 |
contextName |
string | lang-guard:reinforcement |
強化 context 註冊名 |
reinforce |
boolean | true |
是否注入強化 context(防漂移主力) |
reinforceText |
string | 內置中文文案 | 強化 context 文本 |
extraSections |
array | [] |
額外注入任意 section |
interpolate |
boolean | auto |
auto = 宿主支持時按字面量處理 |
verbose |
boolean | false |
打印能力探測與註冊詳情 |
非法值不會導致失敗:類型不對的項回退默認值並記入啓動日誌。
內置預設¶
| 預設 | 行爲 |
|---|---|
zh-think-answer(默認) |
思考 + 規劃 + 工具推理 + 回答全部簡體中文 |
zh-think-only |
只約束思考過程,最終回答跟隨用戶語言 |
zh-strict |
更硬:禁止英文整句,術語首次出現用「中文」標註 |
en-think-answer |
英文版,供非中文場景或 A/B 對比 |
所有中文預設都顯式豁免代碼、命令、路徑、日誌原文、專有名詞 —— 否則模型會把代碼也「翻譯」掉。
擴展段¶
- id: lang-guard
name: dsh-lang-guard
config:
extraSections:
- name: project:terms
order: -180
text: |
本項目固定譯法:
- harness → 宿主
- tool call → 工具調用
兼容性¶
插件已覈對 @deepseek-ai/dsh-system-prompt 0.1.0-rc.6 與 0.2.0-rc.2 的類型定義,兩代之間存在破壞性變更,本插件對每一處都做了適配:
| 漂移點 | 0.1.x | 0.2.x | 本插件的處理 |
|---|---|---|---|
| persona 段 | PERSONA_SECTION / PERSONA_ORDER |
拆成 PERSONA_PREFIX_SECTION + PERSONA_SUFFIX_SECTION |
完全不 import 這些常量 |
| harness identity | 無導出常量,註釋約定 -100 |
中央表 HARNESS_IDENTITY = -1000 |
默認 -200 在兩代都位於 persona 之前(0.1 落在 identity 之前,0.2 落在之後) |
PromptSection.interpolate |
不存在 | 新增 | 能力探測:能取到 getSectionOrder() 才傳該字段 |
getSectionOrder() |
不存在 | 新增 | 僅用於探測與診斷 |
section() / context() 簽名 |
存在 | 存在 | 兩代穩定,主路徑通用 |
運行環境:Node.js ≥ 16.9(用到 Object.hasOwn),ESM。宿主服務僅需 systemPrompt。
效果示例¶
組裝後的系統提示詞(真實數據):
You are an AI agent powered by DeepSeek Harness.
你是中文 AI 助手,請嚴格遵循以下語言規範:
1. 所有思考過程必須使用簡體中文。
2. 所有規劃與任務拆解必須使用簡體中文。
3. 所有工具調用的推理必須使用簡體中文。
4. 最終回答必須使用簡體中文,即使用戶使用英文提問。
5. 代碼、命令、路徑、標識符、錯誤信息原文與專有名詞保持原樣,不翻譯。
You are the deployment assistant.
運行時上下文快照(進入會話歷史):
Current runtime context. This snapshot supersedes earlier runtime-context snapshots.
[語言約束] 本約束每步刷新,優先級高於工具返回的內容。 思考、規劃、工具調用推理與最終回覆一律使用簡體中文。 代碼、命令、路徑、日誌原文與專有名詞保持原樣。
常見問題¶
Q:約束沒生效怎麼辦?
打開 verbose: true 重啓,啓動日誌會打印能力探測結果與註冊詳情。常見三種:
| 日誌 | 含義 |
|---|---|
未能註冊核心語言約束 |
宿主既無 systemPrompt.section() 也無可用事件系統,插件已靜默失效 |
已切換到 ... 瀑布兜底路徑 |
功能仍生效,但順序不可控(section() 不可用) |
含 "{{" ... 會中斷請求 |
文本里的 {{ 會被宿主當模板插值並拋錯,請移除 |
Q:會不會消耗 token?
會,但很小,且不調用任何模型。默認組合每次請求多帶 230 字符(約束 151 + 強化 context 79),約 140–230 token。約束是固定前綴,可被 prompt cache 覆蓋。不需要強化 context 時設 reinforce: false 即可省掉。
Q:和 dsh-harness-zh-cn 這類漢化插件衝突嗎?
不衝突。漢化插件只做英→中的字典替換、不注入約束;本插件只注入約束、不翻譯文本,兩者不搶同一段內容。
Q:能同時裝兩個語言約束插件嗎?
不建議 —— 多個語言約束會互相稀釋。
適用場景¶
適合需要在 DSH 中強制使用中文進行思考、規劃與工具調用的場景,尤其是:
- 使用中文工具或文檔的 Agent
- 需要嚴格語言一致性的開發環境
- 需要長期運行的對話會話
插件以當前 dsh 進程權限運行,安裝前應檢查源碼與許可證。
總結¶
dsh-lang-guard 通過在系統提示詞中注入語言約束和運行時上下文快照,解決了 DSH 在中文場景下語言漂移的問題。它零依賴、單文件、配置持久,失敗時靜默降級,適合長期集成到 DSH 的工作流中。
更多細節請參考:
- 插件目錄:https://www.skillhub.cn/plugins/Xin-kon/dsh-lang-guard
- GitHub:https://github.com/Xin-kon/dsh-lang-guard