iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0
AI Engineering

《30 天從零拆解 AI Agent:從 Tool Calling 到多 Agent 協作》系列 第 28

【AI Agent 28】DeepSeek Harness 架構拆解:如果連 Agent Loop 都只是一個 Plugin,Harness 會變成什麼?

  • 分享至 

  • xImage
  •  

Day 25 到 Day 27,我們看了三種很不一樣的 Agent Harness。

Claude Code:

完整 Production Coding Harness。

Hermes Agent:

長期存在、會記憶、會排程、跨 Channel 的 Agent。

mini-swe-agent:

把 Harness 壓到最小,只留 Loop、Bash、Budget 與 Eval。

今天要看第四種方向。

它不是單純問:

Harness 應該有多少功能?

而是問:

Harness 本身要怎麼被組裝?

這就是 DeepSeek Harness 最有辨識度的地方。

Awesome Agent Architecture 目前研究的版本固定在:

dsh-v0.1.0-rc.7

在 A3 的 system matrix 裡,它被定位成:

Plugin-first harness: even the loop is a replaceable plugin.

而 companion repo learn-deepseek-harness 把它濃縮成一句更直接的規則:

Everything is a plugin, and every registration is reversible.

這篇的重點不是介紹 DeepSeek Model。

也不是比較 Coding 能力。

而是拆一個非常不同的 Harness 思想:

  1. Plugin Kernel
  2. Durable Session Log
  3. Derived Model View
  4. Scoped Tool Pipeline
  5. Capability Seams
  6. Runtime Composition

第一個錯誤等號:Plugin = 額外功能

一般系統談 Plugin,常常是:

Core Agent
+
Optional Plugin A
+
Optional Plugin B

也就是:

Core 先存在,Plugin 只是加功能。

DeepSeek Harness 更激進。

它的核心方向更接近:

Kernel
↓
Plugins register capabilities
↓
Composition becomes the Agent

甚至 Agent Loop 本身也是可替換的一個 Plugin。

這代表:

不是 Core Agent 擁有 Plugins,而是 Plugin Composition 定義了這次 Agent 到底是什麼。

這是理解 dsh 最重要的第一步。


1. Cordis Kernel:Harness 先解決「怎麼組裝」,再解決「Agent 做什麼」

DeepSeek Harness 建在 Cordis 這類 Plugin Runtime 上。

最核心的概念不是:

class Agent

而是:

Context
+
Services
+
Events
+
Effects
+
Plugins

Plugin Mount 時可以:

  • 註冊 Service
  • 註冊 Tool
  • 註冊 Event Listener
  • 提供 Capability
  • 修改 Composition

Plugin Unmount 時,這些 Registration 必須能被撤回。

所以 companion repo 把第一個核心規則定義成:

Every registration is reversible.


2. 為什麼 Reversible Registration 很重要?

想像你有一個 Plugin:

github-tools

它載入時註冊:

  • Tool
  • Event Listener
  • Prompt Section
  • Service

如果 Unload 時每個 Plugin 都要自己記得 Cleanup:

remove tool
remove listener
remove prompt
remove service

很容易漏。

漏掉一個 Listener,就可能出現:

  • 重複執行
  • Ghost Tool
  • Stale Prompt
  • Memory Leak
  • Old Policy 還在作用

所以 DeepSeek Harness 的 Kernel 更接近:

Plugin mount
↓
所有 registration 綁在同一個 lifecycle

Plugin dispose
↓
Runtime 自動 reverse effects

這讓「卸載能力」變成 Framework Property。

不是每個 Plugin 作者的自律。


3. 這和 Hooks 有什麼不同?

Hooks 是:

在已知 Lifecycle Event 插入行為。

Plugin Kernel 更廣。

Plugin 可以提供:

  • Hook
  • Tool
  • Service
  • Agent Loop
  • Session Behavior
  • Prompt Provider
  • Scheduler
  • Integration

所以 Hook 是 Extension Point。

Plugin 是 Composition Unit。

兩者不要混在一起。


4. Session Log:DeepSeek Harness 最值得學的第二個核心

一般 Agent 最常保存的是:

messages[]

也就是:

User
Assistant
Tool
Assistant
...

DeepSeek Harness 的設計方向更接近:

Session 先保存完整 Event Log,再從 Log 推導模型要看的 messages[]。

也就是:

Append-only Session Events
↓
deriveMessages()
↓
Model-visible History

這是一個很重要的反轉。

messages[] 不再是 Durable Truth。

它只是一個 Projection。


5. Log 是 Truth,messages[] 是 View

可以想像 Session 中保存:

turn/start
user/message
step/start
assistant/chunk
assistant/message
tool/call
tool/result
step/end
turn/end

真正 Durable 的是這些 Event。

模型下一輪要看的:

messages[]

deriveMessages() 從 Event Log 重新建立。

所以:

Session Log
=
Truth

Model Context
=
Derived View

這和 Day 9 Context Management 的概念非常一致。

Storage 不等於 Context。


6. 為什麼 Append-only Log 這麼有價值?

如果你直接修改 messages[]

刪除舊 Tool Result
替換舊 Summary
插入新的 Compaction

很難回答:

原本真正發生過什麼?

Append-only Log 則保留歷史。

你可以:

  • Replay
  • Resume
  • Inspect
  • Audit
  • Telemetry
  • Re-derive View

這對 Long-running Agent 特別重要。

因為:

Context 可以被壓縮,但歷史事實不一定要被銷毀。


7. Model-visible ≈ Logged

DeepSeek Harness 架構中特別值得注意的一個 invariant 是:

如果某個資訊真的影響模型,它應該可以從 Session Log 重建。

也就是概念上:

Model-visible
⇔
Logged

這個原則非常強。

因為它直接改善 Debug:

如果 Agent 做出一個奇怪決策,我們可以問:

它當時到底看到了什麼?

然後從 Log 重新 Projection。

而不是猜某個 Runtime Object 當時長什麼樣。


8. Compaction:縮 View,不改 Truth

如果 Log Append-only,那 Context 快滿時怎麼辦?

這就是 DeepSeek Harness Context Management 最有特色的地方。

它不一定要刪掉原始 Event。

可以改:

哪些 Event 被投影到目前 Model Surface。

概念:

Full Log
↓
Surface / Projection
↓
Compact Model View

A3 對 DeepSeek Harness 的整理是:

spill
↓
prune
↓
summary event

歷史 Log 仍然存在。

縮小的是模型當下看到的 View。

這可以用一句話記住:

History is durable. Context is replaceable.


9. 這比 Summary-only 有什麼優點?

如果你直接:

Old History
↓
Summary
↓
Delete Old History

Summary 一旦漏掉資訊,很難恢復。

如果原始 Log 還在:

Summary
只是目前 View

Raw Events
仍然可以重新讀

就能做到:

  • Rehydration
  • Replay
  • Better Future Summary
  • Audit

代價則是:

  • Disk Log 持續成長
  • Persistence 更複雜
  • Projection / Surface 需要更多規則

這是一個很清楚的 Trade-off。


10. Agent Loop 本身也是 Plugin

這是 DeepSeek Harness 和前三個系統差異最大的地方。

一般架構:

Agent Core
內建 Loop

dsh 的方向:

Agent Interface
↓
Default Agent Loop Plugin

也就是 Default Loop 只是某個 Provider。

理論上可以被替換。

這代表:

Loop 不再是產品不可動的中心,而是一個 Capability Implementation。

如果未來要換:

  • Different Loop
  • Different Turn Machine
  • Different Model Driver

不一定需要 Fork 整個 Harness。


11. 每一步重新 Assemble Prompt、重新 Derive History

既然:

Log = Truth

那每次 Step 就可以:

Read Log
↓
Derive messages[]
↓
Assemble System Prompt
↓
Resolve Tools
↓
Call Model

這和一般「持有一個 mutable messages list 一路 append」的 Mental Model 很不一樣。

它更接近:

Runtime State 每一輪重新投影成 Model Request。

這正是 Day 11 Prompt Assembly 的極端版本。


12. Tool Pipeline:Denied / Error 也要變成正常 Observation

DeepSeek Harness 的 Tool Layer 也很值得看。

companion repo 把它整理成:

scoped registry
↓
pre
↓
ask
↓
guard
↓
execute
↓
post

這說明 Tool Call 不只是:

name → function

而是一條 Execution Pipeline。

更重要的是:

Denied 或 Error 的 Tool Call 也應該產生正常 Tool Result。

為什麼?

因為對 Agent 來說:

Permission Denied

也是 Environment Observation。

如果 Runtime 直接 Crash,Loop 無法學到:

這條路不能走。


13. Synthetic Result:即使沒有真的執行,也要把狀態閉合

DeepSeek Harness 的 Tool Scheduler 還有一個很值得研究的細節:

如果某個平行 Tool Call 因為前面的 Exclusive Operation 或 Abort 而沒有真的開始,系統仍可能需要產生一個對應 Result。

為什麼?

因為 Model 已經產生:

tool/call

如果沒有對應:

tool/result

Session Protocol 會留下半個 Interaction。

所以:

Protocol Completeness 有時比「真的有執行」更重要。

即使 Tool 沒跑,也要告訴模型:

這個 Call 被取消 / 未執行。


14. Parallel Tool Scheduler:平行不是全部一起跑

DeepSeek Harness 對 Tool Scheduling 也提供一個很好的例子。

有些 Tool:

read-only
parallel-safe

可以重疊執行。

有些 Tool:

exclusive
state-mutating

需要形成 Barrier。

所以 Scheduler 不能只是:

asyncio.gather(all_tools)

而要知道:

哪些可以平行,哪些必須序列化。

這和 Day 7 Subagent 的 Parallelism 問題完全一樣。

Parallel 是 Scheduling Decision。

不是「有多個 Call 就一起跑」。


15. Inbox:Steering 不應該隨時插進正在執行的 Step

Long-running Agent 常需要接受新資訊:

使用者補充需求
外部 Event
新的 Steering

但如果任何時間都直接插入 Runtime,可能破壞:

  • Tool Call / Result Pair
  • Current Step
  • State Consistency

DeepSeek Harness 用 Inbox / Step Boundary 的概念處理這件事。

可以理解成:

New Message
↓
Inbox
↓
在安全 Boundary Claim
↓
進入下一個 Step / Turn

也就是:

Interrupt 有入口,但不是任意時刻 Mutation。


16. System Prompt:Dynamic State 不一定全部塞 System Role

DeepSeek Harness 的 Prompt Assembly 還有一個有趣選擇。

Stable Section 可以組成 System Text。

但 Runtime Dynamic State 可以被重新發射成一個 Context Snapshot,而不是把所有東西都永久混進 System Prompt。

這讓不同來源維持比較清楚的身份:

Stable System Policy

Tool Schemas

Dynamic Runtime Context

Session History

這和 Day 11 的核心完全一致:

Prompt 是 Assembly Result,不是一個靜態字串。


17. Skills:Catalog 進 Context,Body 透過 Tool Load

DeepSeek Harness 的 Skill 方向也非常符合 Progressive Disclosure。

不是:

所有 Skill Body
全部塞 Context

而是:

Skill Catalog
先讓模型知道有什麼

需要時
Tool Call 載入 Skill Body

也就是:

Discover
↓
Select
↓
Load

這和 Day 8 的 Skill Architecture 對得非常乾淨。


18. Capability Seam:不是有 Interface 就算可替換

DeepSeek Harness companion repo 特別把 Capability Seam 拆成三個角色:

  1. Definition
  2. Provider
  3. Consumer

例如 Filesystem:

Definition
定義 Filesystem Capability

Provider
Local FS / Remote FS / Sandbox FS

Consumer
Model-facing Tool 或其他 Plugin

只有 Interface 不夠。

如果 Consumer 還直接 import 某個 Local Implementation,就沒有真正可替換。

所以真正的 Seam 必須是:

定義、實作、使用者三者分離。


19. Provider Swap 可以搬動整個 Execution World

這個 Capability Seam 的價值在 Sandbox / Remote Environment 特別明顯。

如果:

Filesystem
+
Subprocess

都依賴同一個 Execution Provider。

把 Provider 從 Local 換成 Remote Sandbox 後:

File
Shell
PTY
LSP

都可以跟著移動。

不需要每個 Tool 各自寫:

LocalTool
RemoteTool
DockerTool

這是 Plugin-first Architecture 真正的收益。


20. Jobs:Background Work 的重點是 Ownership

DeepSeek Harness 的 Job Capability 很適合對照 Day 14。

一旦 Background Job 建立:

job_id

下一個問題不是:

怎麼 Poll?

而是:

誰擁有取消這個 Job 的權限?

如果 Child 建了一個 Job,Parent 是否可以 Cancel?

Session Dispose 時 Job 怎麼辦?

所以 Job Protocol 需要:

  • Owner
  • Handle
  • Cancellation
  • Result

這就是 owner-fenced background-work protocol 的價值。


21. Subagent:用 Provider Registry,而不是 subclass Agent

另一個很有 Plugin 味道的設計是 Subagent。

一般 OOP 直覺可能會做:

class ResearchAgent(Agent)
class CodingAgent(Agent)

DeepSeek Harness 更接近:

Delegation Interface
↓
Named Provider Registry
↓
某個 Provider 建立 Child
↓
回傳 Run Handle

也就是 Subagent 是 Capability。

不是固定 Class Hierarchy。

這讓不同 Child Runtime 可以被替換。


22. Composition:Agent 是一組 Mount 起來的 Capability

前面所有東西最後會在 Composition 層相遇。

例如一個 Agent Preset 可以決定:

  • 哪個 Loop
  • 哪些 Tools
  • 哪些 Prompt Providers
  • 哪個 Sandbox
  • 哪些 Skills
  • 哪些 Integrations
  • 哪些 Guards

所以真正的 Agent 更像:

Composition
=
Plugin Set
+
Config
+
Providers

不是:

One giant Agent class

這是 DeepSeek Harness 和 Claude Code / mini-swe-agent 最不同的 Mental Model。


23. 為什麼 Patch 是 Whole-config Replace,而不是 Deep Merge?

Companion repo 對 Composition 有一個很值得學的決策:

Patch Layer 對整個 Config Entry List 做 Replacement,而不是偷偷 Deep Merge。

原因是 Deep Merge 很容易產生:

  • 不知道哪一層留下舊值
  • Array Merge Semantics 不清楚
  • 刪除某個設定很困難
  • Config Provenance 難追

Whole-config Replace 雖然比較明確地要重述 Config,但結果更容易推理:

這一層最後到底產生什麼 Composition?

對 Plugin System 來說,可預測性很重要。


24. ACP:Agent Runtime 和 Client Interface 可以分離

DeepSeek Harness 還有 ACP 這類 Automation / Editor Bridge。

它再次說明:

Agent Core 不應該和某一個 UI 綁死。

外部 Client 可以透過 Protocol:

  • 建 Session
  • Send Prompt
  • Receive Update
  • Cancel
  • Handle Permission

而 Agent 內部仍然使用同一套:

Session
Agent
Tools
Events

這和 Day 18 Protocol / Day 20 Channels 的邊界一致。


25. DeepSeek Harness 和 Claude Code 的差異

可以簡化成:

Claude Code DeepSeek Harness
核心印象 完整 Coding Harness Plugin-first Runtime
組裝方式 完整產品內部 Harness Cordis Plugin Composition
Session Mental Model Interactive coding session Append-only event-sourced log
Loop Harness 核心的一部分 可替換 Agent Loop Provider
Context Reduction / compaction 從 durable log 投影 Surface
擴充 Hooks / Tools / MCP / Subagents Services / Events / Plugins / Providers
最值得學 Production control surface Runtime composition and durable truth

兩個都很完整。

但設計重心不同。


26. DeepSeek Harness 和 mini-swe-agent 的差異更極端

mini-swe-agent:

One loop
One bash tool
One environment
One budget

DeepSeek Harness:

Kernel
+
Plugin Lifecycle
+
Event Log
+
Projection
+
Capability Seams
+
Composition

mini 的問題是:

最少要多少 Harness?

dsh 的問題是:

Harness 變大後,怎麼讓每個部分仍然可替換、可卸載、可重組?

這是兩個完全不同的最佳化方向。


27. DeepSeek Harness 最值得學的不是 Plugin 數量

如果只看目錄,你可能會覺得:

這只是很多 Package。

真正有價值的是背後三個 Invariant。

  1. Everything is a plugin, and every registration is reversible.:能力不是永久黏在 Core 上。
  2. Session log is durable truth.:Model Context 是 Projection,不是唯一 State。
  3. Model-visible state should be reconstructable.:如果資訊影響 Model,就應該能從 Runtime Record 找回來。

Failure Modes

Plugin-first Architecture 也不是免費的。

  1. Plugin Dependency 變複雜:如果 Plugin 依賴關係很多,Load Order 和 Capability Availability 會變難推理。
  2. Event Vocabulary 失控:所有 Plugin 都能擴展 Event,Persistence / Compatibility 會變成重要問題。
  3. Session Log 無限增長:Context 可以縮,但 Durable Log 仍然需要 Storage / Compaction Strategy。
  4. Projection Bug:Log 是對的,但 deriveMessages() 或 Surface Projection 錯。模型仍然會看到錯的世界。
  5. Provider Swap 破壞隱含假設:Interface 一樣,不代表 Performance / Side Effect / Latency 一樣。Capability Seam 仍然需要 Contract Test。
  6. Plugin 太自由:Everything is a plugin 不代表所有 Plugin 都應該被信任。Permission 與 Trust Boundary 仍然存在。
  7. Composition 太動態:如果每一輪 Composition 都能任意改,Debug 會非常困難。所以 Preset / Version / Session Record 很重要。

從 DeepSeek Harness 可以帶走的八個原則

  1. Agent 不一定是一個 Class,也可以是一組 Plugin Composition。
  2. Plugin 的重點不是能 Load,而是能乾淨 Unload。
  3. Durable Truth 和 Model View 應該分開。
  4. Context Compaction 可以縮 Projection,不必銷毀 History。
  5. Denied / Cancelled Tool Call 也要形成完整 Observation。
  6. 真正的 Capability Seam 需要 Definition、Provider、Consumer 三者分離。
  7. Background Job、Subagent、Loop 都可以是 Capability,不一定是硬寫在 Agent Core。
  8. Composition 本身就是 Harness Architecture。

四個系統放在一起看

到 Day 28,我們已經有四個非常不同的答案:

System 最值得學的地方 核心問題
Claude Code Full Harness Model 怎麼安全地碰真實 Repository?
Hermes Agent Memory / Skills / Always-on Agent 怎麼跨時間長期存在?
mini-swe-agent Minimal Loop / Budget / Eval 最少多少 Harness 就夠?
DeepSeek Harness Plugin Kernel / Session Log / Composition Harness 變大後怎麼保持可組裝與可替換?

這四個系統不是互相取代。

它們其實對應四種不同壓力:

Claude Code
Complex Environment

Hermes
Long Time Horizon

mini-swe-agent
Minimal Research Surface

DeepSeek Harness
Runtime Composition Complexity

這也是為什麼學 Agent Architecture 最有效的方法,不是只追一個 Framework。

而是:

用同一套 Mechanism Lens 去比較不同 Harness,在不同 Failure Mode 下做了什麼取捨。


今天的結論

DeepSeek Harness 最有價值的設計,不是「它用了 Plugin」。

而是它把 Plugin 思想一路推到 Harness 核心:

Loop
Tools
Prompt
Session
Jobs
Subagent
Capability
Composition

都可以透過明確的 Seam 被組裝。

同時,它用 Append-only Session Log 把:

發生過什麼

和:

模型現在看到什麼

分離。

最後可以把整篇壓成一句:

Claude Code 教我們怎麼控制 Agent,Hermes 教我們怎麼讓 Agent 長期存在,mini-swe-agent 教我們怎麼刪掉不必要的 Harness,而 DeepSeek Harness 教我們怎麼讓 Harness 本身可組裝。

完整系列與程式碼範例收錄於 https://github.com/hardness1020/awesome-agent-architecture


上一篇
【AI Agent 27】mini-swe-agent 架構拆解:你的 Agent 真的需要那麼多 Harness 嗎?
下一篇
【AI Agent 29】Eval-first:不要先加複雜架構,先驗證你在解決什麼問題
系列文
《30 天從零拆解 AI Agent:從 Tool Calling 到多 Agent 協作》29
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言