第 10 章:多轮对话状态管理:延续与脱离

10.1 工程问题的本质:对话不是单轮问答

真实业务对话是多轮的:「我要报销」之后跟着「500元」「差旅」「出差参加客户现场验收」。系统必须正确回答两个问题:这一轮还是上一轮的事吗? 若是,则延续状态并收集信息;若否,则脱离旧状态开始新任务。

设计原理: 对话状态管理的本质是记忆边界的管理——系统需要记得"进行到哪一步、已收集什么、还缺什么",同时要能识别"用户已转向新话题"。这两个能力缺一不可:只记得不转向,会吞掉新意图;只转向不记得,则流程无法推进。状态管理的质量,最终体现为"多少用户输入被错误地延续"与"多少补充信息被错误地打断"两个错误率的权衡。

10.2 状态记忆:跨轮的延续对象

框架以跨轮状态对象保存「业务意图 + 已收集槽位 + 流程实例引用」:

第 1 轮:用户「我要报销」        → 启动流程,挂起状态
第 2 轮:用户「500元」           → 补充信息 → 沿用状态 → 字段收集
第 3 轮:用户「差旅」            → 同上
第 4 轮:用户「出差参加客户现场验收」→ 同上 → 字段集齐 → 提交审批

原理: 状态的挂起与清除时机决定对话质量。挂起过宽(任务完成仍遗留状态)会吞掉下一轮新查询;清除过早(用户还在补充信息)则流程无法推进。框架的两个关键决策:只读查询执行完毕不遗留状态;Agent 向用户索要参数时才挂起。

10.3 延续与脱离的判定:零延迟收敛与发散

核心判定函数回答"这一轮是不是上一轮的事":输入是纯槽位值(产品码/数量/订单号/金额)→ 补充信息,延续(收敛);输入含明确业务名词(库存/订单/排产)→ 新业务话题,脱离(发散)。

原理: 收敛必须零延迟——补充信息是高频、确定、无歧义的,不值得走模型识别(曾因补充信息匹配失败触发模型语义识别,导致数秒延迟进而引发浏览器超时);发散必须走强模型——新话题的识别需要语义能力。这一"规则收敛 + 模型发散"的分工,是第 9 章"规则优先、模型兜底"在多轮场景的延伸。

字段收集中的特殊形态进一步体现了"收敛"的边界:流程字段收集进行中,输入只要能提取到当前流程必填字段(即使被误识别为显式业务意图,如"事由:出差参加客户现场验收"含"客户"),仍沿用收集器消化。字段收集时,输入优先被当作字段值解读——这是对"用户正在配合流程"这一情境的信任。

10.4 复合句拆解:一句话多个任务

一句话包含多个流程时("先查排班再下单 100 套""看库存够不够,够的话下单"),拆解为子任务执行:仅对显式标记拆解(顺序式/条件式/分析→动作链),普通连词不拆(保守原则防误拆);子任务逐一带授权过滤;有序链串行(后段注入前段结果摘要),其余并行;未授权子任务显式报告,不静默忽略。

原理: 拆解是"把用户的复合意图还原为系统可独立裁决的原子动作"。保守拆解原则对应一个判断:误拆的代价高于漏拆。漏拆(当作单任务处理)至多是能力不足,误拆(把一句话切成语义错误的片段)会产生错误执行。授权过滤则保证每个原子动作都在权限边界内——多跳不等于越权。

10.5 对话状态的形式化与会话持久化

10.5.1 状态的形式化:belief state

对话状态管理可以形式化为信念状态(belief state):系统对"对话进行到哪一步、已收集哪些槽位值"的信念集合。每一轮输入是信念状态上的一次更新:

belief_state = {intent: 报销, slots: {amount: 500, expense_type: 差旅, reason: 待补}, flow: 字段收集}
    输入「出差参加客户现场验收」
    → 槽位提取 {reason: ...}
    → 更新 belief_state.slots.reason
    → 校验必填字段齐备
    → 状态迁移:字段收集 → 待审批

形式化的价值有三:状态可枚举(任何时刻系统处于哪个阶段可判定)、迁移可定义(什么输入触发什么更新)、缺失可检测(哪些必填槽位为空可计算)。缺乏形式化时,状态管理退化为"把东西塞进字典"——看似自由,实则无法验证。

10.5.2 状态持久化与恢复

跨轮状态若只存于进程内存,进程重启即丢失——用户刷新页面或服务重启后,对话"失忆"。状态持久化需要两个能力:

能力机制语义
持久化状态序列化写入会话存储(Redis 注入/内存降级)重启后按会话 ID 恢复
恢复按会话 ID 加载状态 + 历史多端/多轮延续

原理: 状态持久化与记忆管理的分层(第 15 章)一致:短期记忆需要可恢复性,长期记忆需要可检索性。持久化不改变状态的语义,只改变状态的存续范围——会话内有效,但跨重启仍可恢复。

10.5.3 状态与并发的互斥

同一会话的多轮请求若并发到达(用户连发两条),状态更新必须互斥——否则两个请求各自读取旧状态、各自写回,后写覆盖先写,丢失一次更新。状态更新的读-改-写必须原子化(加锁或串行化),这是第 17 章并发正确性在状态管理层的具体形态。

10.6 失败模式与权衡

失败形态根因设计应对
查询完成遗留状态吞掉新查询查询意图挂起 pending只读查询不挂起
补充信息触发模型识别延迟每轮补充都走 LLM纯槽位值规则收敛、零 LLM
字段值被误判为新话题字段含业务名词(如"客户")字段收集期优先按字段值解读
复合句被错误拆解连词过度拆解仅显式标记拆解 + LLM 校正(防幻觉校验)

权衡: 延续与脱离的判定是一个"持续校准"的过程——收敛过度的版本会吞掉用户明确的新意图,发散过度的版本会打断字段收集。框架通过可训练的业务名词表与槽位形态规则,把校准权交给业务侧,而非固化在代码中。

10.7 本章小结