dsh-result-budget:給工具結果按模型上下文窗口設限

前言

在 DeepSeek Harness 上跑本地小模型時,一個 cat 或 read 就可能塞滿上下文:read 的默認上限是 2000 行 / 50 KB,bash 是 16000 字符。對 128k 的雲端模型無所謂,對 4k–32k 的本地模型,一次調用就能把窗口占滿。而自動 compaction 只在對話已經接近窗口時才觸發,擋不住單個超長結果。dsh-result-budget 就是用來在這條通路上加一道按窗口計算的預算。

下面是這個插件的定位、機制、安裝方式和注意事項。

這是什麼

dsh-result-budget 是 DeepSeek Harness 插件,由 Wildchiken 維護,分類是「模型推理」。它的用途是讓每個工具結果的大小貼合當前模型的上下文窗口,使本地和小窗口模型不會被單個超長輸出淹沒。預算隨模型切換而變化,不是爲某一個具體模型調好的固定數字。

插件只改變模型看到的內容,會話日誌裏仍然保留工具的真實輸出,事後仍然可以查看。它的寫入方式與宿主自帶的 tool-result pruner 用的是同一對原語:先按 compaction/prune 的 shadow 價格計算,再以 tool/result 替換節點表面。這依賴 dsh-token-meter,它屬於基礎 bundle。

爲什麼需要

官方 dsh 用固定數值限制工具輸出。對小窗口本地模型來說,問題主要有三點:

1、50 KB 的 read 大約等於 13k token,一個 8k 窗口的模型調用一次就滿了。
2、自動 compaction 只在對話已經接近窗口時才運行,無法阻止單個結果把窗口填滿。
3、小模型在長上下文裏退化很快,即使不溢出,無關輸出也會拉低質量和速度。

工作機制

在每一步之前,插件對從上一步以來到達的結果做處理:

budget = max(ratio × (contextWindow − reservedOutput), minTokens)   # 如果設置了 maxTokens,則被其封頂

contextWindow 與預留輸出的取值方式和官方 dsh-compaction-basic 一致:通過 llm.resolveModelInfo 取會話路由到的 provider/model;預留輸出取請求的 maxTokens,沒有則取模型默認值。

超出預算的文本保留開頭 75% 和結尾 25%,並在中間插入一行提示,告訴模型怎樣查看剩餘部分,例如 shell 工具用 grep/head/tail。默認參數下,不同窗口的單結果預算大致是:

窗口(預留輸出) 單結果預算
4k(1k) 約 460 token
8k(2k) 約 920 token
32k(4k) 約 4300 token
128k(8k) 約 18400 token(工具自身上限通常先生效)
未知 2000 token

read 的處理不同:它從開頭保留完整行,並給出準確的 offset 繼續讀取。分頁文件中間挖洞會被靜默跳過,所以不留尾部。如果連一行都放不下,提示會指向 bash 而不是同樣的 offset。

token 估算按文本類型區分:每個數字按一個 token 計,標點和中日韓字符逐個計數,字母按單詞長度計。宿主使用的固定 4 字符/token 在數字和哈希上偏差最高達 4 倍。這裏的權重是在三個本地模型報告的 token 數上擬合的,又在未參與擬合的文件上驗證:平均誤差 6%,固定比例是 25%。

圖片等非文本塊直接透傳。插件首次見到會話之前的歷史不做處理,provider 的 prompt cache 因此得以保留。如果模型沒有聲明 contextWindow 或查詢失敗,則套用 fallbackTokens。

安裝與啓用

按 profile 安裝:

dsh plugin --profile <name> add "github:Wildchiken/dsh-result-budget"

作爲 bundle,它會作用於該 profile 裏的所有 agent。

如果只想讓插件覆蓋某一個 agent preset,可以跳過 bundle,在 preset 的 plugins 裏列出它,此時它只覆蓋該 preset 的 agent:

- insert:
    - id: preset-local
      name: '@deepseek-ai/dsh-agent-preset'
      config:
        id: local
        name: Local
        plugins:
          # ...該 preset 自帶的工具...
          - id: result-budget
            name: dsh-result-budget
            config:
              ratio: 0.15

也可以從自己的插件裏組合它:

import { installResultBudget } from 'dsh-result-budget'

export function apply(ctx) {
  ctx.inject(['llm'], (ctx) => installResultBudget(ctx, { ratio: 0.1 }))
}

配置項

Key 默認值 含義
ratio 0.15 單個結果可佔用可用窗口的最大比例,取值 (0, 1]
minTokens 384 預算下限
maxTokens null 可選預算上限;默認不設,避免大窗口模型丟內容
fallbackTokens 2000 窗口未知時的預算
headShare 0.75 保留文本中開頭所佔的比例,其餘爲結尾;read 不使用
exclude [] 跳過的工具名,允許 * 通配,例如 ["mcp_*"]

配置不合法時(未知 key、ratio 越界、非正整數、minTokens > maxTokens)會在加載時報錯,而不是靜默回退到默認值。

與其他組件的關係

  • tool-result-pruner 只在 compaction 觸發時裁剪歷史結果;這個插件在結果進入對話時就限制。可以兩者同時使用。
  • spill-policy 在基礎 bundle 裏,固定上限 12500 token,會把完整結果存到模型可讀的文件裏,並跳過 read。它先運行,這個插件保留的文本結尾正好是 spill 的提示所在位置。結果落在這個預算與 spill 上限之間時不會生成文件。
  • Per-tool caps(readLimit、maxOutputChars)可以保持默認值,這個插件在它們之後運行。
  • 相關項目 argszero/dsh-tool-output-budget 更早出現,同樣在結果到達時限定單個結果並保留日誌,但它的預算是固定的字符數。想要所有模型用同一個數字可選它;想要預算跟隨模型窗口則選這個插件。

效果與侷限

README 給出了一組在 Spark X2.6 4B(LM Studio)上通過 headless runner 跑 6 個大量工具輸出任務的對比,測試版本 v0.2.1,原始數據在 bench/ 目錄:

窗口 插件關 插件開 觸達上下文上限的次數(關/開)
8k 7 / 12 12 / 12 4 / 0
16k 9 / 12 11 / 12 1 / 1(插件關另有 2 次超時)
32k 11 / 12 4 / 6 1 / 0
  • 8k 和 16k:按任務配對後,有 7 次只在啓用插件時通過,沒有一次只在關閉時通過(p ≈ 0.016)。平均耗時也更短(8k 時 48 秒對比 69 秒,16k 時 57 秒對比 108 秒)。
  • 32k:可能反而有害。兩次失敗都是本來能放下的結果被裁掉了——一個 read 在模型需要的行之前被截斷,一個 grep 的關鍵行落在被刪掉的中間部分。32k 的樣本很小(啓用插件只有 6 次運行)。在 32k 及以上窗口,可以考慮調高 ratio 或不啓用插件。
  • 只測了一個模型,任務也是特意選了大量輸出的場景,所以反映的是它在哪裏有用,而不是普遍性。

其他已知侷限:

  • 預算用的是估算而非模型的 tokenizer,只在三個本地模型上擬合,其他模型上可能有差異;對會合並數字的模型來說在數字和哈希上偏高,這類結果會被裁得比實際需要的更早。
  • 被省略的內容模型無法直接讀到,除非 spill-policy 存過文件。模型要麼重新獲取,要麼按 shell 工具提示的方式收窄輸出重跑,後者意味着帶副作用的命令會執行第二次。
  • 小模型可能忽略提示。測試中一個本地 4B 模型跳過了建議的 offset,改用 grep。
  • 默認值只在一個本地模型上驗證過。

另外,宿主模型客戶端 pi-ai 本身也會限制輸出:它把最大輸出設爲 window − estimated input − 4096,至少爲 1。在 8k 窗口下,上下文超過大約 4k token 後模型只剩一個 token,回合會以 max-tokens 結束。這也是上表中插件關閉時大多數失敗的原因。

適用場景與結論

適合在本地或端側跑小窗口模型、且會收到大量工具輸出的 DSH 場景。插件以安裝時的 dsh 進程權限運行,安裝前應當檢查其源碼與許可證(本插件爲 MIT 許可)。

它的價值在於把「固定上限」換成「跟隨當前模型窗口的預算」,讓小窗口模型不至於被單個結果沖垮,同時保留完整日誌。代價是估算存在偏差、被裁內容需要重新獲取,且在 32k 以上窗口默認參數可能裁掉本來夠用的結果。

插件目錄頁:https://www.skillhub.cn/plugins/Wildchiken/dsh-result-budget

源碼與文檔:https://github.com/Wildchiken/dsh-result-budget

需要說明的是,SkillHub 是獨立社區站點,與 DeepSeek / 幻方沒有官方從屬關係。

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

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

小夜