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/

智元界将持续分享可运行的技术实战、架构设计、问题排查与企业应用案例。