前言¶
在 DeepSeek Harness(DSH)裏跑智能體時,工具結果會原樣進入會話歷史,並在後續每一輪隨請求重發。若某次 read、grep 或命令輸出在截斷路徑上把 emoji 從 UTF-16 代理對中間切開,日誌裏會留下一個合法的 JavaScript 字符串、卻在 API 側無法被正確解析的「落單代理」。表現往往是 serde_json: unexpected end of hex escape,對應 HTTP 400 INVALID_REQUEST;一旦寫進會話,重試和重啓都無法恢復,只能手工改會話文件。下面介紹社區插件 dsh-surrogate-guard(維護者 fengxiforcy,分類:工作流),它在內容進入會話日誌之前,把這些孤立代理替換成 U+FFFD,避免會話被永久拖死。
這是什麼¶
dsh-surrogate-guard 是 DSH 工作流類插件:在工具結果與用戶消息寫入會話之前,掃描並中和 UTF-16 孤立代理(高位 0xD800–0xDBFF 或低位 0xDC00–0xDFFF 單獨出現、未組成合法代理對的情況)。源碼與說明見 GitHub,目錄頁見 SkillHub。許可爲 MIT;當前 package 版本爲 0.1.4(以倉庫 package.json 爲準)。
它解決什麼問題¶
工具結果在部分截斷實現裏會對行文本做固定長度截取(例如核心側 truncateLine 使用裸 substring),可能從代理對中間切斷,只保留半個字符。在 JS 裏 JSON.stringify 仍會安靜轉義,但 DeepSeek API 解析會失敗:
serde_json: unexpected end of hex escape at line 1 column NNNNN
→ 400 INVALID_REQUEST
官方 Harness 討論裏也有同類現象(如 deepseek-ai/deepseek-harness 的 #8846、#1449)。本插件做的是事後中和,不能從截斷源頭消除孤立代理;與針對「區域指示符對 / 國旗 emoji」、報錯多爲 Content Exists Risk 的 dsh-text-guard 靶子不同——兩種症狀都可能讓會話永久 400,需要按病因分別安裝。
核心功能¶
插件通過 Cordis patch 掛在若干入口上,對經過的字符串做掃描:發現孤立代理則替換爲配置的替換符(默認 U+FFFD),合法代理對與普通文本不動;無命中時返回原引用,不額外分配。
默認配置項如下(寫入 profile 插件配置即可調整):
- id: surrogate-guard
config:
replacement: '?' # 默認 U+FFFD
toolResults: true # tools/post-execute + tools/ptc-dispatch-log
userMessages: true # agent/pre-step
log: true # 只記數量,不記內容
tools/post-execute 側會按 value → content → meta → data → output → result → lines 的順序找第一處命中並只改一處,以滿足 accept 決策不能同時替換 value 與 content 的合約;read 工具行文本在 data.meta.lines[].text 等字段也會被覆蓋到(0.1.1 起修復 read 路徑漏掃,0.1.4 修復同時改 value/content 的迴歸)。
已知限制(README 原文):
- 經由系統提示段落的文本不經過這些入口。
- 改寫有損,但隻影響殘字本身。
- 無命中時零額外分配。
安裝與啓用¶
插件以當前 DSH 進程權限運行;安裝前請自行查看倉庫源碼與 MIT 許可證。Node 引擎要求爲 ^22.19 || >=24。
安裝命令以 README 爲準:
dsh plugin --profile <profile> add github:<your-github>/dsh-surrogate-guard
# 或發到 npm 後:dsh plugin --profile <profile> add dsh-surrogate-guard
將實際 GitHub 路徑替換爲維護者倉庫(例如 fengxiforcy/dsh-surrogate-guard 時使用 github:fengxiforcy/dsh-surrogate-guard)。然後把 dsh-surrogate-guard 加入該 profile 的 package.json 裏 dsh.profile.bundles,重啓 DSH 後生效。
典型用法與自測¶
日常無需額外調用:啓用 bundle 後,工具結果與配置開啓的 userMessages 會在進入會話前自動處理。
離線自測可在插件目錄執行:
node test/guard.test.mjs
README 說明共 17 項檢查(含乾淨文本、孤立高位/低位代理、合法代理對、read 結構、同時命中只改一處等);npm 包自 0.1.3 起包含 test/ 目錄,裝包後可直接運行上述命令。
適用場景與注意¶
適合:經常 read 大文件、grep 含 emoji 或二進制誤讀文本、依賴聯網抓取結果寫入會話的 DSH 工作流;已遇到過 unexpected end of hex escape 或希望與 dsh-text-guard 互補覆蓋兩種「永久 400」病因的場景。
注意:插件不能替代核心側碼點對齊截斷;若只需合規過濾國旗類 emoji,應使用 dsh-text-guard。社區目錄 SkillHub 與 DeepSeek / 幻方無官方從屬關係,安裝來源以你信任的 GitHub 或 npm 爲準。
結尾¶
dsh-surrogate-guard 把工具與用戶消息裏因截斷產生的 UTF-16 孤立代理在進會話前換成安全替換符,降低整段會話因 400 無法繼續的風險。詳情與更新日誌見 GitHub 倉庫,插件條目見 SkillHub 目錄頁。