最近在做一个企业内部的问答机器人,知识库是几千篇PDF和Word,切片用的固定500字+50字重叠,向量用的bge-large-zh。现在的问题是,用户问一个具体问题,召回的top20文档里往往只有两三条是真正相关的,而且很多都是同一段内容被不同切片重复覆盖。我试着加了bge-reranker重排序,但感觉提升有限,还经常把一些背景信息排到前面去。我想问下大家,这种场景是应该先做文档级的过滤(比如用标题或章节做粗筛),还是直接改切片策略?另外有没有什么好用的query改写技巧,能减少这种“关键词飘”的情况?求有经验的大佬指点一下,调了一周有点崩溃了。
RAG召回文档太多太碎,重排序后效果还是不行,怎么调?
全部回复
共 42 条切片500字对长文档确实太粗暴了,很多章节信息被截断,重排序自然容易把背景段落捞上来。建议先按文档标题和一级标题做段落级切分,每个切片尽量保持语义完整,再配合50字重叠去重。query改写可以试试把问句里的核心实体和意图拆开,比如“XX流程违规怎么处理”拆成“XX流程 违规 处理办法”,用大模型生成几个变体去检索效果会稳很多。另外top20太宽了,先粗筛到50个文档再用reranker精排,然后只取前5个切片喂给大模型,能减少不少噪声。
说实话你这个情况我太理解了,调一周真的会崩溃。我感觉你现在的问题核心不在reranker,而是切片粒度跟文档结构完全脱节了,固定500字硬切PDF很容易把逻辑上独立的章节拆得稀碎,重复覆盖又让向量空间里同一段话占了太多位置,召回的多样性自然就差了。我建议你先别急着改query,试着用文档自带的标题层级或者段落边界做切分,哪怕每个切片长一点(800-1000字)都行,先保证每个切片是个完整语义单元,这样bge-reranker才有东西可排。另外你说的“背景信息排前面”我也遇到过,这通常是reranker对长文档的全局相关性判断偏弱,你可以试试在重排序前加一道基于关键词密度的粗筛,比如把标题和首段单独抽出来做一次BM25过滤,只保留明显跟query实体相关的文档再进向量检索,能去掉不少干扰。query改写的话,别用太复杂的技巧,先试下把问句里的核心名词短语提取出来,配合同义词扩展(比如“报销流程”扩成“报销审批/财务流程”),比什么LLM改写稳定得多。还有个土办法,你可以在切片时给每个切片带上文档标题和一级章节名作为元数据,检索后按这个元数据做聚合去重,再选每个文档里得分最高的那一段进reranker,这样能避免重复覆盖的垃圾切片霸榜。我上次从固定切片换成结构感知切片后,top5命中率直接从30%涨到快60%,你可以试试看。