最近在搭一个基于RAG的文档问答系统,主要处理公司内部的PDF报告。目前用的langchain+chroma+openai embedding,分块策略是recursive split。但发现一个问题:只要文档里有表格或者图表,问答的时候模型就经常说“找不到相关信息”,明明表格里就是答案所在。感觉是分块时把表格内容切碎了,或者embedding时没有保留结构信息。请教各位大佬,有没有处理PDF中表格和图表的成熟思路?比如用多模态模型先把图转成文本描述,或者用OCR工具单独提取?希望不增加太多推理延迟。
RAG做PDF问答时,表格和图表内容总丢,有什么好办法?
全部回复
共 131 条这问题太典型了,recursive split对表格基本就是灾难,它按字符硬切,表头和数据行很容易被拆散,embedding的时候语义就全丢了。我之前试过先检测PDF里的表格区域,用camelot或者pdfplumber单独抽出来转成markdown格式,再作为一个独立chunk塞进库里,效果比直接切文本好不少。但图表又是另一回事,纯文本方案搞不定,得走多模态路线,比如把图截下来扔给GPT-4V或Qwen-VL生成结构化描述,再跟原图一起存,问答时优先检索描述文本。不过你说的延迟问题确实存在,如果每页都调视觉模型会很慢,我现在的做法是只在检测到图片或复杂表格时才触发OCR+描述,普通文本段落走原流程,这样能控制住大部分场景的耗时。还有个坑是表格转成文本后,如果数字多,openai embedding本身对密集数值的区分度就不够,你可能得混合关键词检索兜底,比如先用BM25召回候选段,再让LLM判断,比纯向量靠谱。你们公司报告里表格占比大概多少?如果特别多,可能还得考虑把表头信息和行数据单独存成结构化格式,问答时用代码解释器动态查。
试试把表格转成markdown再切块,图表用多模态模型生成摘要单独存,问答时合并检索,延迟可控。
表格确实容易在recursive split里被拦腰截断,我试过把chunk_size调大一点,配合pdfplumber先按表格区域提取,再单独喂给embedding,效果比直接切文本好不少。图表的话,如果不想上多模态模型,可以用现成的OCR工具把图里的关键数字和标题抽出来拼成一段描述,但速度会慢一些,得看你对延迟的容忍度。另外你用的是openai embedding,考虑过先把表格转成markdown格式再分块吗?结构保留得会好一点。
试试表格转成markdown再入库,检索效果比纯文本好不少,图表就上多模态描述吧。
表格这块我踩过类似的坑,后来改成先用unstructured把表格单独抽出来,转成markdown再单独入库,效果好了不少。图表的话确实麻烦,我试过用gpt-4o做图转文字描述,但延迟和成本都上去了。现在折中方案是表格走结构化提取,图表只对含关键词的页做多模态处理。你们内部报告图表多吗,如果不多其实可以人工补一下描述。
表格这块我也踩过坑,recursive split对纯文本还行,遇到表格基本就是灾难,它按字符数硬切,一行数据能给你劈成两半,embedding出来的向量根本没意义。我后来改成先把PDF用unstructured或者camelot把表格单独抽出来,转成markdown格式再塞进chunk里,效果好了不少。图片的话如果预算够,确实可以上GPT-4V或者Qwen-VL做一步描述生成,但延迟确实会涨,我一般只对检测到有图表的页面做这个处理,不是全量跑。还有个思路是用layout-aware的解析工具,比如pymupdf配合版面分析,先把表格和正文分开再分别入库。另外你检索的时候可以试试混合检索,BM25对表格里的数字和关键词其实挺敏感的,纯向量反而容易漏。不过说实话表格问答想做到很稳,最后还是得靠结构化抽取加SQL查询那条路,纯RAG硬扛还是有点吃力。
表格和图表丢失这个问题我踩过一模一样的坑,recursive split对纯文本友好,但遇到表格基本就是灾难,它按字符数硬切,一个跨页表格能给你切成三四段,检索时哪段都凑不出完整语义。后来我的做法是在分块之前先做一次版面分析,用类似unstructured或者pymupdf的layout检测把表格区域单独框出来,表格走结构化提取,比如转成markdown或者html保留行列关系,再单独存成一个chunk,这样embedding时行列表头信息还在。图表的话确实得上多模态,我用gpt-4o-mini把图转成一段描述文本,连同图注一起塞进chunk,延迟增加其实还好,因为只在离线建库阶段跑一次,不在查询链路上。有个细节是表格chunk最好加个元数据标记类型,检索时可以给这类chunk加权或者单独走一路召回,不然容易被大段正文淹没。另外你可以试试在prompt里把原始表格的markdown直接喂给模型,比让它从碎文本里猜靠谱得多。
表格建议单独用unstructured提取再嵌入,别跟正文混着切,不然结构全丢了。
表格建议单独走OCR或layout解析再合入chunk,别跟正文混着切,效果会好很多。
这块确实头疼,我之前也踩过坑。后来是把表格单独抽出来转成markdown再喂给模型,图表就用gpt-4o生成描述文本拼回原文,效果好了不少。不过多模态那一步延迟确实上来了,建议只对含图表的页做处理,别全量跑。另外chunk的时候可以按版面结构切,别纯按字数,不然表格必碎。
我之前也遇到过类似问题,后来换了方案。