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 · script_params · action · state · context后端填充话术、执行动作、保存参数与状态
| 参与方 | 职责 |
|---|---|
| 后端 | 提供对话、state 与 context;按 target_workflow 请求业务;按 code 取话术模板、用 script_params 填充动态字段,按 action 执行动作,保存完整 state 与 context。 |
| 主路由 | 结合本轮输入、历史对话、业务状态与会话参数选择本轮目标;决定 state 保留或清空,读取 context 辅助判断。 |
| 业务 Workflow | 处理本轮输入,组织当前话术需要的动态参数,返回 code、script、script_params、action、完整 state 与 context,结束本轮执行。 |
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、script_params、action、state 和 context。
交互完成、话术无动态参数、无需后端动作且尚无会话参数时的返回:
{
"code": "<话术编码>",
"script": "<参考话术>",
"script_params": {},
"action": null,
"state": null,
"context": {}
}
| 字段 | 类型 | 含义 |
|---|---|---|
code | string | 话术编码,后端据此从话术库选择模板。 |
script | string | 已代入本轮动态参数的参考话术,用于开发联调和调用测试。 |
script_params | object | 当前 code 所需的话术参数,供后端替换模板中的动态字段;没有动态参数时为 {}。 |
action | string 或 null | 需要后端执行的单个动作标识;无需执行动作时返回 null。 |
state | object 或 null | 本轮处理后的完整续接状态。仍需用户反馈时返回状态对象;无待续接业务时返回 null。 |
context | object | 本轮处理后的完整会话参数。已有参数继续保留,业务按本轮结果补充或更新;尚无参数时为 {}。 |
后端按 code 取得模板,用 script_params 填充后展示;按 action 调用约定的动作处理逻辑,并分别用完整 state、context 替换已保存值。
同一业务可以根据不同处理结果返回不同 code。话术含义应与本轮动作、后续状态保持一致,例如等待用户确认时,对应话术应询问是否认可。
2.4 动态话术
话术库用 <话术编码>.<参数名> 标识动态字段。script_params 的键使用参数名,后端以 code + "." + 参数名 对应模板字段。例如 A_COMPLAINT_01.contract_no 对应本轮 script_params.contract_no。
- 业务 Workflow 从会话参数、业务接口或本轮处理结果中组织话术参数。
- 每个
code约定所需参数的名称与含义;业务完整提供,后端展示前检查是否齐全。 - 同一
code下的候选话术共用同一套参数约定。 script_params用于本轮话术展示;下一轮按现有请求结构传入state、context等字段。
2.5 后端动作
业务 Workflow 返回动作标识,后端负责执行并确认结果。例如 action: "TRANSFER_COLLECTIONS" 表示请求转催收人工客服,话术可表达“将为你转接”;转接成功或失败由后端实际执行结果确定。
action 表达本轮要执行的动作,state 表达业务是否需要下一轮续接,两者独立:
| 处理结果 | action | state |
|---|---|---|
| 仅询问用户,等待反馈 | null | 续接状态对象 |
| 请求执行动作,之后仍需用户反馈 | 约定的动作标识 | 续接状态对象 |
| 请求转人工,当前业务自动交互结束 | "TRANSFER_COLLECTIONS" | null |
| 正常结束,无后端动作 | null | null |
转人工场景中,后端负责转接失败的反馈与后续处理;转接成功后进入人工服务流程。
3. state 与 context
3.1 状态结构
state: null 表示没有待续接业务。有待续接业务时使用以下结构,两处 <业务workflow标识> 保持一致:
{
"routing": {
"active_workflow": "<业务workflow标识>"
},
"workflows": {
"<业务workflow标识>": {
"status": "waiting_input",
"resume_from": "<续接入口>"
}
}
}
| 字段 | 类型 | 含义与更新方 |
|---|---|---|
routing.active_workflow | string | 当前待续接的业务 Workflow 标识,由业务根据处理结果设置。 |
workflows | object | 以业务 Workflow 标识为键,保存当前业务的一份续接记录,由业务 Workflow 更新。 |
workflows.<业务workflow标识>.status | string | 当前记录使用 waiting_input,表示等待用户反馈。 |
workflows.<业务workflow标识>.resume_from | string | 下一轮进入的业务处理分支,由该业务定义取值并更新。 |
workflows.<业务workflow标识>.variables | object,可选 | 该业务需要跨轮保留的值,内部字段由业务按需定义和更新。 |
每次业务新执行从入口开始:没有本业务记录时进入首次处理;已有记录时,通过入口 Switch 按 resume_from 进入相应分支。
3.2 本轮目标与待续接业务
| 字段 | 表达什么 |
|---|---|
target_workflow | 本轮调用哪个业务,由主路由返回。 |
state.routing.active_workflow | 当前保存了哪个业务的续接状态,由业务 Workflow 返回。 |
需求不明确时,本轮目标可以是 other,已有状态仍指向原业务。other 返回澄清话术编码及联调参考,保留原状态,下一轮再由主路由判断归属。
3.3 状态流转
| 本轮情况 | 主路由返回 | 业务 Workflow 返回的 state |
|---|---|---|
| 首次进入 | 目标业务标识 + state: null。 | 需要反馈时生成状态;交互完成时为 null。 |
| 继续当前业务 | 当前业务标识 + 原状态。 | 按本轮结果更新状态;交互完成时为 null。 |
| 明确切换业务 | 新业务标识 + state: null。 | 新业务从首次处理开始,返回自身状态,或完成后返回 null。 |
| 需求不明确 | target_workflow: "other" + 原状态。 | 保留原状态。 |
主路由决定旧续接状态的保留或清空;业务 Workflow 生成和更新具体业务状态。这里的“完成”指本项对话交互完成,外部业务事项按各自流程继续处理。
3.4 会话参数的保留与更新
context 在同一个 session_id 的会话期间保留,供不同轮次、不同业务使用。业务完成或切换时,state 可以清空,已有 context 继续传递。
- 后端传入当前保存的完整
context。 - 业务在传入参数的基础上补充或更新本轮已确认的信息,保留其他已有字段。
- 参数无变化时原样返回;后端保存完整返回值,下一轮继续传入。
| 字段 | 用途 | 示例 |
|---|---|---|
context | 会话期间可跨轮复用的会话参数 | 合同号、手机号。 |
script_params | 当前话术模板所需的展示参数 | 本轮话术使用的合同号、预计反馈天数。 |
state | 当前待续接业务及其处理位置 | 等待用户确认,下一轮进入反馈分支。 |
state.variables | 当前业务记录中需跨轮保留的业务变量 | 验证码尝试次数。 |
4. 业务扩展项
| 扩展项 | 定义与使用 |
|---|---|
| 业务 Workflow 标识 | 各业务定义标识;主路由据此选择,后端维护标识到调用地址的映射。 |
code 取值 | 按业务处理结果约定话术编码,与后端话术库对应。 |
script_params 内部字段 | 按 code 约定话术参数的名称与含义;业务提供值,后端填入模板。 |
action 取值 | 业务与后端共同约定动作标识,由后端维护标识到处理逻辑的映射。 |
resume_from 取值 | 各业务定义可续接入口,并配置对应的入口 Switch 分支。 |
variables 内部字段 | 业务定义需跨轮保留的值,随 state 返回并由后端保存。 |
context 内部字段 | 按业务约定会话参数的字段与来源;后端传入,业务补充或更新,完整回传后由后端保存。 |
合同号与手机号在示例中均使用字符串。手机号是否验证通过、是否与合同匹配,由相应业务校验结果确定。
调用示例
以下以扣费投诉的服务安排确认为例:后端按业务返回的编码取得模板,填入话术参数,展示安排并询问是否认可;用户可能认可、改问发票,或纠正当前理解。另以转催收人工展示后端动作。业务标识、话术编码、续接入口、对话排版和话术均为示例设定。
“首次进入”展示第一轮;“继续处理”“切换业务”“需求不明确”分别从第一轮返回的投诉状态继续。“转催收人工”使用独立会话。
投诉相关示例由后端提供已取得的合同号与手机号,业务完整回传 context;补充示例展示如何新增手机号。参数值仅用于演示。
前置状态
本轮用户
保存 state
保存 context
下一轮
补充示例
script_params:模板、参数与展示结果
“首次进入”使用的 A_COMPLAINT_01 话术模板:
关于合同 {{A_COMPLAINT_01.contract_no}} 的扣费问题,我们预计在 {{A_COMPLAINT_01.feedback_days}} 个工作日内反馈。你是否认可这个安排?
占位符外层的 {{ }} 仅用于展示,实际沿用话术库格式。
| 模板动态字段 | 业务返回的参数 | 本例取值 |
|---|---|---|
A_COMPLAINT_01.contract_no | script_params.contract_no | "HT20260001",取自 context.contract_no。 |
A_COMPLAINT_01.feedback_days | script_params.feedback_days | 3,由业务确定本次安排的预计反馈天数。 |
业务 Workflow 返回:
{
"code": "A_COMPLAINT_01",
"script": "关于合同 HT20260001 的扣费问题,我们预计在 3 个工作日内反馈。你是否认可这个安排?",
"script_params": {
"contract_no": "HT20260001",
"feedback_days": 3
},
"action": null,
"state": {
"routing": {
"active_workflow": "complaint"
},
"workflows": {
"complaint": {
"status": "waiting_input",
"resume_from": "handle_feedback"
}
}
},
"context": {
"contract_no": "HT20260001",
"phone_no": "13800000000"
}
}
后端按 code 取得上述模板,填充后展示:
关于合同 HT20260001 的扣费问题,我们预计在 3 个工作日内反馈。你是否认可这个安排?
script_params.contract_no 用于本轮话术填充,context.contract_no 供后续业务继续使用;本例的 script 与填充结果一致,作为联调参考。其余示例话术采用固定文本,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": "好的,我们会按上述安排继续核查并反馈。",
"script_params": {},
"action": 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": "验证码不正确,还可以尝试一次。",
"script_params": {},
"action": 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 使用验证服务返回的次数;用户追问“没收到验证码”等未进行有效校验的情况,次数保持。