跳到导航

结构化流程

智能体每次都会以相同方式执行的固定类型化步骤序列

概览

结构化流程是一种按固定顺序执行步骤的流程。自由格式流程是由智能体根据实际情况理解和调整的自然语言指导。结构化流程则是有序的类型化步骤列表,只要该流程适用,智能体每次都会按顺序执行。

当每通电话都必须以相同方式完成特定步骤时,请使用结构化流程:例如验证来电者身份、升级工单或收款。你只需编写一份简短的自然语言步骤列表。

与所有流程一样,结构化流程也有一个用于说明适用时机的触发条件。当对话匹配触发条件时,智能体会按顺序执行流程步骤,然后返回其余对话。

结构化流程
编辑器

何时使用结构化流程

当特定步骤每次都必须以相同方式执行,但你仍希望通过简单步骤快速编写时,请使用结构化流程。结构化流程比 workflow 更容易编写,但表达能力较弱。如需了解它与自由格式流程、workflow 和系统提示词的区别,请参阅何时使用流程。

结构化流程的组成

结构化流程由三部分组成:名称、触发条件和有序步骤列表。

名称

用于在控制台中识别流程的简短标签。名称绝不会发送给 LLM,因此不会影响智能体行为。

触发条件

说明智能体何时应执行此流程的自然语言描述,例如 当用户要求退款订单时。智能体会将用户意图与每个流程的触发条件进行比较,并执行匹配的流程,因此触发条件应具体且彼此有明显区别。智能体只能看到触发条件文本,绝不会看到流程名称或 ID。触发条件的工作方式与其他流程相同;请参阅编写触发条件。

将触发条件留空,可使该流程成为仅在其他流程调用时才执行的子流程。

步骤

流程主体是一个有序的类型化步骤列表。可用的步骤类型有多种,你可以组合它们来描述任务。

步骤功能
询问向用户询问信息并等待回复。会持续询问,直到用户作答。这是唯一会暂停以等待用户的步骤。
告知让智能体用自己的话传达信息,然后进入下一步。
朗读让智能体逐字朗读准确消息,然后进入下一步。朗读步骤可为智能体支持的每种语言分别配置不同的翻译。
工具调用指定工具。你可以使用自然语言指示 LLM 如何调用工具,也可以在需要最高确定性时明确固定参数值。还可定义工具调用失败时执行的步骤。
如果按顺序评估一个或多个条件,并执行第一个匹配项的步骤。可选的 Else 会在没有任何条件匹配时执行。
子流程执行另一个结构化流程。其步骤完成后,控制权会返回到当前(调用方)流程的下一步。
系统工具执行内置系统操作。目前仅支持结束通话。
重试重新执行工具步骤的失败处理程序,包括工具调用在内,最多重试 3 次。仅可在工具步骤的失败处理程序中使用。

结构化流程步骤类型
菜单

并非所有步骤都能出现在任何位置。在 If 分支内,除另一个 If 或 Retry 外,你可以使用任何步骤。在工具步骤的失败处理程序内,除 If 或另一个工具外,你可以使用任何步骤。

API 步骤参考

结构化流程的 content 是包含 steps 数组的 JSON 编码文档。每个步骤都是通过其 type 标识的对象。触发条件是流程中独立的顶级字段,不属于 content。API 和 SDK 载荷中,流程本身使用 type: "deterministic"。

询问

询问步骤指示智能体请求信息,并等待用户提供合适的回复。

  • API 类型:ask
  • instruction:必填,非空字符串。
{
"type": "ask",
"instruction": "Ask the user for their order ID."
}

告知

告知步骤指示智能体用自己的话生成一条消息。继续执行前不会等待用户回复。

  • API 类型:tell
  • instruction:必填,非空字符串。
{
"type": "tell",
"instruction": "Explain that the refund normally takes five to ten business days."
}

朗读

朗读步骤会完全按照提供的文本朗读,然后继续执行。通过 message_translations 为智能体支持的每种其他语言提供准确消息,并以语言代码作为键。

  • API 类型:say
  • message:必填,非空字符串。
  • message_translations:可选对象,将语言代码映射到 { "value": "..." }。
{
"type": "say",
"message": "Your refund has been submitted.",
"message_translations": {
"es": { "value": "Su reembolso ha sido enviado." }
}
}

If、else if 和 else

If 步骤包含一个或多个有序条件分支。第一个匹配的分支会执行。可选的 fallback 数组即 Else 分支。

  • API 类型:branch
  • branches:必填,非空条件分支列表。
  • fallback:可选的 Else 步骤列表。
  • 每个分支都需要 condition 和非空 steps 列表。
{
"type": "branch",
"branches": [
{
"condition": {
"type": "llm",
"condition": "The user is on an annual plan."
},
"steps": [
{
"type": "say",
"message": "Your annual plan is eligible for a prorated refund."
}
]
}
],
"fallback": [
{
"type": "tell",
"instruction": "Explain that the account's plan could not be determined."
}
]
}

其行为类似于 if/else-if/else:

  1. 按顺序评估条件。
  2. 执行第一个匹配的分支。
  3. 如果没有条件匹配,则执行 fallback。
  4. 分支完成后,流程会重新回到主序列。

上述示例使用文本条件,由模型通过自然语言评估。条件也可以是针对动态变量的表达式:

{
"type": "expression",
"expression": {
"type": "eq_operator",
"left": {
"type": "dynamic_variable",
"name": "plan_tier"
},
"right": {
"type": "string_literal",
"value": "annual"
}
}
}

表达式条件用于测试动态变量,这些变量由工具结果填充,或在对话开始时设置。它无法读取用户最近一次回复。如需根据用户所说的内容进行分支,请使用文本条件。

同一 If 步骤中的所有分支必须使用相同条件类型:llm 或 expression。

工具

工具步骤调用指定工具。

  • API 类型:tool_call
  • tool_id:必填,非空工具 ID。该工具必须已附加到智能体。
  • tool_name:必填工具名称,必须与工具匹配。
  • instruction:可选,用于描述如何调用工具的指令。
  • schema_overrides:可选,用于固定工具参数的值。
  • on_failure:可选,失败处理程序。
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "lookup_order",
"instruction": "Look up the order using the order ID provided by the user."
}

固定参数值

当参数必须始终使用特定值时,请使用 schema_overrides。模型不会看到或选择被覆盖的参数。键为工具 schema 中的参数路径;每个值都指定一个来源:

source字段行为
constantconstant_value始终发送给定值。
dynamic_variabledynamic_variable发送指定动态变量的当前值。
llmprompt(可选)让模型选择值,并可选择覆盖提示词。
omit在调用中省略该参数。
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "update_ticket",
"schema_overrides": {
"request_body.status": { "source": "constant", "constant_value": "pending" },
"request_body.ticket_id": { "source": "dynamic_variable", "dynamic_variable": "ticket_id" }
}
}

失败处理

未设置 on_failure 时,工具调用失败会结束对话。请添加 on_failure,以改为执行恢复步骤。

  • fallback:必填,工具失败时执行的非空步骤列表。
  • branches:预留用于条件化失败处理。请将其留空。
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "lookup_order",
"on_failure": {
"branches": [],
"fallback": [
{
"type": "tell",
"instruction": "Explain that the order could not be retrieved and offer to connect the user with support."
}
]
}
}

失败处理程序可包含询问、告知、朗读、子流程、系统工具和重试步骤。不能包含工具或 If 步骤。处理程序执行后,流程会继续执行工具步骤后的步骤。

重试

重试步骤会重新执行包含它的失败处理程序,包括工具调用。每次尝试都会再次调用工具;如果再次失败,则再次执行处理程序中的每个步骤。尝试次数用尽后,对话将结束。

  • API 类型:retry
  • max_retries:可选整数,范围为 1 至 3。默认为 1。
  • 此值统计原始工具调用之后的尝试次数。
  • 重试仅在 on_failure 内有效。
  • 重试必须是失败处理程序的最后一步,因为后续步骤将无法执行。
{
"type": "retry",
"max_retries": 2
}

子流程

子流程步骤执行另一个结构化流程。该流程步骤完成后,执行将返回子流程步骤后的步骤。

  • API 类型:sub_procedure
  • procedure_id:必填,非空流程 ID。
  • 目标流程必须存在于同一智能体上。
  • 目标必须是结构化流程。
  • 流程不能调用自身。
{
"type": "sub_procedure",
"procedure_id": "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3"
}

系统工具

系统工具步骤执行内置系统操作。

  • API 类型:system_tool
  • system_tool_name:必填系统工具名称。
  • 目前仅支持 end_call。后续可能会添加更多系统工具。
  • 由于 end_call 是终止操作,它必须是所在序列、分支或失败处理程序的最后一步。
{
"type": "system_tool",
"system_tool_name": "end_call"
}

验证规则

发布智能体或保存智能体草稿时,如果结构化流程违反以下任一规则,操作将被拒绝。错误信息会通过路径标明违规步骤。

  • 两个 If 步骤不能连续放置。
  • If 步骤不能嵌套。
  • 使用表达式条件的 If 步骤不能直接位于询问步骤之后。
  • 同一 If 步骤中的所有条件必须属于同一类型,即 llm 或 expression。
  • Retry 只能出现在 on_failure 内,且必须是其中的最后一步。
  • end_call 必须是其所在列表中的最后一步。
  • 失败处理程序的 fallback 至少必须包含一个步骤。
  • 子流程必须指向同一智能体上现有的结构化流程,且不能指向自身。
  • tool_id 必须是智能体上的工具,tool_name 必须匹配,且 schema_overrides 必须符合工具的 schema。
  • steps 列表、每个 instruction 以及每个 message 都不得为空。

如需了解如何重构违反这些规则的流程,请参阅最佳实践。

完整 API 示例

此示例根据配送状态处理订单取消。它固定一个工具参数、从失败的工具调用中恢复、调用另一个结构化流程,然后结束通话。

{
"steps": [
{
"type": "ask",
"instruction": "Ask the user for their order ID."
},
{
"type": "branch",
"branches": [
{
"condition": {
"type": "llm",
"condition": "The user says the order has already shipped."
},
"steps": [
{
"type": "tell",
"instruction": "Explain that shipped orders must be returned before they can be refunded."
}
]
},
{
"condition": {
"type": "llm",
"condition": "The user says the order has not shipped."
},
"steps": [
{
"type": "tool_call",
"tool_id": "tool_abc123",
"tool_name": "cancel_order",
"instruction": "Cancel the order using the order ID provided by the user.",
"schema_overrides": {
"request_body.notify_customer": { "source": "constant", "constant_value": true }
},
"on_failure": {
"branches": [],
"fallback": [
{
"type": "tell",
"instruction": "Apologize that the cancellation did not go through and say you will try once more."
},
{
"type": "retry",
"max_retries": 1
}
]
}
}
]
}
],
"fallback": [
{
"type": "ask",
"instruction": "Ask whether the order has already shipped."
}
]
},
{
"type": "sub_procedure",
"procedure_id": "agtprc_6qbpwdq8n01bxhk44bgjy6f10ck3"
},
{
"type": "say",
"message": "Thank you for contacting us. Goodbye.",
"message_translations": {
"es": { "value": "Gracias por contactarnos. Adiós." }
}
},
{
"type": "system_tool",
"system_tool_name": "end_call"
}
]
}

结构化流程的运行方式

将结构化流程步骤转换为智能体可执行的形式称为编译。保存智能体草稿或发布智能体时,平台会编译每个结构化流程;编写者无需自行编译任何内容。

当用户请求匹配某个流程的触发条件时,平台会进入该流程并按顺序执行步骤。在结构化流程中,智能体会专注于逐一执行每个步骤。到达末尾后,平台会将控制权返回给其余对话。

workflow 边无法连接到结构化流程,也无法从中连接出去。请使用子流程步骤来串联结构化流程。平台会管理匹配触发条件时的进入和完成过程,包括将控制权返回到流程开始的 workflow 节点。

以下规则说明步骤在运行时的行为。

除询问外的每个步骤都会立即执行,控制权会在同一轮次内转到下一步。告知或朗读步骤会传递消息后继续执行。除询问外, 没有其他步骤会暂停对话,也没有步骤会结束当前轮次。如果需要用户输入,请使用询问步骤。如果应结束对话, 请使用 end_call 系统工具。

最后一步完成后,流程结束,智能体会在该轮次仍保持开启的情况下返回其余对话,因此可能继续说话。子流程完成时, 控制权会返回调用它的流程中的下一步。

工具步骤无法根据状态码或响应正文进行分支。如果工具成功,流程会继续。如果失败且该步骤没有失败处理程序,对话将结束。如果 有失败处理程序,则执行处理程序步骤,流程再继续下一步。处理程序中的重试会再次运行工具;若再次失败,则再次执行 处理程序中的每个步骤,直至工具成功或尝试次数用尽。若次数用尽,对话将结束。

条件按顺序评估,第一个匹配项会执行。没有任何匹配时会执行 Else 分支。如果没有 Else 且没有任何匹配,流程会继续执行 If 之后的步骤。未处理的情况并非错误。

If 分支中做出的任何决定都不会被后续步骤记住。如果分支中获知的信息需要在之后使用, 请通过工具调用或动态变量明确持久化。

只有工具步骤可以调用工具。无需告知询问、告知或朗读步骤不要调用 工具;它们无法调用。

管理结构化流程

在控制台中打开智能体,然后选择 流程。 使用 + 创建结构化流程。添加触发条件,为每个步骤选择类型,然后 发布智能体更改。

控制台会在编辑时验证结构化流程。如果流程违反 验证规则,发布按钮会显示错误状态, 流程标签页会显示错误徽章,且在修复流程前无法启动预览。 选择错误指示器,可查看受影响的流程和步骤。

结构化流程编辑器:发布按钮处于错误状态,并显示 1 个错误
徽章

验证详情对话框,列出失败流程以及需要填写
消息的步骤

最佳实践

每种步骤类型都会自行约束其行为,因此通常无需额外说明。写清每个步骤的意图,剩下的交给步骤类型处理。以下指南涵盖了值得注意的情况。

如需测试结构化流程,请参阅 迭代流程。

选择步骤类型

Ask 步骤会等待一个回答。若在一条指令中包含多个问题,智能体往往会跳过部分问题或将它们合并。每条信息使用一个 Ask 步骤。

Tell 步骤会传达消息后继续执行,不会等待回复。以问题形式表述的 Tell 不会得到回答。如果步骤需要用户回复,就应使用 Ask。

Ask 步骤在获得合适的回答后会继续执行。如果仅凭问题无法明确什么算作回答,请在指令中说明,例如 询问订单 ID;有效 ID 为 8 位数字。

当智能体应自行组织消息时使用 Tell 步骤;当措辞必须逐字一致或需要翻译时使用 Say 步骤。两者都只会发送一条消息,因此无需指示步骤发送单条消息。

Ask、Tell 和 Say 步骤无法调用工具。在其中写入 不要调用任何工具 不会改变行为,只会增加指令噪音。

组织流程

两个 If 步骤不能连续放置。为了满足此规则而在中间插入无关的 Tell 或 Say,会让智能体说出不该说的话。请将第二个判断作为额外的 Else if 分支合并到第一个 If 中,或将其移至子流程。

If 步骤不能嵌套。当一个判断依赖于另一个判断时,请将内部判断放在独立的结构化流程中,并从需要它的分支通过 Sub-procedure 步骤调用。

没有 Else 的 If 步骤在没有任何条件匹配时,会继续执行下一步。如果未匹配的情况应有不同处理方式,请为其添加 Else 分支。

在 If 分支内作出的判断之后不会被记住。如果后续步骤依赖于分支中获取的信息,请在该分支内通过工具调用或动态变量记录它。

表达式条件会测试动态变量。使用这些变量的 If 步骤应紧接在设置这些变量的 Tool 步骤之后。如需根据用户所说内容进行分支,请使用文本条件。

当多个结构化流程共用相同序列(例如转接人工客服)时,请将其放入一个触发条件为空的结构化流程中,并从各个流程调用。复制的序列会随着时间推移而产生差异。

使用工具

Tool 步骤始终会调用其工具。写入指令的条件,例如 如果工单已添加标签则跳过此步骤,无法阻止调用。如果并非每次都应调用,请在 Tool 步骤之前添加 If 步骤来设置条件。

当参数必须始终采用特定值时,请在 schema_overrides 中使用 constant 覆盖进行设置。像 始终将 status 设为 pending 这样的指令只是要求模型遵守;覆盖设置会被强制执行,无法跳过。

如果没有 on_failure,任何工具失败都会结束对话。请添加处理程序,告知用户发生了什么,并重试、升级处理或继续执行。

Tool 步骤只会运行工具;智能体无法在此期间说话或作出决定。如需与用户交流,或根据工具返回结果进行分支,请在 Tool 步骤前后另设单独步骤。

编写指令

流程控制接下来运行的内容,智能体在执行当前步骤时并不知道后续步骤。让步骤顺序处理流程衔接。

写入步骤指令的句子,例如 这是本轮的最后一条消息,是在要求智能体强制执行平台并不支持的边界。请使用 Ask 步骤等待用户,或使用 end_call 系统工具结束对话。

语气、格式、结束语和拒绝策略应放在系统提示词中。步骤指令只应说明该步骤特有的内容。

组合流程

组合流程的通用指南同样适用于结构化流程;请参阅自由形式流程页面中的组合流程。

混合类型时有一种特定模式:自由形式流程可以引用结构化流程。将开放式处理保留在自由形式流程中,并将每次都必须以相同方式执行的部分(如身份验证或升级处理)交由结构化流程。

限制

  • If 步骤不能嵌套,两个 If 步骤也不能连续放置。
  • 唯一支持的系统工具是 end_call。
  • 结构化流程无法引用知识库文档。
  • 流程完成时无法结束当前轮次;智能体会保持当前轮次打开,并可能继续说话。
  • workflow 边无法连接到结构化流程,也无法从结构化流程连接出去。请使用 Sub-procedure 步骤串联结构化流程;进入和完成由平台管理。
  • 启动流程会增加延迟:智能体会通过工具调用进入流程,然后执行生成的工作流。

模型提供商支持

进入子流程和完成流程时,结构化流程会强制进行内部工具调用。主要的 OpenAI、Anthropic、Gemini 和 Grok 模型系列支持强制工具选择。其他模型或自定义提供商可能无法保证此功能,这会降低子流程切换或流程完成的可靠性。使用其他模型提供商时,请确认其支持强制工具选择。

请参阅流程,了解适用于所有流程的限制,包括内容大小上限,以及结构化流程与自由形式流程的差异。