论文标题:Harness Engineering: Anatomy, Architecture, and Evolution of CodingAgents
中文标题: 驾驭(Harness)工程:编程智能体的解剖、架构与演化——基于11个系统的的源代码研究
论文地址:https://arxiv.org/pdf/2609.00006
Harness Engineering:智能体框架工程 / 管控工程 / 驾驭工程 / 外围系统(脚手架)工程
Coding Agents:编码智能体 / 编程智能体 / 代码智能体
Harness Engineering 深度解读:Agent = 模型 + Harness,11 个主流编程 Agent 源码拆解
最近 harness engineering 很火。很多人问:harness 到底是什么?为什么说Agent = 模型 + Harness?我系统拆解了 11 个主流编程 Agent 的源码,大约 400 万行代码,从编码、智能体结构、架构到演化,梳理出这份解读。看完你会知道:
harness 到底是什么
主流编程 agent 是怎么工作的
自己搭建一个时可以借鉴哪些设计
一、一句话结论:Agent = 模型 + Harness
该图清晰展示了 Harness 的 7 大子系统(接口层、LLM集成、智能体循环、工具、记忆、编排、安全与权限),在正文中翻译并解释这七个模块的作用,说明这是本篇论文提出的“标准解剖结构”。
先给公式:
Agent = Model + Harness
模型提供理解、推理和生成能力;harness 是模型之外的一切运行时系统:循环、工具、上下文、安全、编排、扩展接口。
说得更直白一点:
harness 就是围绕大模型搭建的一整套运行系统,负责把模型接入实际工作环境。
模型可以生成“读取文件”的命令,但真正执行命令、取得文件内容、把内容交回模型,需要外部程序完成。模型提出修改代码,也需要程序执行修改,并检查权限。这些程序共同组成 harness。
这里要分清几个容易混淆的概念:
prompt:交给模型的指令。
上下文管理:决定模型每一轮能看到什么。
harness:还要负责执行过程,包括权限控制、停止条件、异常处理。
所以 harness engineering 研究的就是:这套运行系统应该怎样设计和改进。
二、Harness 的七个子系统
该图展示了一个从极简(Mini-SWE-Agent 只有 4 个工具)到极繁(OpenClaw 有 109 个工具)的谱系。说明:工具并不是越多越好,而是要考虑平台的封装粒度。
所有系统,从 100 行的 Mini-SWE-Agent 到百万行生产 CLI,都必须对七个部分做出选择。
| 子系统 | 作用 | 最小实现 | 最大实现代表 |
|---|---|---|---|
| Agent Loop | 交替推理与行动执行,负责停止条件和失败恢复 | Mini-SWE-Agent:线性 while + 一个 bash 工具 | OpenHands:事件溯源对话 + 持久事件日志 |
| LLM Integration | 说 provider 协议,组装 prompt,管理缓存、思考、路由 | Mini-SWE-Agent:一次 LiteLLM 调用 | Hermes:5 种自有传输,29 个 provider profile |
| Tools & Actions | 定义并执行 agent 能做什么,尤其是文件编辑 | Mini-SWE-Agent:只有 bash | Claude Code:43 个类型化工具 + 延迟加载 |
| Memory & Context | 配给上下文窗口,跨轮次和会话持久化知识 | Mini-SWE-Agent:无界线性历史 | Codex:agent 维护的跨会话记忆管道 |
| Safety & Permissions | 决定什么能跑、什么要问、什么禁止,隔离执行 | Mini-SWE-Agent:成本和步数限制 | Codex:策略规则 + LLM 审批 + 三平台 OS 沙箱 |
| Orchestration | 生成和协调子 agent,连接其他 agent | Aider:无,单 agent 设计 | Claude Code:递归组合;Omnigent:跨 vendor 协调 |
| Extensibility | 让用户和生态添加能力:配置、hooks、skills、插件、MCP | Mini-SWE-Agent:Python Protocol | Pi:一切皆扩展;Codex:市场分发插件 |
此外还有两个横切面:
Interface Layer:TUI、CLI、IDE 协议、HTTP server、SDK。
Session Substrate:transcript、持久化、resume/fork。
七个子系统围绕 Agent Loop,LLM Integration、Tool & Action System、Memory & Context、Safety & Permissions、Orchestration、Extensibility 各司其职,Interface Layer 在外层驱动。
三、11 个主流编程 Agent 源码拆解
这次拆解覆盖了 11 个生产级 coding harness,外加 Omnigent 作为 meta-harness 对照:
| 系统 | 厂商/来源 | 语言 | 特点 |
|---|---|---|---|
| Claude Code | Anthropic | TypeScript | 延迟工具加载、prompt cache 共享 fork、被大量模仿 |
| Codex CLI | OpenAI | Rust | agent 维护跨会话记忆;工具调用作为 V8 执行代码 |
| Gemini CLI | TypeScript | 模型路由作为运行时调度;唯一 A2A server | |
| Mistral Vibe | Mistral | Python | 中间件管道循环;rewind 暴露在 ACP |
| OpenHands | 开源 | Python | 事件溯源对话;可托管 rival harness 作为 ACP 后端 |
| Aider | 开源 | Python | 13 种多态编辑格式;唯一 ranked repo map |
| Mini-SWE-Agent | 开源 | Python | 100 行研究下限,七子系统最小实现 |
| Hermes | Nous Research | Python | 自改进 skill loop;lineage compaction;verify-on-stop |
| Pi | 开源 | TypeScript | 最小核心反趋势;一切皆扩展;session-tree 版本控制 |
| OpenCode | 开源 | TypeScript | client/server harness;语法感知命令权限 |
| OpenClaw | 开源 | TypeScript | 多通道网关;Active Memory 子 agent |
| Omnigent | Databricks | Python | 首个 meta-harness,编排 11 个 vendor harness |
重点不是排名,而是描述和比较这些系统是怎么构建的。
四、最值得关注的三个共性发现
1. 没有系统依赖通用 Agent 编排框架
检查了所有依赖清单和源码导入,覆盖约 400 万行 Python、TypeScript、Rust:
没有 agent runtime 导入 LangChain、LangGraph、AutoGen、CrewAI、LlamaIndex、Pydantic AI、Genkit、Google ADK、Semantic Kernel 等通用 agentic framework。
甚至 Gemini CLI 也没有用 Google 自己的 Genkit 或 ADK。
所有循环都是手写的:
Python:asyncio、同步阻塞
TypeScript:Promise、async iterator
Rust:Tokio
工具注册表也是自定义:Pydantic、Zod、TypeBox、Effect Schema、Rust enum。
唯一边界案例是 OpenCode 使用 Vercel AI SDK 处理模型和工具调用,但那是 provider abstraction,不是 agent orchestration framework。
结论:核心循环可以直接实现,采用通用编排框架并不是搭建 agent 的前提。
2. 代码检索不用向量嵌入
搜索了 vector store、embedding 库、RAG 相关文件:
0/11 系统用向量嵌入做代码检索。
它们用的是:
ripgrep、glob、find
tree-sitter 符号提取
文件路径、关键词搜索、代码结构分析
自动发现的 Markdown 上下文文件:CLAUDE.md、AGENTS.md、GEMINI.md、SKILL.md
例如:
Claude Code 用 ripgrep + Bash + on-demand Read。
Aider 用 tree-sitter 生成 RepoMap,是唯一 ranked repository map。
Hermes 用 SQLite FTS5 做会话历史检索,BM25 + trigram,不做 LLM 调用。
OpenClaw 默认混合 embedding 搜索,但只用于对话记忆,不用于源码树。
结论:代码有丰富的确定性结构,语义相似度检索无法替代;代码分钟级变化,预索引 embedding 很快过时;ripgrep + tree-sitter 已经足够。
3. 扩展标准收敛:Skills 超过 MCP
统计结果:
Skills:9/11
MCP:8/11
Aider 和 Mini-SWE-Agent 不用 skills;Pi 支持 skills,但明确拒绝 MCP。
Skills 的形态基本统一:
目录里有
SKILL.mdYAML frontmatter:name、description,可选 paths、requires、user-invocable
发现路径:
.agents/skills/、~/.claude/skills/、~/.gemini/skills/、~/.vibe/skills/等8/9 支持 skills 的系统采用延迟加载:先加载名称、描述,需要时再读完整内容
还有一个很实用的细节:
OpenCode 会搜索
~/.claude/skills和.claude/目录,所以为 Claude Code 安装的 skills 可以在 OpenCode 中不改动直接用。
Skills 还长出了供应链:
远程 registry
trust tier
预安装扫描
quarantine
provenance 验证
甚至 agent 自写 skills:Hermes 自改进循环、Gemini CLI extraction inbox
五、Agent Loop 的三种范式
Iterative(迭代)、Reflection(反思)、Coordinator(协调者)是底层逻辑,图文结合最容易让读者理解智能体是如何“动起来”的。
11 个系统的循环分成三类:
| 范式 | 代表系统 |
|---|---|
| 迭代行动-观察 | OpenHands、Claude Code、Codex、Gemini CLI、Mistral Vibe、Mini-SWE-Agent、Hermes、Pi、OpenCode |
| 反思增强 | Aider |
| Coordinator-worker 覆盖 | Claude Code、Codex;Hermes 配置门控 |
最极端的对比:
Mini-SWE-Agent:线性 while,一个 bash 工具,无状态机、无事件溯源、无并发。
OpenHands:事件溯源对话引擎,事件写入持久 EventLog,对话状态是一棵可移动 head 的树,支持 replay、fork、branch navigation。
Codex:Tokio async state machine,
FuturesOrdered有序并行工具执行。Gemini CLI:async generator + scheduler,工具走 Validating → Executing → Completed/Errored。
Hermes:预算循环 + stop-guards,verify-on-stop 可以否决过早最终答案。
Pi:约 790 行功能核心,无 planner、无 reflection、无 turn cap、无 stuck detection、无 cost kill-switch,全是设计拒绝。
OpenCode:
while(true),消息日志同时是工作队列,天然可恢复。
六、安全是架构,不是规模副产品
“Claude Code 采用了静态规则、LLM分类器和用户交互三层机制”。
一个很关键的发现是:
OS 级沙箱是最昂贵的代码能力之一,而且是一种选择,不是规模的必然结果。
对比:
Codex:四层权限栈
Starlark ExecPolicy 规则
生命周期 hooks,事件词汇几乎照搬 Claude Code
Guardian LLM 审批 reviewer
原生 OS 沙箱:Linux Bubblewrap、macOS Seatbelt、Windows restricted token
Claude Code:三层权限系统
静态 hook 规则
LLM 权限分类器
交互式用户对话框
Gemini CLI:四种审批模式
PLAN:只读
DEFAULT:每次工具调用交互审批
AUTO_EDIT:编辑自动批准,shell 仍询问
YOLO:全部自动批准
Hermes:无 OS 级隔离,但政策地板在
--yolo下仍然保留 12 个 hardline patterns,YOLO 环境变量在模块导入时冻结,防止 prompt-injected skill 运行时翻转。Pi:明确拒绝内置沙箱,认为部分进程内沙箱“容易被误解为安全边界”。
结论:安全要求根据部署环境提前确定。个人交互、共享环境、自动运行,对权限、隔离和审计的要求完全不同。
七、记忆与上下文:threshold compaction 成为事实标准
上下文窗口管理是当前开发智能体的一大痛点。这张图清晰展示了从 Linear(不修剪)到 Compaction(基于阈值压缩)的演化过程,具有很强的工程指导意义,也是论文提出的“事实标准”。
7/11 系统采用阈值触发的 LLM compaction:
Claude Code:剩余上下文低于 13K buffer 时触发,压缩后恢复最多 5 个文件。
Gemini CLI:历史超过 50% 时触发,保留最近 30% 逐字。
Mistral Vibe:AutoCompactMiddleware 在每轮前检查,压缩后重新注入先前用户消息。
Hermes:lineage compaction,压缩不重写 transcript,而是结束当前 SQLite session,旋转到 child session,通过
parent_session_id链。Pi:在 session tree 上压缩,摘要迭代合并。
OpenCode:锚定增量摘要,保留上一份 summary,合并“仍为真”的细节,删除过时细节。
更前沿的是持久记忆写入路径:
Codex:agent 维护,后台两阶段管道,sandboxed 内部 sub-agent 合并到 git-baselined
~/.codex/memories/。Gemini CLI:human-gated,异步 skill-extraction sub-agent 写入 per-project
.inbox/,用户通过/memory审核应用。Hermes:两个有界 Markdown 文件,
MEMORY.md2200 字符,USER.md1375 字符,冻结快照保证 prompt cache 不失效。OpenClaw:Active Memory 插件,在主回复前运行专用 memory sub-agent。
结论:compaction 设计已经趋同;现在区分 field 的是 memory write path。
八、多 Agent:coordinator-worker 趋同,但子 agent 仍走进程内
这张图非常惊艳地总结了目前主流的 6 种多智能体拓扑结构(单智能体、顺序委托、并行子会话、分层线程树、递归组合、注册表协议)。这是许多开发者非常关心的进阶话题。结合图下方的文字,解释不同模式的优缺点以及代表系统(如 Claude Code 属于递归组合,OpenHands 属于并行子会话)
9/11 系统支持多 agent。识别出六种模式:
单 agent:Mini-SWE-Agent、Aider、Pi core
顺序委派:Mistral Vibe
并行子会话:OpenHands、OpenCode
层级线程树:Codex
递归组合:Claude Code
Registry + 跨进程协议:Gemini CLI、OpenClaw、Hermes swarm
该图展示了如何约束子智能体权限,Coordinator 如何分配 Research、Implement、Verify 三个角色,且每个 Worker 限制 16 个工具的白名单。。
但关键发现是:
8/9 多 agent 系统在协调自己的子 agent 时,仍使用进程内原语,或者跨进程时用非标准协议。Pi 用 JSONL,Hermes swarm 用 SQLite blackboard。
标准协议 ACP 的新角色是托管别的 harness:
OpenHands 通过 ACP 把 Claude Code、Codex、Gemini CLI 当作可替换执行后端。
Hermes 消费 ACP agent 作为模型传输。
Omnigent 用 adapter fleet 驱动 Goose、Qwen 等。
结论:ACP 已经有三重角色:
编辑器 ↔ agent
Agent-as-backend,harness 托管
A2A 跨 vendor mesh,仍只有 Gemini CLI
九、双重缺失:为什么不用 LangChain,也不做 Code RAG?
最反直觉的发现是“双缺失”:
缺失 1:没有通用 agentic framework
0/11 系统在 agent runtime 中使用 LangChain、LangGraph、AutoGen、CrewAI、LlamaIndex、Pydantic AI、Genkit、Google ADK、Semantic Kernel。
原因和 Anthropic 的《Building Effective Agents》一致:
框架常常制造额外抽象层,遮蔽底层 prompt 和 response,让调试更困难。
生产 SWE agent 的失败模式——silent prompt corruption、opaque caching、version-incompatible tool schemas——代价太高,不能靠框架抽象糊过去。手写、可调试的代码赢了。
缺失 2:没有代码向量检索
0/11 系统用 vector embedding RAG 做代码检索。
原因:
代码有路径、语言服务器、tree-sitter parse、类型信息,语义相似度无法复制。
代码分钟级变化,预索引 embedding 几乎天然过时。
每个编码环境已经自带近乎最优的检索系统:ripgrep、find、glob。
在典型 SWE-agent 任务上,RAG 增加 embedding 计算、向量库维护、漂移管理,却没有边际价值。
一句话:
生产 harness 与通用 LLM 应用处于不同的复杂度预算。当失败模式是修改真实代码时,可调试性和 prompt 透明性优先于框架复用。
十、从 90 行最小 harness 到成熟产品
一个约 90 行 Python 的 minimum-viable-harness scaffold 包含:
线性 while 循环
middleware 风格策略
四个工具:
bash、read_file、write_file、search_replace分层 Markdown 上下文自动发现:
AGENTS.md阈值 compaction
这是供开发者复制和修改的起点,还不能直接当完整产品使用。
成熟产品需要处理的是任务执行过程中不断出现的具体问题:
模型连续生成格式错误响应,要不要一直重试?
用户需要回退操作,如何通过 git 快照恢复文件?
编辑工具匹配不上原文,是直接报错还是处理空格、缩进差异?
终端输出经常截断文件内容,是否增加专门文件读取工具?
每次重写整个文件太费 token,是否增加局部替换工具?
任务是否真的适合并行,再引入多 agent?
18 条设计建议里,最实用的几条:
从线性 while 循环开始,只有出现三个以上正交 turn 策略时才升级 middleware pipeline。
如果工具数超过 15 个,采用 deferred tool loading。
编辑契约要匹配模型层级:前沿模型用 exact unique substring,弱模型用 fuzzy cascade。
自动发现分层 Markdown 上下文文件。
实现 threshold compaction,保留最近尾部,增量合并 summary,并让同一 routine 对 overflow 响应式触发。
不要为代码建 RAG。用 ripgrep、glob、tree-sitter。
开发者工具用 PLAN / DEFAULT / YOLO 三模式审批;企业/共享/自动化环境用 OS 沙箱 + policy-as-code + 审计。
无论哪个层级,把安全规则写成数据或专用 policy 文件,YOLO 也要保留地板。
保持单 agent,直到能指出一个明确 breadth-first 探索阶段,证明并行上下文隔离明显优于串行搜索。
发布 ACP server:它现在同时买到 IDE、托管 harness、meta-orchestrator 三类消费者。自己的子 agent 保持进程内。
Skills 用于能力模板,MCP 用于外部集成,优先级按这个顺序。
不要用 LangChain、LangGraph、AutoGen、CrewAI、LlamaIndex、Pydantic AI、Genkit、Google ADK、Semantic Kernel 作为 agent runtime。
不要为代码建向量嵌入检索层。
不要把每个上游 SaaS API 都包成 1:1 工具。
不要过度设计 stuck detection,但便宜的上限要加:连续格式错误上限、时间上限、费用上限。
十一、平台转向:Harness 正在从工具变成平台
最核心的判断是:
2026 年上半年,coding harness 完成了从 tool 到 platform 的转向。
证据:
Harness 变成可导入 SDK:Claude Agent SDK、openai-codex SDK、OpenHands agent SDK。
Framework 厂商开始发 harness:LangChain Deep Agents、Pydantic AI Harness、Strands harness-sdk。
能力分发出现市场:Codex 插件市场、skills registry、trust tier、quarantine。
Vendor 互相写 importer:Codex 导入 Claude Code 的 session JSONL 和 settings.json。
企业治理层出现:Codex 配置栈支持 MDM、host-wide、enterprise cloud-delivered bundles 和 constraint engine。
Agent 本身可作为 OpenAI 兼容 endpoint 被调用。
Meta-harness 出现:Omnigent 编排 11 个 vendor harness,其中 5 个来自本文语料库。
Omnigent 是第一个 meta-harness:
四层进程拓扑:server ⇌ host daemon ⇌ runner ⇌ per-conversation harness subprocess
23 个 canonical harness adapter
五种集成模式:sdk-in-process、cli-subprocess、acp-subprocess、native-tui、native-server
跨 harness policy:session → agent → admin;六阶段;CEL、Python 或 LLM-classifier evaluator
统一沙箱和 egress stack
可分享多设备 session
它不实现编辑循环、不做 repo context、不做 edit-application strategy。它赌的是:harness 已经变成商品组件,持久价值在上层。
十二、对开发者的启示
如果你准备开发 agent,路线图很清楚:
先写最小 harness:线性循环 + 少量工具 + 上下文文件 + compaction。
不要从框架开始:直接用原生 SDK 和宿主语言 async 原语。
不要做代码 RAG:ripgrep + tree-sitter + glob + Markdown context files。
工具按失败模式增加:先 bash,再 read_file、write_file、search_replace。
工具超过 15 个就 deferred loading。
编辑策略要模型感知:强模型精确替换,弱模型 fuzzy cascade。
安全按部署环境设计:个人工具、企业共享、自动运行是三种不同产品。
单 agent 优先:只有明确 breadth-first 并行探索需求时才上多 agent。
发布 ACP server:让 IDE、托管 harness、meta-orchestrator 都能接入你。
扩展优先 Skills,其次 MCP。
每增加一项设计,都要能说明它解决了哪个已经遇到的问题。
如果要做平台,就要有 SDK、registry、trust tier、governance、session importer。
总结
Agent = Model + Harness。
模型提供智能;harness 把智能变成工作。
harness 的七个子系统是:循环、LLM 接入、工具、记忆与上下文、安全与权限、编排、扩展。
最重要的两个缺失:不用通用 agent 框架,不做代码 RAG。
最重要的趋势:harness 正在从工具走向平台,而 meta-harness 已经在编排多个 vendor harness。
如果你只记一句话:
别再只盯着模型了。2026 年,真正决定 agent 能不能落地的是 harness。