1. 调用流程与职责
每轮自动交互对应两次独立请求:后端先请求主路由,再请求选中的业务 Workflow。两类 Workflow 各自通过 Webhook 接收请求并返回响应。
- 后端 → 主路由
session_id · content · history · state · contextstate、context = 后端保存值 - 主路由 → 后端
target_workflow · state本轮调用目标与交接状态 - 后端 → 业务 Workflow
session_id · content · history · state · contextstate = 路由返回值;context 沿用 - 业务 Workflow → 后端
code · script · data · state · context后端填充话术、执行动作、保存参数与状态
| 参与方 | 职责 |
|---|---|
| 后端 | 提供对话、state 与 context;按 target_workflow 请求业务;按 code 取话术模板、用 data.script_params 填充动态字段,按 data.action 执行动作,保存完整 state 与 context。 |
| 主路由 | 结合本轮输入、历史对话、业务状态与会话参数选择本轮目标;决定 state 保留或清空,读取 context 辅助判断。 |
| 业务 Workflow | 处理本轮输入,返回 code、script、data、完整 state 与 context,结束本轮执行。动作与话术动态参数放在 data 中。 |
other Workflow | 处理需求不明确等情况,返回澄清或兜底话术的编码与联调参考,保留已有业务状态与会话参数。 |
同一会话只保留一个待续接业务。继续自动交互时,下一轮由后端携带新的对话、最新 state 与 context,再次请求主路由。
2. 请求与返回
2.1 公共请求
后端请求主路由和业务 Workflow 时,使用同一套字段。以下为尚无续接状态与会话参数时的请求结构:
{
"session_id": "<会话标识>",
"content": "<本轮用户发言>",
"history": "<历史对话>",
"state": null,
"context": {}
}
| 字段 | 类型 | 提供方式 | 含义 |
|---|---|---|---|
session_id | string | 每轮传入 | 会话标识。后端据此保存、取回历史对话、业务状态与会话参数。 |
content | string | 每轮传入 | 本轮用户发言。 |
history | string | 每轮传入 | 本轮之前的历史对话内容。 |
state | object 或 null | 每次请求传入 | 请求主路由时使用上轮保存的状态;请求业务 Workflow 时使用本轮主路由返回的状态。 |
context | object | 每次请求传入 | 同一会话中跨轮保留、传递和更新的会话参数,例如合同号、手机号;使用后端当前保存的完整值,尚无参数时为 {}。 |
2.2 主路由返回
以上述空状态请求为例:
{
"target_workflow": "<业务workflow标识>",
"state": null
}
| 字段 | 类型 | 含义 |
|---|---|---|
target_workflow | string | 本轮需要调用的业务 Workflow 标识。需求不明确时选择 other。 |
state | object 或 null | 交给本轮业务的状态;保留或清空规则见第 3 节。 |
后端按 target_workflow 选择业务调用地址,沿用原请求的 session_id、content、history 和完整 context,将 state 设为主路由返回值,再请求目标业务。主路由保持 context 内容不变,由后端继续传递。
2.3 业务 Workflow 返回
所有业务 Workflow(包括 other)统一返回 code、script、data、state 和 context。
交互完成、话术无动态参数、无需后端动作且尚无会话参数时的返回:
{
"code": "<话术编码>",
"script": "<参考话术>",
"data": null,
"state": null,
"context": {}
}
| 字段 | 类型 | 含义 |
|---|---|---|
code | string | 话术编码,后端据此从话术库选择模板。 |
script | string | 已代入本轮动态参数的参考话术,用于开发联调和调用测试。 |
data | object 或 null | 供后端展示话术、执行动作等使用的数据,例如话术动态参数、动作标识。没有此类数据时返回 null。 |
state | object 或 null | 本轮处理后的完整续接状态。仍需用户反馈时返回状态对象;无待续接业务时返回 null。 |
context | object | 本轮处理后的完整会话参数。已有参数继续保留,业务按本轮结果补充或更新;尚无参数时为 {}。 |
后端分别用完整 state、context 替换已保存值。
同一业务可以根据不同处理结果返回不同 code。话术含义应与本轮动作、后续状态保持一致,例如等待用户确认时,对应话术应询问是否认可。
2.4 data:话术参数与后端动作
data 有值时包含以下两个字段;没有动作、话术动态参数或其他约定数据时,返回 data: null。
| 字段 | 类型 | 用途 |
|---|---|---|
data.script_params | object | 后端填入话术模板的动态参数;无动态参数时为 {}。 |
data.action | string 或 null | 需要后端执行的单个动作标识;无需动作时为 null。 |
话术参数
后端根据 code 从话术库取得模板,再用 data.script_params 中的值填入模板。
例如,话术库中的 A_COMPLAINT_01(用 {{ }} 示意待填内容):
关于合同 {{A_COMPLAINT_01.contract_no}} 的扣费问题,
我们预计在 {{A_COMPLAINT_01.feedback_days}} 个工作日内反馈。
你是否认可这个安排?
业务 Workflow 返回的相关字段:
{
"code": "A_COMPLAINT_01",
"data": {
"action": null,
"script_params": {
"contract_no": "HT20260001",
"feedback_days": 3
}
}
}
后端取出这条模板,将合同号填为 HT20260001、反馈天数填为 3,用户最终看到:
关于合同 HT20260001 的扣费问题,
我们预计在 3 个工作日内反馈。
你是否认可这个安排?
话术库负责模板,业务 Workflow 提供本次要填入的值,后端完成填充和展示。
每条话术需要哪些参数,由话术库与业务 Workflow 共同约定;同一编码下的候选话术使用相同参数。业务提供完整值,后端展示前检查是否齐全。
后端动作
例如 data.action: "TRANSFER_COLLECTIONS" 表示请求转催收人工客服。后端负责执行转接、确认结果,并处理失败情况;转接成功后进入人工服务流程。
data 用于本轮展示与动作处理,state 用于下一轮业务续接,两者独立。
3. state 与 context
state 保存业务处理进度,context 保存会话参数。后端保存两者,并在下一轮请求时传入。
3.1 state:下一轮如何继续业务
state 保存当前业务的处理进度,以及下一轮继续处理所需的业务变量。没有待继续的业务时,返回 null。
有待续接业务时使用以下结构,两处 <业务workflow标识> 保持一致:
{
"routing": {
"active_workflow": "<业务workflow标识>"
},
"workflows": {
"<业务workflow标识>": {
"status": "waiting_input",
"resume_from": "<续接入口>"
}
}
}
| state 内字段 | 类型 | 含义与更新方 |
|---|---|---|
routing.active_workflow | string | 当前待续接的业务 Workflow 标识,由业务根据处理结果设置。 |
workflows | object | 以业务 Workflow 标识为键,保存当前业务的一份续接记录,由业务 Workflow 更新。 |
workflows.<业务workflow标识>.status | string | 当前记录使用 waiting_input,表示等待用户反馈。 |
workflows.<业务workflow标识>.resume_from | string | 下一轮进入的业务处理分支,由该业务定义取值并更新。 |
workflows.<业务workflow标识>.variables | object,可选 | 该业务需要跨轮保留的值,内部字段由业务按需定义和更新。 |
例如,业务询问用户是否认可安排后,将 resume_from 设为 handle_feedback。后端保存这份状态。下一轮主路由确认继续该业务后,业务新执行从入口开始,通过 Switch 进入处理反馈的分支。没有本业务记录时,从首次处理分支开始。
业务变量保存在 state.workflows.<业务workflow标识>.variables 中,例如验证码已尝试次数;业务按需提供,没有跨轮变量时可以省略。
3.2 主路由如何交接 state
target_workflow:本轮调用哪个业务 Workflow。state.routing.active_workflow:当前保留的是哪个业务的续接状态。
主路由根据本轮对话,按以下规则保留或清空 state。
| 本轮情况 | 主路由返回 | 业务 Workflow 返回的 state |
|---|---|---|
| 首次进入 | 目标业务标识 + state: null。 | 需要反馈时生成状态;交互完成时为 null。 |
| 继续当前业务 | 当前业务标识 + 原状态。 | 按本轮结果更新状态;交互完成时为 null。 |
| 明确切换业务 | 新业务标识 + state: null。 | 新业务从首次处理开始,返回自身状态,或完成后返回 null。 |
| 需求不明确 | target_workflow: "other" + 原状态。 | 保留原状态。 |
例如,投诉处理中,用户说“你理解错了”,主路由选择 other 进行澄清,同时保留投诉状态。因此,本轮调用目标是 other,状态中保存的业务仍是投诉。下一轮再由主路由结合对话与状态判断归属。
主路由决定旧续接状态的保留或清空;业务 Workflow 生成和更新具体业务状态。这里的“完成”指本项对话交互完成,外部业务事项按各自流程继续处理。
3.3 context:会话参数如何保留和更新
context 保存同一个 session_id 会话期间可跨轮、跨业务使用的参数,例如合同号、手机号。
例如,后端已保存合同号,请求中的会话参数为:
{
"context": {
"contract_no": "HT20260001"
}
}
用户本轮补充手机号,业务保留原合同号,并返回更新后的完整参数:
{
"context": {
"contract_no": "HT20260001",
"phone_no": "13800000000"
}
}
后端保存返回的完整 context,下一轮继续传入。业务根据本轮已确认的信息补充或更新参数,保留其他已有字段;无变化时原样返回,尚无参数时为 {}。
业务交互完成或切换时,state 可以清空,已有 context 继续保留。
4. 业务扩展项
| 扩展项 | 定义与使用 |
|---|---|
| 业务 Workflow 标识 | 各业务定义标识;主路由据此选择,后端维护标识到调用地址的映射。 |
code 取值 | 按业务处理结果约定话术编码,与后端话术库对应。 |
data 扩展字段 | 按需约定新的本轮输出字段及其含义,由业务返回、后端消费。 |
data.script_params 内部字段 | 按 code 约定话术参数的名称与含义;业务提供值,后端填入模板。 |
data.action 取值 | 业务与后端共同约定动作标识,由后端维护标识到处理逻辑的映射。 |
resume_from 取值 | 各业务定义可续接入口,并配置对应的入口 Switch 分支。 |
variables 内部字段 | 业务定义需跨轮保留的值,随 state 返回并由后端保存。 |
context 内部字段 | 按业务约定会话参数的字段与来源;后端传入,业务补充或更新,完整回传后由后端保存。 |
合同号与手机号在示例中均使用字符串。手机号是否验证通过、是否与合同匹配,由相应业务校验结果确定。
调用示例
以下以扣费投诉的服务安排确认为例:后端按业务返回的编码取得模板,填入话术参数,展示安排并询问是否认可;用户可能认可、改问发票,或纠正当前理解。另以转催收人工展示后端动作。业务标识、话术编码、续接入口、对话排版和话术均为示例设定。
“首次进入”展示第一轮;“继续处理”“切换业务”“需求不明确”分别从第一轮返回的投诉状态继续。“转催收人工”使用独立会话。
投诉相关示例由后端提供已取得的合同号与手机号,业务完整回传 context;补充示例展示如何新增手机号。参数值仅用于演示。
前置状态
本轮用户
保存 state
保存 context
下一轮
补充示例
data.script_params:模板、参数与展示结果
“首次进入”使用的 A_COMPLAINT_01 话术模板:
关于合同 {{A_COMPLAINT_01.contract_no}} 的扣费问题,
我们预计在 {{A_COMPLAINT_01.feedback_days}} 个工作日内反馈。
你是否认可这个安排?
占位符外层的 {{ }} 仅用于展示,实际沿用话术库格式。
| 模板动态字段 | 业务返回的参数 | 本例取值 |
|---|---|---|
A_COMPLAINT_01.contract_no | data.script_params.contract_no | "HT20260001",取自 context.contract_no。 |
A_COMPLAINT_01.feedback_days | data.script_params.feedback_days | 3,由业务确定本次安排的预计反馈天数。 |
业务 Workflow 返回:
{
"code": "A_COMPLAINT_01",
"script": "关于合同 HT20260001 的扣费问题,我们预计在 3 个工作日内反馈。你是否认可这个安排?",
"data": {
"action": null,
"script_params": {
"contract_no": "HT20260001",
"feedback_days": 3
}
},
"state": {
"routing": {
"active_workflow": "complaint"
},
"workflows": {
"complaint": {
"status": "waiting_input",
"resume_from": "handle_feedback"
}
}
},
"context": {
"contract_no": "HT20260001",
"phone_no": "13800000000"
}
}
后端按 code 取得上述模板,填充后展示:
关于合同 HT20260001 的扣费问题,
我们预计在 3 个工作日内反馈。
你是否认可这个安排?
data.script_params.contract_no 用于本轮话术填充,context.contract_no 供后续业务继续使用;本例的 script 与填充结果一致,作为联调参考。
固定话术且无需动作的示例返回 data: null;转催收人工示例返回 data.action: "TRANSFER_COLLECTIONS",data.script_params 为 {}。
业务标识与续接入口
| 示例业务 Workflow 标识 | 示例 resume_from | 处理分支 |
|---|---|---|
complaint(投诉) | handle_feedback | 处理对安排的认可、追问或异议。 |
complaint(投诉) | handle_adjustment | 已询问调整诉求,处理用户的具体要求。 |
invoice(发票) | collect_invoice_title | 处理用户提供的发票抬头。 |
verification(验证码) | verify_code | 处理本轮验证码或相关问题。 |
collections(催收) | — | 本例返回转催收人工动作,结束自动交互。 |
other(澄清 / 兜底) | — | 结合对话与已有状态返回澄清话术编码及联调参考,保留原业务记录。 |
用户只回答“不认可”时,示例投诉业务返回询问具体要求的话术编码,并保存 handle_adjustment;收到要求并给出新安排后,保存 handle_feedback,等待用户确认。
context:合同号与手机号的保留、更新
| 示例字段 | 类型 | 含义 |
|---|---|---|
contract_no | string | 当前业务使用的合同号。 |
phone_no | string | 当前业务使用的手机号。 |
另一种输入情况:已有合同号,用户本轮认可安排并补充联系手机号。主路由返回 complaint 并保留原状态,后端沿用原 context 请求投诉 Workflow:
{
"session_id": "S001",
"content": "可以,就按这个安排。联系手机号是 13800000000。",
"history": "[用户] 这次扣费不对,我要投诉。\n[客服] 关于合同 HT20260001 的扣费问题,我们预计在 3 个工作日内反馈。你是否认可这个安排?",
"state": {
"routing": {
"active_workflow": "complaint"
},
"workflows": {
"complaint": {
"status": "waiting_input",
"resume_from": "handle_feedback"
}
}
},
"context": {
"contract_no": "HT20260001"
}
}
业务记录本轮提供的手机号,保留原合同号,完成确认后返回:
{
"code": "A_COMPLAINT_02",
"script": "好的,我们会按上述安排继续核查并反馈。",
"data": null,
"state": null,
"context": {
"contract_no": "HT20260001",
"phone_no": "13800000000"
}
}
后端保存 state: null 与完整 context;下一轮继续传入合同号和手机号。后续取得并确认新的参数值时,业务更新相应字段,完整回传。
手机号验证与合同匹配由相应业务校验结果确定。
variables:验证码尝试次数
示例验证码业务通过 variables.attempts_used 保留已尝试次数。主路由已返回 target_workflow: "verification" 并保留原状态,后端请求验证码 Workflow:
{
"session_id": "S002",
"content": "222222",
"history": "[客服] 请输入 6 位验证码。\n[用户] 111111\n[客服] 验证码不正确,还可以尝试两次。",
"state": {
"routing": {
"active_workflow": "verification"
},
"workflows": {
"verification": {
"status": "waiting_input",
"resume_from": "verify_code",
"variables": {
"attempts_used": 1
}
}
}
},
"context": {
"phone_no": "13800000000"
}
}
验证服务确认本次为第二次失败,业务 Workflow 返回:
{
"code": "A_VERIFICATION_02",
"script": "验证码不正确,还可以尝试一次。",
"data": null,
"state": {
"routing": {
"active_workflow": "verification"
},
"workflows": {
"verification": {
"status": "waiting_input",
"resume_from": "verify_code",
"variables": {
"attempts_used": 2
}
}
}
},
"context": {
"phone_no": "13800000000"
}
}
attempts_used 使用验证服务返回的次数;用户追问“没收到验证码”等未进行有效校验的情况,次数保持。