最近在做一个基于RAG的客服Agent,发现多轮对话场景下效果很差。比如用户先问“退换货政策是什么”,我检索到了相关文档;接着用户问“那运费谁出”,这时候检索就完全跑偏了,召回的都是不相关的物流文档。我试过把上一轮的检索结果拼到当前query里,结果又引入了噪音,模型开始答非所问。想请教一下大家,多轮RAG到底该怎么处理历史上下文和检索的关系?是每轮都重新检索,还是维护一个对话级的向量摘要?有没有比较成熟的做法?
楼主
2天前
RAG做多轮对话时,历史检索结果要不要拼进下一次query里?
请 登录 后发表回复
全部回复
共 3 条
2楼
1天前
这个问题我也踩过坑,后来发现关键不是拼不拼历史检索结果,而是得先把“那运费谁出”这种指代消解成完整query再检索。我现在的做法是用一轮轻量LLM把当前问题结合上一轮query改写成一个自包含的检索query,历史检索结果只在生成阶段用,不进检索。另外召回跑偏也可能是embedding对短query本身就不友好,可以先试试query改写加多路召回再rerank。
3楼
1天前
我之前也踩过这个坑,后来发现关键不是把检索结果拼进query,而是先把用户当前这句话改写成能独立检索的query。比如“那运费谁出”可以补成“退换货场景下运费由谁承担”,这样检索就准多了。每轮重新检索是必须的,但别直接塞原始对话历史,容易把语义带偏。维护一个对话级的query改写模块比向量摘要更实在,成本也低。
4楼
1天前
这个问题我也踩过坑,后来发现关键是把“检索query改写”和“答案生成”分开处理。可以先用一个小模型把当前问题和上一轮意图合并成一个独立的检索query,比如“退换货 运费谁承担”,而不是把整段历史文档塞进去。另外每轮最好重新检索,但可以给上一轮的文档打个低权重的分,别直接拼原文。我试过维护对话级的向量摘要,效果一般,容易丢细节,不如query改写来得实在。