扩展托管智能体:将大脑与执行层解耦
摘要
Anthropic 在 Claude 平台推出托管智能体(Managed Agents),这是一项托管服务,通过将智能体组件解耦,提升长程任务的扩展性与可靠性。
暂无内容
查看缓存全文
缓存时间: 2026/05/08 09:25
# 扩展托管智能体:将大脑与双手解耦
来源:https://www.anthropic.com/engineering/managed-agents
*开始使用 Claude 托管智能体,请参阅我们的文档 (https://platform.claude.com/docs/en/managed-agents/overview)。*
工程博客中一个持续讨论的话题是如何构建有效的智能体 (https://www.anthropic.com/engineering/building-effective-agents) 以及如何为长时间运行的工作设计管控框架 (https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents) (https://www.anthropic.com/engineering/harness-design-long-running-apps)。这些工作的一个共同点是,管控框架编码了关于 Claude 自身无法完成哪些任务的假设。然而,这些假设需要经常被质疑,因为随着模型改进,它们可能会过时 (http://www.incompleteideas.net/IncIdeas/BitterLesson.html)。
仅举一例,在先前的研究中我们发现 (https://www.anthropic.com/engineering/harness-design-long-running-apps),Claude Sonnet 4.5 会在感知到上下文限制即将接近时过早结束任务——这种行为有时被称为"上下文焦虑"。我们通过在管控框架中添加上下文重置来解决这个问题。但当我们将相同的管控框架用于 Claude Opus 4.5 时,发现该行为已经消失。重置变成了累赘。
我们预期管控框架会继续演进。因此,我们构建了托管智能体:Claude 平台中的一项托管服务,通过一小套旨在比任何特定实现(包括我们今天运行的实现)更持久的接口,代表您运行长周期智能体。
构建托管智能体意味着要解决计算领域的一个老问题:如何为"尚未想到程序"设计系统 (http://www.catb.org/esr/writings/taoup/html/ch03s01.html)。几十年前,操作系统通过将硬件虚拟化为足够通用的抽象——*进程、文件*——来解决这个问题,这些抽象适用于当时还不存在的程序。这些抽象比硬件更持久。`read()` 命令并不关心它访问的是 1970 年代的磁盘组还是现代 SSD。上层的抽象保持稳定,而下层的实现可以自由变化。
托管智能体遵循相同的模式。我们将智能体的组件虚拟化:会话(所有发生事件的只追加日志)、管控框架(调用 Claude 并将其工具调用路由到相关基础设施的循环)和沙箱(Claude 可以运行代码和编辑文件的执行环境)。这允许每个组件的实现被替换而不影响其他组件。我们对这些接口的形状有明确主张,但对它们背后运行什么没有预设。
## 不要养宠物
我们最初将所有智能体组件放入单个容器中,这意味着会话、智能体管控框架和沙箱共享一个环境。这种方法有好处,包括文件编辑是直接系统调用,而且不需要设计服务边界。
但将所有东西耦合到一个容器中后,我们遇到了一个老的基础设施问题:我们养了一只"宠物" (https://cloudscaling.com/blog/cloud-computing/the-history-of-pets-vs-cattle/)。在宠物与 cattle 的类比中,宠物是命名的、亲手照料的个体,你承受不起失去它的代价,而 cattle 是可互换的。在我们的情况中,服务器变成了那只宠物;如果容器故障,会话就会丢失。如果容器无响应,我们必须将其恢复健康。
照料容器意味着调试无响应的卡死会话。我们唯一的窗口是 WebSocket 事件流,但它无法告诉我们故障*出现在哪里*,这意味着管控框架中的 bug、事件流中的丢包或容器离线都呈现相同的现象。为了找出问题所在,工程师必须进入容器内部打开 shell,但由于该容器通常也包含用户数据,这种方法实质上意味着我们缺乏调试能力。
第二个问题是管控框架假设 Claude 处理的任何内容都与它同在容器中。当客户要求我们将 Claude 连接到他们的虚拟私有云时,他们必须要么将他们的网络与我们的网络对等,要么在他们自己的环境中运行我们的管控框架。管控框架中根深蒂固的假设在我们想要将其连接到不同基础设施时变成了问题。
我们最终得出的解决方案是将我们视为"大脑"(Claude 及其管控框架)的部分与"双手"(执行操作的沙箱和工具)以及"会话"(会话事件的日志)解耦。每个部分都成为对其他部分很少做假设的接口,每个部分都可以独立故障或被替换。
**管控框架离开容器。** 将大脑与双手解耦意味着管控框架不再生活在容器内部。它调用容器的方式与调用任何其他工具相同:`execute(name, input) → string`。容器变成了 cattle。如果容器死亡,管控框架将故障捕获为工具调用错误并将其返回给 Claude。如果 Claude 决定重试,可以用标准配方重新初始化新容器:`provision({resources})`。我们不再需要将无法恢复的容器恢复健康。
**从管控框架故障中恢复。** 管控框架本身也变成了 cattle。因为会话日志位于管控框架外部,管控框架中没有任何东西需要在崩溃后存活。当一个管控框架故障时,可以用 `wake(sessionId)` 重启一个新的,使用 `getSession(id)` 获取事件日志,并从最后一个事件恢复。在智能体循环期间,管控框架使用 `emitEvent(id, event)` 写入会话,以保持事件的持久记录。
**安全边界。** 在耦合设计中,Claude 生成的任何不受信任代码与凭证运行在同一个容器中——因此提示注入只需说服 Claude 读取其自身环境。一旦攻击者获得这些令牌,他们就可以生成新的、不受限制的会话并将工作委托给它们。缩小范围是明显的缓解措施,但这编码了关于 Claude 无法用有限令牌做什么的假设——而 Claude 正变得越来越聪明。结构性的修复是确保令牌从 Claude 生成代码运行的沙箱中无法触及。
我们使用两种模式来确保这一点。认证可以与资源捆绑,或保存在沙箱外部的保险库中。对于 Git,我们在沙箱初始化期间使用每个仓库的访问令牌克隆仓库,并将其接入本地 git 远程。Git `push` 和 `pull` 在沙箱内部工作,而智能体本身从不处理令牌。对于自定义工具,我们支持 MCP,并将 OAuth 令牌存储在安全保险库中。Claude 通过专用代理调用 MCP 工具;该代理接收与会话关联的令牌。然后代理可以从保险库获取相应的凭证并向外部服务发起调用。管控框架永远不会获知任何凭证。
## 会话不是 Claude 的上下文窗口
长周期任务通常会超出 Claude 上下文窗口的长度,解决这个问题的标准方法都涉及关于保留什么的不可逆决策。我们在上下文工程的先前研究 (https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents) 中探讨了这些技术。例如,压缩允许 Claude 保存其上下文窗口的摘要,而记忆工具允许 Claude 将上下文写入文件,实现跨会话的学习。这可以与上下文修剪配对,选择性移除旧工具结果或思考块等令牌。
但选择性保留或丢弃上下文的不可逆决策可能导致故障。很难知道未来的回合需要哪些令牌。如果消息经过压缩步骤转换,管控框架会从 Claude 的上下文窗口中移除压缩后的消息,而这些消息只有在被存储的情况下才可恢复。先前的工作已探讨 (https://arxiv.org/pdf/2512.24601) 通过将上下文存储为生活在上下文窗口*外部*的对象来解决这一问题的方法。例如,上下文可以是 REPL 中的对象,LLM 通过编写代码来过滤或切片它以编程方式访问。
在托管智能体中,会话提供了相同的好处,作为生活在 Claude 上下文窗口外部的上下文对象。但与存储在沙箱或 REPL 内不同,上下文持久存储在会话日志中。接口 `getEvents()` 允许大脑通过选择事件流的位置切片来查询上下文。该接口可以灵活使用,允许大脑从上次停止读取的位置继续,在特定时刻之前回退几个事件查看前因,或在特定操作之前重新读取上下文。
任何获取的事件也可以在传递给 Claude 的上下文窗口之前在管控框架中进行转换。这些转换可以是管控框架编码的任何内容,包括为实现高提示缓存命中率而进行的上下文组织以及上下文工程。我们将可恢复上下文存储在会话中的关注点与管控框架中的任意上下文管理分离,因为我们无法预测未来模型需要什么样的特定上下文工程。接口将上下文管理推入管控框架,只保证会话是持久的且可供查询。
## 多个大脑,多双手
**多个大脑。** 将大脑与双手解耦解决了我们最早的客户投诉之一。当团队希望 Claude 针对他们自己 VPC 中的资源工作时,唯一的途径是将他们的网络与我们的网络对等,因为容纳管控框架的容器假设每个资源都坐在它旁边。一旦管控框架不再在容器中,该假设就不复存在了。同样的变化带来了性能回报。当我们最初将大脑放入容器时,这意味着许多大脑需要同样多的容器。对于每个大脑,在该容器配置完成之前无法进行任何推理;每个会话都预先支付了完整的容器设置成本。每个会话,即使是从不接触沙箱的会话,都必须克隆仓库、启动进程、从我们的服务器获取待处理事件。
这段死时间表现为首令牌时间(TTFT),衡量会话从接受工作到产生第一个响应令牌需要等待多长时间。TTFT 是用户最能*感受到*的延迟。
将大脑与双手解耦意味着容器由大脑通过工具调用 `execute(name, input) → string` 仅在需要时配置。因此,不需要立即使用容器的会话无需等待。一旦编排层从会话日志中提取待处理事件,推理就可以开始。使用这种架构,我们的 p50 TTFT 下降了约 60%,p95 下降超过 90%。扩展到多个大脑只是意味着启动多个无状态管控框架,并仅在需要时将它们连接到双手。
**多双手。** 我们还希望有能力将每个大脑连接到多双手。在实践中,这意味着 Claude 必须推理多个执行环境并决定发送工作到哪里——这比在单个 shell 中操作是更困难的认知任务。我们从单个容器中的大脑开始,因为早期模型无法做到这点。随着智能体规模扩大,单个容器反而变成了限制:当该容器故障时,我们失去了大脑正在触及的每双手的状态。
将大脑与双手解耦使每双手成为一个工具,`execute(name, input) → string`:输入名称和输入,返回字符串。该接口支持任何自定义工具、任何 MCP 服务器以及我们自己的工具。管控框架不知道沙箱是容器、手机还是宝可梦模拟器。而且因为没有手与任何大脑耦合,大脑可以将手传递给彼此。
## 结论
我们面临的挑战是一个老问题:如何为"尚未想到程序"设计系统。操作系统通过将硬件虚拟化为足够通用的抽象,已经持续了几十年,适用于当时还不存在的程序。通过托管智能体,我们旨在设计一个容纳未来围绕 Claude 的管控框架、沙箱或其他组件的系统。
托管智能体是同样精神下的元管控框架,对 Claude 未来需要的*特定*管控框架没有预设主张。相反,它是一个具有通用接口的系统,允许多种不同的管控框架。例如,Claude Code 是我们广泛使用的优秀管控框架。我们还展示了特定任务的智能体管控框架在狭窄领域中表现出色。托管智能体可以容纳任何这些,随着时间的推移匹配 Claude 的智能。
元管控框架设计意味着对围绕 Claude 的接口有明确主张:我们预期 Claude 将需要操作状态(会话)和执行计算(沙箱)的能力。我们还预期 Claude 将需要扩展到多个大脑和多双手的能力。我们设计接口时考虑了这些可以在长时间范围内可靠且安全地运行。但我们对 Claude 需要的大脑或手的数量或位置不做假设。
## 致谢
本文由 Lance Martin、Gabe Cemaj 和 Michael Cohen 撰写。感谢 Nodir Turakulov 和 Jeremy Fox 就这些话题进行的有益讨论。特别感谢 Agents API 团队和 Jake Eaton 的贡献。
相似文章
智能代理界面的演变:使用Claude Managed Agents进行构建(13分钟阅读)
Anthropic推出了Claude Managed Agents,这是一组可组合的API,用于构建和部署生产级代理,解决了将原型与生产分离的基础设施挑战。
用于长时间运行代理的有效工具
Anthropic 推出了一种由两部分组成的解决方案,使用初始化代理和编码代理,使 Claude Agent SDK 能够有效处理跨多个上下文窗口的长时间运行任务,并通过保持干净、增量的状态来实现。
Anthropic 开发由 Claude 驱动的托管项目(2分钟阅读)
Anthropic 正在内部测试 Claude 的“托管项目”,这是一种新的项目类型,AI 能够主动管理任务、维持持久性上下文并运行计划任务,融合了其开发者平台和协作工具的功能。
Claude 推出自我改进型智能体(5 分钟阅读)
Anthropic 宣布为 Claude Managed Agents 带来多项新功能,包括用于自我改进记忆的“dreaming(梦境)”功能、基于结果的评估循环,以及多智能体编排能力。
未来,你只需要给Claude一个成果和预算就能完成一个目标。这就是方向……
Anthropic在其Code with Claude开发者大会上发布了新的托管代理功能,用户只需提供成果和预算即可完成目标,Claude将作为可扩展的云计算机全天候运行代理任务。