前言¶
DeepSeek Harness(DSH)在工具輸出側會按 output.schema 校驗;對不上就拋 ToolOutputError。工具輸入側的 parameters 主要寫進模型提示詞,host 默認不會在調用前按 schema 攔一層。類型錯了往往一路進工具函數體,最後在 Node 裏變成裸 TypeError——例如 The "path" argument must be of type string、p.replace is not a function。對 5 個已發佈插件做 148 次參數模糊調用時,有 47 次以這類錯誤結束,來自 12 個不同入口點。
@bushizhanghan/dsh-arg-guard 是維護者 bushizhanghan 發佈的 DSH 插件,分類爲 admin-security。它在 host 唯一的入參關卡 tools/pre-execute 瀑布裏,用工具自己聲明的 parameters 做入參校驗;違規則拒絕,並把確切的 JSON 路徑與期望類型交給模型,便於改參數而不是對着堆棧猜。
這是什麼¶
一句話:在每次工具執行前,按工具定義的 JSON Schema 風格 parameters 校驗實參;通過則放行,不通過則 deny(或 warn 只記日誌)。
- 倉庫:bushizhanghan/dsh-arg-guard
- 社區目錄:SkillHub 插件頁
- 許可證:MIT(見倉庫)
- 當前包版本(package.json):0.1.0;運行環境要求 Node
>=22
插件只讀:不寫磁盤、不髮網絡請求;統計計數器僅在內存中。
缺口在 host 裏的位置¶
下面事實來自對 host 源碼的核對(README 中引用),不是推測:
| 位置 | 事實 |
|---|---|
_dsh-tools.js:3321 |
tools/pre-execute 瀑布是唯一的入參關卡 |
_dsh-tools.js:3345 |
拒絕理由會原樣變成模型看到的 Error: <reason> |
_dsh-tools.js:3091 / 3107 |
get / resolveExecution 能拿到帶 parameters 的工具定義 |
| 輸出側 | output.schema 已有強制校驗 |
因此:schema 寫給模型看,默認並不按同一套規則檢查入參;各插件作者若手寫 typeof 守衛,容易漏。本插件把校驗集中到 host 瀑布裏,並用統一的理由格式回給模型。
核心功能¶
校驗行爲¶
註冊 tools/pre-execute 處理器,對每次調用根據該工具的 parameters 判定 allow 或 deny(warn 模式下只記錄仍放行)。
拒絕理由格式固定爲:<工具名>.<JSON 路徑>: expected <類型>, got <類型> (<值>);根級錯誤省略點號。
README 中 publish_gate 的真實示例:
{"dir":123} → deny: publish_gate.dir: expected string, got number (123)
{"mode":"fix"} → deny: publish_gate.dir: required but missing
{"dir":"E:/p","mode":"slow"} → deny: publish_gate.mode: expected one of "check", "fix", got string ("slow")
{"dir":"E:/p","extra":1} → deny: publish_gate.extra: unexpected property (allowed: dir, mode)
{"dir":"E:/p","mode":"fix"} → allow
支持的 schema 規則¶
| 規則 | 說明 |
|---|---|
| 原始類型 | string / number / integer / boolean / null |
| 類型聯合 | 如 type: ["string","null"] |
| 必填 | required;undefined 等同未傳 |
| 枚舉 / 常量 | enum、const |
| 嵌套對象 | properties 遞歸,路徑用點號連接 |
| 數組 | items(對象或元組) |
| 封閉對象 | additionalProperties: false(patternProperties 命中鍵可放行) |
| 組合 | oneOf / anyOf / allOf |
明確不做的校驗¶
- 不做類型強轉:例如 schema 要求
integer時,字符串"3"視爲錯誤。 - 未實現的 JSON Schema 關鍵字一律忽略:如
$ref、if/then/else、format、dependencies等——看不懂則不據此拒絕。 - 不校驗輸出(host 已負責)。
- 不跨進程:只作用於同一 host 內註冊的工具。
Agent 輔助工具¶
| 工具 | 作用 |
|---|---|
arg_guard_status |
查看 hook 是否掛上、mode、skip、計數器(checked/allowed/denied/warned/skipped/errors)、最近 10 條違規 |
arg_guard_check |
對 {tool, args} 幹跑,返回與真實 hook 一致的 verdict 與理由,不執行、不計數 |
典型用法:某次調用被拒後,用相同參數幹跑查明原因;或在發請求前自檢,減少往返。
安裝與啓用¶
在 profile 爲 desktop 時,安裝命令(須與資料原文一致):
dsh plugin --profile desktop add @bushizhanghan/dsh-arg-guard
安裝後重啓 DSH 生效。
配置¶
在插件 config 中可設置:
- id: arg-guard
name: "@bushizhanghan/dsh-arg-guard"
config:
enabled: true # 總開關,默認 true
mode: deny # deny = 攔截;warn = 只記錄、放行
skip: [] # 不檢查的工具名,例如 [bash]
上線順序建議:先用 mode: warn 跑一段時間,通過 arg_guard_status 查看 violations 是否有誤報(工具聲明的 schema 比真實契約更嚴時可能誤報),確認後再切 deny。
安全與誤攔策略¶
插件第一原則是:守衛弄壞的調用,比沒有守衛更糟。
- 處理器整體包在
try/catch中,異常時 fall through 到allow。 - 解析不到定義、未聲明
parameters.properties、schema 畸形、類型名不認識等情況 →allow。 - 可通過
skip放行指定工具名,或用mode: warn先觀測。
校驗覈心在 lib/engine.js 的純函數 validateArguments;README 稱其有 38 個測試用例直接斷言,含「定義查詢拋錯仍放行」等路徑。開發側可運行:
npm test # node --test
適用場景與注意¶
適合誰:在 DSH 上開發或運維多工具智能體、希望把「錯類型」從 Node 堆棧前移到可讀的拒絕理由;尤其當工具 parameters 已寫完整、希望 host 統一 enforcement 時。
使用前請知悉:
- 插件與當前 DSH 進程同權限運行;安裝前應自行閱讀 GitHub 源碼 與 LICENSE。
- 社區目錄 SkillHub 爲獨立生態站點,與 DeepSeek / 幻方無官方從屬關係;DSH 理念是「一切皆插件」,按需從目錄或 GitHub 安裝即可。
- 不認識的 schema 關鍵字會被忽略,不能替代對複雜契約(大量
$ref等)的完整 JSON Schema 校驗器。
結尾¶
dsh-arg-guard 補上 host 在工具入參側的空缺:在 tools/pre-execute 按各工具自報的 parameters 校驗,把裸 TypeError 換成帶 JSON 路徑的類型說明,並可通過 warn / skip 與 arg_guard_check 控制風險。
- 目錄頁:https://www.skillhub.cn/plugins/bushizhanghan/dsh-arg-guard
- GitHub:https://github.com/bushizhanghan/dsh-arg-guard