跳到正文
实时
Anthropic Research·· 2026-04-08精选74

Anthropic 推出 Claude Managed Agents,将智能体的 brain 与 hands 解耦

Scaling Managed Agents: Decoupling the brain from the hands

要点速览

Anthropic 在 Claude Platform 上线托管服务 Managed Agents,把智能体拆成 session、harness 和 sandbox 三个可独立替换的接口,用来运行长周期任务。

Why it matters

Anthropic 公开了托管智能体的架构取舍,读者可看到把会话、harness 与沙箱拆开后,延迟与安全边界如何变化。

正文 · AI 翻译

通过我们的 文档 开始使用 Claude Managed Agents。

工程博客上有一个持续讨论的话题,是如何 构建有效的代理 和 设计适配器 用于 长期运行的工作。这项工作的共同点是,适配器编码了关于 Claude 无法独立完成的假设。然而,这些假设需要经常质疑,因为随着模型的改进,它们可能会 过时。

仅举一个例子,在之前的工作中 我们发现,Claude Sonnet 4.5 在感知到其上下文限制临近时会过早地结束任务——这种行为有时被称为“上下文焦虑”。我们通过向适配器添加上下文重置来解决此问题。但是,当我们使用相同的适配器在 Claude Opus 4.5 上时,我们发现这种行为消失了。重置变得毫无用处。

我们预计适配器将继续发展。因此,我们创建了 Managed Agents:Claude 平台中的一个托管服务,通过一组旨在超越任何特定实现的接口(包括我们今天运行的那些)代表您运行长期代理。

构建 Managed Agents 意味着解决一个古老的计算问题:如何设计一个系统用于“尚未想到的程序”。几十年前,操作系统通过将硬件虚拟化为抽象——进程、文件——来解决此问题,这些抽象足够通用,适用于尚未存在的程序。这些抽象超越了硬件。read() 命令无论访问的是 1970 年代的磁盘包还是现代 SSD,都是不可知的。顶层抽象保持稳定,而底层实现可以自由变化。

Managed Agents 遵循相同模式。我们虚拟化了代理的组件:一个会话(所有发生事情的追加日志),一个适配器(调用 Claude 并将 Claude 的工具调用路由到相关基础设施的循环),以及一个沙盒(Claude 可以运行代码和编辑文件的执行环境)。这允许每个实现的交换而不会影响其他组件。我们对这些接口的形状有意见,而不是对它们后面运行的内容有意见。

不要养宠物

我们最初将所有代理组件放入一个容器中,这意味着会话、代理适配器和沙盒都共享一个环境。这种方法有一些好处,包括文件编辑是直接的系统调用,并且没有设计服务边界。

但是,通过将所有内容耦合到一个容器中,我们遇到了一个古老的基础设施问题:我们养了一个 宠物。在宠物与牛的类比中,宠物是一个命名的、需要人工照料的个体,您不能失去它,而牛是可以互换的。在我们的例子中,服务器就是那个宠物;如果容器失败,会话就会丢失。如果容器无响应,我们必须将其恢复健康。

修复容器意味着调试无响应的会话。我们唯一的入口是 WebSocket 事件流,但它不能告诉我们 哪里 出现了故障,这意味着适配器中的错误、事件流中的数据包丢失或容器离线都呈现相同的情况。为了找出出了什么问题,工程师必须打开容器内的 shell,但由于该容器通常还包含用户数据,这种方法本质上意味着我们缺乏调试能力。

第二个问题是,连接器假设Claude所处理的一切都生活在与它一起的容器中。当客户要求我们将Claude连接到他们的虚拟私有云时,他们必须要么将他们的网络与我们的网络对等,要么在自己的环境中运行我们的连接器。连接器中嵌入的一个假设在我们要将其连接到不同基础设施时变成了一个问题。

我们找到的解决方案是将我们认为是“大脑”(Claude及其连接器)的东西与“手”(执行操作的沙盒和工具)以及“会话”(会话事件日志)分离。每一项都变成了一个很少对其他项做出假设的接口,并且每一项都可以独立地失败或被替换。

连接器离开了容器。 将大脑与手分离意味着连接器不再生活在容器内。它像调用任何其他工具一样调用容器:execute(name, input) → string。容器变成了牛。如果容器死亡,连接器会将失败捕获为工具调用错误并传递给Claude。如果Claude决定重试,可以使用标准配方重新初始化一个新的容器:provision({resources})。我们不再需要照顾失败的容器使其恢复健康。

从连接器故障中恢复。 连接器也变成了牛。因为会话日志位于连接器外部,连接器中的任何东西都不需要生存崩溃。当它失败时,可以使用wake(sessionId)重新启动一个新的,使用getSession(id)来获取事件日志,并从最后一个事件恢复。在代理循环期间,连接器使用emitEvent(id, event)写入会话,以保持事件的可持久记录。

安全边界。 在耦合设计中,Claude生成的任何不受信任的代码都在与凭证相同的容器中运行——因此一个提示注入只需要说服Claude读取它自己的环境。一旦攻击者获得了这些令牌,他们就可以生成新的、不受限制的会话并将工作委托给他们。范围狭窄是一种明显的缓解措施,但这编码了一个关于Claude无法用有限的令牌做什么的假设——而Claude正变得越来越聪明。结构上的修复是确保令牌永远不会从Claude生成的代码运行的沙盒中可达。

我们使用了两种模式来确保这一点。认证可以与资源捆绑或保存在沙盒外部的保险库中。对于Git,我们使用每个仓库的访问令牌在沙盒初始化期间克隆仓库并将其连接到本地git远程。Git push 和 pull 从沙盒内部工作,代理本身永远不会处理令牌。对于自定义工具,我们支持MCP并将OAuth令牌存储在安全的保险库中。Claude通过一个专用代理调用MCP工具;这个代理接收与会话关联的令牌。然后代理可以从保险库中获取相应的凭证并对外部服务进行调用。连接器永远不会意识到任何凭证。

会话不是Claude的上下文窗口

长时任务经常超过Claude的上下文窗口的长度,而解决此问题的标准方法都涉及不可逆的决定关于要保留什么。我们在 先前工作 中探索了上下文工程的这些技术。例如,压缩允许Claude保存其上下文窗口的摘要,而内存工具允许Claude将上下文写入文件,从而实现跨会话的学习。这可以与上下文修剪配对,它选择性地删除令牌,例如旧的工具结果或思考块。

但不可逆地决定选择性地保留或丢弃上下文可能导致失败。很难知道未来轮次需要哪些标记。如果消息通过压缩步骤进行转换,则 harness 会从 Claude 的上下文窗口中移除压缩的消息,并且只有当它们被存储时才能恢复。先前的工作 已经探索 了通过将上下文存储为存在于上下文窗口 之外 的对象来解决这个问题的方法。例如,上下文可以是一个 REPL 中的对象,LLM 通过编写代码来访问它以过滤或切片它。

在 Managed Agents 中,会话提供了相同的好处,作为一个存在于 Claude 的上下文窗口 之外 的上下文对象。但上下文不是存储在沙盒或 REPL 中,而是持久存储在会话日志中。界面,getEvents(), 允许大脑通过选择事件流的位置切片来查询上下文。该界面可以灵活使用,允许大脑从上次停止阅读的地方开始,在特定时刻之前回放几个事件以查看前因后果,或在特定操作之前重新阅读上下文。

任何检索到的事件在传递给 Claude 的上下文窗口之前也可以在 harness 中进行转换。这些转换可以是 harness 编码的任何内容,包括上下文组织以实现高提示缓存命中率以及上下文工程。我们将会话中可恢复上下文存储和 harness 中任意上下文管理的职责分离开来,因为我们无法预测未来模型将需要什么样的特定上下文工程。界面将上下文管理推向 harness,并仅保证会话是持久的并且可供查询。

许多大脑,许多手

许多大脑。将大脑与手解耦解决了我们最早期的客户投诉之一。当团队希望 Claude 在他们自己的 VPC 中工作时,唯一的路径是将其网络与我们的网络对等,因为包含 harness 的容器假设每个资源都紧挨着它。一旦 harness 不再在容器中,这种假设就消失了。同样的改变带来了性能上的收益。当我们最初将大脑放入容器时,这意味着许多大脑需要同样多的容器。对于每个大脑,在容器配置完成之前无法进行任何推理;每个会话都预先支付了完整的容器设置成本。每个会话,即使那些永远不会接触沙盒的会话,也必须克隆仓库,启动进程,从我们的服务器获取挂起的事件。

这种空闲时间体现在首次标记时间 (TTFT) 上,它衡量会话在接受工作后等待生成其第一个响应标记的时间。TTFT 是用户最敏锐感受到的延迟。

将大脑与手解耦意味着只有当需要时,大脑才通过工具调用 (execute(name, input) → string) 通过 orchestration 层从会话日志中获取挂起的事件来配置容器。因此,不需要立即需要容器的会话就不会等待。一旦推理开始,使用这种架构,我们的 p50 TTFT 降低了大约 60%,p95 降低了 90% 以上。扩展到许多大脑只需启动许多无状态 harness,并且仅在需要时将它们连接到手。

人多力量大。 我们还希望每个大脑都能连接到许多双手。在实践中,这意味着Claude必须推理许多执行环境,并决定将工作发送到哪里——这比在单个shell中操作更具认知挑战性。我们从单个容器中的大脑开始,因为早期的模型无法实现这一点。随着智能的扩展,单个容器成为了限制:当那个容器失败时,我们失去了大脑所触及的每个双手的状态。

将大脑与双手解耦使每双手成为一个工具,execute(name, input) → string:输入一个名称和输入,返回一个字符串。该接口支持任何自定义工具、任何MCP服务器以及我们自己的工具。连接器不知道沙盒是容器、手机还是宝可梦模拟器。并且由于没有双手与任何大脑耦合,大脑可以相互传递双手。

结论

我们面临的挑战是一个老问题:如何设计一个系统来适应“尚未想到的程序”。操作系统通过将硬件虚拟化为足够通用的抽象,从而持续了数十年,这些抽象足以支持尚未存在的程序。通过管理代理,我们旨在设计一个能够适应未来连接器、沙盒或其他围绕Claude的组件的系统。

管理代理是一种元连接器,在同样的精神下,对Claude未来需要的具体连接器持中立态度。相反,它是一个具有通用接口的系统,允许许多不同的连接器。例如,Claude代码是一个极好的连接器,我们广泛用于各种任务。我们还证明,针对特定任务的代理连接器在狭窄的领域表现出色。管理代理可以适应所有这些,随着时间的推移匹配Claude的智能。

元连接器设计意味着对Claude周围的接口持中立态度:我们预计Claude将需要操纵状态(会话)和执行计算(沙盒)的能力。我们还预计Claude将需要扩展到许多大脑和许多双手的能力。我们设计了接口,以便这些可以在长时间内可靠和安全地运行。但我们没有假设Claude将需要的大脑或双手的数量或位置。

来源: Anthropic Research · anthropic.com