dsh-prompt-inject:爲 complete 預設注入可配置的 prompt 變量

前言

在 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 在仍有引用時會拒絕執行。

核心功能

  1. 註冊 prompt 變量:默認變量名爲 inject,可在 cordis.patch.yml 中改爲符合 [a-z][a-z0-9_]* 的名字;預設 persona 的 prefix 末尾通過工具腳本追加 {{variable}}(冪等)。
  2. 內容來源:支持 textFile(UTF-8 絕對路徑,按 mtime 自動重載)或內聯 text;textFile 優先;兩者都空則不注入任何內容。
  3. 作用範圍:可選 presets、sessions、cwds 白名單;enabled 總開關;可選 stateFile / stateKey 跟隨外部 JSON 開關(鍵嚴格等於 true 才注入)。
  4. 配套腳本:install.mjs / uninstall.mjs 管理 profile 的 dsh.profile.bundles;enable.mjs / disable.mjs 管理預設引用;check.mjs 列出 profile 內全部變量引用並在危險時以退出碼 1 結束。
  5. 容錯: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 列表相對穩定)。

啓用流程概要:

  1. 在 profile 的 cordis.patch.yml 中配置插件(見下一節)。
  2. 爲目標預設掛上變量引用:
   node tools/install.mjs
   node tools/enable.mjs --preset preset-<你的預設 id>
   node tools/check.mjs
  1. 重啓 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 與白名單、開關決定何時返回空串。

典型用法

  1. 準備一段只給某個 complete persona 用的規則或上下文,保存爲 UTF-8 文件,在配置裏填 textFile。
  2. 對目標 agent 預設執行 node tools/enable.mjs --preset preset-<id>,在 persona prefix 末尾追加 {{inject}}(或你配置的 variable)。
  3. 用 node tools/check.mjs 確認引用與 bundles 配對正常後再重啓 DSH。
  4. 需要臨時關閉注入時,可設 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 爲準。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜