Claude智能体系列第 21 / 22 篇

托管智能体进阶:多个智能体协作、动态工作流,以及把沙箱放在自己的机器上

一个智能体忙不过来时,可以让它把活派给子智能体,或者自己写一段工作流让几百个智能体在后台跑;数据不能出内网时,可以把工具的执行搬到自己的机器上。本文按官方文档整理这两部分的用法、上限和安全分工,全文未实测。

发布 · 约 14 分钟读完 · 经人工审核()· 本站的内容怎么来的

本文根据公开分享整理,本站尚未实测。操作前请对照文末的原始来源。

本页目录(8 节)
  1. 一、把活交出去的三种办法
  2. 二、子智能体
  3. 三、动态工作流
  4. 四、顾问
  5. 五、自托管沙箱:执行放在你的机器上
  6. 六、自托管时,安全上谁负责什么
  7. 和 Claude Code、Agent SDK 的对应
  8. 没有实测的部分

这是托管智能体三篇里的最后一篇,讲两件进阶的事:

  • 一个智能体干不过来:要审三百份合同、要同时查很多个来源。怎么让多个智能体一起干?
  • 数据不能离开自己的网络:智能体要碰内网的服务和数据。怎么把执行放在自己的机器上?

前两篇是《托管智能体入门》和《环境和数据》。

全文按官方文档整理,没有实测:这组接口只在官方平台上有,中转站返回 404。示例代码来自官方文档,本站没有运行过。

一、把活交出去的三种办法

会话运行的那个智能体,可以用三种方式借助别的智能体或模型。都在智能体定义的 multiagent 字段里设置:

办法 发生了什么 什么时候用
子智能体 它自己把任务派给子智能体,读每个子智能体的汇报,再决定下一步 需要和子智能体来回沟通;需要你指定的、各有自己提示词和工具的专门角色
动态工作流 它写一段程序,由服务端在后台运行。程序分阶段启动很多智能体,把结果汇总 大多数需要不止一个智能体的活:量大、可以拆、可以并行
顾问 它自己干活,在关键时刻向一个更强的模型请教 一个智能体就够,只是在定方案、收尾检查时要更好的判断

把 multiagent 的类型设成 multiagent_20261001 后,三样可以同时用,各自能开能关。默认是子智能体开、动态工作流开、顾问关。

三种模式都好在哪:并行(互不相干的子任务同时做)、分工(安全审查、写文档各有专门的提示词和工具,而不是把所有能力塞给一个智能体)、升级(难的那一小部分交给更强的模型)。但每多一个智能体就多一份 token,官方另有一篇文章专门讲什么时候不该用多智能体。

二、子智能体

预定义的和临时的

每个被派活的智能体是两种之一:

  • 预定义的:你事先建好、列在 multiagent 里的智能体。它用自己的配置:自己的模型、提示词、工具、MCP 服务器、skill。
  • 临时的:没有保存的智能体,由派活的那一方当场定义。它沿用派活方的模型、工具、MCP 服务器和 skill。
lead_agent = client.beta.agents.create(
    name="Engineering Lead",
    model="claude-opus-5-5",
    system="You coordinate engineering work. Delegate code review to the reviewer agent "
           "and test writing to the test writer agent.",
    tools=[{"type": "agent_toolset_20260401"}],
    multiagent={
        "type": "multiagent_20261001",
        "subagents": {
            "type": "enabled",
            "predefined_agents": [
                {"type": "agent", "id": reviewer_agent.id},
                {"type": "agent", "id": test_writer_agent.id},
            ],
        },
    },
)

规则:

  • 只有一层。 被列出来的智能体自己不能再有 multiagent 设置,否则请求返回 400。
  • 版本是钉住的。 列表里的智能体在保存的那一刻就定在当时的版本,之后它们更新了也不会自动跟上。
  • 每个列表最多 20 个不同的智能体。同一个可以被叫起多份。
  • 列表里可以写 {"type": "self"},表示它自己的副本。
  • 临时智能体默认是允许的。只想让它用你列出来的那些,把 inline_agents 设成关闭。
  • 所有相关的智能体要么都不指定推理地区,要么指定同一个。

线程:每个智能体一条

所有智能体共用同一个沙箱、同一套文件、同一批保险库凭据,但每个智能体在自己的线程里运行,各有各的对话历史,上下文互不相通。

  • 主线程就是会话一级的事件流。上面是所有活动的浓缩版:看得到子智能体开始和结束、它们之间传的消息,看不到子智能体内部的每一步。
  • 要看某个子智能体具体做了什么,去读或者订阅它自己线程的事件流。
  • 子智能体的线程是持续的。主智能体可以回头给之前叫过的子智能体追加消息,它还记得之前的事。
  • 只要有一条线程在运行,整个会话的状态就是运行中。
  • 一个会话同时最多 25 条子线程,空闲的也算,归档了才腾出位置。顾问和工作流的线程不占这个名额。

两件和安全、权限有关的事:

  • 子智能体等你回应的调用,会转发到主线程上。 需要确认的工具调用、自定义工具调用,都在主线程的事件流里出现,带着来源线程的 ID。你照常回应,服务端自己会送到对的线程。不用等会话空闲,事件一到就可以回。
  • MCP 服务器按智能体配,凭据按会话配。 只想让某个角色碰 GitHub,就只在它的定义里声明那个服务器。但临时智能体沿用派活方的全部配置,限制不了;要严格限制,就关掉临时智能体。

三、动态工作流

子智能体的模式里,每一步都要主智能体自己读汇报、做决定。活的规模一大(文档的例子是审三百份合同),这样太慢,上下文也装不下。

动态工作流换了一个办法:主智能体写一段程序,程序自己去启动智能体、收结果、决定下一步,主智能体不再逐步参与。服务端在后台把这段程序跑成一次“工作流运行”。

程序能做的事:

  • 同时跑很多智能体(扇出)。
  • 把一个智能体的结果传给另一个。 结果回到程序手里,不经过主智能体。
  • 重复和分支。 比如一份草稿反复改,直到复查通过或者用完规定的轮数。
  • 处理失败。 某个智能体失败了,程序可以兜住,也可以让整次运行结束。

运行可以分阶段,比如“读合同”“核对结论”,你靠阶段事件跟进度。运行结束后,主智能体得到一轮机会去读结果,然后回答你,或者再开一次运行。

怎么让它开一次运行

没有专门的接口。 你在用户消息里描述活,由智能体自己决定要不要、什么时候开一次运行。你能做的是引导:在系统提示词里写清楚哪类任务该用运行、哪类小事自己做。文档给的几个方向:

  • 怎么拆:“一份合同一个智能体。再让第二个智能体把每一份都复查一遍,不只是复查有发现的那些。”
  • 失败了怎么办:“一个智能体失败不能让整次运行失败。读不了的合同列为未覆盖。”
  • 时间上限:“给这次运行一小时的时限。”

运行只用在真正需要的任务上,因为运行里的每个智能体都在花 token。

跟着一次运行走

运行的事件出现在会话的事件流里:

事件 含义
workflow_run.created 开了一次运行。带着运行的 ID、名字、说明,和它声明的各个阶段
workflow_run.status_running 开始执行,或者暂停后恢复
workflow_run.status_idle 暂停了,比如到了会话的预算
workflow_run.phase_started、phase_ended 进入、离开一个阶段
workflow_run.status_ended 结束了,带着结果
workflow_run.error 运行出错,或者启动被服务端拒绝

结束时的结果:

结果 含义
completed 程序跑完了
stopped 智能体把它停了,或者会话被归档
出错:timeout_error 到了运行的时限
出错:program_error 程序本身失败,或者某条线程失败而程序没兜住
出错:thread_limit_error 启动的智能体超过了上限

completed 只说明程序跑完了,不说明活干成了。 运行可以在线程上的工作失败、甚至线程没建起来的情况下以 completed 结束。要知道有没有失败的部分,得去读各条线程的事件。

怎么算“做完了”

这是用工作流时最容易判断错的地方。运行期间,会话可能一直是运行中,也可能因为运行被暂停而空闲。会话空闲不等于活做完了。 文档给的判断是两条同时成立:

  1. 你见过的每一次运行,都已经收到了它的 workflow_run.status_ended。
  2. 在那之后,收到一个原因是 end_turn 的会话空闲事件,并且不是你自己打断造成的。

还要留意:智能体读完结果可能再开一次运行,所以要重新检查。

打断、限制和上限

  • 打断不会结束任何运行。 发 user.interrupt 只停下主智能体当前这一轮。要停掉运行,发一条用户消息请它停;要继续,发一条消息请它继续。
  • 运行开着的时候,不能改会话的智能体配置(返回 400,错误码是 workflow_run_open);归档和删除会话也可能被拒。
  • 运行里的线程也会来找你要工具结果或确认,照常在主线程上回应。
  • 只有主线程上的智能体能开运行,运行里的智能体不能再开,运行不嵌套。
  • 你看不到程序的代码。运行结束后可以发消息让智能体把它写的工作流原样打出来。
上限 数值
一次运行里同时工作的线程 64
一次运行从头到尾启动的智能体 1,000
一次运行的时限 默认 24 小时,智能体可以设得更短
一个会话同时开着的运行 默认 10

费用和限流:

  • 运行没有单独的价格。里面的 token 和会话别的 token 一样计费,算进会话的预算。到了预算,所有开着的运行暂停;每条正在工作的线程会把手头那次请求跑完,所以可能超出一点。
  • 运行里的模型请求占用你组织的消息接口限流额度,和你别的流量算在一起。一次扇出几十个智能体,要给它留余量。
  • 服务端可能为同一件活建不止一条线程,所以文档提醒:让智能体调的工具做到调用两次也安全。

四、顾问

给会话配一个顾问模型,主线程可以在一轮当中向它请教:定方案、卡住了、收尾前检查。

multiagent={"type": "multiagent_20261001",
            "advisor": {"type": "enabled", "model": "claude-opus-5-5"}}
  • 只有主线程能请教,子智能体不能。它不是子智能体,不占线程名额。
  • 顾问模型不能比智能体自己的模型弱,同档可以。不合规的搭配在保存智能体时就会被拒。
  • 建议通过线程事件送达。你的程序看不看得到建议的原文,取决于顾问模型:有的返回明文,有的返回一个“已隐去”的占位。
  • 请教失败或被打断不会让智能体这一轮失败,它会在收到一个“请教失败”的提示后接着干。
  • 上面的例子只开了顾问,子智能体和工作流仍然是默认的开启状态。要一个“只请教、活全自己干”的智能体,把那两样显式关掉。

消息接口上也有顾问,是一个服务器端工具,见《服务器端工具》第六节。两处的原理相同,配置的字段和结果送达的方式不同。

五、自托管沙箱:执行放在你的机器上

默认情况下,工具在 Anthropic 托管的云端沙箱里执行。自托管沙箱把这一部分搬到你控制的机器上:循环和模型仍然在 Anthropic 那边,工具的执行、文件、进程、出网流量留在你这边。

适合的场合:数据不能出你的网络边界;要访问公网到不了的内部服务;要在你们自己的合规和审计之下运行。

它是怎么工作的

一个 self_hosted 类型的环境就是一个工作队列。你在自己的机器上跑一个 worker 进程来消费它:

  1. 你建一个指向这个环境的会话,Anthropic 把它放进队列。
  2. 你的 worker 领走这个任务,下载智能体的 skill 和会话挂的记忆库。
  3. Claude 在 Anthropic 那边运行,发出工具调用;worker 在本地执行每一个调用,把结果送回去。

要想清楚的一点:工具的输入和输出仍然会经过 Anthropic,模型得看到结果才能决定下一步。留在你这边的是执行本身、文件和网络访问,不是全部数据。

云端环境 自托管沙箱
工具在哪执行 Anthropic 的沙箱 你的机器
能访问什么网络 Anthropic 的出网控制 你的网络策略
挂文件和代码仓库 Anthropic 负责 不支持,你自己放
记忆库 直接挂载 worker 下载到本地再同步回去
生命周期 Anthropic 管 你管

自托管的会话只能挂记忆库,带文件或仓库资源的会话会被直接拒绝。要给会话准备文件,文档的办法是:把文件的位置(比如对象存储的路径、提交的哈希)写进会话的 metadata,由你的启动脚本读出来、提前放进工作目录。

跑起第一个 worker

  1. 建一个 self_hosted 环境(接口或控制台都行)。
  2. 在控制台里给它生成一把环境密钥。这把密钥只能在控制台生成,它只管这一个环境的队列。
  3. 在 worker 的机器上设好环境 ID 和环境密钥,启动 worker:
sudo mkdir -p /workspace && sudo chown "$USER" /workspace
ant beta:worker poll --workdir /workspace
  1. 在你自己的机器上建会话、发任务。没有 worker 在线时,会话会在队列里等着,不会失败。

worker 的机器只需要有 /bin/bash 和出站的 HTTPS。

一条反复出现的提醒:不要把你的 API key 放在 worker 的机器上。 智能体的工具调用就在那台机器上执行,能读到环境变量。worker 用环境密钥就够了;建会话、看队列这些操作在你自己的机器上用 API key 做。

两个要做的选择

怎么领任务:

  • 常驻:一个长期运行的进程不停轮询。最简单,只要出站 HTTPS。
  • 由 webhook 触发:收到会话开始运行的通知才起来干活。省掉一个空转的轮询进程,但要有一个 Anthropic 访问得到的 webhook 地址。

每个会话在哪跑:

  • 同一个进程里:领任务的 worker 自己执行工具调用,所有会话共用一个工作目录。
  • 每个会话一个沙箱:轮询的进程为每个领到的会话起一个全新的沙箱。隔离更强:独立的文件系统、资源限制、各自的网络控制。

官方提供了现成的 worker:命令行工具 ant 里一个,Python、TypeScript、Go 的 SDK 里各一个。能力有差别:

能力 ant 命令行 SDK
常驻轮询 有 有
webhook 触发 没有 有
每个会话一个沙箱 有 有
记忆库 有,同步设置用默认值 有,可以调
自定义工具 没有 有

也可以直接调队列的接口自己写一个。文档另外列了十来个沙箱平台各自的接入指南。

在 worker 里提供自定义工具

自定义工具本来是“你的程序执行”的工具。在自托管的场景里,worker 可以就是那个程序:它在你的沙箱里运行,够得着内网的服务和凭据。这要用 SDK 的 worker,命令行的那个不支持。

由此有一个很实用的做法:把只在内网里的 MCP 服务器包成自定义工具。 平台的 MCP 连接是从 Anthropic 那边连出去的,服务器必须公网可达(或者走隧道)。换一个方向:让 worker 去当 MCP 的客户端,把服务器上的工具逐个声明成智能体的自定义工具。模型调用时,worker 把请求转给内网的服务器,再把结果送回去。服务器不需要任何入站的连接。

如果智能体上声明了一个自定义工具,却没有任何 worker 或客户端来执行它,会话会一直停在等待你回应的状态。

记忆库在自托管下

用法和云端一样,区别是谁来落地:worker 把每个记忆库下载到 /mnt/memory/ 下的一个目录,把智能体的改动同步回去。默认最多每 15 秒同步一次,会话结束时再同步一次。

要求:ant 1.33.0 以上或 SDK 的 worker;POSIX 文件系统(不支持 Windows);/mnt/memory 目录存在并且 worker 的用户可写。

只读挂载的记忆库,保护的是“不会被传回去”,不是“本地改不了”:worker 的写和编辑工具会拒绝,但沙箱里的别的进程(比如一条 bash 命令)仍然可能改到本地那份副本,只是不会同步。

看队列,停任务

字段 含义 用来
depth 等着被领的任务数 决定要不要加 worker,或者对积压告警
pending 被领走但还没确认的任务数,正常时接近零 发现卡在半路的 worker
oldest_queued_at 队列里最老的任务的时间 看最久等了多长
workers_polling 最近 30 秒里轮询过的 worker 数 存活告警

停一个任务有两种:默认是优雅地停,worker 在下一次心跳时发现,取消正在跑的工具调用再确认;加 force 是立刻标记为已停。停 worker 要让它收到终止信号后正常退出;直接杀掉的进程什么收尾都不做。

六、自托管时,安全上谁负责什么

Anthropic 负责控制面:会话和队列的完整性、多租户隔离。沙箱以内都是你的事:

  • 镜像和运行时的加固。 Anthropic 不检查你的镜像。去掉不需要的权限、用非 root 用户、根文件系统只读。
  • 出网控制。 由你的防火墙和网络规则决定。不限制的话,一次被攻破的工具执行可以连到任意外部主机。
  • 环境密钥的存放和轮换。 放进密钥管理服务,不要写进环境文件或镜像。怀疑泄露立刻吊销重发,吊销在 worker 下一次请求时就生效。
  • 隔离不可信的工作负载。 环境密钥管的是一整个环境的队列。跑不可信的代码时,考虑按信任边界分工作区和环境。
  • 每个会话的密钥。 每个任务可以带一个只属于这个会话的密钥,访问记忆库必须用它。只传给服务这个会话的沙箱,不要写进日志。
  • 工具执行的影响范围。 工具以你的进程的权限运行。进程用户给最小权限,只挂工具需要的目录。
  • 日志和会话内容的留存。 对话内容和工具输出经过你的 worker、留在你的环境里,保留多久、要不要脱敏,按你们自己的规定办。

Anthropic 做不到的:知道你的密钥泄露了;验证你的 worker 是不是你以为的那个版本;替你在沙箱内部把工具彼此隔开;替你在你的环境里执行数据留存策略。

和 Claude Code、Agent SDK 的对应

这三篇里的很多东西在 Claude Code 里有对应:子智能体、skill、MCP、权限确认、定时任务、云端会话。区别是一贯的那一条:Claude Code 和 Agent SDK 跑在你这边,托管智能体跑在 Anthropic 那边,再由你的程序通过事件去驱动。

  • 想自己掌握运行环境、已经在用 Claude Code 的工作方式:Agent SDK,部署见《把智能体部署上线》。
  • 不想管任何基础设施、任务又长又异步:托管智能体。
  • 执行要留在内网,其余不想管:托管智能体加自托管沙箱。

没有实测的部分

  • 全文没有实测。 托管智能体只在官方平台上有,本站用的中转站对这组接口返回 404。
  • 示例代码来自官方文档,本站没有运行过。
  • 各项上限(25 条子线程、64 条并发线程、1,000 个智能体、24 小时、10 次运行)是文档当前的数字,文档自己也说其中有的不作保证、可能调整。
  • 动态工作流的实际效果(智能体写出来的程序质量如何、什么情况下会选择开一次运行)没有观察过,文中只转述了文档的说明。
  • 自托管 worker 没有搭过,包括各沙箱平台的接入指南。

来源

通过 API 中转站使用这些模型?到 Veridrop 免费检测中转站给你的是不是它声称的模型,或者看看中转站排行榜前 100 名。

相关文章