多轮对话的指代消解
多轮问答里当前这句话经常带着“它”“上面那个报错”这样的指代或省略,直接拿它去检索,向量里没有任何可辨识的主题词,结果自然是一片无关内容。解决办法是先结合历史把当前句改写成独立、自包含的问题再检索,同时控制历史窗口长度——历史越长,旧话题越容易把改写带偏。改写与检索在日志里要成对记录,才能判断是改写跑题还是检索失效。
基本信息
| 输入 | 最近 1~2 轮对话加当前问题 |
|---|---|
| 输出 | 补全指代、保留实体的独立问句 |
| 窗口控制 | 按 token 预算限轮数,越近的轮次权重越高 |
| 判断前置 | 已自包含的问题跳过改写以省一次调用 |
| 记录要求 | 原问题与改写结果一并写入日志 |
典型使用场景
- 连续追问:用户先问组件再问它的默认端口,第二轮必须补全组件名
- 纠错对话:用户说“不是这个,是另一个版本”,需要把修正意图并入查询
- 话题切换检测:发现用户已换话题时清空历史影响,避免旧实体污染
- 多轮摘要:长会话先对历史做摘要再改写,控制提示词长度
- 效果评估:抽样对比改写前后的检索命中率,验证改写是否真的在起作用
改写示例
改写示例
历史:用户问“Qdrant 支持过滤吗”,答“支持”;
当前:用户问“那 Milvus 呢?”
改写 → “Milvus 支持向量过滤吗?”
# 只补全指代,不引入原句没有的条件改写提示词要点
改写提示词要点
输入:最近 1~2 轮对话 + 当前问题
要求:补全指代、保留专名与数字、不添加新条件、不做推测
输出:独立可检索的完整问句(只输出这一句)历史窗口策略
| 策略 | 优点 | 风险 |
|---|---|---|
| 只取最近 1~2 轮 | 改写准确,长度可控 | 跨轮指代会丢失 |
| 取全部历史 | 上下文完整 | 旧话题干扰,提示词超预算 |
| 历史做摘要 | 长度可控且保留要点 | 摘要丢失细节,改写出错 |
| 把历史一起向量化 | 省掉一次生成调用 | 实现复杂,检索质量不稳定 |
改写会增加一次模型调用:高频短会话里可以先用规则判断问题是否已自包含,命中就跳过改写,把延迟省下来。