最近在做一个基于公司内部文档的问答机器人,用的LangChain + OpenAI embedding + Chroma。文档是PDF和Word混合的,有的表格很长,有的段落特别碎。我自己感觉chunk_size调到500,overlap设50已经挺合理了,但检索出来的top-5总有一半是无关内容,甚至有时候问“报销流程”,返回的是“差旅标准”这种沾边但不对的段落。
RAG系统检索结果总是不准,是我chunk切得不对还是embedding模型该换?
全部回复
共 3 条说实话你这个现象我太熟了,之前调内部知识库也卡在这。500/50这个参数对普通文本可能凑合,但PDF表格和碎段落混着来的时候,纯按字符切分很容易把表格的语义拆散,或者把碎段落里本该连着的上下文硬生生隔开,检索出来自然就串味了。我后来改成按文档结构切,表格单独提取成markdown,段落按标题层级聚合,效果立竿见影。另外embedding模型倒不急着换,OpenAI那个对中文长尾语义本来就一般,你先试试把query和chunk都做一下关键词扩展,或者用HyDE先生成个假设答案再去检索,能救回来不少。你那个“报销流程”返“差旅标准”的情况,我猜是chunk里都提到了“费用”这类共性词,向量距离拉不开,可以尝试给每个chunk加个摘要前缀,把核心实体和意图显式写进去,检索相关性会明显提升。你现在的知识库大概有多少条chunk?如果几千条以内,换个bge-m3或者text-embedding-3-small对比下top-5命中率,成本也不高。
我之前也踩过这个坑,后来发现问题不一定在chunk大小,而是表格和碎段落混一起时,语义边界根本没切开。你试试按文档结构先做层级拆分,比如表格单独提取成csv再灌进去,效果会比统一500字好很多。另外OpenAI embedding对长文本确实容易“跑偏”,有条件的话可以对比下bge-m3或者cohere的embed模型,同样数据下top-5准确率差别挺明显的。你现在的chunk策略是全局统一,还是说针对不同板块有单独调过?
我之前也踩过这个坑,建议先别急着换embedding,试试按文档结构切chunk,表格和长段落单独处理,比固定500字靠谱多了。另外top-5里混进差旅标准这种,很可能是overlap太小加上向量检索本身只认语义近似,你可以加个reranker或者用关键词过滤强制约束一下。要是改完还不行,再考虑换bge-m3这类中文embedding,效果比openai的默认模型在内部文档上通常好不少。