做简历问答的RAG,用bge-large-zh转向量,chunk按256字切、重叠32。测试集100道题,召回率只有62%,top5里经常混进完全不相关的内容。试过调chunk大小和重叠数,效果不明显。也试过混合检索(BM25+向量),涨了3个点但还是不理想。现在不确定是该换更强的embedding(比如gte或openai的),还是应该上rerank,或者直接改切分逻辑——比如按段落而不是固定长度切。有没有做过的朋友给点方向?另外,重排模型对中文长文档效果到底明不明显?
RAG的召回率一直上不去,是chunk切分问题还是embedding该换了?
全部回复
共 45 条说实话你这个情况我太熟了,之前做法律文书问答也是卡在召回率60%出头,折腾半天发现chunk切法比换embedding影响大得多。固定256字切对中文尤其不友好,经常把一段完整的因果逻辑拦腰截断,尤其简历里“项目经历-负责内容-取得结果”是强序列关系,切断后向量根本学不到上下文。建议你先按语义段落切,再用滑动窗口补一下段落边界,比如把每个段落的开头结尾各加20字上下文,成本低但通常能涨5-8个点。embedding我觉得bge-large其实够用,除非你的简历里专业术语特别偏门,否则换gte或openai未必有质变,但重排一定要上,尤其top5里混不相关结果的时候,bge-reranker对中文长文本的区分度比向量模型明显,我实测top5准确率能拉高10个点左右。另外你BM25+向量混合召回之后,有没有试过把分数做归一化再加权融合?直接拼接或简单加权有时候会互相干扰,用min-max归一化或者学习一个权重,可能比单纯加个检索方式涨得更多。最后想问你一句,那100道题的测试集是单跳问答还是多跳?如果答案分布在简历不同段落,那切分逻辑得改成按模块切,不然重排也救不回来。
这个情况我遇到过类似的,问题可能不在embedding本身,而是简历这种文档信息密度高、字段结构性强,固定256切分很容易把关键经历和技能拆散。建议先试试按换行符或语义段落切,简历每段相对独立,效果往往立竿见影。另外rerank对这类场景提升挺明显的,尤其top5里混入不相关内容时,它能直接压掉噪声,你可以先用bge-reranker-base跑一下看看。如果还不行再考虑换gte-large,但要先确认你的检索链路里有没有做query改写,简历问答的提问方式往往和原文表述差异很大。
说实话你这个情况我太熟了,当初做合同问答也是卡在召回率上。先别急着换embedding,bge-large在中文上没那么差,问题多半出在简历这种文档的结构性上——固定256字切分会把“工作经历”和“项目描述”硬拆开,语义被切碎了,top5里混进不相关的内容基本就是这原因。我建议你先试试按段落或按语义块切,比如用句号、换行符做边界,简历里每个bullet point其实就是一个天然单元,召回率可能直接涨5个点。如果切分改完还不行,再考虑rerank,但要注意中文长文档的rerank模型(比如bge-reranker)对长度很敏感,超过512token效果会明显衰减,得先做好截断或分段处理。至于换gte或openai的embedding,我猜提升有限,因为你目前的问题更像检索粒度不对,而不是向量空间区分度不够。另外混合检索只涨3个点很正常,BM25和向量结果重合度太高,你可以试试把BM25的权重调高,或者用RRF融合时给不同召回来源加不同系数。最后问一句,你top5里混进的不相关内容,是跟简历主题完全无关,还是跟当前问题无关?这俩排查方向完全不一样。
做过类似的简历问答,你这个情况大概率不是embedding的锅,bge-large在中文语义上够用了。建议先别急着换模型,试试按段落切分,简历结构其实挺固定的,教育经历、工作经历这种天然边界比固定长度靠谱得多。rerank我觉得值得上,尤其top5里混无关内容的时候,它能把那3-5个候选重新排准,我之前用bge-reranker-base效果挺明显,中文长文档大概能提5-8个点。另外你BM25+向量只涨3个点,可能权重没调好,试试把向量分拉高一点,或者对简历里的关键词做一下加权。
别急着换embedding,62%这个数更像是召回链路的问题而不是模型问题。你简历这种强结构化文本,固定256切分很容易把技能项和时间线拦腰截断,试试按换行或条目边界切,哪怕长度不齐都行。rerank对这类场景提升挺明显的,尤其长文档,建议先上个bge-reranker看看,成本低见效快。另外top5混入无关内容,也可能是query本身太短,比如问“五年Java经验”这种,最好先做一下意图补全再检索。