前言¶
在 DSH(DeepSeek Harness)裏跑帶大段代碼或 HTML 的工具調用時,有時會出現一種很誤導人的現象:界面顯示 turn 已正常完成,實際上沒有任何工具被執行,而 <invoke>、<parameter> 或帶 antml: 前綴的調用標記卻混進了 assistant 正文。Harness 不報錯,agent 循環直接當作 {kind:'completed'} 結束。壞樣本還會留在歷史裏,模型容易繼續模仿同一格式;fork 會把父會話裏的損壞輸出一併繼承。社區裏也有人把這類連鎖失敗叫作 chain reaction。
dsh-tool-call-leak-fix 是維護者 IRwDONE 發佈的工作流類宿主插件(GitHub 倉庫 IRwDONE/dsh-tool-call-leak-fix,npm 包 @irwdone/dsh-tool-call-leak-fix,當前資料中的版本爲 0.5.1,MIT 許可證,零運行時依賴)。它針對「調用標記泄漏爲正文、調用未執行卻 turn 靜默關閉」這一類失敗,在分發前攔截、在同一 turn 內糾偏、fork 時簡報、並在模型可見面上作廢已進入歷史的損壞輸出。下面介紹它解決的問題、機制、安裝方式與配置邊界。
這是什麼¶
一句話:DSH 宿主插件,把「工具調用沒跑、標記卻進正文、turn 像成功一樣關掉」從靜默 no-op 變成可感知、可糾正的行爲,並在 fork 與上下文回放側儘量切斷壞樣本對後續模型的影響。
維護者 IRwDONE;分類爲工作流;插件在 SkillHub 目錄頁爲 dsh-tool-call-leak-fix。實現爲純 ESM JavaScript,僅使用 Node 內置模塊,不需要額外構建或前端半邊。
故障長什麼樣¶
README 裏保留了一段真實形態的節選:思考內容裏模型甚至意識到該用 antml: 前綴,但整段調用仍作爲正文輸出,隨後 turn 結束且沒有工具卡。常見形態包括:
- V1 結束序列增殖:調用尾部結束標記重複出現。
- V2 開場標記缺失:只剩參數開場,沒有外層 invoke 開場。
- V3 泄漏爲正文:調用信封混進 assistant 正文,未被識別爲真正工具調用。
- V4(相關):容錯 JSON 解析把非法參數降級爲
{},工具帶着空參數執行。
泄漏方言既有裸標籤(<invoke / <parameter),也有 antml: 前綴形式;還有「僞造工具結果」——正文出現結果形標記但該步並未調用工具。三種核心形態都是靜默失敗:不執行、不報錯,turn 正常關閉。
用戶在對話裏讓模型自行修復、僅 fork、或 compact,往往不能從根上去掉歷史裏的壞樣本;README 說明裝上本插件後,fork 之後損壞輸出可在模型可見面上被作廢,後續對話可不再出現同類泄漏型失敗(具體還依賴 M9 等開關,見下文配置)。
核心功能¶
插件 README 將能力歸納爲多條守衛(平時不主動打擾用戶):
攔截(M2)¶
工具調用分發前掃描已解析參數。若某字符串參數邊界已損壞(例如尾部結束序列增殖、結構中途截斷),且體量達到閾值(默認 ≥2000 字符或 ≥20 行),則拒絕本次調用並給出可操作說明(如建議拆成 ≤100 行分塊重發)。同時處理「聲明必填卻收到空 {}」的情況。已現場驗證:真實會話中 22 行以上且結構截斷的參數在分發前被拒,目標文件未被創建。
糾偏(M3)¶
寫入類工具執行後,若結果中有機器可讀的空轉證據(如 noop: true、status: "noop"、written: 0 且確實帶了內容),在結果後補一句短提示,不做自由文本猜測。由配置項 noopCheck 控制總開關。
自愈(M4)¶
觀察已提交的 assistant 消息:若某步輸出損壞且該步沒有任何工具調用,在 turn 即將關閉時注入糾正,保持 turn 打開、讓模型在同一 turn 內重發。糾正次數有上限,由 maxCorrectionsPerTurn 控制;本 bundle 的 patch 將默認改爲 2,以便「第一次糾正後又寫壞」時還能再給一次更硬的指令。到頂即停,避免循環。已現場驗證 turn 不關閉並繼續的完整鏈條。
fork 簡報(M7)¶
fork 會話繼承父歷史且歷史本身難以改寫(README 稱凍結請求 D-8)。插件在 fork 的第一個模型步之前注入一次代碼生成的簡報:把歷史裏「沒有對應工具卡的孤立調用標記」標爲損壞、未執行,請模型勿模仿。每個會話只放一次;非 fork 零開銷。由 forkBrief 控制。
上下文修復(M9)¶
已進入歷史的壞樣本仍會被逐字回放。插件在模型可見 surface 上遮蔽損壞步驟(該步損壞且無工具調用),換成靜態說明(「此處原爲損壞輸出、已作廢,請勿模仿」),日誌原始事件保留,零模型調用。啓用前用自建探針自檢 surfaceOp.replace 語義;自檢失敗則整個會話故障關閉。fork 繼承的損壞步驟可在每會話第一次 turn 結束時一併掃描遮蔽。由 repairContext 控制,設爲 false 可完全停用。
裝上之後的行爲對比(摘要)¶
| 以前 | 現在(插件生效時) |
|---|---|
| 壞調用不執行、不報錯 | 分發前攔截並說明原因 |
| 泄漏後 turn 靜默關閉 | turn 保持打開,同 turn 內糾正重發 |
| 寫入工具自報成功卻無改動 | 結果後補空轉提示(M3) |
| 歷史壞樣本持續被模仿 | 當場機制縮短故障窗口;不能改寫已寫入的歷史(見邊界) |
README 明確:刻意不做 system-prompt 規則塊注入,也不做「強制小塊寫入工具」。
安裝與啓用¶
用 Harness 自帶的插件管理器安裝,不要手改 profile 來「假裝掛上」。三種方式任選其一。
方式 A:在插件市場 / 插件管理器搜索 dsh-tool-call-leak-fix 或 @irwdone/dsh-tool-call-leak-fix,點擊安裝。
方式 B:一條命令安裝時使用 npm 包名或 GitHub 地址(資料原文如下,勿自行拼接其它 install 語法):
@irwdone/dsh-tool-call-leak-fix
或(倉庫需公開):
https://github.com/IRwDONE/dsh-tool-call-leak-fix
方式 C:克隆倉庫後,對 install_bundle 的 target 填倉庫根目錄(含 package.json),不要填到 plugin/ 子目錄。
安裝之後:
install_bundle返回application: "applied"即表示已生效;若提示重啓則重啓 Harness。- 判活:插件管理器列表,或 Config 中出現
include:tool-call-leak-fix;更硬判據是是否真的注入了糾正。 - 不要僅通過 grep
~/.dsh/profiles/<profile>/cordis.patch.yml判斷——bundle 自帶 patch(plugin/cordis.patch.yml,由package.json的dsh.bundle.patch聲明),該行本就不一定出現在 profile 的 patch 裏。 - 停用:管理器禁用,或將該行
config.enabled設爲false。
配置¶
config 會校驗並歸一化;非法值回退默認。數值閾值須爲整數且 ≥1(僅 maxCorrectionsPerTurn 允許 0)。
| 鍵 | 默認 | 含義 |
|---|---|---|
enabled |
true |
false 時不註冊任何監聽器 |
maxLines |
100 |
單字符串葉子行數上限(過長預警) |
maxChars |
20000 |
單字符串葉子字符數上限 |
closingTagCount |
8 |
</ 出現次數作「密集」證據,不單獨導致攔截 |
endSequenceRepeats |
2 |
尾部連續結束序列達到幾個判損壞 |
maxCorrectionsPerTurn |
1 |
每 turn 最多自愈次數;本 bundle patch 設爲 2 |
lang |
zh |
注入文案語言:zh / en |
noopCheck |
true |
M3 空轉檢查總開關 |
debugLog |
false |
診斷日誌;false 時不寫文件 |
debugLogPath |
'' |
空串由系統臨時目錄推導 |
contextGuard |
false |
內部保留、未接線 |
contextGuardNote |
'' |
內部保留、未接線 |
forkBrief |
true |
M7 fork 首步前簡報 |
forkBriefNote |
'' |
空串用內置中英文簡報 |
repairContext |
true |
M9 模型可見面遮蔽損壞步驟 |
典型用法與適用場景¶
本插件沒有單獨的「業務 API」:安裝並啓用後,守衛在工具分發、turn 關閉、fork 首步、會話 surface 替換等接縫上自動工作。典型適用場景包括:
- 經常通過 DSH 調用「大段 code / HTML / JSX」類參數的工具,且遇到過 invoke/parameter 標記出現在正文裏。
- fork 父會話後繼續開發,希望 inherited 歷史裏的損壞調用標記被簡報或 M9 作廢,減少模仿。
- 需要把靜默 no-op 變成帶原因的攔截或同 turn 重試,而不是誤以爲任務已完成。
注意:
- 插件以當前 DSH 進程權限運行;安裝前請自行閱讀倉庫源碼與 MIT 許可證,確認可接受其行爲(含 M9 自檢失敗時關閉整個會話等策略)。
- README「已知邊界」:不能改寫歷史(M5 / D-8);壞樣本「不洗白過去」,只能縮短故障窗口。繞法包括新開會話,或明確讓模型忽略某段損壞內容。
M2攔截、M4自愈、M7fork 簡報、M9上下文修復在 README 中標註爲已現場驗證;做不到的部分以倉庫「已知邊界」爲準。
結尾¶
dsh-tool-call-leak-fix 把 DSH 裏一類常見的工具調用靜默失敗——標記泄漏、turn 假完成、歷史污染——拆成攔截、同 turn 自愈、fork 簡報與模型可見面作廢四層處理,零依賴、僅依賴 Host 半邊接縫。社區目錄頁:SkillHub · dsh-tool-call-leak-fix。源碼與完整說明:GitHub · IRwDONE/dsh-tool-call-leak-fix。