前言¶
在 Windows 上用 DeepSeek Harness(DSH)跑 cmd.exe、powershell.exe 或常見本地命令時,agent 看到的 stdout/stderr 裏中文經常變成一串 � 或亂字符。錯誤信息、路徑、日誌都不可讀,排查會偏離真實輸出。問題來自子進程按系統 OEM 代碼頁(簡體中文多爲 GBK/CP936)寫字節,而 DSH 子進程服務卻一律用 UTF-8 解碼。本文介紹社區插件 dsh-utf8-output(維護者 TLEWA,分類:客戶端):在不改內核的前提下,從保留的原始字節重新解碼後再交給上層。
這是什麼¶
dsh-utf8-output 是 DSH 的 cordis 插件,掛到 subprocess 服務上,包裝 spawn(),對 OutputCollector 的 readFrom() / finalize() 做重解碼。目標用戶是 Windows 上使用 DSH 桌面版(profile desktop)、需要正確閱讀子進程中文輸出的開發者。許可證爲 MIT;npm 當前版本爲 0.1.1(見 package.json)。
亂碼從哪來¶
@deepseek-ai/dsh-subprocess-local 對 stdout/stderr 原始字節使用 Buffer#toString("utf8")。Windows 上子進程普遍按 OEM 代碼頁輸出,例如簡體中文 936 / GBK,繁體 950 / Big5,日文 932 / CP932。非法 UTF-8 會被替換成 U+FFFD(�),信息不可逆丟失,agent 只能看到亂碼;這與 bash 工具或命令寫法無關。
README 中的對比例子:亂碼時類似 ����λ�� ��:1 �ַ�: 134;安裝插件後同一輸出爲 所在位置 行:1 字符: 134。
本插件只實現簡體中文相關代碼頁:936 / GBK / GB18030 / CP936。950、932、949 沒有對應解碼器,這些語言輸出仍保持內核原樣(可能仍是亂碼),不會用 GB18030 去猜解以免錯字。
核心功能¶
接入方式¶
apply(ctx)取得subprocess服務並包裝spawn()。- 每個 handle 的
handle.collected.stdout/.stderr保留原始字節的OutputCollector。 - 替換上述 collector 的
readFrom()與finalize(),從原始字節重新解碼後交給上層。
不改命令、參數、退出碼、超時和 spillPath;純 UTF-8 / ASCII 在第 1 步判據下原樣返回。覆蓋所有走 subprocess 的調用(如 ops_bash、bash、pwsh 等)。重複加載、apply() 冪等;dispose 會還原 spawn。非 Windows 平臺 apply() 直接返回,不安裝補丁。
解碼順序¶
| 步驟 | 判據 | 結果 |
|---|---|---|
| 1 | 嚴格 UTF-8(fatal: true)能解 |
原樣返回 |
| 2 | 僅窗口首/尾截斷(≤3 字節殘片),其餘爲乾淨 UTF-8 | 寬容 UTF-8(邊緣可保留一個 U+FFFD) |
| 3 | 按 GB18030 嚴格可解(必要時跳過 1–3 字節重新對齊) | 按 GBK 解碼 |
| 4 | 都不成立 | 原樣返回,不比內核更差 |
第 2 步針對 collector 內存尾部窗口邊界截斷字符的場景,避免把大段正常中文誤判爲非 UTF-8。
安裝與啓用¶
要求:
- DSH 0.2.0 或更新;
- 內核
OutputCollector暴露snapshot()(0.2.x 桌面版),或早期構建的chunks/total字段。
插件以當前 DSH 進程權限運行;安裝前請自行查看 GitHub 倉庫 源碼與 MIT 許可證。
從 npm 安裝(推薦)¶
- 側邊欄 插件 → 安裝插件,輸入:
dsh-utf8-output
- 重啓 DSH(host 插件在 profile 啓動時加載)。
命令行等價寫法:
dsh plugin --profile desktop add dsh-utf8-output
從 GitHub 安裝¶
https://github.com/TLEWA/dsh-utf8-output
固定到標籤:
dsh plugin --profile desktop add github:TLEWA/dsh-utf8-output#v0.1.0
從源碼安裝¶
git clone https://github.com/TLEWA/dsh-utf8-output.git
cd dsh-utf8-output
npm test
dsh plugin --profile desktop add .
經過上面的步驟並重啓後,無需額外配置項;子進程輸出解碼即由插件接管。
典型用法¶
沒有單獨的配置文件或開關。安裝並重啓後,在 Windows 上通過 DSH 執行會走 subprocess 的命令即可驗證:例如 PowerShell 報錯信息、含中文路徑的 dir 輸出,應與系統控制台語義一致,而不再是滿屏 �。
開發與自測可在克隆倉庫後執行:
npm test # node test/run.mjs
npm run check
測試覆蓋解碼判定(UTF-8 截斷、GBK 錯位等)以及 spawn 包裝、冪等性與舊內核回退邏輯(見 README「開發與測試」)。
適用場景與注意¶
適合: Windows + 簡體中文 OEM 代碼頁(GBK/CP936)環境下的 DSH 用戶;依賴 agent 閱讀本地命令 stderr/stdout 的場景。
已知限制(摘自 README):
- GBK 字節序列若恰好是合法 UTF-8,會按 UTF-8 解(概率極低)。
- 窗口首字節截斷且殘片自成合法字符時,可能出現頭部錯字;插件不用啓發式猜解。
- 混合 UTF-8 與 GBK 按整體判斷,不分段嗅探;UTF-16/UTF-32 不處理。
- Big5、CP932、CP949 無解碼器。
- 超大輸出高頻輪詢時,讀取成本仍可能偏高(窗口約 2.8KB,單次約 10µs 量級,但複雜場景仍爲 O(n²) 量級行爲)。
DSH 生態主張「一切皆插件」;SkillHub 目錄頁 爲社區收錄,與 DeepSeek / 幻方無官方從屬關係。
結尾¶
dsh-utf8-output 在字節進入 agent 之前,用 GB18030/GBK 路徑重解 Windows OEM 中文輸出,並儘量保持 UTF-8 輸出不變。若你在 Windows 上被 DSH 子進程亂碼拖慢排障,可按上文 npm 或 GitHub 方式安裝後重啓驗證。
- 目錄頁:https://www.skillhub.cn/plugins/TLEWA/dsh-utf8-output
- 源碼與文檔:https://github.com/TLEWA/dsh-utf8-output