资讯详情

资讯详情

Agent工程真相:循环背后的安全与效率博弈

做一个 Coding Agent接上模型再给它几个工具看起来就可以开始干活了。那为什么同一个模型放在不同的 Agent 里效果会有差别为什么一个简单的循环就能完成一些编程任务做成产品以后却又需要上下文压缩、权限、会话恢复和多 Agent这些能力到底要做到什么程度我觉得讨论 Agent 工程绕不开这几个问题。模型决定了很多事情但开发者交付的是一套能够运行的系统。模型发起工具调用以后谁来执行失败了怎么办下一轮给模型看什么都要由这套系统处理。这部分通常叫 Harness可以理解为 Agent 的运行框架。今天聊一篇专门拆解 Harness 的研究。它检查了 Claude Code、Codex CLI、Gemini CLI、Mistral Vibe、OpenHands、Aider、Mini-SWE-Agent、Hermes、Pi、OpenCode 和 OpenClaw 的源码。论文篇幅很长我挑几个做 Agent 时会遇到的问题展开看看这些系统具体怎么处理也说说我的判断。目录一、一个 while 循环能做多少事情二、都是调用模型为什么还要单独做一层三、工具多了是更强还是更难选四、上下文压缩到底要留下什么五、找代码需要先建向量索引吗六、同意执行命令以后还需要沙箱吗七、多 Agent 能省多少时间先看任务怎么分八、从头做一个 Harness我会先补哪些能力一、一个 while 循环能做多少事情先看一个任务用户要求给现有项目加一个 CSV 导出功能。导出时要沿用当前页面的筛选条件不能影响原有分页。Agent 需要找到页面和接口读代码决定改哪里完成修改再运行验证。中间可能发现接口返回的数据不够也可能遇到类型错误。下一步怎么走要根据前一步的结果决定。基础循环大概就是这样接收目标和上下文 → 调用模型 → 执行模型请求的工具 → 把结果补充到上下文 → 再次调用模型 → 继续执行或结束任务图 2行动与观察循环、加入检查反馈的循环以及协调者与工作者结构。图中间加入了检查步骤。比如完成导出功能的修改以后运行测试把失败信息返回给模型继续修正。Aider 的编辑与检查流程就属于这一类。右边则增加协调者让工作者返回结果以后再决定下一步。几种结构的差异在于怎么组织反馈和分工底层仍然需要执行工具、处理结果。这个结构本身并不复杂。Mini-SWE-Agent 就是一个比较直观的例子围绕简单循环通过 shell 与环境交互。它的设计便于观察执行轨迹也便于研究模型在各轮做了什么。但把这个循环变成开发者每天使用的产品还会遇到其他问题。比如模型请求执行测试测试进程一直没有退出用户点击停止后台命令还在跑工具返回几万行日志下一次模型请求直接超出上下文限制模型连续执行同一条命令结果没有变化却迟迟不结束。这些问题要在模型调用之外处理。运行系统要处理最大轮数、超时、取消、输出长度和预算限制。图 1Harness 的组成模型接入、执行循环、工具、上下文、安全、编排和扩展。界面层可以是终端、IDE、SDK 或服务。我会按图里的七个部分检查一个 Agent。部分要回答的问题循环下一步怎么推进什么时候停止模型接入模型协议、工具调用、流式输出和重试怎么处理工具能读什么、改什么、执行什么结果怎么返回上下文本轮需要哪些信息历史太长怎么办安全操作是否允许执行环境限制在哪里编排子任务怎么分结果怎么汇总扩展技能、外部工具和其他系统怎么接入简单循环的好处是容易理解。每轮发生什么顺着代码就能看清楚。功能多了以后也容易把各种判断都塞进循环执行前检查权限调用前检查预算返回后检查上下文结束前检查状态。Mistral Vibe 提供了另一种做法把多种运行策略组织成中间件。上下文压缩之类的逻辑可以从主循环中拆出来在每轮执行时单独处理。这个取舍我觉得要看功能是否已经互相影响。如果只有几项检查直接写进循环未必有什么问题。预算、压缩、只读模式、审计等规则需要各自调整时拆成独立模块会更容易维护。循环复杂程度不能直接代表 Agent 能力。简单循环也可以完成复杂任务复杂运行系统通常还要满足交互、恢复、安全和扩展要求。比较的时候先问它解决的是哪一类问题。再看几个系统循环里的实现差异会更清楚。OpenHands 更重视执行记录和会话结构。它把事件写入持久化日志模型看到的历史则由当前会话分支上的事件整理而来。会话可以形成树支持回放和分叉。一次模型响应里如果包含多个工具调用系统可以将它们作为一批动作执行。并行时它还按工具声明的资源加锁。比如两个调用都操作同一个文件就需要串行读取不同文件则有机会同时执行。这比简单地判断“读工具能并行写工具不能并行”更细但工具需要准确声明使用的资源运行系统也需要维护锁。放到 CSV 导出任务里前端和后端位于不同文件可以分别操作两个工作者同时修改同一份接口定义就要协调。并行调度需要知道它们实际碰到了什么资源。Claude Code 按工具是否适合并发来分批执行。工具默认不允许并行确认安全的读取、搜索等操作才进入并行批次写入和命令执行采用更保守的处理。和 OpenHands 的资源锁相比这种方式依赖工具类别判断实现更直接。并行读取可以减少等待但两项互不相关的写入操作也可能因为类别限制而无法同时执行。并发粒度不同速度和实现成本的取舍也不同。Codex 用异步状态机组织会话。Codex 的 Rust 实现围绕 Session 处理轮次、模型流式事件和工具执行再向外提供事件读取接口。工具调用也有专门的运行层。这种结构适合把“任务已经接受”“模型正在输出”“工具正在执行”“轮次结束”分别传给界面和上层调用方。Agent 作为服务或 SDK 使用时持续反馈这些状态比等任务结束后只返回一段文字更有用。Pi 的核心循环比较精简也专门处理了用户中途发来的消息。它区分 steering 和 follow-up 两种队列前者在当前轮工具执行完后交给模型处理后者在 Agent 原本准备停止时再处理。比如导出功能做到一半用户补充“只导出选中的记录”这是对当前任务的调整用户又说“做完以后帮我检查另一个页面”则可以等待当前任务结束。运行系统区分这两类输入系统就能区分哪些消息需要立即调整当前任务哪些可以稍后处理。Pi 还有一个具体保护如果模型响应因为长度限制被截断本轮工具调用不执行。参数即使勉强能解析也可能不完整。这个判断发生在执行之前避免在修改内容只输出了一部分时就操作文件。OpenCode 把部分待处理工作写进消息日志。启动子 Agent、压缩上下文等待办动作会作为消息的一部分写入日志再由循环逐项取出处理。进程重启后可以继续识别日志里的待处理工作。不过能恢复队列不代表所有有副作用的工具操作都可以安全重试。文件已经改了但结果没有记录的情况仍然需要结合工具的实际结果和执行记录判断。这几种实现各有侧重OpenHands 围绕事件组织会话Codex 用异步状态机调度Pi 细分用户输入OpenCode 则把待办动作写进日志。选择的时候我觉得可以先明确产品需要哪一种行为再决定循环里要增加什么。二、都是调用模型为什么还要单独做一层模型接入容易被低估。第一版通常只要调用一个接口把消息和工具定义传过去再解析返回值。支持第二个模型以后事情就开始变多。工具调用格式可能不同推理内容的返回方式可能不同模型支持的参数也不同。切换模型时历史里的消息能不能继续用同样需要处理。拿前面的 CSV 导出任务来说。模型输出一个工具调用系统接收的是流式数据。如果参数还没传完就开始解析和执行容易把不完整的内容当作正式输入。模型接入层需要知道什么时候一次工具调用的信息已经接收完整工具执行层再做参数校验。请求失败也需要分类。限流可以等待后重试上下文过长需要减少输入参数不支持需要调整请求。所有错误都原样重试容易造成无效等待。论文里有几种不同安排。厂商自己的 Agent 通常会更多利用自家模型能力支持多家模型的系统则需要维护兼容信息和转换逻辑。Pi、Hermes、OpenCode 都有各自的兼容处理提示词缓存也是其中一部分。我觉得这层抽象至少要让上面的循环知道这次模型请求是否成功拿到了哪些工具调用用了多少 token失败属于哪一类。至于具体厂商的格式差异尽量集中处理。缓存也有类似问题。提示词内容差不多并不意味着服务一定能复用。稳定前缀、消息排列和厂商支持的缓存标记都可能影响结果。例如每轮都在系统提示词开头插入最新时间或变化的项目状态前缀就会变化。把固定规则和基础工具放在相对稳定的位置把动态信息放到后面更便于利用缓存。最终有没有减少成本还要看实际返回的用量。把这些逻辑集中到模型接入层后续接入新模型就有明确的地方处理兼容问题。如果每个 Agent 都自己写一份同类问题就要在多处修复。模型兼容也会直接影响工具接口。OpenCode 会根据模型切换编辑方式GPT 系列模型使用移植自 Codex 的 apply_patch 补丁格式其他模型使用另一套编辑接口。这个做法说明同一个运行系统可以给不同模型提供不同的工具接口。需要付出的成本是维护这些分支并分别验证编辑成功情况。统一成一套接口更容易维护按模型适配则可能更容易利用模型已经熟悉的形式。所以我会把“支持某个模型”拆开看。请求能否成功是一层能够稳定生成工具参数是另一层缓存、上下文和编辑接口能否适配还要继续验证。三、工具多了是更强还是更难选同样是修改代码Agent 可以只用 shell也可以使用专门的读取、搜索、编辑和执行工具。图 3各系统的工具数量与编辑形式。工具少接口简单模型需要通过组合命令完成更多事情。工具多可以直接表达常见操作但每个工具都有参数和说明模型要先理解再选择。所以我更关心工具的输入输出是不是清楚。举例来说Agent 要把导出按钮的处理函数改掉。一个编辑工具要求传文件路径、旧文本和新文本旧文本必须在文件中只匹配一处。匹配不到就返回错误匹配多处也返回错误。这种方式有一个好处模型如果记错了文件内容工具会明确拒绝。它需要重新读文件找到正确位置再修改。如果改成模糊匹配就要处理另一类问题看起来相似的两段代码工具选了哪一段空格或缩进变化可以容忍到什么程度修改完以后怎样确认没有改错位置几个系统在这里有不同选择。Claude Code 等采用较严格的编辑约定Aider 有从精确到模糊的匹配处理Gemini CLI 的实现中还出现了通过额外模型调用修复编辑匹配的方式。我觉得这个差异很具体严格匹配更容易发现文件状态不一致但可能需要模型多读一次宽松匹配能容忍部分输出偏差但要承担错误定位和验证成本。没有一个匹配规则适合所有模型和任务。再展开几个编辑实现。Codex 使用自己的补丁格式。apply_patch 通过补丁块描述文件的新增、修改或删除。这类接口适合一次表达多处变化工具需要负责验证补丁能否应用不能只确认格式能解析。Pi 会统一处理 Unicode 和空白差异但不依赖相似度阈值来放宽匹配。它处理 Unicode 和空白差异检查是否匹配到多个位置以及多次编辑的范围是否重叠并在执行前生成 diff 预览。目标是容忍格式差异同时保留精确修改的约束。Hermes 和 OpenCode 更强调匹配容错。它们有多阶段匹配处理依次尝试精确匹配以及处理空白、缩进和上下文差异。Hermes 还区分验证和应用OpenCode 会把 LSP 诊断补充进编辑结果。拿两个都叫 handleExport 的函数来说宽松匹配不能只回答“找到相似内容了”还要处理是否存在多个候选。修改后补充诊断能够让模型及时看到类型或语法问题但诊断没有报错也不代表业务行为正确。Mistral Vibe 的变化也值得看。论文保留了前后两个时间点的源码。在这段时间里它移除了原先的模糊 SEARCH/REPLACE 方式转向精确且唯一的旧文本匹配。对有歧义的编辑返回工具错误。这个变化说明编辑接口的设计也会调整。随着模型和任务环境变化工具承担多少修复工作也可能调整。自建 Harness 时编辑成功率、错误位置和额外调用成本需要一起观察。工具返回也要说清楚。搜索没有结果与搜索输出被截断是两回事。命令退出失败与命令还在运行也是两回事。模型下一轮能不能处理好取决于它有没有拿到这些状态。再说工具规模。接入多个 MCP 服务以后工具定义本身就会占用上下文。即使本轮只是改一个按钮模型也可能收到一大批完全无关的工具说明。按需发现和加载可以减少这部分开销。Claude Code 提供延迟加载和工具搜索Codex 有基于 BM25 的工具搜索Hermes 会在工具目录占用过多上下文时通过搜索、描述和调用三个入口访问目录。以一个包含代码、文档、工单和发布能力的平台为例当前任务只涉及代码可以先提供基础开发工具。如果用户要求关联工单再检索相关工具定义。这样模型不必每轮阅读完整目录。但这里也有代价。模型要多做一次工具搜索目录描述也要足够准确。工具已经安装却始终搜不到延迟加载就没有解决任务问题。因此我会同时检查上下文成本和能否找到所需工具。外部接口也不必一对一全部暴露。为了回答“这个需求现在卡在哪里”模型可能要查询需求、任务、负责人和状态。固定的数据查询和关联可以由程序完成工具返回整理好的结果。模型再决定是否需要继续查细节。四、上下文压缩到底要留下什么继续看 CSV 导出任务。用户一开始明确要求“沿用当前筛选条件不影响分页”。Agent 读了代码查了依赖运行测试又处理了一次编译失败。如果历史太长系统把它压缩成“正在实现 CSV 导出”信息就不够了。接下来模型可能生成一个能下载的文件却把筛选条件忘了。这个例子说明压缩需要保留任务状态。只概括讨论过哪些主题很难支持后续执行。图 4四种上下文管理方式完整历史、递归摘要、上下文压缩器和阈值压缩。Aider 的做法比较容易理解历史消息超出 token 预算以后把较早的一部分交给模型总结保留最近的原始消息。如果摘要加上近期消息后仍然过长就继续处理。这里保留近期消息有实际用途。正在修复编译错误时最近的错误堆栈和代码比一句“编译失败正在处理”更有用。OpenHands 把这部分做成可插拔的 Condenser。早期提供的压缩器种类较多后来的 SDK 精简了实现同时把压缩请求和结果也放进事件记录。这有助于排查一个具体问题Agent 到底是在压缩之前忘了筛选条件还是压缩结果漏掉了它如果压缩本身留下记录就能比较前后状态。上下文超限或历史格式出错时也可以转入压缩处理而不一定直接结束会话。其他系统会按 token 阈值触发压缩。Gemini CLI 会生成状态快照并保留近期历史Mistral Vibe 会把之前的用户消息重新放进压缩后的上下文Pi 和 OpenCode 等实现会利用已有摘要继续合并信息。这几种做法分别解决不同问题保留当前调试现场让原始目标继续存在避免多次压缩后丢掉早期决策。我会让摘要至少回答这些问题任务是什么约束有哪些已经改了哪些文件做过什么验证目前卡在哪里接下来准备做什么。对于导出功能摘要里应该明确保留“筛选条件要进入导出请求分页行为保持不变”。如果已经发现后端导出接口不支持某个筛选字段也要写进去。否则模型后面可能重复采用已经排除的方案。触发压缩时也要为后续消息预留空间。当前请求没有超限但工具马上返回一份大文件下一轮就可能超限。历史预算和工具输出预算需要一起安排。较长的内容可以存到外部文件或存储中只把存储位置和必要片段返回给模型。Agent 需要时再读取。完整记录仍然保存模型本轮不必全部看到。这样既能控制上下文也能在排障时回到原始数据。这几种实现里还有一些与会话恢复直接相关的做法。Hermes 在压缩时保留会话之间的关联。压缩时结束当前 SQLite 会话再创建通过 parent_session_id 关联的子会话。新的上下文变短之前的记录仍然保留可以沿着父子关系查询。如果一个导出任务经历过三次压缩就不会只剩下最后一份摘要。排查时可以回到每段会话检查早期要求和修改过程。这需要维护会话关系查询历史时也要处理跨会话的重复信息。Pi 的会话底层是追加式 JSONL 树。每条记录有自己的标识和父标识用一个指针标记当前会话所在的分支。分叉、回看和探索另一条路径可以建立在同一份结构上。读过和改过的文件清单也能跨压缩保留。这里有个边界切换会话分支并不自动恢复文件系统。模型的对话历史回到了之前的状态磁盘上的代码可能已经发生变化。产品如果提供回退就要说清楚回退的是对话还是对话和文件一起恢复。OpenCode 的摘要按固定栏目记录任务状态。它把之前的摘要再交给压缩 Agent按目标、重要细节、工作状态、下一步和相关文件合并。仍然成立的信息保留过期的信息移除。对长开发任务这类结构化摘要比一段泛泛的对话概括更容易核对。导出接口已经确认测试还没通过就可以分别写进“工作状态”和“下一步”。上下文压缩和持久化记录要分开。摘要用于下一轮推理完整事件记录用于恢复、回放和审计。不能因为模型暂时不需要一段日志就把唯一的执行证据删掉。长期记忆同样需要区分。项目的测试命令可以长期保存一次测试失败和临时推测应该留在当前任务里。否则下次任务可能继承已经失效的信息。五、找代码需要先建向量索引吗对 Coding Agent我会先用好代码本身的结构。用户要求增加 CSV 导出入口可能是当前页面的组件名、筛选字段或请求路径。找到页面后再沿着事件函数、请求封装和后端接口继续读。每一步的结果都能在文件里确认。ripgrep、glob、语法树和语言服务可以覆盖很多这样的定位工作。它们返回路径、行号或符号方便 Agent 继续操作也能反映当前工作目录里的变化。这篇研究的一个观察是样本没有采用向量嵌入检索代码。我觉得可以据此调整起步顺序先验证文本和结构检索能做到什么再判断是否需要额外索引。代码定位、对话记忆和跨文档查询的需求不同。OpenClaw 等系统在记忆检索中仍然使用向量检索需要根据具体任务选择。如果要增加语义检索我会拿一组现有搜索难以处理的任务来比较。例如用户只给出业务描述没有明显关键词语义检索是否更容易找到相关代码找到以后是否减少了后续读取索引维护和同步增加了多少成本这些都可以具体测。项目规则文件也属于上下文来源。AGENTS.md、CLAUDE.md 等文件负责提供代码里不容易直接看出的要求。例如根目录说明通用的测试和格式规范某个子目录要求兼容旧接口。Agent 修改这个目录之前需要加载对应规则。把全部目录说明一次性加载进来会增加输入按需加载则必须保证规则在修改之前生效。研究中的多个系统都在采用这种分层 Markdown 上下文。它的优势是规则放在项目里可以检查和维护。实际实现还要说清楚加载范围、覆盖关系和更新时间避免模型拿着旧规则工作。Aider 的 RepoMap 也可以单独看。它通过 tree-sitter 提取代码符号根据当前对话对相关信息排序在有限的 token 预算内生成仓库地图。比如当前讨论导出接口仓库地图可以帮助模型先看到相关符号和结构再读取具体文件。它与直接全文搜索提供的是不同信息一个帮助了解代码关系一个帮助定位具体内容。最终修改仍要回到实际文件。另外代码上下文和长期记忆也别混在一起。几个系统在“谁负责把信息写成记忆”上选择很不一样。Codex 采用后台提取和整理。研究中的记忆流水线先从会话记录提取信息再由受限制的内部 Agent 整理成文件。整理过程没有网络访问只允许指定范围内的本地写入并对变化进行检查。Gemini CLI 增加了人的审核。它会从已结束的会话中提取信息生成补丁放到项目的 inbox用户审阅以后再采用。这样记忆形成得慢一些但哪些内容会成为后续任务的依据需要经过用户确认。Hermes 使用有大小限制的 Markdown 记忆文件。会话开始时加载一份记忆在本次会话中保持不变后续更新写入磁盘不立即改动固定的提示词前缀。查询历史记录则依赖 SQLite 全文搜索也可以通过插件接入向量检索。OpenClaw 的比较重点不同。它更接近多渠道助理网关论文的文件编辑表也没有把它列为专门的代码编辑器。把它纳入样本是为了比较通用 Agent 的会话、记忆和扩展结构。它的 Active Memory 插件可以在主 Agent 回复之前运行专门负责记忆检索的子 Agent补充相关信息。这里要解决的是“这次回答需要哪些历史记忆”与 Coding Agent 查函数定义并不相同。多渠道和长期使用还会带来会话路由、记忆范围与工具可见性的问题。我觉得长期记忆的设计需要先回答一个问题什么信息可以变成未来任务的默认依据“这个仓库的导出接口不支持某个字段”也许值得保存但接口升级以后就需要更新一次临时猜测不能因为写入了记忆就变成项目事实。六、同意执行命令以后还需要沙箱吗需要。操作授权和执行隔离解决的是不同问题。用户同意 Agent 运行测试允许的是这次测试操作。测试进程实际能读取哪些文件、访问哪些地址、启动什么子进程还要由执行环境限制。拿导出功能来说Agent 修改完代码要运行项目测试。测试脚本可能调用其他程序。权限层判断允许执行测试并不自动保证这些程序只能访问项目目录。图 5论文中的 Claude Code 权限设计静态 Hook 规则、模型权限分类、用户确认对话。分层判断的思路是让不同规则处理不同情况。可写路径、工具限制等明确要求可以由程序检查项目自己的校验可以接到 Hook需要理解意图的操作可以交给模型辅助判断或请求用户确认。但模型判断允许执行之后执行环境仍然需要自己的边界。尤其是共享、托管或无人值守任务文件系统、网络和进程的访问范围都要单独配置。授权范围也要具体。允许修改当前项目不等于允许修改上级目录。用户同意了一条命令后面参数发生变化也要判断原授权是否适用。取消是另一个需要检查的地方。用户点停止以后模型请求停了工具是否停了工具停了子进程是否还在多 Agent 情况下工作者是否继续执行界面显示“已停止”时实际执行也应该已经结束。还有会话恢复。某次写入已经完成但执行结果还没保存运行实例就退出了。恢复以后如果系统直接重试可能产生重复副作用。因此会话里需要记录执行状态区分调用已发起、正在执行、已返回结果。对有副作用的工具再根据具体场景处理幂等、状态查询和人工介入。不能只保存一份聊天历史就认为恢复完成了。我觉得权限、隔离、执行记录和恢复需要一起设计。它们最后都要回答这次动作到底能不能做已经做了没有出问题以后怎么接着处理。七、多 Agent 能省多少时间先看任务怎么分任务长不一定适合多 Agent。例如 CSV 导出功能前端和后端都要改。如果两边还没有确认接口参数各自启动一个 Agent 同时写最后可能对不上。先确定参数和返回格式再让双方在独立目录里实现才有并行空间。如果只有一处小改动启动多个 Agent 还需要传递任务、等待结果和合并修改可能比一个 Agent 直接处理更慢。图 6单 Agent、顺序委派、并行子会话、层级线程树、递归组合以及注册表与协议。实线表示启动或调用虚线表示返回。我觉得多 Agent 有两类比较清楚的用途。第一类是独立任务并行推进。接口约定已经明确前端、后端和测试可以分别处理。但要安排工作目录和合并避免同时覆盖文件。各自通过测试以后合在一起仍然需要集成验证。第二类是分开处理信息。一个工作者调查导出接口另一个检查筛选逻辑主 Agent 拿到结果后决定怎么改。主会话不用装入每一次搜索和所有文件内容可以继续保留总体目标。这两类收益也对应两类成本并行需要协调修改分开处理信息需要保证汇总结果准确、完整。子任务应该写到什么程度我会明确目标、范围、工具和返回内容。例如“检查后端导出接口支持的筛选参数返回文件位置、参数定义和不支持的条件暂不修改代码”。主 Agent 拿到这份结果就能继续决定接口方案。如果只说“帮我看看后端”工作者不知道查到哪里算结束主 Agent 也很难判断报告是否够用。图 7协调者模式工作者按工具白名单执行任务再向协调者返回结果。这个实现里我更关注工具白名单。调查任务可以限制在读取和搜索实施任务再提供编辑与执行能力。主 Agent 可以按阶段委派避免所有工作者从一开始就修改环境。研究中的协调流程包括调查、汇总、实施和验证。对应到导出任务就是先查前后端现状确认接口再分派修改最后验证筛选、分页和下载结果。这样每个阶段的输入和结束条件都比较明确。工作者的结果也要能核对。哪些结论来自代码哪些是推测有没有运行验证都应该写清楚。几个工作者意见不一致主 Agent 需要回到文件或环境里确认不能只是把报告拼在一起。再看几个系统具体怎么委派差异就更明显了。Codex 给工作者独立的线程标识和历史。父子线程通过类型化消息交互上下文继承可以选择完整历史或最近若干轮。这样既能让工作者接续已有调查也能限制它看到的信息。Mistral Vibe 的委派是顺序执行。父 Agent 通过 task 工具启动新的 AgentLoop等待子任务完成再接收事件和结果。它限制可以委派的角色避免随意递归到更宽权限的配置。所以看到“支持子 Agent”不能马上理解成“能够并行加速”。顺序委派的价值更多是分开任务和上下文父任务仍然要等待。Gemini CLI 使用 Agent 注册表。定义可以来自用户、项目和扩展本地与远程执行通过统一的会话接口组织并有实验性的 A2A 服务。在企业里如果某个检查能力已经是远程 Agent可以沿这个边界接入不一定把所有执行代码放进同一进程。Hermes 对子任务权限采用交集。工作者的工具集合不能超过父任务已有的能力并额外限制递归、用户交互、记忆写入等操作。默认委派比较保守也提供通过配置启用的编排和共享数据库协作方式。Pi 把子 Agent 放在扩展里。核心没有 spawn 工具示例扩展通过启动独立 Pi 进程执行子任务解析 JSONL 输出汇总进展和成本。上下文因此天然分开父子通信、资源管理则要由扩展处理。OpenHands 用独立会话组织工作者OpenCode 用子会话。前者为工作者建立独立事件记录把摘要和指标带回父任务后者沿用已有会话引擎再根据权限配置收窄子会话能力。它们共同需要解决目标、上下文、权限和结果返回但分别通过线程、进程、注册表或会话实现。对于自建平台我会先明确需要哪一种隔离和恢复再挑合适的委派方式。主任务的预算和取消也要传到子任务。父任务已经停止子任务不能继续消耗资源或改代码。几个系统还在“怎么发现任务没有进展”上做了不同安排。OpenHands 检查重复动作与观察、反复报错、交替模式等多类情况。Gemini CLI 先通过哈希比对发现重复内容和工具调用执行轮数较多时再让模型自检。两者都在尝试识别无效的重复执行但维护成本和误判情况需要分别验证。OpenCode 连续遇到相同调用时会进入权限确认让用户决定是否继续。Hermes 的默认设置更偏向把重复失败警告写回工具结果它另有 verify-on-stop 检查可以在修改代码后缺少新的验证证据时要求继续执行。这个停止检查比较具体Agent 不需要每一轮都做一遍完整反思而是在准备结束时检查是否缺少验证。对于导出任务代码已经改了但没有新的测试或检查结果就还有事情没做完。这类机制仍然不能替代验收。执行过测试只能证明有验证动作筛选条件是否生效、导出数据是否正确需要相应检查覆盖。八、从头做一个 Harness我会先补哪些能力看完这些实现我觉得可以先把一个任务的完整过程做扎实。1. 能查清执行过程的循环。模型输入、工具参数、执行结果和结束原因都能按会话查到。先给出轮数、时间和预算限制避免失败后无限重试。2. 一组能重复运行的任务。既有正常修改也有文件找不到、编辑歧义、测试失败、工具超时和用户中断。每项能力加进去以后都用这些任务重新检查。3. 长任务的上下文处理。大输出按需读取摘要保留目标和进度近期调试信息保留原文。再验证压缩和恢复后Agent 是否继续遵守原来的要求。4. 实际产物验证。导出任务不能只看测试命令退出成功还要检查筛选有没有生效、分页有没有变化、CSV 内容是否正确。运行状态和用户验收要分别判断。5. 权限和执行环境。可写范围、网络限制、授权与取消都需要落到代码和配置中。有副作用的操作考虑失败后怎样确认执行状态。这些基础能力做好以后再按需要接入技能、MCP 或多 Agent。技能适合保存常用流程与领域知识MCP 解决外部工具连接ACP 可以用于编辑器交互或 Harness 互操作。具体协议要看系统边界内部委派未必需要跨系统协议。这篇研究还提供了一个约 90 行的最小 Harness 示例。它适合看清循环、工具和上下文如何连在一起。用于真实项目还要补齐模型兼容、输入校验、预算、权限、取消和恢复不能把示例行数当成完整产品的实现成本。为了方便对照我把这 11 个系统在本文涉及的特点放在一起。系统本文重点展开的实现Mini-SWE-Agent简单线性循环、shell 工具、执行时间与连续错误次数限制Aider编辑后检查与修正、多种编辑格式、RepoMapClaude Code工具并发分类、延迟加载、协调者与工作者Codex CLI异步会话状态机、补丁工具、线程委派、后台记忆整理Gemini CLI调度与循环检查、模型编辑修复、上下文处理、注册表与远程 AgentMistral Vibe每轮执行前的中间件检查、精确编辑、压缩后保留用户目标、顺序委派OpenHands持久事件日志、资源锁、可插拔压缩、独立工作者会话Hermes停止前验证、编辑容错、父子会话关联、受限委派Pi用户输入队列、响应截断保护、会话树、扩展式子 AgentOpenCode日志兼作队列、按模型选择编辑接口、增量摘要、子会话OpenClaw多渠道助理网关、回复前检索记忆、通用 Agent 扩展这个对照还有一个用途避免把所有功能都列成自建系统的第一版需求。一个单人使用的代码工具未必需要复杂会话路由企业托管平台却要优先考虑运行状态、权限和恢复。目标不同先补的能力也不同。最后说一下我会怎么衡量改动。一个新能力加进去任务是否更容易完成失败位置有没有变化耗时和成本增加多少人需要介入几次都要记录。比如加入子 Agent前后端修改同时推进了但合并冲突增加整体耗时未必下降。摘要减少了 token如果同时丢掉筛选约束产物就不符合要求。工具增加了如果模型选择错误还是会走弯路。这些都需要回到执行记录里看。对于前面的 CSV 导出我会检查 Agent 有没有读到必要代码、确认接口、保留约束、正确修改并验证结果。哪一步出了问题就改对应的运行环节。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →