DeepSeek Harness · 系統地圖

一切皆外掛:官宣與原始碼對照

發布文裡說的四種模式、外掛生態,在 deepseek-harness 倉庫裡對應哪個檔案?本課一條條對上。

課程目標讀完本課,你能把發布文裡的說法講成兩個思路:為什麼 DSH 把模型轉接器、工具乃至 agent loop 全做成外掛;為什麼官宣的四種模式在原始碼裡只是四份外掛清單。你還能說出 PTC 模式在原始碼裡的真名。
互動演示 · 先玩再學

下面的演示把四份外掛清單做成了可切換的面板。點上面四個模式按鈕,看外掛卡片怎麼亮、怎麼滅:綠色是新增,紅色是移除,琥珀色是同名但配置變了。底部字幕會告訴你每一步發生了什麼。先玩明白,後面講的思路都在這塊面板裡演過一遍。

相對上一模式新增 相對上一模式移除 同名外掛、配置不同 本模式啟用 本模式未掛載
外掛清單摘自 apps/cli/config/agent-presets/ 下四份 agent.cordis.yml(核對日期 2026-08-13),外掛 id 與包名均為原始碼真名。macOS 視角,未列入僅 Windows 啟用的 tool-pwsh 與兩條 disabled 狀態的委派行。進入視野時自動輪播一遍四個模式,之後可自由點選。
思路一 · 核心只管裝卸,業務全是外掛

它解決什麼問題。想像你在用一個單體架構的 Agent 產品,想換掉它的會話日誌格式。你得 fork 倉庫,在幾十萬行原始碼裡找到日誌實現,改完重新構建,之後官方每發一版你都要重新合併一次補丁。這還只是日誌這種邊角能力,要是想換 agent loop 主迴圈,基本等於重寫產品。能力和產品原始碼焊死在一起,任何深度客製都會變成長期維護負擔。

思路是什麼。DSH 把核心縮到最小。vendor 進倉庫的 Cordis 框架只做三件事:把外掛裝進共享上下文、把外掛卸下來、把每次註冊記成可逆的副作用,外掛解除安裝時自動回滾。業務邏輯一行都沒有。然後所有能力搬進 packages/,49 個分組、219 個包,全部以外掛形式存在:模型轉接器是外掛,工具是外掛,會話日誌是外掛,連 agent loop 主迴圈本身也是外掛。根 AGENTS.md 第 3 行用加粗英文寫著「everything is a plugin」。官方文件的原話:

Cordis 是 dsh 底層的框架:外掛向共享上下文貢獻服務、型別化事件和可逆的副作用。產品的每一部分都是外掛,包括模型轉接器、工具註冊表、會話日誌,以及 agent loop(智慧體迴圈)本身,因此每一部分都可以從配置替換。

不存在需要打補丁的特權核心:擴充 dsh 的方式是把外掛掛載到其他外掛旁邊,而各項註冊都是副作用,會在其外掛解除安裝時撤銷。

docs/architecture.zh.md · 第 11、13 行
vendor/ Cordis 核心 外掛載入 / 解除安裝 依賴解析 副作用回滾,零業務邏輯 packages/ · 49 組 · 219 個包 · 全是外掛 core/ 產品 API 主幹 session · system-prompt · tools · agent-loop 能力 seam 系列 llm · fs · shell · sandbox · web · compaction … 會話與資料 session · storage · settings · credentials … 入口與 UI boot · host · client · api · acp · sdk 組合與生態 bundle · preset · extensions · hooks agent-presets/ 四份外掛清單 standard/ 標準 code/ PTC minimal/ 極簡 cordis/ 創造
教學化結構圖:分組歸類依據 AGENTS.md「Repository layout」與 packages/README.zh.md,內容經過課程化整理;包數為 2026-08-13 本地統計。

想給 DSH 加能力,也不用碰它的倉庫。樹外(out-of-tree,指官方倉庫之外的)外掛用 dsh plugin --profile <name> add <package> 裝進 profile,執行時掛載,解除安裝時註冊的副作用自動回滾。README 還約定外掛倉庫統一打 dsh-plugin 話題標籤,方便互相發現。發布文邀請大家共建生態,機制是現成的。

出處:packages/bundle/README.zh.md 第 13 行;README.zh.md 第 40 行;docs/architecture.zh.md 第 13 行

為什麼長期成立。微核心思想比這份程式碼老得多。作業系統課上的 Mach 和 L4,瀏覽器的擴充套件體系,VS Code 的外掛生態,走的都是同一條路:變化快的能力放外圈,幾乎不變的裝卸機制放核心。DSH 明年把 agent loop 重寫一遍,Cordis 的裝卸邏輯一行不用動;換個語言把整個 harness 再寫一遍,這個分層照樣管用。所以記這門課的結構比記它的程式碼划算,程式碼只是這個思路的某一版實現。

變化快的能力住在外掛裡,幾乎不變的裝卸住在核心裡。
思路二 · 模式就是一份清單

它解決什麼問題。多數產品的模式是硬編碼的:程式碼裡散著一堆類似 if (mode === 'lite') 的分支,模式數量在寫程式碼的那一刻就定死了。想新增一個模式,要改程式碼、過測試、等發版;想微調某個模式裡的一個能力,還是這套流程。使用者更沒得選,只能在官方給的幾個套餐裡挑。

思路是什麼。DSH 裡一個模式就是 apps/cli/config/agent-presets/ 下的一個目錄,目錄裡兩個檔案。preset.yml 只有 3 行,管 UI 上的展示名和排序;agent.cordis.yml 是外掛清單,啟動時 Cordis 照著清單逐行掛載,輸出一個組裝好的 Agent。切換模式就是換一份清單重新組裝,原始碼裡沒有任何模式分支。四種模式的差異,看四張卡就夠了:

標準模式

agent-presets/standard/ · 251 行
給誰用
日常寫程式碼的人,這是預設檔。
與其他模式的關係
它就是基準:23 個外掛全開(macOS 視角),檔案編輯、shell、檢索、計劃、子代理、工作流都在。其餘三個模式全部描述成對它的加減。
背後的思路
先定義一個能力齊全的參照系,別的組合才有資格用一句話說清自己。
出處:standard/agent.cordis.yml 全文

PTC 模式

agent-presets/code/ · 262 行
給誰用
跑多步長任務、嫌一次一個工具呼叫往返太慢的人。
比標準多了什麼少了什麼
standard 一行不動,末尾多掛一個 tool-presentation,配置 mode: code。模型改寫一段 TypeScript 小程式,run_code 一次執行原本要五次往返的操作。
背後的思路
改的只是工具的呈現方式,能力本身沒變,所以差異只配擁有一行。
出處:code/agent.cordis.yml 第 259 至 262 行,第 3 行註釋寫明 standard 全量未動

極簡模式

agent-presets/minimal/ · 62 行
給誰用
跑模型基準測試的人。
比標準多了什麼少了什麼
只剩 6 個外掛。persona 一句話寫死(complete: true,別的外掛想追加提示詞也加不進去),工具只有持久 bash 和 str_replace_editor,沒有 compaction(上下文壓縮)。
背後的思路
把 harness 的變數排乾淨,剩下的表現就是模型本身。
出處:minimal/agent.cordis.yml 全文 62 行,persona 見第 8 至 13 行

創造模式

agent-presets/cordis/ · 262 行
給誰用
想讓 Agent 造 Agent 的人。
比標準多了什麼少了什麼
standard 全套之上加 tool-cordis 工具集、一個教組合寫法的 skill,persona 也換了版本。Agent 能在執行時檢查並掛載自己的外掛,寫出的組合能存成新 preset。
背後的思路
組裝器自己也是外掛,所以能開放給 Agent 用。檔案頭註釋提醒把這個模式的會話當 shell 權限對待。
出處:cordis/agent.cordis.yml 第 245 至 246 行,權限提醒見第 9 至 12 行

順帶點破一個行銷詞。code/preset.yml 第 1 行寫 name: PTC 模式,但目錄叫 code,原始碼註釋和文件裡這套機制叫 Code Mode,全倉庫找不到名為 PTC 的實現。PTC 只活在 UI 文案層,跟人聊原始碼時說 Code Mode 才對得上號。

切換模式,就是換一份清單重新組裝。

為什麼長期成立。這條思路有個通行的名字,配置即架構:把系統之間的行為差異收斂進一份宣告式清單,架構問題就降維成文字問題。想知道兩個模式差在哪,diff 兩份 YAML;想造新模式,複製目錄改幾行;出了問題,回滾清單就行。Kubernetes 用 YAML 宣告叢集,Docker 用 Dockerfile 宣告映像,同一個思路在不同層面反覆出現。DSH 的外掛實現哪天全部重寫,清單這層抽象照樣成立。

橫向對比 · 加能力要不要改倉庫原始碼

一切皆外掛的價值放到同行裡才看得清。同一個問題,想給 Agent 加一個新能力,需不需要動它的倉庫原始碼,三家給出三種答案:

DSH:外掛樹

不需要改倉庫

能力就是一個樹外 npm 包。dsh plugin --profile <name> add <package> 裝進 profile,執行時掛載,解除安裝時註冊副作用自動回滾。模式級差異也只是 YAML 裡增刪幾行。

出處:packages/bundle/README.zh.md 第 13 行;docs/architecture.zh.md 第 13 行

Claude Code:產品單體

看情況

還原原始碼是一棵 TypeScript 單體原始碼樹(restored-src/src/,入口 main.tsx),改內建功能要動產品原始碼。對外留了 hooks、MCP、Skills 這些擴充點,能加工具和攔截點,換不掉會話日誌這類深層實現。基於已公開證據(還原原始碼目錄結構)。

Grok Build:Cargo Workspace

需要改倉庫

根 Cargo.toml 的 members 陣列列了 79 個 workspace 成員(本地計數),能力按 crate 切分、編譯期組合。新增能力要新建 crate、改根清單、重新編譯。切分細節見 12-1 · 79 個 Workspace 成員如何組成產品。

三家沒有絕對優劣。Grok 用編譯期組合換 Rust 的型別和效能保證,Claude Code 用單體換產品迭代速度,DSH 用外掛樹換執行時可拔插。只是如果你想要一個可替換、可審計的執行時,DSH 是三家裡唯一讓第三方無需 fork 倉庫就能替換深層能力的。

課堂練習
01

從清單推演行為差異

把 standard/agent.cordis.yml 裡 id: compaction 的整個 group(第 137 至 155 行)刪掉,得到的會話和極簡模式在上下文壓力下的表現是否等價?再對照 minimal/agent.cordis.yml 的 persona 三個欄位(第 8 至 13 行),說出除了壓縮之外還差哪兩點。

Takeaway:DSH 的核心只管外掛的載入、解除安裝與依賴,能力全部是 packages/ 裡的外掛。官宣的四種模式在原始碼裡是四份 agent-presets 外掛清單,切模式就是換清單重新組裝。PTC 這個名字只活在 preset.yml 的展示名裡,機制的真名叫 Code Mode。