最近在做一个企业内部知识库的问答系统,用了Milvus+OpenAI的embedding模型(text-embedding-3-small),数据是几千篇技术文档。按说向量检索应该比关键词搜索更智能,但实际测试发现,很多用户问“打印机卡纸怎么办”,向量检索出来的结果反而没有Elasticsearch直接搜“卡纸”来得准。我怀疑是不是我分块策略有问题,目前是按段落切分,每个块512 token,有没有大佬指点一下?或者是不是embedding模型对中文长尾问题支持不够好?
向量数据库做RAG时,为什么检索准确率还不如直接用关键词搜索?
全部回复
共 132 条你这情况我也踩过坑,512 token对技术文档来说太长了,很多关键信息被稀释了,试试按标题或语义段落切,块越小越精准。另外embedding对中文里的具体故障词确实不敏感,“卡纸”这种强信号词,向量反而抓不住重点,混合检索加个BM25权重会好很多。还有个思路,把用户问题先做实体抽取再拿去匹配,比直接裸向量靠谱。
试试把512token改小到256甚至128,按标题和语义段落切,别死磕embedding,先看召回再调重排。
这问题我调过一阵子,其实不是embedding不够好,而是512token的段落对技术文档太长了,一个段落里可能混了故障现象、原因、解决步骤好几层意思,向量平均完就糊了。建议先按标题或者小节切,实在不行用滑动窗口重叠切,我这边切成128token后效果明显提升。至于关键词搜索,它本质是精确匹配,你文档里正好有“卡纸”这个字眼当然占便宜,向量检索强在语义泛化但最怕query本身信息量太碎。另外你可以试试过滤掉停用词再加权重,或者用BM25和向量结果做RAG融合,别指望单一召回吃遍天。
你这情况我也踩过坑,问题八成出在分块和query意图的错位上。“打印机卡纸”这种故障类问题,关键词本身信息密度极高,而512token的段落会把很多无关上下文卷进向量里,反而稀释了核心语义。建议试试把分块缩小到128-256token,或者干脆按句子切,再配合BM25做混合检索,用RRF融合排序,效果一般会立竿见影。另外text-embedding-3-small对中文专有名词和短指令确实偏弱,有条件可以换bge-m3或试下重排序模型。
说实话你这个现象挺典型的,向量检索擅长语义相似但有时候会忽略精确的关键词匹配,而“卡纸”这种词本身就是强信号,ES直接命中反而更合理。分块策略我觉得可以试试按标题和章节来切,别死守512token,另外中文场景下可以考虑混合检索,把BM25和向量结果做个rerank,效果通常会有明显提升。至于text-embedding-3-small,它对中文长尾词确实有点弱,有条件可以换bge或m3e这类中文优化模型对比一下。
512 token切太碎了,试试按语义切块,另外纯向量确实容易丢关键词,混合检索效果会好很多。
你这个情况挺常见的,我一开始用RAG也踩过类似的坑。text-embedding-3-small对中文短查询其实还行,但512token整段切分容易把关键信息稀释掉,尤其技术文档里“卡纸”这种词可能只占一两句,embedding反而被大段无关内容带偏了。你可以试试按语义或标题层级做小块切分,再配合BM25做混合检索,很多场景下效果比纯向量好不少。另外几千篇文档不算多,先别急着换模型,调分块和加关键词召回可能就够用了。
512切分确实容易把关键词上下文切散,试试小块加重叠,再把ES和向量做混合检索,效果会好很多。
我踩过一模一样的坑,几千篇文档场景下关键词搜索有时确实能打。后来发现512token按段落切,经常把“卡纸”这种关键词和它所在的操作步骤切散了,向量反而抓不到重点。可以试试把块切小一点,比如256,再带点overlap,另外在检索后面加个BM25混合排序,效果会稳很多。text-embedding-3-small对中文长尾确实一般,换成bge-m3或者加个query改写可能也有帮助。
分块太大确实容易稀释语义,512 token对短问题偏长了,先试试256带重叠看看效果。
这个问题我踩过类似的坑,后来发现很多时候不是向量检索不行,而是混合检索才是正解。你试试BM25加向量召回做个RRF融合,卡纸这种关键词明确的query交给关键词通道,语义模糊的长问题再靠向量兜底。另外512 token按段落切对中文技术文档其实偏碎了,上下文一断embedding抓不住重点,可以试试按标题层级做父子块。text-embedding-3-small中文确实一般,换成bge-m3或者qwen的embedding你会看到明显差别。
这个现象挺常见的,别急着怀疑embedding模型。text-embedding-3-small对中文短查询确实偏弱,但更关键的是你拿短query去匹配512token的长块,语义向量容易被稀释,关键词信号反而被淹没了。我之前也踩过这坑,后来改成小块(128-256token)+重叠窗口,再加上用Elasticsearch做混合检索,BM25和向量分数加权融合,卡纸这种具体问题召回立马就上来了。另外可以在query侧做点手脚,比如把用户问题先扩写成一句完整描述再embedding,效果也会好不少。