多智能体编排(multiagent orchestration)允许一个智能体与其他智能体协调以完成复杂的工作。智能体可以在各自独立的上下文中并行执行,这有助于提高输出质量,也可以缩短完成时间。
不确定多智能体设置是否适合您的问题?请参阅何时使用多智能体系统(以及何时不使用)。
Managed Agents API 请求需要 managed-agents-2026-04-01 beta 标头,但内存存储端点除外,它们使用 agent-memory-2026-07-22。SDK 会自动设置正确的 beta 标头。请参阅Beta 标头。
所有智能体共享相同的沙盒、文件系统和保险库凭证,但每个智能体都在自己的会话线程(session thread)中运行,这是一个具有自己对话历史的上下文隔离事件流。协调器在主线程(primary thread)中报告活动(与会话级事件流相同);当协调器委派工作时,会在运行时生成额外的线程。
线程是持久的:协调器可以向之前调用过的智能体发送后续消息,该智能体会保留其之前轮次中的所有内容。
每个智能体使用自己的配置:模型、系统提示、工具、MCP 服务器和技能。会话级智能体配置覆盖是例外;它们适用于协调器及其 self 副本。工具、MCP 服务器和上下文不共享。
多智能体协调最适合复杂任务,这些任务要么需要跨多种界面开展工作,要么由多个范围明确的任务共同实现一个总体目标。
行之有效的模式:
在定义您的智能体时,设置 multiagent 来声明协调器可以委派的智能体名单:
ant beta:agents create <<YAML
name: Engineering Lead
model: claude-opus-4-8
system: You coordinate engineering work. Delegate code review to the reviewer agent and test writing to the test agent.
tools:
- type: agent_toolset_20260401
multiagent:
type: coordinator
agents:
- type: agent
id: $REVIEWER_AGENT_ID
- type: agent
id: $TEST_WRITER_AGENT_ID
YAMLmultiagent.agents 可以接受以下任意一种:
{"type": "agent", "id": agent.id} 通过 ID 引用先前创建的 agent。如果未指定 version,则该引用会固定到创建协调器时该智能体的最新版本。{"type": "agent", "id": agent.id, "version": agent.version} 固定特定的智能体版本。{"type": "self"} 允许协调器生成自身的副本。如果会话是使用智能体配置覆盖创建的,这些覆盖也适用于这些副本;通过 ID 引用的名单条目不受影响。协调器的配置(包括其 multiagent.agents 名单)在创建或更新协调器时会被快照。被引用的智能体会保持固定在当时解析的版本,不会自动获取其定义的后续更新。要委派给被引用智能体的较新版本,请更新协调器,使其名单引用该版本。
协调器只能委派给一层智能体;引用一个自身拥有 multiagent.agents 名单的智能体会导致创建或更新请求因验证错误而失败。multiagent.agents 中最多可以列出 20 个唯一的智能体,但协调器可以调用每个智能体的多个副本。
创建一个引用协调器的会话。协调器会根据需要委派给其名单中的智能体。
session = client.beta.sessions.create(
agent=coordinator.id,
environment_id=environment.id,
)MCP 服务器是智能体作用域的(每个智能体定义声明自己的服务器和工具),而保险库凭证是会话作用域的(在创建会话时传递的 vault_ids 适用于每个线程)。这对您的集成有两点影响:
在创建会话时,智能体配置覆盖可以替换协调器及其 self 副本的 MCP 服务器。
research_agent = client.beta.agents.create(
name="researcher",
model="claude-haiku-4-5",
mcp_servers=[
{"type": "url", "name": "github", "url": "https://api.githubcopilot.com/mcp/"},
],
tools=[{"type": "mcp_toolset", "mcp_server_name": "github"}],
)
coordinator = client.beta.agents.create(
name="coordinator",
model="claude-opus-4-8",
tools=[{"type": "agent_toolset_20260401"}],
multiagent={
"type": "coordinator",
"agents": [{"type": "agent", "id": research_agent.id}],
},
)
session = client.beta.sessions.create(
agent=coordinator.id,
environment_id=environment.id,
vault_ids=[vault.id],
)
print(session.id)在此示例中,只有研究员声明了 GitHub MCP 服务器,因此协调器没有访问权限。会话的 vault_ids 向研究员的线程提供 GitHub 凭证。
如果在您声明服务器后,智能体的 MCP 调用身份验证失败,请确认凭证的 mcp_server_url 与智能体的 mcp_servers[].url 指向同一服务器。两个 URL 在匹配前都会被规范化(协议和主机名转为小写,去除默认端口和尾部斜杠),因此主机名大小写、默认端口或尾部斜杠的差异不会妨碍匹配;但不同的路径、子域名或非默认端口则会。
会话级事件流(/v1/sessions/{session_id}/events/stream)被视为主线程,包含所有线程中所有活动的精简视图。您看不到子智能体的全部活动,但可以看到它们工作的开始和结束,以及诸如工具权限请求之类的阻塞事件。
会话线程是您深入查看特定智能体活动的地方。
会话 status 是所有智能体活动的聚合;如果至少有一个线程处于 running 状态,则整个会话状态也为 running。
最多支持 25 个并发线程。协调器可以调用名单中单个智能体的多个副本,从而创建与一个 agent 关联的多个线程。
按如下方式列出与会话关联的所有线程:
for thread in client.beta.sessions.threads.list(session.id):
print(f"[{thread.agent.name}] {thread.status}")完整列表包括主线程。主线程的 parent_thread_id 为 null。
这些事件在 /v1/sessions/{session_id}/events/stream 的主线程上呈现多智能体活动。消息方向事件的命名是相对于其所在流的线程而言的:agent.thread_message_received 表示有消息从另一个线程到达此线程,而 agent.thread_message_sent 表示此线程发送了一条消息。例如,协调器委派的任务会作为 agent.thread_message_received 事件到达子线程自己的流上。
| 类型 | 描述 |
|---|---|
session.thread_created | 创建了一个线程。包含 session_thread_id 和 agent_name。 |
session.thread_status_running | 线程开始活动。 |
session.thread_status_idle | 与该线程关联的智能体正在等待输入。包含一个 stop_reason,指示智能体停止的原因。 |
session.thread_status_terminated | 线程已归档或遇到终止性错误。 |
agent.thread_message_received | 在主线程上,某个智能体向协调器发送了报告或问题。包含 from_session_thread_id、from_agent_name 和 content。 |
agent.thread_message_sent | 在主线程上,协调器向另一个智能体发送了任务或后续消息。包含 to_session_thread_id、to_agent_name 和 content。 |
关键事件会被代理到主线程。但是,您可能仍然想要调查特定智能体的推理和工具调用。为此,请从关联的会话线程流式传输或列出事件。
每个会话线程在 /v1/sessions/{session_id}/threads/{thread_id}/stream 都有自己的事件流,并且它接受与会话级流相同的 event_deltas[] 参数,因此您可以在模型生成时预览子智能体的文本。一个连接只预览它正在读取的线程:子线程的预览永远不会出现在会话级流上,因此要实时观察子智能体,请打开其自己的线程流。有关选择启用、累积和协调预览的信息,请参阅预览会话线程事件。
with client.beta.sessions.threads.events.stream(
thread.id,
session_id=session.id,
) as stream:
for event in stream:
match event.type:
case "agent.message":
for block in event.content:
if block.type == "text":
print(block.text, end="")
case "session.thread_status_idle":
break如果子智能体需要从您的客户端获取某些内容,例如运行 always_ask 工具的权限,或者自定义工具的结果,该事件会被交叉发布到主线程,并通过 session_thread_id 标识发起的会话线程。
{
"type": "session.thread_status_idle",
"id": "sevt_01ABC...",
"session_thread_id": "sth_01DEF...",
"agent_name": "code-reviewer",
"stop_reason": {
"type": "requires_action",
"event_ids": ["toolu_01XYZ..."]
}
}发布 user.tool_confirmation(带有 tool_use_id)或 user.custom_tool_result(带有 custom_tool_use_id);服务器会自动将响应路由到正确的线程。
以下示例扩展了工具确认处理程序以路由回复。同样的模式也适用于 user.custom_tool_result。
for event_id in stop.event_ids:
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.tool_confirmation",
"tool_use_id": event_id,
"result": "allow",
}
],
)Was this page helpful?