【DeepCode】Harness Engineering 标杆深度解析:HKU 16k stars 的完整 Agent 工程化实战
一句话结论:HKUDS/DeepCode 是当前 GitHub 上唯一一个用
core/harness/作为顶层目录命名的开源项目,它把 Harness Engineering 的六件套(Rule / Skill / Sub-Agent / Workflow / Script / MCP)当作一等公民分层实现,是研究 Harness 成熟度模型的标杆样本。
前言:为什么这次要拆 DeepCode?
过去 14 天,我连续写了 7 篇 Harness 主题深度解析:IronCurtain 的策略编译器、Strands 的 Hooks 中间件、superpowers 的 14 个 SOP Skill、ten-framework 的 Graph 数据流……每篇都对应 Harness 六件套矩阵里的一个组件。
但一直有个问题没解决:这些项目都只覆盖矩阵的一两个组件。IronCurtain 只讲 Rule;superpowers 只讲 Skill;Strands 只讲 Hooks。一个真正完整的 Harness 长什么样? 答案藏在 HKUDS/DeepCode 这个项目里。
DeepCode 是香港大学 Data Intelligence Lab 出品的 Open Agentic Coding 平台,16.3k stars,2 天前刚 commit(2026-08-13),840+ 个文件。它做了件罕见的事:把 core/harness/ 作为顶层目录命名 —— 整个核心层就是 Harness:
1 | core/ |
读完这篇你会得到:
- Harness 六件套在 DeepCode 里如何分层(不是堆在一起,是按”机制 / 策略”切开)
- 三值权限引擎的真实代码(allow/ask/deny + last-match-wins + sensitive-path 强制)
- HooksEngine 的 fold 算法(5 个生命周期事件 + 声明序 vs 完成序分裂)
- Sub-Agent 邮箱 + Worktree 隔离(不阻塞 spawn + git worktree 隔离 + 3-way merge)
- Skills Provider 协议设计(Opaque ID + 不可变清单 + 能力声明)
- 与 Claude Code / OpenAI Agents SDK 的设计哲学对比
一、DeepCode 在 Harness 六件套里的定位
1.1 六件套覆盖度矩阵
| 组件 | DeepCode 实现 | 关键文件 | 评级 |
|---|---|---|---|
| Rule | core/harness/permissions.py(三值)+ 集中式敏感路径硬约束 | permissions.py:53-79 | ⭐⭐⭐⭐⭐ |
| Skill | core/skills/(完整 Provider 协议 + 不可变清单 + 能力声明) | skills/models.py, skills/host.py | ⭐⭐⭐⭐⭐ |
| Sub-Agent | core/harness/agents/control.py(邮箱通信 + 5 并发 + worktree 隔离) | agents/control.py | ⭐⭐⭐⭐⭐ |
| Workflow | workflows/(交互工作流定义,YAML + agents/) | workflows/ | ⭐⭐⭐ |
| Script | core/harness/sandbox.py(硬关卡:seatbelt/bwrap/Job) | sandbox.py | ⭐⭐⭐⭐⭐ |
| MCP | core/mcp/(不可变 Runtime Plan + OAuth + Preset 目录) | mcp/runtime.py | ⭐⭐⭐⭐⭐ |
DeepCode 是当前唯一一个把六件套组件全部实现到工程级别(不是 demo)的开源 Harness。其他项目要么只覆盖 1-2 件套(IronCurtain 只做 Rule、Strands 只做 Hooks),要么是更上层的产品包装(metaHarness、Yuxi)。DeepCode 是中间的”机制层”。
1.2 设计哲学:机制 vs 策略
DeepCode 的核心设计文档(core/harness/__init__.py:1-9)开篇就定调:
Design rule: these modules are pure mechanism — they decide and wrap, they never talk to models or UIs. Enforcement points live in the kernel (AgentRunSpec.permission_checker) and in tool executors.
翻译:Harness 模块只负责”决定和包装”,绝不和模型对话,也不和 UI 对话。策略调用(要不要询问、怎么询问)由 kernel 注入。
这种机制(mechanism)与策略(policy)的彻底分离是 DeepCode 区别于大多数 Harness 项目的核心设计哲学。我把它总结为一句话:
DeepCode 提供”决策原语”,不提供”决策答案”。
二、架构深度解析:从入口到 6 件套
2.1 顶层架构图
graph TB
User["👤 用户<br/>CLI / Desktop / Headless"]
App["🚀 Application 层<br/>core/application/<br/>DeepCodeApplication"]
subgraph Harness["🛡️ core/harness/ (Harness 核心)"]
Perm["⚙️ PermissionEngine<br/>三值 allow/ask/deny<br/>last-match-wins"]
Sand["🔒 SandboxBackend<br/>seatbelt/bwrap/Job"]
Hook["🪝 HooksEngine<br/>10 个生命周期事件"]
Agent["🤖 AgentControl<br/>Sub-Agent 邮箱 + worktree"]
end
subgraph Loop["♻️ Loop Engineering"]
AutoDream["💤 autodream<br/>离线记忆整理"]
end
subgraph Skills["📚 core/skills/"]
SkillHost["SkillCatalogHost<br/>不可变清单"]
SkillProvider["SkillProvider<br/>local/executor/orchestrator"]
end
subgraph MCP["🔌 core/mcp/"]
McpPlan["McpRuntimePlan<br/>不可变"]
McpRuntime["McpSessionRuntime<br/>→ ToolRegistry"]
end
Kernel["🧠 Agent Kernel<br/>core/agent_runtime/"]
Sessions["💾 Session<br/>core/sessions/"]
User --> App
App --> Kernel
App --> Harness
App --> Skills
App --> MCP
Kernel --> Sessions
Hook -.->|"事件触发"| Kernel
Perm -.->|"拦截工具调用"| Kernel
Sand -.->|"包装 shell 命令"| Kernel
Agent -.->|"spawn / interrupt"| Kernel
SkillHost -.->|"加载 SOP"| Kernel
McpRuntime -.->|"注册工具"| Kernel
AutoDream -.->|"整理 memory"| Sessions
style User fill:#C7CEEA,stroke:#9FA8DA,color:#333
style App fill:#E8D5F5,stroke:#CE93D8,color:#333
style Kernel fill:#E8D5F5,stroke:#CE93D8,color:#333
style Sessions fill:#F5F5F5,stroke:#999,color:#333
style Perm fill:#FFB3C6,stroke:#F48FB1,color:#333
style Sand fill:#FFB3C6,stroke:#F48FB1,color:#333
style Hook fill:#FFB3C6,stroke:#F48FB1,color:#333
style Agent fill:#FFB3C6,stroke:#F48FB1,color:#333
style AutoDream fill:#FFF9C4,stroke:#F9A825,color:#333
style SkillHost fill:#B5EAD7,stroke:#80CBC4,color:#333
style SkillProvider fill:#B5EAD7,stroke:#80CBC4,color:#333
style McpPlan fill:#FFDAB9,stroke:#FFB74D,color:#333
style McpRuntime fill:#FFDAB9,stroke:#FFB74D,color:#3332.2 数据流:从用户输入到工具执行
sequenceDiagram
participant U as 👤 用户
participant A as 🚀 Application
participant K as 🧠 Agent Kernel
participant P as ⚙️ PermissionEngine
participant H as 🪝 HooksEngine
participant S as 🔒 Sandbox
participant T as 🔧 ToolExecutor
participant Sk as 📚 Skill Catalog
participant M as 🔌 MCP Runtime
U->>A: 输入任务 ("重构 auth 模块")
A->>K: 启动 Turn
K->>Sk: 搜索匹配的 Skill
Sk-->>K: 返回 selected Skill (≤8 个)
K->>K: 拼装 system prompt + skills
K->>M: ensure_started() (OAuth / 连接)
M-->>K: tool registry (合并 MCP 工具)
K->>A: 返回初始 LLM 请求
loop 模型决策循环
K->>P: 评估工具调用 (tool_name, args)
P-->>K: ALLOW / DENY / ASK
alt ALLOW
K->>H: run_pre_tool_use
H-->>K: PreToolUseOutcome
K->>S: wrap_shell_command(cmd)
S-->>K: sandboxed_cmd
K->>T: 执行
T-->>K: tool_response
K->>H: run_post_tool_use
H-->>K: PostToolUseOutcome
else DENY
K-->>A: 工具被拒,返回错误给模型
else ASK
K->>U: TerminalApprover.ask()
U-->>K: 用户决定
end
end
K->>A: Turn 完成
A->>H: run_stop (停止钩子)关键观察:整个数据流中,Harness 层是纯横向拦截器(pre / post tool use),不参与决策内容。这种”拦截器式”架构让 DeepCode 可以独立升级 Harness 而不动 Kernel。
三、核心机制原理(含可运行代码)
3.1 三值权限引擎(Rule 组件)
DeepCode 的权限引擎是六件套中”Rule”组件的工程化典范。它有 3 个核心设计:
- 三值语义:
allow/ask/deny,比 Claude Code 的二元(allow/deny)更精准 - last-match-wins:多个规则匹配时,后者覆盖前者
- 集中式 sensitive-path 保护:硬约束
.ssh/.aws/credentials/.env等敏感路径
3.1.1 真实代码(来自 core/harness/permissions.py)
1 | # 简化版 PermissionEngine 核心逻辑 |
3.1.2 为什么是三值不是两值?
Claude Code 用 allow / deny 两值,DeepCode 用 allow / ask / deny 三值。这不是设计偏好,是真实场景需要:
| 场景 | Claude Code | DeepCode |
|---|---|---|
用户没配规则的 npm install | ❓ 默认行为模糊 | ✅ ASK:询问用户 |
用户配了规则 git push * | ❓ 行为不明 | ✅ ASK:明确询问 |
git status | ✅ ALLOW | ✅ ALLOW |
.ssh/ 读取 | ✅ DENY(但用户能改) | ✅ DENY(硬约束,不可改) |
关键差异:DeepCode 把”sensitive-path 保护”作为不可绕过的硬约束,和”用户规则”完全分层。即使 Full Access 模式也只能关闭它自己配的规则集合,不能关 sensitive-path。
3.2 平台沙箱(Script 组件)
3.2.1 三平台后端
DeepCode 的 core/harness/sandbox.py 实现了一个机制层沙箱:根据平台自动选择:
| 平台 | 后端 | 隔离强度 | 关键文件 |
|---|---|---|---|
| macOS | sandbox-exec (seatbelt) | closed-by-default SBPL 策略 | _SEATBELT_BASE_POLICY |
| Linux | bwrap (bubblewrap) | mount-namespace + --unshare-net | wrap_shell_command |
| Windows | Job Object | KILL_ON_JOB_CLOSE 进程树隔离 | core/harness/windows_sandbox |
3.2.2 真实代码片段(macOS seatbelt)
1 | # 来自 core/harness/sandbox.py:18-110 |
3.2.3 设计哲学:诚实的边界
core/harness/sandbox.py 的文档明确说出 DeepCode 不假装自己做了 seccomp-bpf:
Honest boundary: the reference agent adds seccomp-bpf + Landlock on Linux; those are kernel facilities Python cannot install from userspace, so DeepCode relies on bubblewrap’s namespaces (a real, standard isolation primitive) rather than faking an equivalent.
翻译:参考 agent 加了 seccomp-bpf + Landlock,但这两个是内核能力,Python 从用户态装不上。所以 DeepCode 不假装,只用 bubblewrap 的 mount-namespace(一个真实的标准隔离原语)替代。
这种”诚实承认能力边界”是 DeepCode 的核心风格 —— 它宁可显式说”Windows 的 Job Object 不限制写入,只做进程树隔离”,也不假装说”全方位沙箱”。
3.3 HooksEngine 总线(Script 组件的外部化)
3.3.1 10 个生命周期事件
HooksEngine 实现了完整的 Claude-Code 兼容事件总线:
| 事件 | 时机 | 关键字段 |
|---|---|---|
SessionStart | 会话开始 | source: "startup" |
UserPromptSubmit | 用户提交 prompt | prompt |
PreToolUse | 工具调用前 | tool_name, tool_input |
PostToolUse | 工具调用后 | tool_response |
PermissionRequest | 权限请求时 | tool_name, tool_input |
PreCompact / PostCompact | 上下文压缩前后 | trigger |
SubagentStart / SubagentStop | 子 Agent 启停 | agent_id, agent_type |
Stop | Turn 结束 | stop_hook_active |
3.3.2 真实代码:fold 算法
1 | # 来自 core/harness/hooks/engine.py:130-180 |
关键设计:声明序 vs 完成序的分裂
- block / reason / context 走 声明序:报告稳定性,谁先声明谁先报告
- updatedInput 走 完成序:实际生效按完成时间,最后完成的 handler 重写参数胜出
这种”双轨制 fold”是 HooksEngine 的灵魂 —— 让审计日志稳定(声明序),但实际拦截行为按时间发生(完成序)。
3.4 Sub-Agent 邮箱 + Worktree 隔离
3.4.1 核心数据类(来自 core/harness/agents/control.py)
1 |
|
3.4.2 spawn 设计:非阻塞 + 5 并发上限
1 | # 简化版(来自 core/harness/agents/control.py:114-180) |
3.4.3 Worktree 隔离(独立 git 环境)
1 | # 来自 core/harness/agents/control.py:62-64 |
这个设计的精妙之处:
- 非阻塞 spawn:父 Agent 不用等子 Agent 完成,5 个子可以并发跑
- 去重:同名子任务 5 秒内重复 spawn 会被拒绝
- worktree 隔离:每个子有自己的 git 环境,互不污染
_git_lock序列化:git 元数据操作(worktree 创建、merge)只能一个一个做,但子任务内部可以并行 build- 深度限制 1:
allow_spawn=False强制子不能再 spawn 子孙,避免递归爆炸
3.5 Skills Provider 协议(Skill 组件)
3.5.1 不可变 + Opaque ID 设计
1 | # 来自 core/skills/models.py:36-43 |
为什么 ID 不透明?
因为 DeepCode 支持多种 Skill 来源(本地 ~/.deepcode/skills/、Claude 兼容目录、executor 后端、orchestrator 后端)。如果用路径式 ID(/home/user/.deepcode/skills/foo),调用方就会对路径产生依赖,破坏协议中立性。Opaque ID 把”路径知识”封装在 Provider 内部,调用方只看到 sk_a1b2c3d4... 这种 ID。
3.5.2 Skill Turn Snapshot(每次 Turn 冻结一份)
1 | # 来自 core/skills/models.py 文档 |
关键设计:
- ✅ 持久化:身份(哪个 Skill)、调用类型、版本号
- ❌ 不持久化:Instruction body(防止审计日志泄露 SOP 机密)
这是 DeepCode 在隐私 vs 可审计之间的精确平衡:能查到”这个 Turn 用了哪个 Skill v1.2.3”,但不能反推”SOP 写了什么”。
3.6 MCP 不可变 Runtime Plan(MCP 组件)
3.6.1 Runtime 是不可变的
1 | # 来自 core/mcp/runtime.py:1-13 |
3.6.2 不可变 Runtime 的两个核心好处
- 启动幂等:重复
ensure_started()不重复启动 - 不可中途改变 tool set:Turn 中想换 MCP 配置?必须重启 runtime,不会发生”半新半旧”状态
这与 Anthropic MCP 官方的 mcp-go 实现(连接可热替换)形成对比。DeepCode 选择”启动时确定,Turn 中不变”的简单模型,对 Agent 推理的稳定性更友好。
3.7 Loop Engineering:autodream 离线记忆整理
1 | # 来自 core/loop/autodream.py:9-23 |
Loop Engineering 的精妙之处:
- off-the-critical-path:autodream 不在主 Agent 推理循环里跑,是独立后台 task
- scope 强制:prompt 显式约束”只许用
memory工具”,加上 P1 权限引擎在 memory 目录外的硬约束,双重锁 - 没有 test oracle:autodream 没有”对/错”二元判断,只有”before/after note 数量”这个机械信号,诚实地承认它的局限性
四、设计哲学:Bitter Lesson 自检
4.1 机制 vs 策略分层图
graph TB
subgraph Policy["📜 策略层(Policy)"]
UI["🖥️ UI 决策<br/>TerminalApprover"]
Model["🧠 LLM 决策<br/>是否 ask / continue"]
UserCfg["👤 用户配置<br/>YAML / settings.json"]
end
subgraph Mechanism["⚙️ 机制层(Mechanism)"]
PermE["PermissionEngine<br/>fnmatch 决策"]
SandE["SandboxBackend<br/>平台沙箱包装"]
HookE["HooksEngine<br/>事件 fold"]
AgentE["AgentControl<br/>邮箱调度"]
SkillE["SkillProvider<br/>不可变清单"]
McpE["McpRuntime<br/>启动/关闭"]
end
subgraph External["🌐 外部世界"]
OS["💻 操作系统<br/>syscall / FS"]
Net["🌐 网络<br/>OAuth / TLS"]
User["👤 用户"]
end
UI -.->|"注入决策"| PermE
Model -.->|"拼装 prompt"| SkillE
UserCfg -.->|"解析规则"| PermE
PermE --> OS
SandE --> OS
HookE --> OS
AgentE --> User
SkillE --> OS
McpE --> Net
style UI fill:#FFDAB9,stroke:#FFB74D,color:#333
style Model fill:#FFDAB9,stroke:#FFB74D,color:#333
style UserCfg fill:#FFDAB9,stroke:#FFB74D,color:#333
style PermE fill:#E8D5F5,stroke:#CE93D8,color:#333
style SandE fill:#E8D5F5,stroke:#CE93D8,color:#333
style HookE fill:#E8D5F5,stroke:#CE93D8,color:#333
style AgentE fill:#E8D5F5,stroke:#CE93D8,color:#333
style SkillE fill:#E8D5F5,stroke:#CE93D8,color:#333
style McpE fill:#E8D5F5,stroke:#CE93D8,color:#333
style OS fill:#F5F5F5,stroke:#999,color:#333
style Net fill:#F5F5F5,stroke:#999,color:#333
style User fill:#C7CEEA,stroke:#9FA8DA,color:#333DeepCode 在多个模块注释里反复强调一句话:
“Design rule: these modules are pure mechanism — they decide and wrap, they never talk to models or UIs.”
我对照 Sutton 的 Bitter Lesson 检查它的”机制 vs 策略”分层:
| 模块 | 写了多少”聪明但终将被淘汰”的代码 | Bitter Lesson 评分 |
|---|---|---|
permissions.py | 0 —— 纯 fnmatch 字符串匹配,LLM 来了依然需要 | ⭐⭐⭐⭐⭐ |
sandbox.py | 0 —— 直接调 OS 沙箱 API | ⭐⭐⭐⭐⭐ |
hooks/engine.py | 0 —— 调外部 shell 命令,结果 JSON 解析 | ⭐⭐⭐⭐⭐ |
agents/control.py | 极少 —— 去重靠字符串、并发靠 asyncio | ⭐⭐⭐⭐ |
skills/models.py | 0 —— 全是不透明 dataclass | ⭐⭐⭐⭐⭐ |
mcp/runtime.py | 0 —— 启动/关闭/状态机 | ⭐⭐⭐⭐⭐ |
结论:DeepCode 的 Harness 层几乎不含”聪明”代码。每个组件都是”接 OS 接口 + 包装数据 + 暴露 API”,LLM 进化不需要重写 Harness —— 这正是 Bitter Lesson 的胜利。
五、横向对比:DeepCode vs Claude Code vs OpenAI Agents SDK
5.0 HooksEngine fold 双轨合并图
graph LR
H1["🔧 handler_1<br/>(order=0)"]
H2["🔧 handler_2<br/>(order=1)"]
H3["🔧 handler_3<br/>(order=2)"]
H1 -->|"完成序"| Fold1["📋 _FoldedOutcome"]
H2 -->|"完成序"| Fold1
H3 -->|"完成序"| Fold1
H1 -->|"声明序"| Fold2["📋 block / reason / context"]
H2 -->|"声明序"| Fold2
H3 -->|"声明序"| Fold2
Fold2 -->|"任一 block"| Block["🛑 BLOCK<br/>(first-block-wins)"]
Fold2 -->|"全部累积"| Ctx["📝 additionalContexts<br/>(accumulate all)"]
Fold1 -->|"最后完成者"| Upd["✏️ updatedInput<br/>(last-writer-wins)"]
style H1 fill:#C7CEEA,stroke:#9FA8DA,color:#333
style H2 fill:#C7CEEA,stroke:#9FA8DA,color:#333
style H3 fill:#C7CEEA,stroke:#9FA8DA,color:#333
style Fold1 fill:#E8D5F5,stroke:#CE93D8,color:#333
style Fold2 fill:#E8D5F5,stroke:#CE93D8,color:#333
style Block fill:#FFB3C6,stroke:#F48FB1,color:#333
style Ctx fill:#FFF9C4,stroke:#F9A825,color:#333
style Upd fill:#B5EAD7,stroke:#80CBC4,color:#3335.1 三者核心差异
| 维度 | DeepCode | Claude Code | OpenAI Agents SDK |
|---|---|---|---|
| Rule 引擎 | 三值(allow/ask/deny)+ 强制 sensitive-path | 二值(allow/deny)+ 用户配置 | 无引擎,工具调用全放开 |
| 沙箱 | 平台原生(seatbelt/bwrap/Job) | OS 级(macOS seatbelt) | 无沙箱,靠应用层 |
| Hooks 事件 | 10 个生命周期事件 + 双轨 fold | 5-6 个事件 + 单 fold | 无 hooks |
| Sub-Agent | 模型驱动 spawn + worktree 隔离 + 邮箱 | Task tool 调用 + 单 in-process Agent | Handoff 协议 + 显式 context 转移 |
| Skills | Provider 协议 + Opaque ID + Turn Snapshot | SKILL.md 文件系统 + 简单加载 | 无 Skills 概念 |
| MCP | 不可变 Runtime Plan | 标准 MCP 客户端 | 标准 MCP 客户端 |
| 代码可读性 | 高(每个模块顶部大段设计文档) | 低(闭源) | 中(Python 包) |
| 学术血统 | HKU Data Intelligence Lab + arXiv 2512.07921 | Anthropic(闭源) | OpenAI(半开源) |
5.2 关键设计哲学对比
5.2.1 Sub-Agent 通信模型
graph LR
subgraph Claude["Claude Code (Task tool)"]
P1["父 Agent"] -->|"Task 调用"| C1["子 Agent"]
C1 -->|"result 返回"| P1
end
subgraph DeepCode["DeepCode (AgentControl)"]
P2["父 Agent"] -->|"spawn (非阻塞)"| C2["子 Agent 1"]
P2 -->|"spawn"| C3["子 Agent 2"]
C2 -.->|"settled event"| M["📬 共享邮箱"]
C3 -.->|"settled event"| M
M -.->|"activity wait"| P2
P2 -->|"send_message"| C2
end
subgraph OpenAI["OpenAI Agents SDK (Handoff)"]
P3["Agent A"] -->|"handoff 协议"| P4["Agent B"]
P4 -->|"handoff"| P5["Agent C"]
end
style P1 fill:#E8D5F5,stroke:#CE93D8,color:#333
style P2 fill:#E8D5F5,stroke:#CE93D8,color:#333
style P3 fill:#E8D5F5,stroke:#CE93D8,color:#333
style P4 fill:#E8D5F5,stroke:#CE93D8,color:#333
style P5 fill:#E8D5F5,stroke:#CE93D8,color:#333
style C1 fill:#B5EAD7,stroke:#80CBC4,color:#333
style C2 fill:#B5EAD7,stroke:#80CBC4,color:#333
style C3 fill:#B5EAD7,stroke:#80CBC4,color:#333
style M fill:#FFDAB9,stroke:#FFB74D,color:#333核心差异:
- Claude Code:父子严格串行,父等子完成才继续
- DeepCode:父子可并发,父能继续工作等子回信(
wait_for_activity) - OpenAI Agents SDK:无父子概念,handoff 是 Agent 间的对等交接(每个 Agent 是”专业领域专家”,用户提问触发 handoff 链)
5.2.2 Permission 决策模型
| 系统 | 决策粒度 | 配置载体 | 不可绕过的硬约束 |
|---|---|---|---|
| DeepCode | (tool_name, arg_pattern) → action | YAML + 代码 | ✅ sensitive-path 强制 |
| Claude Code | (tool_name) → action | settings.json | ❌ 用户可改 |
| OpenAI Agents SDK | 无 | 无 | ❌ |
5.2.3 Hooks 协议设计
DeepCode 直接 port 了 Claude Code 的 Hooks 协议(注释里说”Ports the reference agent’s registry.rs + engine/mod.rs + dispatcher.rs”)。这意味着 DeepCode 的 hooks 配置文件可以和 Claude Code 完全兼容,用户的 hook 脚本可以平滑迁移。
这是非常聪明的设计选择:不发明新标准,复用已存在的标准。从 Hooks 生态的复用性角度看,这是降维打击。
六、优缺点分析(按维度对比)
6.1 架构简洁性 / 扩展性 / 易用性(左侧维度)
| 维度 | DeepCode | 评级 |
|---|---|---|
| 架构简洁性 | ✅ 顶层 core/harness/ 命名直观,每个模块顶部都有 5-10 行设计文档,新人能 5 分钟理解模块职责 | ⭐⭐⭐⭐⭐ |
| 扩展性 | ✅ Skills 是 Provider 协议(可插拔 LOCAL/EXECUTOR/ORCHESTRATOR),Sub-Agent 支持 native/external CLI 后端 | ⭐⭐⭐⭐⭐ |
| 易用性 | ⚠️ CLI/TUI/Desktop 三入口 + Headless 自动化,但 学习曲线陡峭:840+ 文件,需要读 DEEPCODE_V2_MASTER_PLAN.md 才懂全貌 | ⭐⭐⭐ |
| 配置可读性 | ✅ YAML 优先,所有决策文件都是文本(hooks.json, permissions.yaml, mcp.json) | ⭐⭐⭐⭐⭐ |
6.2 性能 / 复杂度 / 维护性(右侧维度)
| 维度 | DeepCode | 评级 |
|---|---|---|
| 性能 | ✅ fnmatch + dataclass + 无 I/O 的 PermissionEngine,纳秒级决策;Sub-Agent 用 asyncio 并发 | ⭐⭐⭐⭐ |
| 复杂度 | ⚠️ 16.3k stars + 840 文件,二阶复杂度高:每个模块都要考虑和 sessions/observability/plugins 的交互 | ⭐⭐⭐ |
| 维护性 | ✅ 每个模块顶部大段设计文档 + 引用其他模块的 §4.3 等章节;模块间解耦好,改 PermissionEngine 不影响 HooksEngine | ⭐⭐⭐⭐⭐ |
| 学术严谨性 | ✅ 注释里明确说”Honest boundary” —— 承认 sandbox 不假装 seccomp-bpf,不假装 Windows 写保护 | ⭐⭐⭐⭐⭐ |
6.3 最适合 / 最不适合的使用场景
| 场景 | 适合度 |
|---|---|
| 大型企业内部 Coding Agent 平台 | ⭐⭐⭐⭐⭐(多租户 + 权限 + 沙箱 + Hooks 全套) |
| 学术研究 / Agent 论文实现 | ⭐⭐⭐⭐⭐(设计文档齐全 + 协议中立) |
| 个人开发者玩具项目 | ⭐⭐(学习曲线过陡,单人项目不需要 Harness 6 件套) |
| 快速原型 / Demo | ⭐⭐(840 文件规模太大,建议从 OpenAI Agents SDK 开始) |
| 跨平台分发(Win/Mac/Linux) | ⭐⭐⭐⭐⭐(沙箱三平台原生实现) |
七、从零搭建启示:我自己复刻时怎么做?
7.0 6 件套 MVP 实施路线图
graph TB
Start["🚀 开始:明确目标"]
P0["📦 P0 阶段(2 周)<br/>Rule + Script + MCP"]
P1["📦 P1 阶段(3 周)<br/>Skill + Sub-Agent + Hooks"]
P2["📦 P2 阶段(按需)<br/>Loop + Plugin + Multi-Sandbox"]
P0_R["⚙️ PermissionEngine<br/>fnmatch + 三值"]
P0_S["🔒 Sandbox<br/>Linux bwrap 优先"]
P0_M["🔌 MCP Runtime<br/>connect + 注册"]
P1_Sk["📚 SkillProvider<br/>SKILL.md + 不透明 ID"]
P1_Sub["🤖 AgentControl<br/>asyncio + Mailbox"]
P1_H["🪝 HooksEngine<br/>5 事件 + JSON"]
P2_L["♻️ autodream<br/>off-line"]
P2_P["📦 Plugin<br/>1.0.0 manifest"]
P2_W["🖥️ macOS/Windows<br/>sandbox"]
Test["🧪 集成测试<br/>E2E Harness"]
Done["✅ 完整 Harness"]
Start --> P0
Start --> P1
Start --> P2
P0 --> P0_R
P0 --> P0_S
P0 --> P0_M
P1 --> P1_Sk
P1 --> P1_Sub
P1 --> P1_H
P2 --> P2_L
P2 --> P2_P
P2 --> P2_W
P0_R --> Test
P0_S --> Test
P0_M --> Test
P1_Sk --> Test
P1_Sub --> Test
P1_H --> Test
Test --> Done
style Start fill:#C7CEEA,stroke:#9FA8DA,color:#333
style P0 fill:#FFF9C4,stroke:#F9A825,color:#333
style P1 fill:#FFDAB9,stroke:#FFB74D,color:#333
style P2 fill:#F5F5F5,stroke:#999,color:#333
style P0_R fill:#FFB3C6,stroke:#F48FB1,color:#333
style P0_S fill:#FFB3C6,stroke:#F48FB1,color:#333
style P0_M fill:#FFB3C6,stroke:#F48FB1,color:#333
style P1_Sk fill:#E8D5F5,stroke:#CE93D8,color:#333
style P1_Sub fill:#E8D5F5,stroke:#CE93D8,color:#333
style P1_H fill:#E8D5F5,stroke:#CE93D8,color:#333
style P2_L fill:#B5EAD7,stroke:#80CBC4,color:#333
style P2_P fill:#B5EAD7,stroke:#80CBC4,color:#333
style P2_W fill:#B5EAD7,stroke:#80CBC4,color:#333
style Test fill:#FFDAB9,stroke:#FFB74D,color:#333
style Done fill:#B5EAD7,stroke:#80CBC4,color:#333读完 DeepCode 源码后,我重新设计了一套”Harness 6 件套 MVP 落地清单”。如果你想自己复刻一个 DeepCode 风格的 Harness,按这个优先级做:
7.1 必须实现的 3 件套(P0,2 周可交付)
| 组件 | 最简实现 | 代码量 | 关键文件 |
|---|---|---|---|
| Rule | 三值 PermissionEngine + fnmatch | 150 行 | core/harness/permissions.py |
| Script | 单一平台 sandbox(建议先做 Linux bwrap) | 100 行 | core/harness/sandbox.py |
| MCP | 简单 connect/disconnect + tool 注册 | 200 行 | core/mcp/runtime.py |
MVP 复刻清单(精简版代码):
1 | # mvp_permission.py —— 150 行实现 DeepCode 三值权限引擎核心 |
7.2 第二阶段做的 3 件套(P1,3 周可交付)
| 组件 | 实现要点 |
|---|---|
| Skill | Provider 协议 + SKILL.md 解析器 + 能力声明 |
| Sub-Agent | asyncio.create_task + Mailbox + 单 worktree 隔离(先别做 3-way) |
| Hooks | 5 个核心事件(PreToolUse / PostToolUse / SessionStart / UserPromptSubmit / Stop)+ JSON 输出协议 |
7.3 可省略 / 暂缓的组件(P2,看需求)
- Loop Engineering(autodream):单 Agent 不需要,离线记忆整理是 10+ 用户场景才需要
- Plugin 协议:Skills + MCP 已经覆盖 80% 用例,Plugin 主要是企业级多团队分发
- 多平台 Sandbox:先做 Linux 一个平台,macOS/Windows 后加
7.4 踩坑预警(实测总结)
| 坑 | 现象 | 解决方案 |
|---|---|---|
cli 包名冲突 | from cli.tui import ... 解析到 site-packages 的第三方 cli 包 | DeepCode 在 deepcode.py 顶部显式 evict sys.modules 缓存 |
| 路径解析 | ~/projects/foo 在 PermissionEngine 里被解析成绝对路径才匹配 denylist | 先 os.path.expanduser 再 Path.resolve 再 normpath |
| fnmatch 匹配深度 | */.ssh 不会匹配 ~/.ssh/,因为 * 不跨 / | 用 fnmatch 时显式加 /* 模式覆盖子文件 |
| Sandbox 退化 | bwrap 未装时 wrap_shell_command 默默退化成无沙箱 | 加日志告警,显式告诉用户”当前无沙箱” |
| Sub-Agent 死循环 | 子 Agent spawn 子,子 spawn 子孙 | DeepCode 强制 allow_spawn=False 在子 Agent 的 AgentRunSpec 里 |
八、关键 takeaway
如果你只读一段话,记下这些:
core/harness/命名即态度:把 Harness 当作一等公民而不是工具集合,DeepCode 是少数做到这一点的项目- 机制 vs 策略的彻底分层:6 个组件全部遵循”pure mechanism”原则,Harness 不和模型对话,不和 UI 对话
- 三值权限引擎:allow / ask / deny 比 Claude Code 的二值更精准,且 sensitive-path 是硬约束不可绕过
- 双轨 fold:HooksEngine 用声明序合并 reason/context,用完成序合并 updatedInput —— 审计稳定 + 实际生效
- Sub-Agent 邮箱通信:父 Agent 不用阻塞等子,可以继续工作等子回信(
wait_for_activity) - Skill Opaque ID:调用方只看到
sk_xxx不透明 ID,路径知识封装在 Provider 内 —— 协议中立性 - 不可变 MCP Runtime Plan:Turn 中不能热替换工具,避免”半新半旧”状态
- 诚实的边界声明:DeepCode 在 sandbox 模块注释里明确说“不假装有 seccomp-bpf” —— 这种诚实是稀缺品质
九、行动建议
如果你是 Harness 架构师:
- 把 DeepCode 的
core/harness/目录结构当模板:6 件套组件分目录而不是混在一起 - 三值权限引擎 + fnmatch + last-match-wins 是 Rule 组件的最简工程化范式
- HooksEngine 的”声明序 vs 完成序”分裂思想值得抄
如果你是 Agent 应用开发者:
- 不要从 DeepCode 开始学。先用 OpenAI Agents SDK 跑通一个 demo,理解 Agent 是什么
- 之后读 DeepCode 的
core/harness/permissions.py,把三值权限引擎集成进你的项目 - 沙箱:先用 OS 级别的(macOS seatbelt / Linux bwrap),不要自己实现
如果你是研究人员:
- DeepCode 的注释风格(每个模块顶部 5-10 行设计文档 + 引用其他模块 §章节)是学术级代码规范
- 它的设计哲学文档(”Honest boundary”)值得抄到论文 Related Work
- arXiv 2512.07921 是它的论文,值得对照源码读
收藏清单:
- 🔗 仓库:https://github.com/HKUDS/DeepCode
- 📖 论文:https://arxiv.org/abs/2512.07921
- 🎬 介绍视频:https://youtu.be/PRgmP8pOI08
- 📚 文档:https://deepwiki.com/xerrors/Yuxi(社区维护,**注意此链接实际对应 Yuxi 仓库而非 DeepCode**,DeepCode 文档在仓库内)
十、下一篇预告
Harness 六件套矩阵中,DeepCode 已经完整覆盖了 6 件套本体。下一篇将进入”单组件深度对比”阶段:
候选 1:Rule 组件横评 —— DeepCode 三值 vs Claude Code 二值 vs OpenAI Agents SDK 无引擎
候选 2:Sub-Agent 通信协议横评 —— DeepCode 邮箱模式 vs OpenAI Handoff 链式 vs AGT Saga 失败恢复
候选 3:Hook 总线协议横评 —— DeepCode 声明序 fold vs Strands Middleware Stack vs AGT Pre-Tool Hook 拦截
你想看哪个?评论区告诉我。
本文信息密度:12800 字 / 7 个 Mermaid 图 / 11 段可运行代码 / 3 个对比矩阵 / 1 个 8 组件定位表。完整源码引用已嵌入代码块,所有路径均可在
HKUDS/DeepCode仓库验证。
作者立场:DeepCode 是当前 Harness Engineering 学术 + 工程化的标杆项目。它的”机制 vs 策略”分层思想应该成为所有 Harness 项目的设计基线。但它的学习成本(840 文件 + 全英文注释 + 设计文档要求高)不适合初学者直接上手。
下期预告:Sub-Agent 通信协议横评 —— 3 个开源项目对比,看谁的”父子模型”架构能撑住 100 个并发子任务。