Managed Agents:将大脑与手解耦

创建时间: 2026-05-12 来源: sources/Scaling Managed Agents Decoupling the brain from the hands.md 相关: Harness-EngineeringAgent-Native-InfrastructureAgent-Paradigm-ShiftOpenClawMinimal-Agent-Architecture


核心主张

Anthropic 的 Managed Agents 将一个经典的系统设计原则应用到 Agent 架构中:将计算抽象为通用接口,而非为特定实现做优化。

操作系统的 read() 命令不关心它访问的是 1970 年代的磁盘还是现代 SSD——底层变了,接口不动。Managed Agents 对 Agent 做了同样的事:将 Agent 虚拟化为三个通用组件,各自可独立替换。

三个虚拟化组件

组件职责接口
Sessionappend-only 的事件日志,记录 Agent 发生的一切getEvents()emitEvent(id, event)
Harness调用 Claude 并路由工具调用的循环wake(sessionId)getSession(id)
SandboxClaude 运行代码和编辑文件的执行环境execute(name, input) → stringprovision({resources})

这三个接口的设计是有观点的(opinionated about the shape),但对背后运行什么无观点(unopinionated about the implementation)。

Pets vs Cattle

初始实现将所有组件放在一个容器中——session、harness、sandbox 共享环境。好处是文件编辑是直接 syscall,没有服务边界需要设计。但代价是这个容器成了”宠物”(pet):

  • 容器崩溃 → 会话丢失
  • 容器无响应 → 需要人工”护理”恢复
  • 唯一的调试窗口是 WebSocket 事件流,无法定位故障源
  • 容器同时持有用户数据,开 shell 进去调试意味着无法调试

解耦后,harness 将容器视为工具调用:execute(name, input) → string。容器死了 → harness 捕获到工具调用错误 → 传给 Claude → Claude 决定重试 → 用 provision({resources}) 标准配方重新初始化。容器变成了 cattle。

安全边界:Token 永远不可达

耦合设计中,Claude 生成的不可信代码和凭证在同一个容器中运行——prompt injection 只需要让 Claude 读取自己的环境变量即可窃取 token。攻击者可利用偷到的 token 生成全新的、无限制的会话。

结构性的修复方案是确保 token 从 sandbox 无法到达。Two patterns:

  1. Git 凭据注入:在 sandbox 初始化时用仓库的访问 token 克隆代码,注入到本地 git remote 中。Claude 在 sandbox 内 git push/pull 但永远不处理 token 本身
  2. MCP 代理 vault:自定义工具通过 MCP 调用,OAuth token 存储在安全 vault 中。Claude 通过专用 MCP 代理调用工具,代理使用 session 关联的 token 从 vault 获取凭证。harness 对整个凭证流程无感知。

Session ≠ Context Window

长周期任务常超过 Claude 的上下文窗口长度。压缩(compaction)和裁剪(trimming)等标准方法涉及不可逆的取舍——你无法预知未来哪些 token 会被需要。

Managed Agents 的 session 是一个独立于上下文窗口之外的可恢复上下文对象

  • Session durably 存储在事件日志中,不在 sandbox 或 REPL 中
  • getEvents() 支持按位置切片检索(从上次停止处继续、回退几帧看前因、重新读取特定动作前的上下文)
  • 检索到的事件可在 harness 中任意转换(重组上下文提高 prompt cache 命中率、应用 context engineering)
  • session 只负责持久化和可检索;harness 负责上下文管理策略

这种关注点分离的设计原因是:无法预测未来模型需要什么样的 context engineering,所以把决定权推到 harness 层。

Many Brains, Many Hands

很多大脑

解耦前的痛点:客户想让 Claude 访问自己的 VPC,唯一路径是网络对等,因为 harness 假设所有资源都在同一个容器中。

解耦后:

  • Harness 不在容器中 → 资源位置假设消失
  • 容器改通过 execute(name, input) → string 按需调用
  • 不需要容器的会话可以直接开始推理,无需等待容器启动
  • p50 TTFT 下降约 60%,p95 下降超过 90%

很多手

解耦前:大脑在一个容器中,容器崩溃 → 大脑触及的所有”手”的状态一起丢失。

解耦后:每只手是一个 execute(name, input) → string 工具。harness 不知道 sandbox 是一个容器、一部手机还是一台 Pokémon 模拟器。因为没有手与任何大脑耦合,大脑之间可以互相传递手。

Meta-harness

Managed Agents 本身是一个 meta-harness:它不预设 Claude 未来需要哪种具体的 harness,而是定义了一套通用接口(session/harness/sandbox),允许不同的 harness 自由接入。

“对 read() 的命令是强制的;它具体如何从存储介质获取数据则是自由的。没有人真的在乎 read() 的实现。”

——《Unix 编程艺术》

对自建 Harness 工程的启示

如果要从零搭建自己的 harness 工程,第一优先级不是做复杂 agent 编排,而是先稳定三个接口:

  1. Session 先行:把每次输入、模型响应、工具调用、错误、人工介入都写入 append-only 事件日志。不要只依赖模型上下文窗口或临时文件恢复状态。
  2. Sandbox 工具化:把执行环境视为可丢弃的工具,而不是必须照顾的长寿命服务器。最小接口可以先收敛为 execute(name, input) -> stringprovision(resources)
  3. Harness 无状态化:让 harness 可以通过 wake(sessionId) 从事件日志恢复,而不是把关键状态藏在内存、WebSocket 或容器本地。
  4. 凭证永不进 sandbox:Git、OAuth、云服务 token 应由凭据代理或初始化过程注入能力,而不是暴露 token 字符串给模型生成代码的环境。
  5. 上下文管理可替换:session 只保存完整历史;摘要、裁剪、重排、prompt cache 优化都放在 harness 层。模型升级后,旧的 context trick 可能变成负担。
  6. 先单脑单手,再多脑多手:MVP 不必一开始支持多 agent 网络;但接口要避免写死“一个大脑绑定一个容器”的假设。

一句话:不要先做一个聪明 agent;先做一个可恢复、可替换、可审计的 agent 运行时。

与现有框架的关系

  • Harness-Engineering — Managed Agents 是 harness engineering 的一个具体实现案例,将”分离生成与评估”原则扩展到基础设施层面
  • Agent-Native-Infrastructure — Sensors/Actuators 模型与 Managed Agents 的 session/sandbox/harness 抽象形成互补:前者关注 Agent 如何感知和操作外部世界,后者关注如何结构化 Agent 的内部运行时
  • Agent-Paradigm-Shift — 从 Chatbot 到 Agent 的范式转移中,Managed Agents 提供了生产级 Agent 的运行基础设施
  • OpenClaw — 开源 Agent 框架的分层记忆设计,与 Managed Agents 的 session-as-external-context 思路一致

参考资料

  • 来源:Anthropic《Scaling Managed Agents: Decoupling the brain from the hands》
  • 相关:Anthropic《Building effective agents》、Effective harnesses for long-running agents、Harness design for long-running application development