dsh-customisations:用單包補丁修正 DSH 美元符號被誤解析爲行內公式

前言

DeepSeek Harness(DSH)在聊天裏用 micromark 開啓 singleDollarTextMath 時,回覆裏常見的美元金額會被當成一對行內數學公式。首尾的 $ 被 KaTeX 吞掉後,空格會坍縮、粗體標記會顯示成字面量,段落裏的 &(例如 P&L)還可能讓渲染整塊標紅。若你爲每個邊角修正單獨裝一個插件,安裝清單和 health 行會越來越長。dsh-customisations 把多類小修正收進同一個 profile 插件:每個修正有穩定 id,一次安裝對應一行 patch 與健康檢查;當前包內首項是 currency-guard,專門處理上述貨幣美元誤解析問題。

這是什麼

dsh-customisations 由 drm-nz 維護,分類上歸入模型推理相關能力,本質是一個 profile 插件包(README 描述爲 one profile plugin)。它不承擔大功能模塊,而是掛載若干彼此獨立、可單獨開關的 fix;bundle 設計目標是「一次安裝、一行 patch、一條 health」,修正列表可增而不拆包。倉庫:drm-nz/dsh-customisations;社區目錄:SkillHub 插件頁(路徑以目錄站爲準)。許可協議爲 MIT;package.json 當前版本爲 0.2.0。

問題從哪來:single-dollar 行內數學與正文美元

DSH 聊天 Markdown 在啓用單行 $ 數學時 沒有內置 currency guard。同一段正文裏,凡是在代碼塊(圍欄或行內)之外的、未轉義的一對 $,按規則會結成一段 inline math:第 1 與第 2 個 $ 一對,第 3 與第 4 個一對,以此類推。貨幣寫法只是最常見的觸發方式。

README 給出的典型壞例:

NVDA fell to **$187.43**; 53 shares remain at a $229.18 average.

在 unguarded 解析下,可能整段被收成一個 math span:空格坍縮、正文變斜體、** 變成 ∗ ∗;span 內裸 & 會讓 KaTeX 失敗並以 #cc0000 輸出整段源碼。GenUI 自帶的行內規則對「閉 $ 後跟數字」更嚴,同一句話在那裏往往正常——問題出在 DSH 聊天這條 micromark 路徑。

修正因此要在 每一對美元對 上判斷:這是公式還是正文(金額 / 散文)。

核心功能:currency-guard

掛載位置

currency-guard 包裝文檔中的 llm/stream waterfall(與 dsh-llm-retry、dsh-llm-replay、dsh-session-checkpoint-policy 等同一條縫),分兩趟處理:

  1. Streaming deltas:流式到達時,對「長得像貨幣」的 $ 立刻轉義,直播視圖儘量正確。
  2. Terminal block-end:以適配器給出的完整塊文本爲準(BlockAssembler 的權威來源),對塊做通用配對:在圍欄與行內代碼之外,給每一對未轉義的 $ 歸類;若對內正文讀作散文(例如體長大於 80 字符、含 **/==、空行、裸 &、或命令參數外的普通英文詞等),則轉義該對兩端;真數學保留。

Markdown 把 \$ 渲染爲字面 $,用戶可見回覆不變。

行爲邊界(README 已寫明)

  • 貨幣形態會轉義(含未成對的 $1,234、$5.、($5)、$97,600,、$5k、$1.2M、$0.5% 等)。
  • 散文型成對 $ 會轉義;真數學保留(如 $x^2$、$2\pi r$、$E = mc^2$、$5$)。
  • 圍欄代碼塊與行內代碼不改動(含 shell 的 $1)。
  • 流式分片時,尾部 $/金額或反引號會跨 delta 暫存,避免 token 被切斷後誤判。
  • 純文本消費者(如 purpose: "session-title" 的會話標題)跳過處理,避免存下的 \$ 帶反斜槓。
  • Fail-open:變換出錯時原樣放行 chunk。

限制

  • 僅 新的 assistant 文本 受保護;歷史消息裏的 $ 不改。
  • 用戶消息不經過 llm/stream。
  • 非貨幣的 $ 對在塊未結束前,直播界面仍可能短暫顯示爲數學;完整判定依賴 terminal pass。
  • 若上游 DSH tokenizer 自帶 currency guard,應移除此 fix。

安裝與啓用

插件在宿主啓動時加載 profile 插件,安裝後需 重啓應用。

官方安裝(desktop profile):

dsh plugin --profile desktop add github:drm-nz/dsh-customisations

從本機已檢出目錄安裝(路徑換成你的絕對路徑):

dsh plugin --profile desktop add link:/absolute/path/to/dsh-customisations

確認掛載狀態,可看共享 health 日誌最後一行:

tail -1 ~/.dsh/health.log
# ... dsh-customisations    ok   fixes=currency-guard

cordis.patch.yml 由 bundle 元數據引用;具體 patch 行以你環境裏的 health / 插件管理輸出爲準。

配置

在 profile 插件配置中可按 bundle 與單 fix 開關(字段名以 README 爲準):

- id: customisations
  name: dsh-customisations
  config:
    enabled: true            # whole bundle
    disabled: []             # fix ids to skip, e.g. [currency-guard]
    fixes:                   # per-fix options, keyed by fix id
      currency-guard: {}

將 currency-guard 填入 disabled 即可跳過該項,其餘 fix 不受影響。

典型效果(可對照測試思路)

README 中的開發測試說明:未防護文本會解析出三個 inlineMath 節點(其一含 P&L);防護後無 inlineMath 節點,且正文僅在每個貨幣 $ 前增加反斜槓。維護者本地驗證命令:

node --test test/

擴展 bundle:如何加一個新 fix

面向插件作者的約定(與 currency-guard 並列):

  1. 在 lib/fixes/<id>.js 導出 id 與 apply(ctx, config),並在該處安裝所需 seam(waterfall、slot、instruction 等)。
  2. 在 lib/fixes/index.js 登記 id。
  3. 若 fix 依賴其他服務,在 lib/index.js 的 inject 中擴展。
  4. 增加測試:fix 能安裝,且出現在 disabled 時會被跳過。

每個 fix 應保持 fail-open、冪等:bundle 每 profile 只裝一次,單個壞 fix 不應拖垮同包其餘項。

適用場景與注意

適合誰:長期在 DSH desktop(或其它使用同一 profile 插件鏈的環境)裏看模型回覆,且回覆中頻繁出現 $ 金額、財務縮寫或帶 & 的公司名;又不想爲每個小修補單獨維護一個 GitHub 倉庫的人。

安全與權限:DSH 插件與當前 dsh 進程同權運行。安裝前請自行閱讀倉庫源碼與 MIT 許可證,確認 patch 與 llm/stream 監聽行爲符合你的策略;社區目錄 SkillHub 爲獨立站點,與 DeepSeek / 幻方無官方從屬關係,並非「官方應用商店」。

生態背景:DSH 奉行「一切皆插件」;dsh-customisations 走的是「單包多 fix」路線,與「一問題一插件」相比,health 與依賴面更集中,適合體量小、邊界清晰的補償邏輯。

結尾

若你遇到的只是聊天里美元被 KaTeX 吞掉、直播偶爾閃一下數學樣式,安裝 bundle、啓用 currency-guard、重啓後在 health 裏看到 fixes=currency-guard 即可驗證。後續修正會以新 fix id 進同一包,用 disabled 或 fixes.<id> 細調。

  • 目錄頁:https://www.skillhub.cn/plugins/drm-nz/dsh-customisations
  • GitHub:https://github.com/drm-nz/dsh-customisations
羽毛球分组比赛记分
小程序二维码

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

小夜