PDF表格在RAG中被拆散怎么办?表头继承、行分块与结构化检索方案
文章摘要
PDF表格进入RAG后,最常见的问题是表头与数据行分离、跨页表格断裂、合并单元格丢失,以及数字脱离业务含义。把表格简单转成纯文本再按Token切分,会让“100”“20%”“A产品”等字段失去对应关系。本文介绍表格检测、Markdown与JSON双表示、表头继承、按行分块、跨页合并、结构化字段检索和质量校验,帮助RAG正确回答参数、价格、库存和统计类问题。
一、为什么表格比普通文本更难处理
普通段落的语义主要来自阅读顺序。
表格语义来自:
行
+列
+表头
+单元格位置
+合并关系
+单位
+标题
例如:
| 产品 | 库存 | 本月销量 | 增长率 |
|---|---|---|---|
| A产品 | 100 | 20 | 10% |
| B产品 | 200 | 30 | -5% |
如果解析成:
产品 库存 本月销量 增长率 A产品 100 20 10% B产品 200 30 -5%
Embedding可能知道内容与库存有关,但模型不一定能准确判断:
- 100属于哪个产品;
- 20是销量还是库存;
- -5%对应哪一行;
- 单位是否为箱、件或万元。
二、第一步:保留表格的双重表示
推荐同时保存:
1. 面向大模型的Markdown
表名:2026年7月渠道库存统计
单位:箱
| 产品 | 库存 | 本月销量 | 增长率 |
|---|---:|---:|---:|
| A产品 | 100 | 20 | 10% |
| B产品 | 200 | 30 | -5% |
2. 面向程序的结构化JSON
{
"table_id": "T-202607-01",
"title": "2026年7月渠道库存统计",
"unit": "箱",
"headers": [
"产品",
"库存",
"本月销量",
"增长率"
],
"rows": [
{
"产品": "A产品",
"库存": 100,
"本月销量": 20,
"增长率": "10%"
}
]
}
Markdown用于上下文,JSON用于过滤、计算和校验。
三、不要把表头和数据行分开
错误Chunk:
Chunk 1:产品 库存 本月销量 增长率
Chunk 2:A产品 100 20 10%
Chunk 3:B产品 200 30 -5%
Chunk 2和Chunk 3失去了字段含义。
正确分块时,每个Chunk都继承:
表名
单位
列名
当前数据行
例如:
表名:2026年7月渠道库存统计
单位:箱
列:产品、库存、本月销量、增长率
数据:A产品、100、20、10%
四、按行分块还是整表分块
小表格
整表放入一个Chunk。
适合:
- 行数少于20;
- 列数较少;
- 总Token不超过上限;
- 用户常做横向比较。
大表格
按多行一组分块:
表头
+第1—20行
表头
+第21—40行
每个Chunk附带:
row_start
row_end
row_keys
table_id
单行实体表
如果每一行代表独立实体,可以一行一个Chunk。
例如:
- 产品参数;
- 客户列表;
- 设备清单;
- 价格表;
- 库存表。
五、横向比较问题需要保留整表视角
用户问:
哪个产品增长率最高?
如果每行单独召回,可能只召回某一行,无法比较全部数据。
解决方案:
方案一:父子Chunk
子Chunk:每行,负责召回
父Chunk:整表或表格摘要,负责比较
方案二:结构化查询
将表格同步写入数据库:
SELECT product, growth_rate
FROM channel_inventory
ORDER BY growth_rate DESC
LIMIT 1;
对于排序、聚合和计算问题,结构化查询通常比向量检索更可靠。
六、跨页表格如何合并
跨页表格常见特征:
第一页有表头
第二页只有数据行
每页重复表头
表格底部出现“续表”
合并判断可以使用:
- 列数一致;
- 表头相同或高度相似;
- 页面连续;
- 表格横向坐标接近;
- 前一页表格没有明确结束;
- 后一页标题包含“续表”。
合并后记录:
page_start
page_end
source_table_ids
merged=true
不要只根据“列数相同”自动合并,不同表格可能恰好有相同列数。
七、合并单元格怎么处理
例如:
| 区域 | 城市 | 销量 |
|---|---|---|
| 华东 | 杭州 | 100 |
| 宁波 | 80 |
第二行区域为空,但真实语义仍是华东。
需要做前向填充:
import pandas as pd
def fill_merged_cells(df: pd.DataFrame) -> pd.DataFrame:
return df.ffill()
但要谨慎:
- 空值可能是真实缺失;
- 不是所有列都应该填充;
- 汇总行不能继承上一行;
- 多级表头需要单独解析。
八、多级表头需要扁平化
原始表头:
| 产品 | 2025年 | 2026年 | ||
|---|---|---|---|---|
| 销量 | 金额 | 销量 | 金额 |
扁平化为:
产品
2025年_销量
2025年_金额
2026年_销量
2026年_金额
避免出现重复列名:
销量
金额
销量
金额
九、数字和单位必须绑定
错误内容:
销售额:120
正确内容:
销售额:120万元
统计周期:2026年7月
口径:含税开票金额
Metadata建议包含:
unit
currency
period
caliber
source_page
模型最容易在单位、百分比和时间范围上出错。
十、表格检索应该使用什么字段
表格Chunk的Embedding文本可以包含:
表名
章节路径
列名
行主键
行内容
单位
示例:
表名:产品价格表
章节:第三章 标准产品
列:产品名称、规格、建议零售价
产品名称:智能终端A
规格:标准版
建议零售价:1280元/台
不要只Embedding:
智能终端A 标准版 1280
十一、表格问题应先分类
查值
A产品库存是多少?
单行检索即可。
比较
A和B哪个销量高?
需要多行或结构化查询。
聚合
总库存是多少?
优先数据库或代码计算。
条件筛选
找出增长率低于0的产品。
优先结构化过滤。
解释
为什么华东库存偏高?
表格数据+文本证据联合RAG。
十二、不要让大模型承担精确计算
错误流程:
向量检索整张表
→ 让大模型自己求和
推荐:
识别计算意图
→ 调用SQL或Python工具
→ 得到精确结果
→ 大模型解释
RAG负责找到数据,工具负责计算。
十三、表格质量门禁
入库前检查:
表头是否为空
列名是否重复
每行列数是否一致
主键是否为空
单位是否存在
数字解析是否成功
跨页是否完整
合并单元格是否恢复
异常状态:
TABLE_VALID
TABLE_PARTIAL
TABLE_HEADER_MISSING
TABLE_COLUMN_MISMATCH
TABLE_MANUAL_REVIEW
十四、测试集要覆盖哪些问题
单元格查值
多行比较
最大值和最小值
求和
百分比
单位换算
跨页数据
多级表头
合并单元格
表格与正文联合问题
不能只测试“表里有没有这个词”。
总结
PDF表格进入RAG时,核心原则是:
不破坏行列关系
不分离表头与数据
保留单位和口径
计算问题交给结构化工具
最佳方案通常是:
Markdown用于大模型理解
+JSON或数据库用于精确查询
+父子Chunk支持召回与比较
延伸阅读
如果你正在关注企业级 AI 应用、RAG、Agent、MCP 与大模型工程化落地,欢迎访问 智元界:
https://www.zyentor.com/
智元界将持续分享可运行的技术实战、架构设计、问题排查与企业应用案例。