最近在搭一个本地知识库问答,用的bge-large-zh-v1.5做embedding,chunk切了512,检索出来的top5相关度看着还行,但生成答案时总感觉上下文衔接不上,尤其涉及多轮对话时,历史信息一多,召回就开始飘。也试过m3e,但感觉对长尾实体名和口语化表述不太友好。想问问大家,开源的embedding模型里,有没有在中文长文本和query改写上表现更稳的?还是说问题出在chunk策略或rerank环节?求指个方向,不想一上来就上付费API。
RAG用开源模型做embedding,中文效果总差口气,有更好的方案吗?
全部回复
共 28 条我怀疑问题更多出在切分和上下文拼接上,512的chunk对多轮对话确实容易把历史信息割碎。可以试试先上bge-reranker对召回结果重排,再拿gte-large-zh或者acge-text-embedding对比一下,中文长尾实体上后者有时更稳。另外多轮场景建议把历史query做一次改写再检索,不然embedding很容易被无关历史带偏。付费API不急着上,先把rerank和query改写这两步补起来,效果通常比换embedding明显。
先别急着换embedding,多轮飘多半是chunk和rerank的锅,加个bge-reranker试试。
bge-large-zh对纯中文短query确实还行,但多轮对话里历史一长,它那个512的窗口就开始丢信息了,召回飘很正常。你可以先试试换成bge-m3,它支持8k上下文,还能同时出稀疏和稠密向量,对长尾实体比m3e稳不少。不过我觉得你问题可能更多在rerank上,top5看着相关不代表排序对,加个bge-reranker-v2-m3重排一下,成本低见效快。另外多轮场景建议把历史做query改写再检索,别直接拿原始对话去搜。
先加个rerank试试,bge-reranker对中文长尾提升挺明显,比换embedding划算。
先别急着换模型,我觉得是chunk和rerank的锅,加个bge-reranker试试,多轮对话得单独处理历史query改写。
你这个问题大概率不在embedding模型本身,bge-large-zh-v1.5在中文里已经算能打的了。多轮对话历史一多召回就飘,八成是query拼接方式的问题——把历史对话原封不动塞进去检索,噪声会稀释掉当前query的语义。建议先把历史做摘要或者只用最近一两轮改写query,再单独试下bge-reranker-v2-m3加个精排,top5里能捞回来的东西会干净不少。chunk 512对问答类其实偏大,长尾实体容易被淹没,可以试试256带重叠切。真要换模型的话,gte-Qwen2或者conan-embedding值得试,但先调检索链路收益更大。
bge-large-zh确实在短查询上还行,但一到多轮对话历史堆长了就容易飘,你描述的这个情况我太熟了。建议先别急着换模型,把rerank加回来试试,bge-reranker-v2-m3对中文长尾实体提升挺明显的,成本也不高。另外chunk 512可能偏大,多轮场景下历史query最好做一下改写压缩再检索,不然噪声太多。如果还不行可以看看gte-Qwen2或者conan-embedding,中文长文本比bge稳一些。
bge-large-zh对长文本确实有点吃力,你试试把chunk降到256再配个滑窗重叠,召回会稳不少。多轮对话飘的问题不一定是embedding的锅,query改写没做好的话历史信息反而会稀释当前意图,可以先加个轻量的改写步骤。另外rerank真的别省,用bge-reranker-base跑一遍top20再截top5,体感提升比换模型明显。真要换embedding可以看看gte-large-zh或者acge,长尾实体的表现比m3e好一些。