最近在做一个人社局政策咨询的 Agent,用的 LangChain + RAG。遇到一个很头疼的问题:用户第一轮问“失业金领取条件”,我检索了 A 文档回答。第二轮用户追问“那要带什么材料”,结果系统又把 A 文档里的“条件”段落重新检索出来拼进 prompt,导致回答里混入了“需缴纳满一年”这类重复信息,甚至有时会跟第一轮答案矛盾。
RAG+Agent 架构下,多轮对话中知识库检索结果总是“串味”怎么办?
全部回复
共 113 条我也遇到过类似情况,后来在检索前加了query改写,把“那要带什么材料”补全成“失业金领取需要哪些材料”,命中率明显好很多。另外可以在prompt里明确告诉模型,历史回答仅供参考,当前轮只依据新检索到的片段作答。还有个思路是把上一轮的引用片段打标,检索时做去重或降权,避免重复内容反复进上下文。
把历史检索结果摘要拼进query再检索,别直接塞原文,能缓解不少。
这个问题我也踩过坑,说白了就是多轮检索时没做 query 改写,把“那要带什么材料”这种指代型追问直接丢给向量库,肯定召回一堆上一轮的旧内容。我的做法是加一层轻量的对话状态跟踪,把追问补全成“失业金领取需要带什么材料”再检索,同时给已用过的 chunk 打个短期标记,降权或过滤掉。另外 prompt 里最好显式区分“历史结论”和“本轮新检索”,别让模型自己瞎揉。
把用户追问改写成独立query再检索,别拿历史答案硬拼,混了才怪。
这个问题我也踩过坑,本质上是每轮都拿原始query去检索,没把上下文带进去。你可以试试把上一轮的问答摘要拼进检索query里,或者用LLM先把“那要带什么材料”改写成完整问题再检索。另外检索完可以做个去重,把已经用过的段落打个标记,别重复塞进prompt。LangChain里有现成的condense question chain,可以先拿来试试看效果。
这个问题我也踩过,本质上是检索query没做改写,第二轮“要带什么材料”单独去检索,肯定还是命中上一轮的条件段落。我当时的做法是让LLM先把多轮对话压缩成一个独立的检索query,再拿去查知识库,效果会好很多。另外可以在prompt里明确标注每段检索结果的来源轮次,让模型知道哪些是历史信息、哪些是当前问题的答案,能减少串味。你们现在有没有做query改写这一步?
这个问题挺典型的,多轮 RAG 里检索 query 不能直接用用户当前那句话,得把历史对话做一下改写或者压缩。我一般会在检索前加一个 query rewrite 步骤,把“那要带什么材料”补全成“失业金领取需要哪些材料”,这样召回的段落就不一样了。另外检索结果进 prompt 前最好按轮次去重,别让上一轮的原文再塞进来。你们现在是用 LLM 做改写还是规则拼的?
可以把追问改写成独立查询再检索,别直接拿原问题拼历史,不然肯定串味。
我之前也踩过这个坑,后来发现关键是检索query没带上轮次意图,第二轮那句“要带什么材料”单独去搜肯定还是命中条件段落。可以在query改写那步加个LLM把追问补全成完整问题,比如“失业金领取需要带什么材料”,再拿去检索就准多了。另外建议给检索结果按轮次打标签,prompt里明确告诉模型哪些是历史答案、哪些是新材料,别让它自己瞎拼。
我之前也踩过这个坑,后来把追问的query和上一轮意图拼一起再检索才好转。你可以试试加个query改写步骤,让模型把“那要带什么材料”补全成“失业金领取需要带什么材料”,别直接拿原话去搜。另外检索时按对话轮次过滤一下历史命中的chunk,避免同一段反复塞进prompt。
这个问题我遇到过,核心是查询改写没做好。第二轮“那要带什么材料”是个指代性追问,直接拿原文去检索肯定召回上一轮的旧内容。建议在检索前加个query rewrite步骤,把历史对话压缩成独立问题,比如改写成“失业金领取需要哪些材料”,再拿去检索。另外可以给检索结果加个时间戳或轮次标记,让模型知道哪些是当前轮的新信息,避免它把两轮内容混着说。
这问题我也踩过,本质上是每轮都拿完整query去检索,没做上下文改写。你可以试试让LLM先把“那要带什么材料”补全成“失业金领取需要带什么材料”,再去检索,命中率会高很多。另外检索结果别直接全塞进prompt,按轮次做个去重或者只保留跟当前意图最相关的段落。我后来还加了个小逻辑,把上一轮用过的chunk打个标记,重复的直接降权,串味基本就没了。
这个问题其实挺典型的,我前段时间做工会政策问答时也踩过一模一样的坑。核心原因是你把每轮检索都当成了独立query,但用户说“那要带什么材料”时,这句话本身几乎没有语义信号,向量检索当然会漂回上一轮的主题。我后来是在query改写上加了对话历史摘要,让模型先把“那要带什么材料”补全成“失业金领取需要哪些材料”,检索命中率一下就上来了。另外你可以试试给检索结果加个时间戳或者轮次标记,prompt里明确告诉模型哪些是当前轮新检索的、哪些是历史上下文,别让它把旧文档段落当新证据用。还有个更狠的办法是做检索结果去重,同一文档的相似段落如果上一轮已经用过,这轮就降权或者直接过滤掉。不过话说回来,如果政策文档本身就把条件和材料写在同一段里,那可能得在切分粒度上再下功夫,按问答对或者条款级别切会更干净。你们现在用的什么embedding模型?有些模型对中文政策文本的短query效果确实一般。