📐 Harness 工程 · 中文翻译

8 工具与动作系统

工具系统定义了智能体真正能做什么:它能调用哪些动作,这些动作如何执行。 在我们研究的每个成熟智能体中,这个子系统都吸纳了很大一部分工程投入。

8.1 工具数量光谱

图 3 展示了从极简到极繁的工具设计光谱。 各系统从一个 bash 工具一直延伸到 109+ 个工具(含媒体处理与通道集成)——Pi 把稀疏端做成一种哲学(内置 7 个工具,默认暴露 4 个,其余皆为扩展),而 Hermes 把通用端推到 69 个内建工具,后面垫一层工具集(toolset)来限定每个平台的模型实际能看到什么。

MinimalMaximal1Mini-SWE-Agent7Pi12Mistral Vibe13Aider17OpenCode25OpenHands27Codex35Gemini CLI43Claude Code69Hermes109OpenClawbash only4 by defaultedit formatsmodel presets+ code mode+ agents, taskstoolset-scoped+ channels
图 3:工具数量光谱(2026 年 7 月)。数字表示独立的内建工具或编辑格式;OpenHands 与 Codex 计的是默认表面(完整目录达到 30+)。Pi 内置 7 个、默认暴露 4 个;Hermes 注册 69 个,但通过工具集层按平台限定可见性。

8.2 工具接口架构

工具接口从一个几乎没有抽象的极端——Mini-SWE-Agent 把一切都塞进单个 shell 调用(subprocess.Popen(shell=True),只包了一层以便超时时杀掉进程组)——延伸到丰富的类型化契约。 Claude Code 的 43 个工具各自把校验、权限检查、并发安全与 UI 渲染声明为独立的接口关切。 Codex 用 Rust trait 对象做运行时多态——注册表存储 Arc<dyn CoreToolRuntime>,其中 CoreToolRuntime: ToolExecutor,这一抽象如今被抽成独立的 codex-tools crate,与 code 模式和扩展共享。 Gemini CLI 经一个状态机 Scheduler 路由调用,让每次调用走过确定性的校验 →\to 执行 →\to 完成/出错阶段。 Mistral Vibe 增加了经 tree-sitter 解析的 bash——一条基于 asyncio.create_subprocess_shell 的执行路径,先用 tree_sitter_bash 校验命令结构再派生进程——以及细粒度权限作用域(命令模式、文件模式、URL 白名单、目录包含)。 Hermes 的单例注册表把注册与暴露分开:69 个工具在导入时自注册,工具集层限定每个平台的模型能看到什么,逐工具的可用性探测(30 秒 TTL 加上一个“上次良好”宽限窗口)避免一次抽风的 docker version 拆掉整个工具集,还有一个纠正模式漂移的强制转换层("42"→\to42),动机来自观察到的开放模型输出。 Pi 给它的 7 个工具各配一个可插拔的 Operations 接口(BashOperations、EditOperations……)——这是唯一的远程化接缝,SSH、容器与微 VM 扩展都经它迁移执行,而不用触碰工具本身。 OpenCode 用 Effect schema 注册 17 个第一方工具,并按模型更换工具表面:GPT 家族模型收到 Codex 的 apply_patch DSL 的移植版,并完全失去 edit/write(第 8.4 节)。 这条光谱反映的是简单性与能力的权衡:接口面越大,安全保证越多,但工程成本也越高。

8.3 工具延迟加载

Claude Code 引入了工具延迟加载:标记 shouldDefer = true 的工具被排除在初始系统提示词之外。 LLM 经 ToolSearchTool 按需发现它们,支持关键词搜索与直接选择(select:<tool_name>)。 这显著减小提示词体积:43 个工具中,初始只加载一个核心子集。 延迟工具集经 getDeferredToolsCacheKey() 缓存,集合变化时失效。

4 月版把这一设计呈现为 Claude Code 独有;到 7 月,它已成为带独立实现、正在扩散的模式。 Codex 给工具(默认是 MCP 工具)打上 defer_loading 标记,并暴露一个由工具规格上的 BM25 词法索引支撑的 tool_search 工具——同样的提示词经济学,只是把子串匹配换成了排序检索。 Hermes 用阈值把想法一般化:当 MCP 与插件 schema 超过上下文窗口的 10% 时,它们折叠成三个桥接工具(tool_search/tool_describe/tool_call),由一个内联 BM25 引擎检索。 OpenCode 延迟加载技能(目录只列名称与描述;原生 skill 工具取回正文),并把其实验性 code 模式当作 MCP 目录延迟:与其暴露每个 MCP 工具,不如用一个 execute 工具对目录运行模型写就的脚本。 Mistral Vibe 的 defer_mcp 标志则不同:它只延迟启动时 MCP 的连接以降延迟,而非提示词可见性——一旦接入,每个 MCP 工具对模型都可见,所以我们不再把它归入提示词级延迟模式。

8.4 文件编辑策略

文件编辑是 SWE 智能体的核心动作。 11 个系统实现了八种根本不同的策略,汇总于表 7。

表 7:11 个系统的文件编辑策略(2026 年 7 月)。
系统 格式 匹配 回退 创新点
Claude Code 精确字符串替换 文件内唯一子串 报错 + 上下文 Zod schema 校验
Codex *** Begin/End Patch 统一 diff hunk hunk 级重试 自定义补丁 DSL;Lark 文法约束变体
Aider 13 种格式(SEARCH/REPLACE、udiff、diff-fenced……) 精确 →\to 模糊(dmp) 相似行建议 RelativeIndenter
OpenHands str_replace_editor(5 个命令)+ apply_patch + 从 Gemini 移植的 edit 精确唯一匹配 错误消息 undo_edit;三种并存的编辑方言
Gemini CLI edit(旧/新字符串)+ write_file 级联:精确 →\to 宽松 →\to 正则 →\to 模糊 LLM“编辑修复器”子调用修复该对 LLM 辅助的编辑修复
Mistral Vibe 精确 edit(旧/新字符串,replace_all)+ 仅创建的 write_file 精确唯一子串 歧义时报工具错误 一个季度内从模糊 SEARCH/REPLACE 迁走(4 月→\to7 月)
Mini-SWE-Agent 经 bash 的 sed/awk 基于正则 shell 报错 无(模型驱动)
Hermes 单个 patch 工具:SEARCH/REPLACE + V4A DSL(+ write_file) 9 策略模糊链(精确 →\to …→\to 块锚定 0.50/0.70 →\to 上下文感知 0.80) 最近行建议;3 次失败后升级为 write_file 先校验后应用的两阶段;后端透明的 shell 文件操作
Pi 多编辑精确替换(edits[],拒绝重叠) 精确 →\to Unicode/空白规范化(无相似度阈值) 唯一性指引错误 字节保真叠加;执行前异步 diff 预览
OpenCode 按模型条件切换:apply_patch DSL(GPT 家族)或 SEARCH/REPLACE edit(其他) 9 阶段替换器级联(Levenshtein 0.65)/ 4 趟补丁放宽 区分“未找到”与“歧义”两种错误 注册表内按模型更换编辑方言;LSP 诊断附加到结果
OpenClaw N/A N/A N/A 不是代码编辑器
两次快照之间,编辑格局重新洗牌。

4 月版把 Mistral Vibe 与 Gemini CLI 描述为一对“按程度多态”的系统——粗糙的整文件工具加模糊的细粒度补丁工具。 这一对的两半都没能活过这个季度。 Mistral Vibe 干脆删除了它的 SEARCH/REPLACE 工具,收敛到 Claude Code 的精确唯一子串契约(带一个 replace_all 逃生舱,以及如今只用于创建的 write_file):一个罕见可观察到的案例——生产级 Harness 在编辑策略簇之间迁移——也是更强模型把最优解从工具侧漂移容忍推向严格契约的证据。6664 月版还夸大了旧机制:复审显示 v2.7.5 的 ≥\geq0.90 模糊匹配器只为错误消息生成“最近匹配”诊断;它从不应用模糊编辑。 细看之下,Gemini CLI 的 edit 是一个旧/新字符串工具,带级联匹配器(精确 →\to 空白宽松 →\to 正则 →\to 模糊),终点却是其他系统都没有的东西:LLM 编辑修复器子调用——针对模型提供的 instruction 修复失败的旧/新字符串对——这是语料库中第一个工具内 LLM 辅助的编辑修复。

模糊级联家族及其可见的谱系。

Mistral Vibe 离开之处,来了两个带着语料库最精巧漂移容忍的新成员,而且它们的源码写明了这套机制的祖源。 OpenCode 的九阶段替换器级联(精确 →\to 行修剪 →\to 块锚定 →\to 空白/缩进/转义规范化 →\to 上下文感知,Levenshtein 阈值 0.65 之下、带失衡匹配守卫)的头注释致谢了 Cline 与 Gemini CLI 的评测;Hermes 的九策略链则标注“受 OpenCode 启发”。 编辑机制如今有了可见的跨 Harness 谱系——经由继承的趋同,而不仅是重新发现。 Pi 则占据第三个位置:根本没有相似度阈值,只有 Unicode/空白的规范化(NFKC、智能引号、尾随空白),替换在规范化空间中计算后再逐行叠加回原始字节,因此未触碰的行保留其精确的原有空白——外加一个在工具执行前渲染的异步 diff 预览。

Aider 的 RelativeIndenter 仍值得特别一提。 它用 Unicode 标记(默认:左箭头 ←\leftarrow,选中它是为避免与文件内容冲突)把绝对缩进转换为相对变化。 make_relative() 方法跟踪相邻行之间的缩进差,make_absolute() 则重建原始缩进。 这让编辑块能跨不同缩进级别工作——其他系统的一个常见失败模式。 再配合经 diff_match_patch 的模糊匹配(阈值 0.95、距离 500),构成一条稳健的编辑管线。

观察 4。文件编辑策略是 SWE 智能体代码修改准确性的最重要决定因素之一,而模型感知的多态已不再是 Aider 独有。Aider 经提示词类工厂按模型选择编辑格式;OpenCode 经工具注册表达到同样的洞见,按模型更换工具集(GPT 家族模型得到 Codex 式的补丁 DSL,并完全失去字符串替换工具)。语料库的编辑机制如今显示出显式的跨 Harness 谱系(Hermes 的匹配器“受 OpenCode 启发”;OpenCode 的级联致谢 Cline 与 Gemini CLI),而且它还在可见地运动:Mistral Vibe 在一个季度内从模糊 SEARCH/REPLACE 迁移到 Claude Code 式精确匹配,而 Gemini CLI 加入了 LLM 辅助的编辑修复。Aider 的 RelativeIndenter 仍是对缩进敏感匹配最精妙的解法。

8.5 执行与沙箱

表 8 详细比较各沙箱方案。

表 8:执行沙箱机制(2026 年 7 月)。
系统 机制 隔离级别 投入
OpenHands Workspace 抽象:Docker、Apptainer、远程 API、云端工作区(应用侧 KVM 直通) 进程 + 文件系统 + 网络 可观
Codex Bubblewrap(源内 vendored、随树编译)+ Landlock 旧版回退(Linux)、Seatbelt(macOS)、受限令牌(Windows) 操作系统级命名空间 + 文件系统 + 网络 可观
Gemini CLI Docker / Bubblewrap / gVisor / LXC(Linux)、经 sandbox-exec 的 Seatbelt(macOS)、受限令牌(Windows);TOML 策略 操作系统级 + 分模式策略 + 环境清洗 中等
Claude Code 经 Anthropic 的 sandbox-runtime(Bubblewrap/Seatbelt)的可选操作系统沙箱,带网络限制;git worktree 做分支隔离 操作系统级(可选)+ 文件系统 中等
Mini-SWE-Agent Docker、Singularity、Bubblewrap(可插拔) 可配置 轻
Hermes 六个可插拔执行后端(本地、Docker、SSH、Singularity、Modal、Daytona);本地后端 = 策略底线,无操作系统原语 按后端(容器/VM);本地无 委托
Mistral Vibe 无操作系统级;可选 --worktree 分支隔离 文件系统(分支级,可选) 无
Pi 无内建(附成文理由);可选扩展(Anthropic sandbox-runtime、QEMU 微 VM)经逐工具 Operations 接缝 默认无 无(扩展空间)
OpenCode 无(权限规则 + tree-sitter 命令解析;影子 git 检查点;树内的“sandbox”指 worktree) 无 无(仅策略)
Aider 无(本地直接执行) 无 无
OpenClaw 无(本地网关执行) 无 无

Codex 是语料库中沙箱投入最重的,如今打包成专门的 sandboxing crate。 在 Linux 上,它运行 Bubblewrap——自 2026 年年中起源内 vendored 并随树编译,经 C FFI 调用——做命名空间隔离(--ro-bind、--unshare-net、--unshare-user、--unshare-pid),Landlock 降级为特性开关之后的旧版回退。 在 macOS 上,它驱动经 /usr/bin/sandbox-exec 的 Seatbelt 配置。 在 Windows 上,它使用受限令牌进程。 受保护路径(.git、.agents、.codex)即使位于可写根之内,也会被重新标记为只读。 其结果是无需容器运行时开销的操作系统级隔离。

Gemini CLI 成为第二个跨平台沙箱实现者。

Gemini CLI 的 SandboxManager 实现了与 Codex 相同的三平台栈:Linux 上 Docker 或 Bubblewrap,macOS 上经 /usr/bin/sandbox-exec 的 Seatbelt,Windows 上受限令牌进程。 Codex 把策略烘焙进 Starlark execpolicy 规则(第 10 节),Gemini CLI 则叠加基于 TOML 的分模式沙箱策略(plan / default / accepting_edits),并在每条命令运行前清洗供应商凭据环境变量(对 TOKEN/SECRET/KEY/AUTH/CREDENTIAL 的名称模式正则、一份拒绝清单,以及 GitHub 令牌取值正则)。 Gemini CLI 的沙箱投入明显轻于 Codex,因为 Gemini CLI 复用 Node 的子进程 API 与操作系统自带的二进制,而非亲自实现底层命名空间管线;Codex 则为更大的足迹买单——vendored Bubblewrap 集成与 Rust 原生命名空间控制。 4 月版曾观察到语料库中最大的两个系统恰好也是唯二拥有原生跨平台沙箱的系统,并追问这种相关性是否是结构性的;扩大的语料库回答否:Hermes(约 ∼\sim64.2 万行)不带任何操作系统级隔离原语,把封禁委托给六个可插拔执行后端,而把安全预算投给内容型威胁;OpenCode(约 ∼\sim57.8 万行)则仅有策略。 规模预测的是某种大型安全投入,而非专门预测沙箱;第 10 节绘制每个系统把钱花在了哪里。