Workflows
Workflow 是您的智能体应一步步做什么的可视化地图 — 谁先说话、要问什么、何时分支、何时转接通话、以及何时将其交给另一个智能体。您通过在画布上放置节点并连接它们来构建它。
当单个 prompt 不够时使用 workflow — 当通话有明确的阶段时(「先资格筛选,再收集细节,然后预约或转接」),当您需要基于呼叫者回答的确定性路由时(而不是「AI 通常能搞定」),或者当一个智能体应该把一部分工作交给专家时。
Prompt 是一条长指令。智能体读一次并在整个通话中使用它。 Workflow 是许多小指令,每个节点一条,节点之间有明确的转换。图驱动通话 — 每个节点的智能体只拥有自己的那一段。
如果您的智能体使用单个 prompt 已经运作良好,您不需要 workflow。当您开始在 prompt 中堆叠「如果 X 则 Y」规则,并且它们变得不可靠时,再转向 workflows。
编辑器
Workflow 编辑器位于智能体页面的独立标签中。您看到一个默认带有 Start 节点和 End 节点的画布。您从工具栏添加节点,拖到画布上,并用边连接。
右侧面板根据您选择的内容而变化:
- 点击节点 — 打开其设置面板(prompt、字段、提取变量等)。
- 点击边 — 打开其触发器的设置(AI decides / Condition / Always)。
- Variables 面板(工具栏按钮)列出每个 workflow 变量,一键跳转到设置或读取它的节点。
直接从编辑器运行浏览器 Test Call — 一个发光的萤火虫实时跟随位置,让您看到任何时刻具体哪个节点处于活动状态。
Workflows 有三种状态:
- Draft — 可编辑,尚未上线。使用 Test Call 进行测试。
- Active — 为真实通话上线。智能体从下次通话开始使用此 workflow。
- Template — 可复用模板,从不直接绑定到某个智能体。您可以在多个智能体上实例化它。
节点
每个节点是对话中的一步。不同类型的节点做不同的事 — 有些说话,有些倾听,有些路由,有些执行工具。
Agent
Agent 节点是 workflow 阶段的核心。当图到达 Agent 节点时,该智能体接管发言并主导对话,直到某事触发转换。
您直接在画布上配置 Agent 节点的人格与任务(点击节点时打开 Prompt 标签) — 这是对话那部分的 prompt,不是整个通话的。您也可以按节点附加知识库和工具。
Greeting — 开场白。如果这是入口节点(Start 之后的第一站),这就是呼叫者听到的第一句话。
当图主管通话时,智能体的主 prompt(Model 标签中的那个)被活动节点的 prompt 替换。这是故意的 — 图按阶段拥有人格和任务,而不是一个固定 prompt 与之竞争。
Subagent
Subagent 是一个内联运行的助手 — 它接管对话执行特定任务,然后把结果返回给调用者。
当一段工作可复用或感觉独立时,subagents 很合适:「验证呼叫者身份」、「收集送货地址」、「用 SPIN 方法筛选潜在客户」。父智能体调用 subagent,subagent 做自己的事并报告结果,父智能体从离开的地方继续。
Subagent 节点与 Agent 节点拥有相同的标签(Prompt、Knowledge、Tools、Actions) — 编辑器自动为您创建一个隐藏的支持智能体。您在主列表中看不到这个隐藏的智能体,它也不计入您套餐的智能体限额。
Return variable — 存储 subagent 结果的字段(例如 identity_verified、lead_score)。
Message (Say)
Say 节点说一句固定的话 — 没有 AI 轮次,没有即兴。用它做转场(「请稍候,我为您转接…」)、强制性法律声明,或措辞重要的预定义确认。
Text — 说什么。支持 {{variable}} token 注入已捕获的值,例如 "谢谢 {{first_name}},我已为您预约 {{appointment_time}}。"
Say 节点消耗回合 — 智能体不会在上面追加任何内容。
Gather Input
Gather Input 节点问一个问题并把呼叫者的回答捕获到变量中。
Prompt — 要问的问题。支持 {{tokens}}。
Variable — 存储答案的字段名。
每当您需要在继续之前获得具体值时使用它 — 邮箱、账号、人数、问题类别。呼叫者的下一个回合成为值;您可以紧接着用 Condition 边在其上分支。
Update State
Update State 节点将一个或多个值写入 workflow 变量,无需说话或询问。用它预设默认值、标记进度标志或从前面步骤组合值。
Variable / Value — 一对键值。 More variables (optional) — 额外的键值对。
键和值都支持 {{tokens}},所以您可以从现有值组合新值。
Condition
Condition 节点是一个纯路由节点 — 不说话,不询问,只把通话沿匹配的出边发送。
条件本身存在于每条出边上,而不是节点上 — 见下方 Condition 边的说明。
当您想在图中有一个明确的「fan-out」点时使用 Condition 节点:依赖于某个变量值的多个分支。与把条件放在 Agent 节点的边上相比,专门的 Condition 节点使路由逻辑在视觉上一目了然。
Tool
Tool 节点作为图步骤执行智能体已连接的工具之一 — AI 在调用上没有发言权。当您想要一个事实而不是对话时使用它:「找到这个客户」、「检查库存」、「GET 当前天气」。
您可以:
- 从智能体的现有工具中选一个(日历查询、知识库搜索、集成的特定操作),或
- 在节点中直接配置内联 HTTP 调用(URL、方法、头、参数、body)。
工具响应对所有下游节点可用。如果响应是 JSON 对象,每个顶级字段都成为自己的变量 — 像 {"is_known": true, "tier": "gold"} 这样的响应同时写入 is_known 和 tier,以便您在它们上分支。
Tool 节点中的每个文本字段 — URL、头值、body — 都支持 {{tokens}}。把变量塞进 URL 路径、头或 body,无需写代码。
如果工具调用失败(HTTP 错误、超时、网络),节点记录失败,图继续 — 没有数据。规划您的下游条件以处理「无值」情况。
Integration
Integration 节点是 Tool 针对已连接外部服务的聚焦变体 — Google Calendar、Outlook、HubSpot。您选择提供商和特定操作(例如 check_availability、create_event),传入参数,节点确定性地调用集成。
如果集成在此智能体未连接,节点无操作通过 — 您的图继续。检查下游条件以处理「未运行」情况。
Phone Transfer
Phone Transfer 节点将通话(warm transfer)转接到外部电话号码。成功转接后,通话已离开您的 workflow — 您的智能体不再在线。
Number — 国际格式的目的地,以 + 开头(例如 +15551234567)。支持 {{tokens}},所以目的地可以来自前面的步骤(例如「请问您要转接哪个办公室?」的答案)。
如果转接未能接通(无效号码、无人接听、电话连接未配置),图回退,当前智能体保持在线。对话正常继续 — 智能体可以致歉并尝试其他路径。
End Call
End Call 节点关闭通话 — 智能体说出配置好的结束语然后挂断。用作「全部完成」分支或难处理 Condition 的「无法帮助,抱歉」分支的干净终点。
除一条入边外,不需要配置。
复用 workflow (Sub-workflow)
Sub-workflow 节点保留用于将另一个 workflow 嵌入为子图。此节点在编辑器中,但尚未完全连接 — 图会原样通过,不执行任何操作。不要在生产通话中依赖它。当我们发布可复用子图时会启用它。
边(连接)
您通过一条边将一个节点连接到下一个。边的触发器决定转换何时触发。
有三种触发器:
| 触发器 | 谁决定 | 何时触发 |
|---|---|---|
| AI decides | AI | 当对话使其成为自然的下一步时。AI 收到一个可以调用的「转换工具」。 |
| Condition | 运行时 | 当某变量匹配您写的规则时。在 AI 响应之前评估。 |
| Always | 运行时 | 无条件 — 源节点结束就触发。无呼叫者输入,无 AI。 |
AI decides(基于意图)
当只有 AI 才能决定何时切换时使用 AI decides — 「如果呼叫者询问价格,转接给销售智能体」、「如果听起来像投诉,运行道歉 subagent」。
您在边上写一段简短的意图描述(例如 「呼叫者询问价格或想要升级」)。AI 将其视为一个用该意图标记的工具,并根据对话决定是否调用。如果存在多条 AI-decides 边,AI 每轮最多选择一条。
Condition(确定性分支)
当您想让图 — 而不是 AI — 根据已知事实决定时使用 Condition:「如果 lead_score > 7,发送给 closer;否则礼貌结束」。
Conditions 在 AI 响应之前评估,所以在那一回合它们总是赢过 AI。AI 无法覆盖匹配的条件。
您可以用这些操作符构建条件:
| 操作符 | 含义 | 示例 |
|---|---|---|
| equals | 精确匹配(文本不区分大小写) | intent equals "billing" |
| not equals | 不匹配 | status not equals "active" |
| contains | 子串匹配(不区分大小写) | feedback contains "broken" |
| greater than | 数值 > | lead_score greater than 7 |
| less than | 数值 < | wait_minutes less than 5 |
您还可以用 All(全部必须匹配 — AND)或 Any(至少一个必须匹配 — OR)组合子句,并嵌套它们。像*「呼叫者是已知的且其等级是 gold 或 premium」*这样的规则变成:
All:
- is_known equals true
- Any:
- tier equals gold
- tier equals premium
如果您引用尚未设置的变量(例如 AI 从未收集过),对它的条件总是失败 — 没有错误,只是不匹配。所以 loyalty_tier equals "gold" 在 loyalty_tier 从未设置过时返回 false。设计您的分支以处理这种情况 — 通常用 else 分支(见下文)。
Else 分支 — 当没有条件匹配时
如果您有多条从节点出来的 Condition 边但没有一条匹配,通话落到最低优先级的非 Condition 边(Always 或 AI-decides 边)。如果根本没有 fallback,AI 重新获得控制权并可以自由继续。
常见模式:为已知路径设几个 Conditions,加上一条到 catch-all 的 Always 边(说点什么,然后 End Call 或转接)。
Always(自动前进)
当下一步是无条件时使用 Always — 无决策,无呼叫者输入。两种自然用法:
- 串联步骤:SAY → UPDATE_STATE → SAY → TOOL → Condition。每步结束,Always 边立刻前进。
- 智能体说完后自动前进:带有出向 Always 边的 Agent 节点意味着 「AI 停止说话时,前进」 — 无需呼叫者回应。对单口流程很有用,比如演讲智能体讲完然后转到下一节。
Condition 和 Always(确定性的)总是赢过 AI decides。 如果 Condition 匹配,AI 的转换工具在那一轮被忽略。这让您可以写 AI 无法绕过的规则。
变量
变量是 workflow 的记忆。Workflow 中大多数事情要么设置一个变量,要么读取一个。
声明变量
Variables 面板(工具栏按钮)显示 workflow 的每个变量及设置或读取它的步骤。点击一个变量跳转到一个 setter;这是找到某事出错位置的最快方式。
您可以在面板中用默认值声明变量 — 对像 escalated=false 这样需要从一开始就存在的标志很有用,这样您的条件就不会因「缺失」而悄悄失败。
变量如何被设置
| 来源 | 示例 |
|---|---|
| 默认值(在 Variables 面板中声明) | escalated = false 在通话开始前设置 |
| Gather Input | 呼叫者的口头回答被捕获到节点的变量中 |
| Update State | 您直接写入一个值(字面量或用 {{tokens}} 组合的) |
| Tool / Integration 结果 | 整个响应以节点名存储;如果响应是 JSON 对象,每个顶级字段也成为自己的变量 |
| Subagent 返回 | Subagent 完成的内容存储在 subagent 节点的 return 变量中 |
读取变量 — {{tokens}}
任何您可以在节点中写文本的地方 — Agent prompt、Say 文本、Gather prompt、Tool 的 URL/body/头、Phone Transfer 号码、Update State 值、条件值 — 您都可以塞入 {{variable}},它在运行时会被替换。
点号路径也适用于嵌套数据 — 例如,如果 Tool 响应是 {"customer": {"name": "Anna", "tier": "gold"}},您可以读 {{customer.name}} 或 {{customer.tier}}。
如果 token 引用不存在的变量,字面文本 {{name}} 按原样保留(不会被清空)。这是有意的 — 让损坏的模板在 test call 中容易被发现,而不是悄悄地咽下去。
常见模式
资格筛选 → 分支 → 路由
Start
└─ Agent (greeting + qualify)
└─ Gather Input (intent)
└─ Condition: intent == "sales" → Agent (sales)
└─ Condition: intent == "support" → Subagent (triage)
└─ Always (catch-all) → Say "Let me connect you" → Phone Transfer
查找 → 个性化
Start
└─ Tool (CRM lookup, writes is_known, name, tier)
└─ Condition: is_known == true → Agent (warm greeting with {{name}})
└─ Always (else) → Agent (cold greeting)
可复用助手(Subagent 侧行)
Agent (main conversation)
└─ AI decides: "Caller mentions an address" → Subagent (address collector)
└─ on finish: result = full_address
└─ Agent continues with {{full_address}}
Workflow 驱动通话期间什么被锁定
当图主管通话时,一些默认值会改变:
- 语言被锁定为 workflow 第一个智能体使用的语言。AI 不能在通话中途切换语言。这防止模型在嘈杂的回合中漂移到错误的语言。
- 智能体的主 prompt 被替换为活动节点的 prompt。这是「图拥有 persona」规则 — 见 Agent 下的 warning。
- 第一条消息来自入口节点的 greeting,而不是智能体的「Begin Message」字段。
防循环 — Step Budget
每个 workflow 每次通话都有一个最大转换数(默认 25)。每次图切换到新节点时,计数器减一。当达到零时,运行时停止做转换以防止失控循环。
您可以为这种情况指定一个 fallback 节点(通常是 Phone Transfer 或 End Call) — 当预算耗尽时,通话会转到那里。
您很少需要考虑这个 — 这是为意外循环的图设置的安全网。如果您在正常使用中达到它,可能某处有循环。
测试
编辑器的 Test Call 按钮以 workflow 的当前草稿打开一个浏览器通话。运行时,发光的萤火虫在画布上的节点之间移动,让您看到通话的确切位置。Test call 期间编辑器被锁定,以防修改使实时状态不同步。
用 Test Call 验证:
- 您的条件匹配您期望的值(看萤火虫是否跳过了您以为会触发的分支)。
- 您的 tokens 被正确替换(如果某值未设置,听听是否有悬挂的
{{name}})。 - 工具失败优雅降级(您的 fallback 路由确实触发)。
需要了解的失败
| 情况 | 发生什么 |
|---|---|
| Tool / Integration 调用失败 | 图无数据继续。您的下游条件应处理缺失的变量。 |
| Phone Transfer 失败(无效号码、无人接听、电话连接未配置) | 图回退,当前智能体保持在线,对话正常继续。 |
| Subagent 启动失败 | 取消这次侧行,父智能体保留,说一句简短的失败台词。 |
文本中的 {{missing_variable}} | 在输出中按字面保留 — 在 test call 中容易发现。 |
| Sub-workflow 节点 | 当前会原样通过,不执行任何操作。暂时不要依赖它。 |
| Step budget 耗尽 | 如果设置了 fallback 节点则转到该节点,否则 AI 重新获得控制权。 |
何时不要用 Workflow
Workflows 很强大,但不是每个智能体的正确答案。在以下情况下坚持单个 prompt:
- 对话是开放式的(「回答呼叫者关于我们产品的问题」)。
- 您没有清晰的分支逻辑 — 大多数决策是 AI 处理得很好的判断。
- 您只会写一个 Agent 节点和一个 End Call — 那只是带额外步骤的 prompt。
在以下情况下转向 workflow:
- 您可以将通话勾勒为有三个或更多不同阶段的流程图。
- 您需要在某个变量上至少一个确定性分支(一个 Condition)。
- 您想在多个智能体之间复用一段对话(一个 subagent)。
- 您已经在 prompt 中堆叠「如果呼叫者说 X 则做 Y」规则,且它们不可靠。