表格和结构化数据进 RAG:纯向量检索为什么会失效,该怎么补
数据截至 2026-07,各项目能力以官方文档当前版本为准。
表格进 RAG 检索不准,绝大多数情况不是嵌入模型不行,而是表格在切块那一步就被拆成了没有语义的碎片:一串脱离表头的数字,向量化之后本来就不该被检索到。补救的方向不是换更贵的嵌入模型,而是让表格在进入向量库之前先变成”人能读懂的一段话”,再把精确条件交给元数据过滤或者直接查数据库。
常见的误解是”表格也是文本,嵌进去就能搜”。这话只在表格很小、结构很规整的时候勉强成立。一旦表格稍微大一些,或者带合并单元格、多级表头,纯向量检索的失败率会陡增,而且失败得很隐蔽——它不会报错,只会安静地召回一堆不相关的块,让模型在错的上下文里编出一个像样的答案。这类问题排查起来比报错麻烦得多。
一、失效的三个机制,先分清是哪一个
同样是”表格搜不到”,底下的原因可能完全不同,对应的修法也不一样。实际遇到的大致是这三类。
第一类:表头和数据被切散了。 大部分默认切块策略是按字符数或者 token 数硬切,一张三十行的表被切成四五块,只有第一块带表头,后面几块就是裸的数字行。用户问”上海仓的库存是多少”,那块含”上海”的分块里可能只有 上海 | 1280 | 340 | 2026-06,模型和嵌入模型都不知道 1280 是库存还是在途。这类问题最好识别:把召回的原文打印出来看一眼就明白了。
第二类:数值本身不带语义。 嵌入模型是按语义相似度工作的,而”1280”和”1290”在语义空间里几乎没有区别,“营收增长 12%“和”营收下滑 12%“的向量距离也远比你直觉中要近。指望向量检索去做”找出毛利率高于 30% 的产品”这种筛选,方向上就是错的——这是数据库该干的活,不是相似度该干的活。
第三类:表格根本没被正确解析出来。 扫描版 PDF、跨页表格、带合并单元格的 Excel 导出件,很多传统文本解析器直接把版面读串行,输出的是一堆错位的字符串。这时候后面无论切块多讲究、嵌入模型多强都救不回来,因为源头的数据已经错了。解析层的坑单独展开可以写一篇,这里只强调一点:先把解析结果落盘看一眼,再谈检索调优。相关排查思路可以参考RAG 解析瓶颈怎么排查。
判断顺序建议倒着来:先看解析对不对,再看切块散没散,最后才怀疑嵌入和检索策略。反过来查会浪费大量时间。
二、先给你的”结构化数据”分类
很多人把三种性质完全不同的东西统称”表格”,然后期待用同一套 RAG 流程处理,结果哪个都不好使。按处理路径分,至少要区分下面三种。
- 文档里的表格:财报附表、产品参数对照表、合同里的费用清单。它们的价值在于”和上下文一起被理解”,需要留在文档里,走 RAG 路线。
- 半结构化的记录集:CSV 导出的工单列表、订单明细、日志表。行与行之间独立,字段固定,查询意图往往是筛选和聚合。
- 真正的业务数据库表:还在线上的 MySQL、数仓里的宽表。数据在变,量级也大。
这三类里,只有第一类适合原样进向量库;第二类要拆成”一行一块 + 元数据”;第三类根本不该做嵌入,应该让模型去生成查询语句直接查库。把第三类硬塞进 RAG,是我见过最常见也最费钱的一种错配——嵌入费花掉了,数据还是隔夜的。
三、路线一:解析阶段就把结构保住
如果语料是版式复杂的 PDF、扫描件、财报或者法律文书,解析层的选择比检索层重要得多。这类语料的处理思路是让解析器理解版面,而不是把页面当成一条字符流。
面向深度文档理解的开源 RAG 引擎在这方面有针对性设计,比如 RAGFlow 的分块会尊重文档本身的结构,并带版面感知的解析能力,在多篇第三方对比里,常被归为扫描版 PDF、财报、版式复杂法律文书这类语料的典型适用方案,同时内置知识图谱构建。LlamaIndex 一侧则以数据摄取和索引为重心,配套的解析服务同样常被用在这个环节。具体能力边界以各自官方文档当前版本为准,不要照搬几个月前的教程。
落地时有两个动作值得固定下来:
- 把解析产物存成中间格式再入库,比如把每张表转成 Markdown 表格或者 HTML 片段单独存一份。这样解析出错时能直接看到,也方便重跑检索而不重跑解析。
- 给表格块打上”这是表格”的标记,后续检索、重排、提示词组装都能根据这个标记走不同分支。
自托管这条路上,RAGFlow 走 Docker 部署,镜像分 slim 和 full 两种,slim 约 2GB、full 约 9GB,区别在于是否内置嵌入模型。如果你已经有独立的嵌入服务,slim 镜像能省不少拉取时间和磁盘;如果是内网离线环境、外部嵌入服务调不通,full 更省事。
四、路线二:给表格块补一段自然语言摘要
这是性价比最高的一招,也是最容易被跳过的一招。做法很简单:切块的时候,不要只把表格原文丢进去,而是给每一块补一段描述性文字,一起嵌入。
具体有三种粒度,按语料特点挑:
- 整表摘要:适合行数不多、整体表达一个结论的表。在块的开头加一句”下表为 2026 年上半年各区域仓库的库存与在途数量,字段包括区域、现货库存、在途数量、统计日期”。这一句话让整块从”数字堆”变成了可检索的语义单元。
- 行级展开:适合记录集类数据。把
上海 | 1280 | 340 | 2026-06展开成”上海仓在 2026 年 6 月的现货库存为 1280,在途数量为 340”。字数会膨胀,但召回准确率的提升通常值这个成本。 - 表头复制:最省事的兜底做法。切块时强制让每一块都带上完整表头,哪怕重复。这一招不解决数值无语义的问题,但至少能解决表头丢失的问题。
三种可以叠加用。摘要文本可以用规则模板生成,不必上模型——模板拼接又快又稳,只有在表结构千奇百怪、模板写不过来的时候才考虑用小模型批量生成摘要,而且要抽样人工核一遍,模型看错表头是常事。
另外提醒一句:摘要是给检索用的,原始表格要原样保留在块的元数据或者正文里,最终喂给模型的应该是原表,不是摘要。只喂摘要会丢精度,模型算出来的数经不起对。
五、路线三:精确条件交给元数据过滤
“2026 年第二季度""华东区""金额大于一万”这类条件,本质是过滤而不是相似度匹配。硬让向量检索去承担这部分,就是在为难它。
正确的拆法是:把查询里的结构化条件抽出来做过滤,剩下的语义部分才走向量。实现上依赖向量库的过滤能力,Qdrant 是这个场景里常见的搭配,它支持条件过滤、payload 索引与量化;第三方资料称其在百万级以上向量规模下可以做到 50 毫秒以内的检索,这是第三方口径,实际表现取决于你的硬件、索引参数和过滤条件复杂度,上线前自己压一遍。
工程上需要注意的点有四个:
- 元数据字段要在写入时就规范化。日期统一成 ISO 格式,区域名统一成一套枚举,不要一半”华东”一半”华东区”。写入时省下的事,查询时会加倍还回来。
- 给高频过滤字段建索引。不建索引的过滤在数据量上来后会明显变慢,很多”向量库慢”的抱怨其实是过滤没走索引。
- 过滤条件要从用户问题里抽取,可以用一个小模型做结构化抽取,输出 JSON,再翻译成向量库的过滤语法。这一步的错误率要单独监控,抽错条件会导致召回直接为空。
- 准备好过滤为空时的兜底:条件过严导致召回零条时,要么放宽过滤重试,要么明确告诉用户没有匹配数据,不要静默降级成全库检索,那样答案会离题很远。
关于混合检索和重排怎么配合过滤使用,可以延伸看RAG 混合检索怎么做和重排模型到底有没有必要。
六、路线四:能查库的就别做嵌入
如果数据本来就在数据库里,而且还在持续更新,那么把它导出来做嵌入这条路从一开始就不划算:数据一变就得重建索引,聚合类问题(求和、计数、排名)向量检索本来也答不了。
更合适的做法是让模型生成查询语句去直接查库,RAG 只负责检索”表结构说明、字段含义、业务口径定义”这类文档,把这些作为上下文喂给模型,帮它把 SQL 写对。也就是说,RAG 检索的是元数据文档,不是数据本身。
这条路线自己也有坑,实事求是地说:生成的 SQL 可能语法对但口径错,必须限制只读账号、限制可访问的表、给查询加超时和行数上限。复杂多表关联的准确率通常不理想,稳妥的做法是把常用查询封装成参数化的函数交给模型调用,而不是让它自由拼 SQL。
七、选框架:按瓶颈选,不按热度选
工具选型上最常见的错误是按 GitHub 热度排队试。截至 2026 年 1 月的第三方统计,GitHub star 数大致是 LangChain 约 12.5 万、Dify 约 11.4 万、RAGFlow 约 7 万、LlamaIndex 约 4.65 万、Haystack 约 2.4 万。这个数只反映关注度,跟你的场景合不合适没有必然关系——表格场景里排名靠后的工具反而可能更对路。
按瓶颈定位更实用:
- 瓶颈在解析(烂 PDF、复杂表格、扫描件):从 LlamaIndex 的解析能力或者 RAGFlow 入手。
- 瓶颈在检索(嵌入、混合检索、重排的调参空间):LangChain、Haystack 这类可调旋钮更多。
- 瓶颈在评估(说不清改动到底有没有变好):在现有框架上加挂 RAGAS,别为了评估换框架。
- 语料是有链接关系的结构化内容:考虑图检索路线,RAGFlow 内置的知识图谱构建可以作为起点。
还有一点值得知道:有第三方评测指出,LangChain 的 LCEL 语法虽然能做复杂的查询重写,但相比 LlamaIndex 的直接检索会多出约 15% 到 20% 的延迟开销。这是第三方基准口径、不是官方指标,不同版本和不同链路结构下差异会很大,只能当作”抽象层是有成本的”这个方向性提示,不要拿来当选型的唯一依据。
最后,这些框架并不互斥。生产环境里常见的组合是用 LlamaIndex 做摄取与索引、LangChain 做编排、LangGraph 承担 agent 工作流。表格场景同理,解析用一个、检索用另一个完全正常,不必强求单一技术栈。更细的搭配思路见RAG 框架怎么选。
八、诚实说局限
上面四条路线能解决大部分问题,但有几件事要提前说清楚,免得期待过高。
一是跨表推理仍然很难。需要同时看三张表、做多步计算才能得出的答案,靠检索加提示词很难稳定做对,这类需求更适合走”查库 + 代码执行”的路子,让模型写计算逻辑而不是心算。
二是摘要生成本身有成本。行级展开会让入库文本量成倍增长,嵌入费用和存储都会上去,量大的时候要先算一笔账再决定粒度。
三是没有一劳永逸的通用配置。表格的形态差异极大,财报表、参数表、工单表需要的处理策略并不一样,多数团队最后都会针对自己的主力语料做一套专用的预处理,通用方案只能作为起点。
四是评估必须先建起来。表格类问题的答案通常可以精确校验(数字对不对),所以务必先攒一批带标准答案的测试问题,改一版跑一遍。没有这个基线的话,所有优化都是凭感觉,很容易改了半天其实是负优化。
小结
表格在 RAG 里失效,先查解析、再查切块、最后才查检索策略,顺序倒过来会白费很多力气。真正有效的动作是让表格在嵌入之前带上人能读懂的语义,把精确筛选条件交给元数据过滤,把还在变的业务数据留在数据库里查。框架按瓶颈选,解析型和检索型工具各有擅长,混搭是常态而不是妥协。最后别忘了先把评估基线建起来——表格问题的对错是可以精确判定的,这是它相比开放问答难得的优势,用好了能省下大量试错时间。