前言¶
在 DeepSeek Harness(DSH)裏,系統提示由多個 section 拼裝。若某個 agent 預設使用了帶 complete: true 的 persona(例如 @deepseek-ai/dsh-persona 獨佔整段人格),assemble() 會只保留這一個 section,其餘通過 ctx.systemPrompt.section() 註冊的段落都會被丟棄。常見做法是再堆 section,但在 complete 場景下這條路走不通。complete 段仍會經過 renderPrompt() 的 interpolate(),因此可以在 persona 文本里寫 {{變量名}},由 prompt 變量 provider 返回值展開。下面介紹 MacilyDots 維護的 dsh-prompt-inject:把工作流裏「一段附加提示」註冊成變量,供預設前綴引用;插件本身不含固定文案,內容由你在配置或外部文件裏提供。
這是什麼¶
dsh-prompt-inject(npm 包名 @macily.dots/dsh-prompt-inject,當前資料中版本 0.1.2)是 DSH 工作流類插件。它向 DSH 註冊一個可配置的 prompt 變量,讓使用 complete: true persona 的 agent 預設仍能在系統提示裏插入一塊自定義文本。維護者爲 MacilyDots;源碼與說明見 GitHub 倉庫,社區目錄頁爲 SkillHub 插件頁。許可爲 MIT。
爲什麼需要 prompt 變量而不是再加 section¶
DSH 系統提示的註冊入口是 @deepseek-ai/dsh-system-prompt 的 ctx.systemPrompt.section()。拼裝時有硬規則:只要存在 complete: true 的 section,最終列表裏只剩該段。此時還能生效的入口是 prompt 變量插值——complete 段不是拼接對象,但照樣參與 interpolate(),前綴或 persona 裏寫 {{inject}}(名稱可配置)即可展開。
需要注意:interpolate() 對未註冊的變量會拋錯(例如 unknown prompt variable "{{x}}" in section "..."),錯誤發生在渲染系統提示階段,該預設下的會話鏈路會整體失敗。因此前綴裏寫了 {{x}},就必須保證註冊 x 的插件處於加載狀態;卸載前先用 tools/disable.mjs 去掉引用;tools/check.mjs 可檢查配對,tools/uninstall.mjs 在仍有引用時會拒絕執行。
核心功能¶
- 註冊 prompt 變量:默認變量名爲
inject,可在cordis.patch.yml中改爲符合[a-z][a-z0-9_]*的名字;預設 persona 的prefix末尾通過工具腳本追加{{variable}}(冪等)。 - 內容來源:支持
textFile(UTF-8 絕對路徑,按 mtime 自動重載)或內聯text;textFile優先;兩者都空則不注入任何內容。 - 作用範圍:可選
presets、sessions、cwds白名單;enabled總開關;可選stateFile/stateKey跟隨外部 JSON 開關(鍵嚴格等於true才注入)。 - 配套腳本:
install.mjs/uninstall.mjs管理 profile 的dsh.profile.bundles;enable.mjs/disable.mjs管理預設引用;check.mjs列出 profile 內全部變量引用並在危險時以退出碼 1 結束。 - 容錯:provider 在
assemble()裏同步調用,拋錯會廢掉會話;插件內部讀文件、讀狀態均 try/catch,最壞返回空串(等同不注入)。
插件不註冊 system-prompt section,因此不參與「多個 complete section」的衝突;同名變量重複註冊仍會報錯,需改 variable 配置避免與其他插件撞名。
安裝與啓用¶
下文用 %DSH_HOME% 表示 DSH 主目錄(Windows 默認 %USERPROFILE%\.dsh,其它平臺 ~/.dsh),profile 名默認 desktop。插件要求 Node >= 22.5。
從 npm 安裝(官方命令):
dsh plugin --profile desktop add @macily.dots/dsh-prompt-inject
說明:npm 上必須使用 scope 包名 @macily.dots/dsh-prompt-inject;無 scope 的 dsh-prompt-inject 已被其它包占用。
手動安裝等價於:將倉庫複製到 profile 的 node_modules/@macily.dots/dsh-prompt-inject,再執行 node tools/install.mjs 寫入 bundles。DSH 是否加載插件由 package.json 的 dsh.profile.bundles 決定,而不是僅改 cordis.patch.yml(GUI 可能重寫 patch,bundles 列表相對穩定)。
啓用流程概要:
- 在 profile 的
cordis.patch.yml中配置插件(見下一節)。 - 爲目標預設掛上變量引用:
node tools/install.mjs
node tools/enable.mjs --preset preset-<你的預設 id>
node tools/check.mjs
- 重啓 DSH。
所有寫操作腳本會在同目錄留 .bak-prompt-inject-<時間戳> 備份;加 --dry 可預覽不落盤。
配置示例¶
在 profile 的 cordis.patch.yml 裏覆蓋插件項:
- id: prompt-inject
config:
variable: inject
textFile: '<文本文件的絕對路徑>'
| 字段 | 默認 | 說明 |
|---|---|---|
variable |
inject |
註冊的變量名;預設裏寫 {{<這個名字>}} |
textFile |
'' |
文本文件路徑(UTF-8),改動後按 mtime 重載 |
text |
'' |
內聯文本;textFile 優先 |
presets |
[] |
agent 預設 id 白名單;空表示不限制 |
sessions |
[] |
會話 id 白名單 |
cwds |
[] |
工作目錄白名單(header.cwd) |
enabled |
true |
總開關 |
stateFile |
'' |
外部 JSON 開關文件 |
stateKey |
enabled |
從 JSON 讀取的鍵,須嚴格爲 true 才注入 |
debug |
false |
寫入 %DSH_HOME%/prompt-inject.log |
variable 與 presets 是兩道獨立閘門:引用決定哪些預設會展開該變量;provider 與白名單、開關決定何時返回空串。
典型用法¶
- 準備一段只給某個 complete persona 用的規則或上下文,保存爲 UTF-8 文件,在配置裏填
textFile。 - 對目標 agent 預設執行
node tools/enable.mjs --preset preset-<id>,在 personaprefix末尾追加{{inject}}(或你配置的variable)。 - 用
node tools/check.mjs確認引用與 bundles 配對正常後再重啓 DSH。 - 需要臨時關閉注入時,可設
enabled: false、收窄白名單,或通過stateFile與其它插件聯動;改文件內容無需重啓(textFile按 mtime 重載)。
適用場景與注意¶
適合:已採用 complete: true persona、又需要在系統提示裏穩定插入團隊規範、項目說明或可變指令塊的 DSH 用戶;希望把注入內容與 persona 倉庫解耦、用外部文件或開關控制的情況。
務必注意:
- 插件以當前 DSH 進程權限運行,安裝前應閱讀源碼與 MIT 許可證,確認
textFile路徑與內容可信。 - 未註冊變量即引用會導致整條預設會話失敗;變更 bundles 或卸載前必須
disable並check。 - 卸載順序:
node tools/disable.mjs --preset <preset-id>→node tools/uninstall.mjs→ 重啓 DSH → 自行刪除node_modules中插件目錄。
結尾¶
dsh-prompt-inject 不試圖繞過 complete section 的拼裝規則,而是利用 prompt 變量插值,在 complete persona 預設上追加可配置文本塊;配合 bundles 安裝、enable/check 腳本和 cordis.patch.yml 配置,把「引用」與「何時注入」分開管理。更多細節以倉庫 README 爲準。