workflow(工作流)是智能体编写的一个程序,用于运行多个智能体并合并它们返回的结果。workflow run(工作流运行)是一个工作流的一次执行。动态工作流是让智能体能够编写工作流并启动运行的功能。您可以通过智能体 multiagent (csharp, go: Multiagent) 块中的 workflows (csharp, go: Workflows) 设置来开启或关闭它。
服务器在后台运行工作流。工作流中的智能体在会话线程中工作,这些线程由服务器根据工作流的需要创建。您可以在会话的事件流上跟踪运行。要停止一个运行,请让智能体停止它(请参阅在有打开的运行时中断会话)。
动态工作流的工作原理
会话所运行的智能体会针对您描述的工作编写每个工作流。工作流是一个程序:它运行其他智能体,收集每个智能体返回的内容,并合并结果。这样,智能体就可以承担对于单次对话来说过于庞大的任务,例如审阅数百份文档。在运行期间,智能体可以继续工作或结束其轮次,并且可以检查运行的状态。
该图展示了一个示例。智能体编写的每个工作流都有自己的阶段和智能体。一次运行包含以下层级:
- 工作流运行:服务器在后台以一次工作流运行的形式运行工作流。一个会话可以同时有多个处于打开状态的运行。
- 阶段: 工作流可以将其工作划分为多个阶段。阶段是运行中一个具名的环节,例如“阅读合同”。您可以通过阶段事件跟踪运行的进度。
- 智能体线程: 在一个阶段中,程序运行智能体。每个智能体在自己的会话线程中,基于程序编写的提示进行工作。运行中的智能体可以是内联智能体(由程序自行定义),也可以是预定义智能体(由您在
workflows(csharp, go:Workflows) 的predefined_agents(java, php:predefinedAgents; csharp, go:PredefinedAgents) 列表中列出)。有关每个线程显示的内容,请参阅运行的线程。
程序可以执行以下操作:
- 同时运行多个智能体:程序可以同时运行许多智能体,这称为“fanning out”(扇出)。在图中,三个智能体在第一阶段阅读合同。
- 将结果从一个智能体传递给另一个智能体:每个智能体将其结果返回给程序。程序可以将该结果传递给另一个智能体。在图中,第二阶段的智能体处理前三个智能体返回的内容。同一运行的各个智能体还会在会话的沙箱中处理相同的文件。
- 自行执行下一步:智能体的结果会返回给程序,而不是返回给会话所运行的智能体。程序决定接下来运行哪些智能体,并编写它们的提示。
- 重复与选择:在一个阶段内,程序可以重复工作,并根据智能体返回的内容选择下一步。例如,它可以让草稿不断修订,直到审阅通过或用完设定的轮数。在图中,程序可以在第二阶段内重复某个步骤。
- 处理失败的智能体: 当其中一个智能体失败时,服务器通常会在一个新线程上再运行该智能体一次,同时该运行的其他智能体继续工作。如果再次失败,程序可以处理该失败,或者让它结束运行。如果程序处理了失败,运行仍可能以
completed结束,因此请告诉会话所运行的智能体报告哪些内容失败了。
运行结束后,会话所运行的智能体会获得一个轮次来读取运行所做的工作。然后它可以回答您,或启动另一个运行。运行事件列出了该轮次延后到来或不会到来的情况。
您可以指导运行如何完成工作,例如如何拆分工作以及智能体失败时该怎么做。请参阅告诉智能体何时使用运行。
运行启动前没有审批步骤:智能体在编写工作流的同一轮次中启动运行。要先审阅计划,请告诉智能体描述该运行并等待您的批准。运行启动时,workflow_run.created 会显示其名称、描述和阶段。如果启动了您未批准的运行,请让智能体停止它(请参阅在有打开的运行时中断会话)。
运行如何在各状态之间转换
运行以运行中或空闲状态开始。例如,达到预算会暂停正在运行的运行,使其变为空闲;随后提高或移除预算会使其再次运行,除非中断也暂停了它。当其工作流完成、智能体停止它、它失败、其生命周期到期或会话被归档时,正在运行的运行会结束。空闲的运行也可能结束,例如当智能体停止它或会话被归档时。
运行从其 workflow_run.created 事件开始到其 workflow_run.status_ended 事件为止处于打开(open)状态,无论它是正在运行还是空闲。运行在暂停期间处于空闲状态,例如在达到会话预算时。运行有一个生命周期,智能体可以在启动运行时设置它。运行等待您的客户端所花费的时间也计入该生命周期。暂停不会阻止运行的生命周期流逝,因此一直处于暂停状态的运行可能会以 timeout_error 结束。以下事件报告运行的开始、其阶段以及其结束。因达到预算而暂停时也会发送一个事件。中断后的暂停可能不会发送任何事件。每个 workflow_run.* 事件都包含 workflow_run_id (java: workflowRunId; php: workflowRunID; csharp, go: WorkflowRunID),仅当未创建运行时,它在 workflow_run.error 上才为 null (python: None; ruby: nil; java: Optional.empty(); go: "")。
运行事件
运行事件到达会话的事件流(即主线程的流),列出会话的事件时也会返回它们。运行事件不会触发 webhook。来自运行线程的状态事件也到达同一个流。每个事件都在 session_thread_id (java: sessionThreadId; php: sessionThreadID; csharp, go: SessionThreadID) 中指明其线程,而运行的线程就是那些 session.thread_created 事件带有该运行的 workflow_run_id (java: workflowRunId; php: workflowRunID; csharp, go: WorkflowRunID) 的线程。
| 事件 | 何时到达 | 如何处理 |
|---|---|---|
workflow_run.created |
智能体启动了一个运行。包含 workflow_run_id (java: workflowRunId; php: workflowRunID; csharp, go: WorkflowRunID)(wrun_…)、运行的 name (csharp, go: Name) 和 description (csharp, go: Description),以及 phases (csharp, go: Phases),即工作流声明的阶段,每个阶段都有一个 id (csharp, go: ID)、一个 name (csharp, go: Name) 和一个 description (csharp, go: Description)。当工作流未提供描述时,description (csharp, go: Description) 为 null (python: None; ruby: nil; java: Optional.empty(); go: "")。phases (csharp, go: Phases) 始终存在,且可以为空。运行和阶段的 name (csharp, go: Name) 和 description (csharp, go: Description) 是模型编写的文本,因此可能会重复您请求中的词语。运行的 name (csharp, go: Name) 也可能是服务器分配的。 |
将该运行记录为打开状态。显示其 name (csharp, go: Name),并根据 phases (csharp, go: Phases) 显示进度。 |
workflow_run.status_running |
当运行开始其工作时(可能在 created 之后一段时间),以及每次在预算处暂停后恢复时。中断后的恢复可能不会发送此事件。以空闲状态开始的运行可能会先收到 workflow_run.status_idle。 |
将运行显示为运行中。 |
workflow_run.status_idle |
运行已暂停,例如达到会话预算时。该事件不说明原因。中断后的暂停可能不会发送此事件。 | 要继续,请参阅成本和预算或在有打开的运行时中断会话。 |
workflow_run.phase_started、workflow_run.phase_ended |
工作流进入或离开了某个阶段,或者运行结束时关闭了仍处于打开状态的阶段。结束事件不说明该阶段的工作是否完成。两者都包含 workflow_run_phase_id (java: workflowRunPhaseId; php: workflowRunPhaseID; csharp, go: WorkflowRunPhaseID)。结束事件还包含 phase_started_id (java: phaseStartedId; php: phaseStartedID; csharp, go: PhaseStartedID),即它所关闭的开始事件的 id (csharp, go: ID)。两者都不包含阶段名称:请通过 workflow_run_phase_id (java: workflowRunPhaseId; php: workflowRunPhaseID; csharp, go: WorkflowRunPhaseID) 在 workflow_run.created 的 phases (csharp, go: Phases) 中查找。 |
更新进度。阶段一次运行一个,按 phases (csharp, go: Phases) 的顺序,每个阶段最多运行一次,但 API 不保证这一点。通过 phase_started_id (java: phaseStartedId; php: phaseStartedID; csharp, go: PhaseStartedID) 将阶段的结束与其开始对应起来。请处理多个阶段同时打开、某个阶段不在 phases (csharp, go: Phases) 中,以及某个已列出的阶段从未开始的情况,即使在已完成的运行中也是如此。每个开始的阶段也都会在运行的 workflow_run.status_ended 之前结束。 |
workflow_run.status_ended |
运行已结束。始终是该运行的最后一个 workflow_run.* 事件。包含 result (csharp, go: Result)。 |
读取 result (csharp, go: Result)(见下表)。然后智能体会获得一个轮次来读取运行是如何结束的。在达到预算时,或在主线程等待您的客户端时,该轮次会延后到来。中断后,该轮次可能不会到来:请发送一个 user.message,或自行读取 result (csharp, go: Result)。归档或终止后,该轮次不会到来。 |
workflow_run.error |
服务器报告运行的错误,或它拒绝的启动。以 error 结束的运行会在其 workflow_run.status_ended 之前收到此事件,带有相同的错误。包含 error (csharp, go: Error):一个 type (csharp, go: Type) 和一个可以安全记录到日志的 message (csharp, go: Message)。当未创建运行时,workflow_run_id (java: workflowRunId; php: workflowRunID; csharp, go: WorkflowRunID) 为 null (python: None; ruby: nil; java: Optional.empty(); go: "")。 |
将其记录到日志,不要将其视为运行的结束。如果 workflow_run_id (java: workflowRunId; php: workflowRunID; csharp, go: WorkflowRunID) 为 null (python: None; ruby: nil; java: Optional.empty(); go: ""),则没有运行启动。否则,请继续跟踪该运行,直到其 workflow_run.status_ended。 |
result |
含义 |
|---|---|
{"type": "completed"} |
工作流已运行完毕。该结果不说明工作是否通过。即使其线程上的工作失败,或某个线程无法创建,运行也可能以 completed 结束。要查找失败的工作,请读取每个运行线程的事件。 |
{"type": "stopped"} |
智能体停止了运行,或会话被归档。该事件不会说明是哪一种。不要将这些视为仅有的原因。 |
带有 timeout_error 的 error |
运行的生命周期已到期,智能体可以设置该生命周期。 |
带有 program_error 的 error |
工作流失败。其代码失败,或违反了工作流的某条规则(限制除外)。或者运行的某个线程失败或无法创建,而工作流让这一情况结束了运行。 |
带有 thread_limit_error 的 error |
运行超出了其对工作流启动的智能体数量的限制。 |
带有 unknown_error 的 error |
服务器无法继续运行,或运行超出了服务器对工作流的其他某项限制。 |
错误结果形如 {"type": "error", "error": {"type": "timeout_error", "message": "..."}},其中 message 可以安全记录。将无法识别的 result.type 视为以其他方式结束的运行,将无法识别的 error.type 视为错误。当会话所依赖的某项内容失败时(例如模型、MCP 服务器、凭据或计费),失败线程的流会收到 session.error。这本身不会结束运行。但如果它导致运行的某个线程失败,而工作流让这一情况结束运行,则运行以 program_error 结束。
例如,您询问合同审查智能体 300 份合同中哪些包含控制权变更条款,智能体启动了一个运行:
workflow_run.created将该运行命名为“Find change-of-control clauses”,并在phases(csharp, go:Phases) 中列出阶段“Read the contracts”和“Reconcile the findings”。随后是workflow_run.status_running。- 阶段事件标记每个阶段,运行创建的每个线程都会发送带有该运行
workflow_run_id(java:workflowRunId; php:workflowRunID; csharp, go:WorkflowRunID) 的session.thread_created。 workflow_run.status_ended到达,带有result: {"type": "completed"}。- 智能体回答“300 份合同中有 41 份包含此条款”,然后
session.status_idle以end_turn到达。
运行的第一个事件列出了其阶段:
{
"type": "workflow_run.created",
"id": "sevt_01abc...",
"workflow_run_id": "wrun_01J8XkN5uT3vHpLqRfWdY2",
"name": "Find change-of-control clauses",
"description": "Reads each contract and lists those that have the clause.",
"phases": [
{
"id": "wrph_01Kd3a1f3",
"name": "Read the contracts",
"description": "Reads each contract for the clause."
},
{ "id": "wrph_01Kd3b7c9", "name": "Reconcile the findings", "description": null }
],
"processed_at": "2026-10-09T14:01:45Z"
}
每个阶段事件通过 workflow_run_phase_id 指明其阶段。它是 phases 中的一个 id,但 API 不保证这一点:
{
"type": "workflow_run.phase_started",
"id": "sevt_01def...",
"workflow_run_id": "wrun_01J8XkN5uT3vHpLqRfWdY2",
"workflow_run_phase_id": "wrph_01Kd3a1f3",
"processed_at": "2026-10-09T14:01:46Z"
}
运行的最后一个事件报告其结束方式:
{
"type": "workflow_run.status_ended",
"id": "sevt_01ghi...",
"workflow_run_id": "wrun_01J8XkN5uT3vHpLqRfWdY2",
"result": { "type": "completed" },
"processed_at": "2026-10-09T14:09:12Z"
}
运行的线程
一次运行中的每个智能体都在自己的会话线程中工作,该线程由服务器根据工作流的需要创建。您可以像对待任何子线程一样列出、读取和流式传输运行的线程,并从主事件流中回答它们的工具调用。要停止它们,请让智能体停止该运行(请参阅在有打开的运行时中断会话)。
- 分组: 运行的线程带有该运行的
workflow_run_id(java:workflowRunId; php:workflowRunID; csharp, go:WorkflowRunID),宣告该线程的session.thread_created事件也是如此。其他线程以及宣告它们的session.thread_created事件的workflow_run_id(java:workflowRunId; php:workflowRunID; csharp, go:WorkflowRunID) 设置为null(python:None; ruby:nil; java:Optional.empty(); go:"")。 - 智能体:
agent(csharp, go:Agent) 显示线程所运行的智能体。对于您在multiagent(csharp, go:Multiagent) 中workflows(csharp, go:Workflows) 的predefined_agents(java, php:predefinedAgents; csharp, go:PredefinedAgents) 列表中列出的智能体,agent(csharp, go:Agent) 包含该智能体的id(csharp, go:ID) 和version(csharp, go:Version),与您列出的子智能体的线程相同。对于工作流定义的智能体(内联智能体),agent(csharp, go:Agent) 的type为inline,且没有id(csharp, go:ID) 或version(csharp, go:Version)。它使用工作流编写的系统提示,而不是会话智能体的系统提示。它还带有工作流为其指定的名称和描述。如果工作流未指定名称,服务器会分配一个。它使用会话智能体(即会话所运行的智能体)的模型。它的工具、MCP 服务器和技能是会话智能体的子集。它会获得全部这些内容,但 API 不保证这一点。它的工具保留各自的权限策略。 - 线程共享的内容: 运行的线程在会话的沙箱中工作,因此每个线程都处理相同的文件。这包括会话挂载的记忆存储中的文件。工作流定义的智能体使用会话为其 MCP 服务器解析的凭据来使用这些服务器。每个线程都有自己的对话历史。
- 事件:运行线程的
session.thread_created、session.thread_status_running、session.thread_status_idle和session.thread_status_terminated事件也会到达主事件流(请参阅运行事件)。其消息事件保留在它自己的流上。其线程 webhook 的发送方式与任何子线程相同。关于线程自身的流记录了什么,请参阅会话线程事件。 - 阶段: 没有任何事件或字段说明线程在哪个阶段工作,并且同一运行的线程可能具有相同的
agent_name。请通过运行的阶段事件跟踪其进度,并通过session_thread_id(java:sessionThreadId; php:sessionThreadID; csharp, go:SessionThreadID) 区分其线程。 - 归档: 服务器最迟在运行结束时归档每个线程。一旦线程返回其结果或运行不再需要它,服务器可以更早地归档它。如果此时线程仍在运行或正在等待您的客户端,服务器会先停止它。已归档的线程仍保留在线程列表中,状态为
terminated。您无需自行归档运行的线程。 - 工具: 运行可能会为同一项工作创建多个线程,因此请确保您的智能体调用的工具可以安全地被调用两次。
提示
您可以向智能体索要它为您的请求编写的工作流。等待运行结束且会话处于
idle状态。然后发送一条user.message,要求智能体逐字打印它用于启动运行的工作流,并且不要启动另一个运行。Print the workflow that you started the run with, word for word, in one code block. Do not start another run.
了解工作何时完成
当运行处于运行中时,即使其线程都没有在工作,会话也应保持 running。当没有线程在工作且有线程在等待您的客户端时,会话会以 requires_action 变为 idle。空闲本身并不意味着工作已完成。当以下两项都成立时,工作才算完成:
- 您看到创建的每个运行都有其
workflow_run.status_ended。 - 在此之后,一个
session.status_idle到达,其stop_reason(java, php:stopReason; csharp, go:StopReason) 为end_turn,并且它不是由您自己的请求(例如中断)引起的。在您中断之后,只计算在您下一个user.message或user.define_outcome之后到来的空闲。
- 已暂停的运行:已暂停的运行不会使会话保持
running,因此会话可能在运行仍打开时变为空闲。例如,在达到预算时,会话以budget_reached变为空闲。在运行结束之前,工作并未完成。 - 另一个运行:智能体在读取结果时可以启动新的运行,因此请再次检查。
- 结果:如果您定义了结果,则在运行打开期间(无论处于运行中还是空闲状态)不会开始评估。智能体读取运行结果的那个轮次可以开始评估。
retries_exhausted: 智能体的轮次因错误而失败:重试次数已用完,或者该错误无法重试,例如计费失败。当此空闲到来时,某个运行可能仍在运行。如果某个运行已结束而智能体尚未读取其结果,服务器会在没有您输入的情况下启动一个新轮次。会话会再次变为running,因此请等待下一次空闲。如果会话保持空闲,请读取在它之前到来的session.error并修复原因。然后发送一个user.message,或自行读取每个运行的result(csharp, go:Result)。
跟踪运行
此示例跟踪一个会话,从您的消息到智能体的回答。它打开流并发送消息。然后执行以下操作:
- 跟踪每个运行,从其
workflow_run.created到其workflow_run.status_ended,并在每个阶段开始时打印该阶段。 - 回答自定义工具调用,在每个
agent.custom_tool_use到达时进行回答,因为运行的线程可能在会话保持running时等待您的客户端。如果您的智能体的工具要求确认,请添加一个分支,回答每个evaluated_permission(java, php:evaluatedPermission; csharp, go:EvaluatedPermission) 为ask的agent.tool_use或agent.mcp_tool_use。示例中没有这样的分支,因为允许每个调用的分支会把always_ask变成始终允许。 - 停止:当工作完成时停止:没有打开的运行,并且会话以
end_turn变为空闲。如果会话终止,它也会停止。当空闲的停止原因不是requires_action而是其他原因(例如budget_reached、retries_exhausted或refusal)时,它会打印原因并停止,因此请在您自己的代码中处理这些情况。即使服务器即将自行启动新轮次,它也会在retries_exhausted时停止。在requires_action时,以及在运行打开期间的end_turn时,它会继续等待。
cURL
此工作流需要的逻辑超出了单个 shell 命令所能实现的范围。请使用 Claude SDK 运行它。
CLI
此工作流需要的逻辑超出了单个 shell 命令所能实现的范围。请使用 Claude SDK 运行它。
Python
open_runs: dict[str, str] = {} # workflow_run_id -> run name
phase_names: dict[tuple[str, str], str] = {} # (run ID, phase ID) -> phase name
# 先打开流,再发送用户消息
with client.beta.sessions.events.stream(session_id) as stream:
client.beta.sessions.events.send(
session_id,
events=[
{
"type": "user.message",
"content": [
{
"type": "text",
"text": "Which contracts in /contracts have a change-of-control clause?",
},
],
},
],
)
for event in stream:
match event.type:
case "workflow_run.created":
open_runs[event.workflow_run_id] = event.name
for phase in event.phases:
phase_names[event.workflow_run_id, phase.id] = phase.name
print(f"Run started: {event.name}")
case "workflow_run.phase_started":
phase_id = event.workflow_run_phase_id
key = (event.workflow_run_id, phase_id)
print(f" Phase: {phase_names.get(key, phase_id)}")
case "workflow_run.status_ended":
name = open_runs.pop(event.workflow_run_id, event.workflow_run_id)
print(f"Run ended: {name} ({event.result.type})")
case "agent.custom_tool_use":
# 事件到达时进行应答。运行的线程可能会等待您的
# 客户端,而会话保持运行状态。
result = call_tool(event.name, event.input)
try:
client.beta.sessions.events.send(
session_id,
events=[
{
"type": "user.custom_tool_result",
"custom_tool_use_id": event.id,
"content": [{"type": "text", "text": result}],
},
],
)
except anthropic.BadRequestError as error:
# 如果结果来得太晚(在服务器归档该调用的线程之后),
# 服务器会拒绝该结果。请继续跟踪该运行。
print(f" Answer to {event.name} refused: {error.message}")
case "session.status_idle":
# 当所有运行都已结束且智能体已完成其轮次时即完成
if not open_runs and event.stop_reason.type == "end_turn":
break
# 带有 requires_action 的 idle 会等待您的客户端,因此请继续读取。
# 遇到任何其他停止原因时,打印该原因并停止。
if event.stop_reason.type not in ("end_turn", "requires_action"):
print(f"Session idle: {event.stop_reason.type}")
break
case "session.status_terminated":
break
TypeScript
const openRuns = new Map<string, string>(); // workflow_run_id -> run name
const phaseNames = new Map<string, string>(); // "run ID:phase ID" -> phase name
// 先打开流,再发送用户消息
const stream = await client.beta.sessions.events.stream(sessionId);
await client.beta.sessions.events.send(sessionId, {
events: [
{
type: "user.message",
content: [
{
type: "text",
text: "Which contracts in /contracts have a change-of-control clause?"
}
]
}
]
});
events: for await (const event of stream) {
switch (event.type) {
case "workflow_run.created":
openRuns.set(event.workflow_run_id, event.name);
for (const phase of event.phases) {
phaseNames.set(`${event.workflow_run_id}:${phase.id}`, phase.name);
}
console.log(`Run started: ${event.name}`);
break;
case "workflow_run.phase_started": {
const phaseId = event.workflow_run_phase_id;
const phaseName = phaseNames.get(`${event.workflow_run_id}:${phaseId}`);
console.log(` Phase: ${phaseName ?? phaseId}`);
break;
}
case "workflow_run.status_ended": {
const name = openRuns.get(event.workflow_run_id) ?? event.workflow_run_id;
openRuns.delete(event.workflow_run_id);
console.log(`Run ended: ${name} (${event.result.type})`);
break;
}
case "agent.custom_tool_use": {
// 事件到达时进行应答。运行的线程可能会等待您的
// 客户端,而会话保持运行状态。
const result = await callTool(event.name, event.input);
try {
await client.beta.sessions.events.send(sessionId, {
events: [
{
type: "user.custom_tool_result",
custom_tool_use_id: event.id,
content: [{ type: "text", text: result }]
}
]
});
} catch (error) {
// 如果结果来得太晚(在服务器已归档该调用的线程之后),
// 服务器会拒绝该结果。请继续跟踪该运行。
if (!(error instanceof Anthropic.BadRequestError)) {
throw error;
}
console.log(` Answer to ${event.name} refused: ${error.message}`);
}
break;
}
case "session.status_idle": {
// 当所有运行都已结束且智能体已完成其轮次时即完成
const reason = event.stop_reason.type;
if (openRuns.size === 0 && reason === "end_turn") {
break events;
}
// 带有 requires_action 的 idle 表示正在等待您的客户端,因此请继续读取。
// 遇到任何其他停止原因时,打印该原因并停止。
if (reason !== "end_turn" && reason !== "requires_action") {
console.log(`Session idle: ${reason}`);
break events;
}
break;
}
case "session.status_terminated":
break events;
}
}
C#
var openRuns = new Dictionary<string, string>(); // workflow_run_id -> run name
var phaseNames = new Dictionary<(string, string), string>(); // (run ID, phase ID) -> phase name
// 先打开流,再发送用户消息。raw-response 调用
// 会立即打开流。普通调用则会等到第一次读取时才打开。
using var stream = await client.Beta.Sessions.Events.WithRawResponse.StreamStreaming(sessionId);
await client.Beta.Sessions.Events.Send(sessionId, new()
{
Events =
[
new BetaManagedAgentsUserMessageEventParams
{
Content =
[
new BetaManagedAgentsTextBlock
{
Text = "Which contracts in /contracts have a change-of-control clause?",
},
],
},
],
});
await foreach (var streamEvent in stream.Enumerate())
{
if (streamEvent.Value is BetaManagedAgentsWorkflowRunCreatedEvent created)
{
openRuns[created.WorkflowRunID] = created.Name;
foreach (var listed in created.Phases)
{
phaseNames[(created.WorkflowRunID, listed.ID)] = listed.Name;
}
Console.WriteLine($"Run started: {created.Name}");
}
else if (streamEvent.Value is BetaManagedAgentsWorkflowRunPhaseStartedEvent phase)
{
var phaseId = phase.WorkflowRunPhaseID;
var key = (phase.WorkflowRunID, phaseId);
Console.WriteLine($" Phase: {phaseNames.GetValueOrDefault(key, phaseId)}");
}
else if (streamEvent.Value is BetaManagedAgentsWorkflowRunStatusEndedEvent ended)
{
var name = openRuns.GetValueOrDefault(ended.WorkflowRunID, ended.WorkflowRunID);
openRuns.Remove(ended.WorkflowRunID);
var outcome = ended.Result.Value switch
{
BetaManagedAgentsWorkflowRunResultCompleted => "completed",
BetaManagedAgentsWorkflowRunResultStopped => "stopped",
BetaManagedAgentsWorkflowRunResultError => "error",
_ => "ended",
};
Console.WriteLine($"Run ended: {name} ({outcome})");
}
else if (streamEvent.Value is BetaManagedAgentsAgentCustomToolUseEvent toolUse)
{
// 在事件到达时作出应答。运行的线程可能会等待您的
// 客户端,而会话保持运行状态。
var result = await CallTool(toolUse.Name, toolUse.Input);
try
{
await client.Beta.Sessions.Events.Send(sessionId, new()
{
Events =
[
new BetaManagedAgentsUserCustomToolResultEventParams
{
CustomToolUseID = toolUse.ID,
Content = [new BetaManagedAgentsTextBlock { Text = result }],
},
],
});
}
catch (AnthropicBadRequestException error)
{
// 如果结果来得太晚(在服务器归档该调用的线程之后),
// 服务器会拒绝该结果。继续跟踪该运行。
Console.WriteLine($" Answer to {toolUse.Name} refused: {error.Message}");
}
}
else if (streamEvent.Value is BetaManagedAgentsSessionStatusIdleEvent idle)
{
// 当所有运行都已结束且智能体已完成其轮次时即完成
var finished = idle.StopReason?.Value is BetaManagedAgentsSessionEndTurn;
if (openRuns.Count == 0 && finished)
{
break;
}
// 带有 requires_action 的 idle 状态在等待您的客户端,因此继续读取。
// 遇到任何其他停止原因时,将其打印出来并停止。
if (!finished && idle.StopReason?.Value is not BetaManagedAgentsSessionRequiresAction)
{
var reason = idle.StopReason?.Json.GetProperty("type").GetString();
Console.WriteLine($"Session idle: {reason}");
break;
}
}
else if (streamEvent.Value is BetaManagedAgentsSessionStatusTerminatedEvent)
{
break;
}
}
Go
openRuns := map[string]string{} // workflow_run_id -> run name
phaseNames := map[[2]string]string{} // {run ID, phase ID} -> phase name
// 先打开流,再发送用户消息
stream := client.Beta.Sessions.Events.StreamEvents(ctx, sessionID, anthropic.BetaSessionEventStreamParams{})
defer stream.Close()
if _, err := client.Beta.Sessions.Events.Send(ctx, sessionID, anthropic.BetaSessionEventSendParams{
Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
OfUserMessage: &anthropic.BetaManagedAgentsUserMessageEventParams{
Content: []anthropic.BetaManagedAgentsUserMessageEventParamsContentUnion{{
OfText: &anthropic.BetaManagedAgentsTextBlockParam{
Text: "Which contracts in /contracts have a change-of-control clause?",
},
}},
},
}},
}); err != nil {
panic(err)
}
events:
for stream.Next() {
switch event := stream.Current().AsAny().(type) {
case anthropic.BetaManagedAgentsWorkflowRunCreatedEvent:
openRuns[event.WorkflowRunID] = event.Name
for _, phase := range event.Phases {
phaseNames[[2]string{event.WorkflowRunID, phase.ID}] = phase.Name
}
fmt.Printf("Run started: %s\n", event.Name)
case anthropic.BetaManagedAgentsWorkflowRunPhaseStartedEvent:
phaseName, ok := phaseNames[[2]string{event.WorkflowRunID, event.WorkflowRunPhaseID}]
if !ok {
phaseName = event.WorkflowRunPhaseID
}
fmt.Printf(" Phase: %s\n", phaseName)
case anthropic.BetaManagedAgentsWorkflowRunStatusEndedEvent:
name, ok := openRuns[event.WorkflowRunID]
if !ok {
name = event.WorkflowRunID
}
delete(openRuns, event.WorkflowRunID)
fmt.Printf("Run ended: %s (%s)\n", name, event.Result.Type)
case anthropic.BetaManagedAgentsAgentCustomToolUseEvent:
// 事件到达时进行应答。运行的线程可能会等待您的
// 客户端,而会话保持运行状态。
result := callTool(event.Name, event.Input)
if _, err := client.Beta.Sessions.Events.Send(ctx, sessionID, anthropic.BetaSessionEventSendParams{
Events: []anthropic.BetaManagedAgentsEventParamsUnion{{
OfUserCustomToolResult: &anthropic.BetaManagedAgentsUserCustomToolResultEventParams{
CustomToolUseID: event.ID,
Content: []anthropic.BetaManagedAgentsUserCustomToolResultEventParamsContentUnion{{
OfText: &anthropic.BetaManagedAgentsTextBlockParam{
Text: result,
},
}},
},
}},
}); err != nil {
// 如果结果来得太晚(在服务器已归档该调用的线程之后),
// 服务器会拒绝该结果。请继续跟踪该运行。
var apiErr *anthropic.Error
if !errors.As(err, &apiErr) || apiErr.StatusCode != http.StatusBadRequest {
panic(err)
}
fmt.Printf(" Answer to %s refused: %v\n", event.Name, err)
}
case anthropic.BetaManagedAgentsSessionStatusIdleEvent:
// 当所有运行都已结束且智能体已完成其轮次时即完成
switch event.StopReason.AsAny().(type) {
case anthropic.BetaManagedAgentsSessionEndTurn:
if len(openRuns) == 0 {
break events
}
// 带有 requires_action 的 idle 表示正在等待您的客户端,因此请继续读取。
// 遇到任何其他停止原因时,打印该原因并停止。
case anthropic.BetaManagedAgentsSessionRequiresAction:
default:
fmt.Printf("Session idle: %s\n", event.StopReason.Type)
break events
}
case anthropic.BetaManagedAgentsSessionStatusTerminatedEvent:
break events
}
}
if err := stream.Err(); err != nil {
panic(err)
}
Java
var openRuns = new HashMap<String, String>(); // workflow_run_id -> run name
var phaseNames = new HashMap<String, String>(); // "run ID:phase ID" -> phase name
// 先打开流,再发送用户消息
try (var stream = client.beta().sessions().events().streamStreaming(sessionId)) {
client.beta().sessions().events().send(
sessionId,
EventSendParams.builder()
.addEvent(BetaManagedAgentsUserMessageEventParams.builder()
.addTextContent("Which contracts in /contracts have a change-of-control clause?")
.build())
.build()
);
Iterable<BetaManagedAgentsStreamSessionEvents> events = stream.stream()::iterator;
events:
for (var event : events) {
switch (event.type().value()) {
case WORKFLOW_RUN_CREATED -> {
var created = event.asWorkflowRunCreated();
openRuns.put(created.workflowRunId(), created.name());
created.phases().forEach(phase ->
phaseNames.put(created.workflowRunId() + ":" + phase.id(), phase.name()));
IO.println("Run started: " + created.name());
}
case WORKFLOW_RUN_PHASE_STARTED -> {
var started = event.asWorkflowRunPhaseStarted();
var phaseId = started.workflowRunPhaseId();
var key = started.workflowRunId() + ":" + phaseId;
IO.println(" Phase: " + phaseNames.getOrDefault(key, phaseId));
}
case WORKFLOW_RUN_STATUS_ENDED -> {
var ended = event.asWorkflowRunStatusEnded();
var name = openRuns.getOrDefault(ended.workflowRunId(), ended.workflowRunId());
openRuns.remove(ended.workflowRunId());
var result = ended.result();
var outcome = result.isCompleted() ? "completed"
: result.isStopped() ? "stopped"
: result.isError() ? "error"
: "ended";
IO.println("Run ended: " + name + " (" + outcome + ")");
}
case AGENT_CUSTOM_TOOL_USE -> {
// 事件到达时进行应答。运行的线程可能会等待您的
// 客户端,而会话保持运行状态。
var toolUse = event.asAgentCustomToolUse();
var result = callTool(toolUse.name(), toolUse.input());
try {
client.beta().sessions().events().send(
sessionId,
EventSendParams.builder()
.addEvent(BetaManagedAgentsUserCustomToolResultEventParams.builder()
.customToolUseId(toolUse.id())
.addTextContent(result)
.build())
.build());
} catch (BadRequestException e) {
// 如果结果来得太晚(在服务器归档该调用的线程之后),
// 服务器会拒绝该结果。请继续跟踪该运行。
IO.println(" Answer to " + toolUse.name() + " refused: " + e.getMessage());
}
}
case SESSION_STATUS_IDLE -> {
// 当所有运行都已结束且智能体已完成其轮次时即完成
var stopReason = event.asSessionStatusIdle().stopReason();
if (openRuns.isEmpty() && stopReason.isEndTurn()) {
break events;
}
// 带有 requires_action 的 idle 会等待您的客户端,因此请继续读取。
// 遇到任何其他停止原因时,打印该原因并停止。
if (!stopReason.isEndTurn() && !stopReason.isRequiresAction()) {
IO.println("Session idle: " + stopReason.type().asString());
break events;
}
}
case SESSION_STATUS_TERMINATED -> {
break events;
}
default -> {}
}
}
}
PHP
$openRuns = []; // workflow_run_id => run name
$phaseNames = []; // run ID => [phase ID => phase name]
// 先打开流,再发送用户消息
$stream = $client->beta->sessions->events->streamStream($sessionId);
$client->beta->sessions->events->send(
$sessionId,
events: [
[
'type' => 'user.message',
'content' => [
['type' => 'text', 'text' => 'Which contracts in /contracts have a change-of-control clause?'],
],
],
],
);
foreach ($stream as $event) {
switch (true) {
case $event instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsWorkflowRunCreatedEvent:
$openRuns[$event->workflowRunID] = $event->name;
foreach ($event->phases as $phase) {
$phaseNames[$event->workflowRunID][$phase->id] = $phase->name;
}
echo "Run started: {$event->name}", PHP_EOL;
break;
case $event instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsWorkflowRunPhaseStartedEvent:
$phaseId = $event->workflowRunPhaseID;
echo ' Phase: ', $phaseNames[$event->workflowRunID][$phaseId] ?? $phaseId, PHP_EOL;
break;
case $event instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsWorkflowRunStatusEndedEvent:
$name = $openRuns[$event->workflowRunID] ?? $event->workflowRunID;
unset($openRuns[$event->workflowRunID]);
echo "Run ended: {$name} ({$event->result->type})", PHP_EOL;
break;
case $event instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsAgentCustomToolUseEvent:
// 事件到达时进行应答。运行的线程可能会等待您的
// 客户端,而会话保持运行状态。
$result = callTool($event->name, $event->input);
try {
$client->beta->sessions->events->send(
$sessionId,
events: [
[
'type' => 'user.custom_tool_result',
'custom_tool_use_id' => $event->id,
'content' => [['type' => 'text', 'text' => $result]],
],
],
);
} catch (\Anthropic\Core\Exceptions\BadRequestException $error) {
// 如果结果来得太晚(在服务器已归档该调用的线程之后),
// 服务器会拒绝该结果。请继续跟踪该运行。
echo " Answer to {$event->name} refused: {$error->getMessage()}", PHP_EOL;
}
break;
case $event instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsSessionStatusIdleEvent:
// 当所有运行均已结束且智能体已完成其轮次时即完成
$finished = $event->stopReason->type === 'end_turn';
if (!$openRuns && $finished) {
break 2;
}
// 带有 requires_action 的 idle 表示正在等待您的客户端,因此请继续读取。
// 遇到任何其他停止原因时,打印该原因并停止。
if (!$finished && $event->stopReason->type !== 'requires_action') {
echo "Session idle: {$event->stopReason->type}", PHP_EOL;
break 2;
}
break;
case $event instanceof \Anthropic\Beta\Sessions\Events\ManagedAgentsSessionStatusTerminatedEvent:
break 2;
}
}
$stream->close();
Ruby
open_runs = {} # workflow_run_id => run name
phase_names = {} # [run ID, phase ID] => phase name
# 先打开流,再发送用户消息
stream = client.beta.sessions.events.stream_events(session_id)
client.beta.sessions.events.send_(
session_id,
events: [{
type: "user.message",
content: [{type: "text", text: "Which contracts in /contracts have a change-of-control clause?"}]
}]
)
stream.each do |event|
case event
when Anthropic::Beta::Sessions::BetaManagedAgentsWorkflowRunCreatedEvent
open_runs[event.workflow_run_id] = event.name
event.phases.each { |phase| phase_names[[event.workflow_run_id, phase.id]] = phase.name }
puts "Run started: #{event.name}"
when Anthropic::Beta::Sessions::BetaManagedAgentsWorkflowRunPhaseStartedEvent
phase_id = event.workflow_run_phase_id
puts " Phase: #{phase_names.fetch([event.workflow_run_id, phase_id], phase_id)}"
when Anthropic::Beta::Sessions::BetaManagedAgentsWorkflowRunStatusEndedEvent
name = open_runs.delete(event.workflow_run_id) || event.workflow_run_id
puts "Run ended: #{name} (#{event.result.type})"
when Anthropic::Beta::Sessions::BetaManagedAgentsAgentCustomToolUseEvent
# 事件到达时进行应答。运行的线程可能会等待您的
# 客户端,而会话保持运行状态。
result = call_tool.call(event.name, event.input)
begin
client.beta.sessions.events.send_(
session_id,
events: [{
type: "user.custom_tool_result",
custom_tool_use_id: event.id,
content: [{type: "text", text: result}]
}]
)
rescue Anthropic::Errors::BadRequestError => error
# 如果结果来得太晚(服务器已归档该调用的线程),
# 服务器会拒绝该结果。继续跟踪该运行。
puts " Answer to #{event.name} refused: #{error.message}"
end
when Anthropic::Beta::Sessions::BetaManagedAgentsSessionStatusIdleEvent
reason = event.stop_reason.type.to_sym
# 当所有运行都已结束且智能体已完成其轮次时即完成
break if open_runs.empty? && reason == :end_turn
# 带有 requires_action 的 idle 正在等待您的客户端,因此请继续读取。
# 遇到任何其他停止原因时,打印该原因并停止。
unless %i[end_turn requires_action].include?(reason)
puts "Session idle: #{reason}"
break
end
when Anthropic::Beta::Sessions::BetaManagedAgentsSessionStatusTerminatedEvent
break
end
end
在有打开的运行时中断会话
发送不带 session_thread_id (java: sessionThreadId; php: sessionThreadID; csharp, go: SessionThreadID) 或带有主线程 ID 的 user.interrupt。它会停止智能体的轮次。它不会结束任何运行。会话的运行可能会暂停或继续运行,而它们的事件可能不会显示是哪一种。已暂停运行的生命周期会继续流逝,因此运行可能在暂停期间以 timeout_error 结束。
- 等待中的工具调用: 中断后,运行线程的工具调用可能仍在等待您的客户端。请逐一回答。要取消要求确认的调用,请拒绝它。要取消自定义工具调用,请发送一个结果,将
is_error(java, php:isError; csharp, go:IsError) 设置为true,并在content(csharp, go:Content) 中提供说明原因的文本。当会话以requires_action处于idle状态时,user.message会返回 400,因此请先回答这些调用。 - 停止运行:发送一条
user.message,要求智能体停止其运行。已停止的运行以result{"type": "stopped"}结束。当会话以budget_reached处于idle状态时,在您提高或移除预算之前,user.message会返回 400。提高或移除预算还会恢复因预算而暂停的运行,除非这些运行也因该中断而暂停。 - 继续:发送一条
user.message,要求智能体继续其运行。中断后,运行可能会等待这条消息。如果会话以budget_reached处于idle状态,请先提高或移除预算。 - 运行结果:在中断后结束的运行仍会发送
workflow_run.status_ended。
运行处于打开状态时
| 请求 | 运行打开期间 | 如何处理 |
|---|---|---|
| 归档或删除会话 | 在运行打开期间,无论会话处于何种状态,都可能返回 400。错误的 error.details.error_code 可能为 "workflow_run_open"。也可能成功。 |
让智能体停止其运行,或等待每个运行结束。已暂停的运行只有在其生命周期到期时才会自行结束。然后在会话处于 idle 状态时发送请求。成功的归档会以 {"type": "stopped"} 结束每个打开的运行。归档后,运行的 workflow_run.status_ended 以及仍处于打开状态的阶段的 workflow_run.phase_ended 不会到达流上。请列出会话的事件来读取它们。成功删除后,不会有 workflow_run 事件报告会话运行的结束。 |
| 归档运行的某个线程 | 在运行打开期间(无论运行中还是空闲),返回 400 并带有 error.details.error_code: "workflow_run_open",除非服务器已经归档了该线程。 |
无需操作。服务器会归档运行的线程。 |
更新会话的 agent (csharp, go: Agent) |
在有任何运行处于打开状态时(即使是已暂停的运行)返回 400,带有 error.details.error_code: "workflow_run_open"。更新底层智能体仍会被接受,会话会保留自己的副本。同时发送其他字段(例如 budget (csharp, go: Budget))的请求会被整体拒绝。 |
等待每个运行都有其 workflow_run.status_ended,或让智能体停止其运行。 |
| 回答来自运行线程的工具调用或工具确认 | 允许。它会到达主事件流,其 session_thread_id (java: sessionThreadId; php: sessionThreadID; csharp, go: SessionThreadID) 指明了线程。 |
在事件到达后立即回答,将事件的 id (csharp, go: ID) 作为 tool_use_id (java: toolUseId; php: toolUseID; csharp, go: ToolUseID) 或 custom_tool_use_id (java: customToolUseId; php: customToolUseID; csharp, go: CustomToolUseID) 传递。不要等待 session.status_idle:在运行的其他线程工作时,会话可能保持 running。一旦服务器归档了该线程,针对其某个调用的工具结果将不起作用,并且可能返回 400。当工具结果返回 400 时,请在线程列表中找到该调用的线程。如果其状态为 terminated,说明结果来得太晚,请将其丢弃。请在单独的请求中发送每个工具结果,因为当服务器拒绝请求中的某个事件时,会拒绝整个请求。来得太晚的工具确认会返回 200,这并不意味着工具已运行。 |
重新连接后重建运行状态
根据会话的事件重建每个运行的状态。流不会重放您错过的内容:新连接只会传递在其打开之后发出的事件。因此,请使用 types (curl: types[]; cli: --type; csharp, go: Types) 过滤器列出事件,每种事件类型一个条目,如列出过去的事件中所述。将每个响应的 next_page (ruby: next_page_; java, php: nextPage; csharp, go: NextPage) 作为 page (cli: --page; csharp, go: Page) 传递,直到 next_page (ruby: next_page_; java, php: nextPage; csharp, go: NextPage) 为 null (python: None; ruby: nil; java: Optional.empty(); go: "") 或缺失为止。workflow_run.created、workflow_run.status_running、workflow_run.status_idle 和 workflow_run.status_ended 给出每个运行的状态,但在中断后暂停的运行可能仍显示为正在运行。workflow_run.phase_started 和 workflow_run.phase_ended 用于重建进度。尚无状态事件的运行尚未开始运行。没有用于列出运行的端点。
成本和预算
运行的模型请求计入会话的预算。运行本身没有单独的价格。其智能体使用的令牌与会话的其他令牌一样,按各模型的费率计费。关于会话的所有费用,请参阅 Claude Managed Agents 定价。
- 单个运行的用量: 列出会话的线程,并将具有该运行
workflow_run_id(java:workflowRunId; php:workflowRunID; csharp, go:WorkflowRunID) 的线程的usage(csharp, go:Usage) 中的令牌数相加。该列表包括已归档的线程(其状态为terminated),因此已完成运行的线程也会被计入。将每个响应的next_page(ruby:next_page_; java, php:nextPage; csharp, go:NextPage) 作为page(cli:--page; csharp, go:Page) 传入,直到next_page(ruby:next_page_; java, php:nextPage; csharp, go:NextPage) 为null(python:None; ruby:nil; java:Optional.empty(); go:"") 或缺失,并跳过没有usage(csharp, go:Usage) 的线程。如果您改为将线程的list_cost(java, php:listCost; csharp, go:ListCost) 相加,则总额不包括会话运行时间,并且每个数值都是单独舍入的。 - 达到预算时: 每个未结束的运行都会暂停,会话报告
idle并附带budget_reached;如果还有工具调用在等待,则报告requires_action。每个线程会完成其已开始的模型请求,因此每个正在工作的线程都可能使运行超出预算一个请求。提高或移除预算会恢复因预算而暂停的运行,除非这些运行也因中断而暂停。如果会话的用量包含没有标价的模型,则只有移除预算才会恢复运行;请参阅没有标价的模型。暂停运行的生命周期会继续计时,因此运行可能在暂停期间以timeout_error结束。
限制
| 限制 | 值 | 达到限制时 |
|---|---|---|
| 单个运行中同时工作的线程数 | 64 | 在有线程完成之前,运行不会再创建新线程。API 不保证此数值。 |
| 工作流在运行整个生命周期内启动的智能体数 | 1,000 | 当工作流请求更多时,服务器不会再启动智能体,运行以 thread_limit_error 结束。服务器可能会在新线程上重新运行失败的智能体,因此一个运行可能拥有超过 1,000 个线程。 |
| 运行生命周期 | 默认为 24 小时,或智能体设置的生命周期 | 运行以 timeout_error 结束。没有事件说明智能体设置了什么生命周期。 |
| 一个会话中同时打开的运行数 | 默认为 10 | 服务器拒绝启动另一个运行。智能体的工具调用会收到错误,您会收到一个 error.type 为 max_workflow_runs_error 的 workflow_run.error。空闲的运行也计入此限制。 |
服务器会将运行或阶段的 name (csharp, go: Name) 截短为 64 个字符,将其 description (csharp, go: Description) 截短为 256 个字符。服务器对工作流还有此处未列出的其他限制和规则。您看到的结果取决于服务器何时发现问题:
| 发生的情况 | 您看到的内容 |
|---|---|
| 智能体启动运行时,工作流超出了其他某项限制 | 启动被拒绝。您会收到一个 workflow_run.error,并且没有运行。 |
| 运行在之后超出了其他某项限制 | 您会收到一个 workflow_run.error,然后运行可能以 unknown_error 结束。 |
| 服务器在启动后发现工作流违反了工作流的某条规则(限制除外) | 您会收到一个 workflow_run.error,然后运行可能以 program_error 结束。 |
一个会话在其生命周期内可以启动任意数量的运行。
- 启动运行: 只有会话主线程上的智能体才能启动运行。在运行的线程中工作的智能体无法启动自己的运行,因此运行不会嵌套。
- 结束运行: 您发送的任何事件都不会结束运行;归档会话可以结束运行。
- 运行的线程: 您无法通过 ID 停止运行的线程,也无法在其运行打开时将其归档。
- 线程限制: 运行的线程不受会话的子线程限制约束。
- 可见性: 您看不到工作流的代码,但可以向智能体索要工作流,如运行的线程中的提示所述。您也看不到智能体为启动和管理运行而进行的工具调用,以及每个线程返回给工作流的结果。
速率限制
运行的工作计入您的组织已有的速率限制。
| 内容 | 计入 | 如何处理 |
|---|---|---|
| 您的客户端检索或列出会话、其线程及其事件的请求 | Managed Agents 端点的读取限制 | 在会话的事件流上跟踪运行,而不是轮询。 |
| 来自运行线程的模型请求 | 您针对每个线程所用模型的 Messages API 速率限制,与您的其他流量一起计算 | 在这些限制中为运行预留空间,或申请更高的限制。 |
当来自运行某个线程的模型请求受到速率限制,或模型过载时,该线程自己的流可能会收到类型为 model_rate_limited_error 或 model_overloaded_error 的 session.error:
- 如果其
retry_status.type为retrying,则服务器正在重试该请求,线程仍在工作。 - 如果为
exhausted,则线程已失败。如果工作流让该失败结束运行,运行将以program_error结束,而它不会指明原因。请读取失败线程的事件来查找原因。
服务器还会限制您组织的所有会话每分钟的工作量。达到此限制的线程会停止,并在其自己的流上收到一个消息中指明速率限制的 session.error。请等待一分钟,然后再让智能体继续。
可用性
动态工作流在所有模型上可用。
API 支持
Managed Agents
- 可用性:可用
| 状态 | 云平台 |
|---|---|
| 可用 | 所有支持的平台 |
所需的 beta 请求头
Beta 请求头让您可以在实验性功能和新模型能力成为标准 API 的一部分之前访问它们。
managed-agents-2026-04-01
数据处理
| 项目 | 零数据保留 | HIPAA |
|---|---|---|
| 状态 | 不具备资格 | 不具备资格 |
| 详细信息 | 会话是有状态的资源;对话记录会一直保留,直到您将其删除。适用于所有 Managed Agents 子功能,包括自托管沙箱。 | 适用于所有 Managed Agents 子功能,包括自托管沙箱。 |
适用的端点:
/v1/agents/v1/sessions/v1/environments