状态控制
1. 对话状态管理
状态的本质
对话状态是指维护在多轮交互中的关键信息,确保模型能够在上下文中保持一致性和连贯性。
对话状态包含:
├── 用户画像 ← 偏好、背景、身份
├── 对话意图 ← 当前目标和历史意图
├── 已确认信息 ← 双方已达成共识的内容
├── 待处理任务 ← 尚未完成的子任务
└── 上下文变量 ← 对话中产生的临时变量
QUESTION 面试高频:大模型应用中如何维护多轮对话的状态?
- 会话级状态:通过消息历史维护在上下文窗口中
- 摘要级状态:将长对话压缩为摘要注入 System Prompt
- 外部状态存储:使用数据库/Redis 存储结构化状态
- 向量记忆:将对话片段存入向量数据库,按需检索
- 混合策略:短期记忆(上下文窗口)+ 长期记忆(向量检索)
2. 多轮记忆策略
记忆层级
| 层级 | 存储 | 容量 | 延迟 | 用途 |
|---|---|---|---|---|
| 工作记忆 | 上下文窗口 | 有限(128K tokens) | 最低 | 当前对话 |
| 短期记忆 | 会话存储(Redis) | 中等 | 低 | 会话内状态 |
| 长期记忆 | 向量数据库 | 无限 | 中 | 跨会话知识 |
| 用户画像 | 结构化数据库 | 中等 | 低 | 用户偏好 |
记忆检索策略
用户发送消息
↓
┌─────────────────────────────────────┐
│ 1. 从工作记忆中读取当前对话历史 │
│ 2. 从短期记忆中读取会话状态 │
│ 3. 从长期记忆中检索相关历史对话 │
│ 4. 从用户画像中读取偏好设置 │
└─────────────────────────────────────┘
↓
组装上下文
↓
调用模型生成回复
↓
更新各层级记忆
记忆更新机制
def update_memory(user_msg: str, assistant_msg: str, session):
# 1. 追加到工作记忆(对话历史)
session.history.append({"role": "user", "content": user_msg})
session.history.append({"role": "assistant", "content": assistant_msg})
# 2. 提取关键信息更新短期记忆
key_info = extract_key_info(user_msg, assistant_msg)
session.state.update(key_info)
# 3. 判断是否需要持久化到长期记忆
if is_important(user_msg, assistant_msg):
embedding = embed(f"{user_msg}\n{assistant_msg}")
vector_db.upsert(session.user_id, embedding, metadata={
"turn": session.turn_count,
"topic": detect_topic(user_msg)
})
# 4. 更新用户画像
profile_updates = extract_profile_updates(user_msg)
user_profile.update(session.user_id, profile_updates)
3. 用户意图跟踪
意图识别与追踪
QUESTION 面试高频:如何在多轮对话中跟踪用户意图的变化? 意图追踪需要维护一个意图状态机:
意图状态模型:
[初始] → [探索] → [明确] → [执行] → [确认]
↑ ↓
└─────── [修正] ←──────────────────┘
意图追踪实现
## System Prompt 中的意图追踪指令
在每次回复前,分析用户的意图状态:
- EXPLORING: 用户在探索可能的选项
- CLARIFYING: 用户在澄清需求
- CONFIRMED: 用户确认了具体需求
- EXECUTING: 正在执行用户确认的任务
- MODIFYING: 用户在修改之前的请求
根据意图状态调整你的回复策略:
- EXPLORING → 提供选项和建议
- CLARIFYING → 提出精确的问题
- CONFIRMED → 执行并报告结果
- EXECUTING → 专注完成当前任务
- MODIFYING → 理解变更并重新执行
槽位填充(Slot Filling)
任务:预订餐厅
必填槽位:
├── 餐厅类型 ← 已确认:中餐
├── 日期 ← 已确认:明天
├── 时间 ← 已确认:18:00
├── 人数 ← 待确认
└── 预算 ← 可选
当必填槽位不完整时,主动询问缺失信息。
4. 上下文中的状态控制
状态注入到提示词
# 当前会话状态
- 用户身份:{user_profile}
- 对话主题:{current_topic}
- 已确认信息:{confirmed_facts}
- 待处理任务:{pending_tasks}
# 行为指令
基于以上状态信息回答用户的问题。
如果用户的问题与当前主题不符,先确认是否切换话题。
状态驱动的行为控制
## 根据对话阶段调整行为
### 开场阶段(Turn 1-3)
- 主动了解用户需求
- 提供概览性信息
- 收集关键参数
### 深入阶段(Turn 4-10)
- 聚焦于具体问题
- 提供详细的分析和建议
- 确认用户的理解
### 收尾阶段
- 总结讨论要点
- 确认下一步行动
- 提供后续支持选项
5. 多轮对话一致性保证
一致性检查清单
| 维度 | 检查内容 | 实现方式 |
|---|---|---|
| 事实一致性 | 不与前文信息矛盾 | 维护事实列表 |
| 角色一致性 | 保持角色设定不变 | System Prompt 锚定 |
| 风格一致性 | 保持语气和格式统一 | 样式示例 |
| 逻辑一致性 | 推理不互相矛盾 | 状态机约束 |
| 承诺一致性 | 不违背已做出的承诺 | 承诺记录 |
矛盾检测与修复
def check_consistency(new_response: str, conversation_state: dict) -> dict:
"""检查新回复是否与已有状态矛盾"""
issues = []
# 检查事实矛盾
for fact in conversation_state["confirmed_facts"]:
if contradicts(new_response, fact):
issues.append(f"与已确认事实矛盾: {fact}")
# 检查承诺矛盾
for promise in conversation_state["promises"]:
if violates(new_response, promise):
issues.append(f"违背了之前的承诺: {promise}")
return {"consistent": len(issues) == 0, "issues": issues}
6. 实践建议
状态管理架构
┌────────────────────────────────────────────┐
│ 应用层 │
├────────────────────────────────────────────┤
│ 状态管理器 │
│ ├── 意图追踪 │
│ ├── 槽位填充 │
│ ├── 一致性检查 │
│ └── 记忆管理 │
├────────────────────────────────────────────┤
│ 存储层 │
│ ├── Redis (会话状态) │
│ ├── 向量DB (长期记忆) │
│ └── SQL (用户画像) │
└────────────────────────────────────────────┘
设计原则
- 最小化上下文状态:只保留必要信息,避免冗余
- 结构化存储:用 schema 约束状态格式
- 增量更新:只更新变化的部分
- 降级策略:状态丢失时有合理的恢复方案
- 可观测性:记录状态变化日志,便于调试