前言¶
在 DSH 裏切到視覺模型後,若會話歷史裏已經堆了很多截圖或附件,請求有時會在上游網關處直接被拒:錯誤裏常見「單請求最多 N 張圖片」一類說明。適配器 dsh-llm-pi-ai 默認按 base64 體積(maxRequestImageBytes,常見默認 20 MiB)做預算,並不按張數限流,因此可能出現「總字節仍在預算內、但圖片張數已超過網關硬上限」的情況。官方 dsh-compaction-image-offload 主要識別 IMAGE_OFFLOAD_REQUIRED,對這種 INVALID_REQUEST 類張數錯誤往往幫不上忙,會話會逐步卡死——再發「繼續」也每步失敗。
下面介紹社區插件 dsh-image-count-guard(維護者 MacilyDots,分類:工作流):在網關按圖片張數拒絕請求時,把最舊的圖片卸載爲佔位文本並重試,複用官方 image/offload 投影,儘量恢復已卡死的視覺模型會話。
這是什麼¶
dsh-image-count-guard 是 DeepSeek Harness 的兜底型工作流插件(npm 包名 dsh-image-count-guard,當前資料中版本 0.1.0,MIT 許可證)。它掛在 agent/request-error 瀑布流上:當失敗信息匹配「圖片張數上限」類英文表述時,統計當前面上尚未 omitted 的圖片出現次數,按模型請求順序選出最舊的一批寫入 image/offload 決策,並返回 { kind: 'retry' } 重試該步(不消耗 provider 的重試預算)。
與官方卸載插件的分工如下(資料原文表格):
| 情況 | 由誰處理 |
|---|---|
適配器因字節預算自行拒絕(IMAGE_OFFLOAD_REQUIRED) |
官方 dsh-compaction-image-offload |
上游網關因圖片張數拒絕(如 INVALID_REQUEST 等) |
本插件 |
兩者寫入同一類 image/offload 事件,語義與佔位、回放、token 與 KV cache 行爲與官方卸載一致;本插件不依賴官方 handler 的註冊順序,只要求 image/offload 投影已註冊。
它要解決的具體問題¶
資料中以 OpenCode Go 爲例:網關單請求硬上限爲 20 張圖片。而 dsh-llm-pi-ai 僅按 base64 字節預算時,可能出現:
- 會話歷史裏圖片不斷累積(資料實測一例:36 張,原始約 11.79 MiB,base64 約 15.72 MiB);
- 切換到視覺模型(如
opencode-go/deepseek-v4.1-flash)後,15.72 MiB 仍低於 20 MiB 默認預算,適配器認爲可發送,將全部 36 張 inline 發出; - 網關返回
400 INVALID_REQUEST:a request may include at most 20 images; - 官方 image-offload 不識別該錯誤 → 步驟失敗;
- 此後該會話每一步都會失敗,會話完全卡死。
本插件則在匹配到張數限制文案後,卸載 max(1, total - (limit - safetyMargin)) 個最舊出現位置(total 爲當前未 omitted 的圖片出現次數),每次重試至少 omit 一處,因此恢復過程會終止:要麼請求通過,要麼無圖可卸、原失敗仍爲終態(不會無限重試)。
錯誤文案匹配需同時包含 image 與數量短語,資料列舉的模式包括:at most N images、maximum of N images、no more than N images、up to N images、too many images 等。
安裝與啓用¶
安裝方式來自倉庫 README:在插件源碼目錄下執行 PowerShell 安裝腳本(腳本會手工改 profile 三處:dependencies、dsh.profile.bundles、pnpm-lock.yaml,並複製一份 node_modules 副本且不運行 pnpm install;修改前備份到 .backup\<timestamp>\,僅保留最近 5 份)。DSH 主目錄取自 $env:DSH_HOME,否則爲 ~\.dsh。
安裝後必須重啓 DSH。
# 在插件源碼目錄執行
pwsh -File .\install.ps1 # 安裝到 desktop profile(默認)
pwsh -File .\install.ps1 -Profile web # 安裝到指定 profile
卸載:
pwsh -File .\install.ps1 -Uninstall
說明:本插件以當前 DSH 進程權限運行;安裝前請自行查看 GitHub 源碼 與 LICENSE,確認符合你的環境與合規要求。DeepSeek Harness 生態強調「一切皆插件」;社區目錄站點(如 SkillHub)與 DeepSeek / 幻方無官方從屬關係,本文不以「官方應用商店」口吻描述安裝來源。
安裝結束時,install.ps1 會打印四項靜態檢查:deps / bundles / node_modules / lock。
可選配置¶
默認無需配置。若需覆蓋,在 profile 的 cordis.patch.yml 中按 id 寫入:
- id: image-count-guard
config:
defaultImageLimit: 20 # 錯誤文案未給出數字時假設的上限
safetyMargin: 2 # 卸載後保留的餘量,避免再加一張又失敗
maxOffloadPerRetry: 80 # 單次重試最多 omit 的圖片出現次數
典型用法與驗證¶
恢復已卡死的會話(聯調驗證)
- 安裝插件並重啓 DSH;
- 打開此前因圖片張數超限而卡死的會話,發送「continue」;
- 插件生效時,會話應記錄
image/offload事件,下一步請求成功。
離線單元測試
在插件目錄執行:
node --test test/guard.test.mjs
資料說明共 11 個用例,覆蓋匹配、選擇、收斂輪次上界、無副作用邊界等。
可選裝配檢查
將插件掛到臨時 profile 後運行 --dump-config,輸出中應包含 # == dsh-image-count-guard 與 - id: image-count-guard,退出碼 0。
診斷:會話內圖片統計
PowerShell 示例(路徑按你的 DSH 會話目錄調整):
# 單會話:張數、已 omit 數、原始字節、base64 估計、平均圖大小
node tools\session-image-report.mjs `
"$env:USERPROFILE\.dsh\sessions\<workspace>\session-<id>\session.v4.jsonl.zstd"
# 掃描最近會話,按圖片張數排序
node tools\session-image-report.mjs "$env:USERPROFILE\.dsh\sessions" --limit 20
資料中兩例會話說明「僅字節預算無法對齊張數上限」:session-c312057f 爲 36 張、base64 約 15.72 MiB(低於 20 MiB 默認預算仍會因 20 張上限被拒);session-b15b99cb 爲 25 張、base64 僅約 1.52 MiB。這正是需要按張數處理、而非只靠 maxRequestImageBytes 的場景。
適用場景與注意¶
適合誰
- 長期使用視覺模型、會話裏截圖/附件較多的 DSH 用戶;
- 上游網關對單請求圖片張數有硬上限,而本地適配器仍按體積預算放行的情況;
- 已安裝或計劃安裝官方
dsh-compaction-image-offload(需其註冊的image/offload投影);若官方插件被禁用、投影未註冊,本插件在append失敗時會捕獲並將失敗交回下游,無副作用。
已知限制(資料原文)
- 卸載不可撤銷:被 omit 的圖片之後以佔位文本呈現(含只讀附件路徑),與官方
image/offload一致;若需再看圖,需讓模型再次調用read_image。 - 錯誤文案須爲英文且同時含
image與數量短語;新網關措辭出現時,需在src/index.js的LIMIT_PATTERNS中增補條目。 - 修改
src/index.js後須重新運行install.ps1同步 node_modules 副本,否則 DSH 仍加載舊代碼。
鏈接¶
- 社區目錄頁:https://www.skillhub.cn/plugins/MacilyDots/dsh-image-count-guard
- 源碼與說明:https://github.com/MacilyDots/dsh-image-count-guard
當網關因圖片張數拒絕請求、官方字節卸載又無法識別錯誤碼時,dsh-image-count-guard 用同一套 image/offload 語義卸最舊圖片並重試,是工作流裏專門補「張數上限」這一環的兜底插件;安裝以 README 中的 install.ps1 爲準,改配置走 cordis.patch.yml,聯調與診斷可按上文命令復現。