• 欢迎关注我的微信公众号“ Falost ” 右边扫描关注 --->>

多模态 RAG 实测(五):把检索从页下沉到表——内容题 Recall@5 涨 4 个点,坐标题仍是 0

AI / 大模型 神棍 130℃ 0评论

上篇留下的尾巴

上篇我把表格通道做成了结构化入库:转写直出 headers + rows,坐标题不再让模型数格子,改成程序按下标取值,干净表上从 8.3% 回到 100%。但上篇有一节数字很难看——检索层:cell 类查询的 Recall@5 是 0.0,col_lookup 只有 0.5641。原因不复杂:页面级检索器只认识整页正文,它不知道表在哪一行,更不知道你要的是哪张表。

这篇我把检索从页下沉到表和行:文本通道先定位候选页,再用表头和行文本做表级检索,答题只带命中的那一张表。同一批 121 道题,剔掉上篇发现的 45 道废题,剩 76 道重跑。

读完你能拿到:表级索引的写法、一条两段式检索链路,以及我撞到的硬边界——坐标题在检索层没有词面信号。

一、口径先说清楚,不然没法比

  • 语料:247 页真实截图(GitHub 仓库页、arXiv、文档站、我自己的博客),走路线 A 图转文。v2 提示词抽出 384 张表、6539 个单元格,落 SQLite 三层表 page/tbl/cell,对 (header, value) 建索引。
  • 题:121 道六种问法——flat 行内查找 43、col_lookup 列锚定 39、cell 行列定位 23、header 值→列名 13、colmax 2、rowmax 1。
  • Gold 表:我重跑出题脚本,记下每道题来自哪张 DOM 表,再按单元格重叠度映射到抽取结果:121 道逐条一致,114 道能定位到唯一 Gold 表。
  • 指标:表级 Recall@5。注意候选池——表级是 384 张表,随机命中期望 5/384 = 1.3%,比页级的 5/247 = 2.0% 更吃亏。

二、表级索引就三行代码

一张表当一个文档,doc = 表头 + 全部行文本,拼成一条:

def tdoc(t, mode="full"):
    head = " | ".join(t["head"])                      # 表头
    body = " ".join(" ".join(r) for r in t["rows"])   # 全部行文本
    if mode == "head":  return head
    if mode == "rows":  return body
    return head + " " + body

切词还是前几篇那个零依赖配方:中文拆单字加相邻二元组,ASCII 按词切,跑纯 Python BM25(k1=1.5,b=0.75)。索引在本地,不花钱。

两段式检索就是在表级搜索上加一层页面白名单:

pages = page_index.search(q, k=10)     # 第一段:文本通道定位候选页
allow = {pos[k] for k in tbl_keys if page_of[k] in set(pages)}
score = tbl_index.search(q, k=500)     # 第二段:表级 BM25
top5  = [i for i in score if i in allow][:5]   # 只在候选页的表里取

三、内容题涨了,值→列名涨得最狠

子集 n 页级 R@5 表级平坦 R@5 两段式 R@5
全部 121 道 121 0.5041 0.5965 0.5702
剔废题 76 道 76 0.8026 0.8421 0.8553

干净 76 道上,页级 0.8026 → 表级 0.8421 → 两段式 0.8553。涨得最狠的是值→列名(header):页级 0.7692,表级 1.0000——页面级检索很难从正文认出”某个值属于哪一列”,而表级文档里表头就在第一位。

全量 121 道上表级平坦(0.5965)反而比两段式(0.5702)高:废题的题源表本身是坏的,页级检索偶尔能蒙对页。后面的结论都只看 76 道干净题。

四、表头才是那张表的身份证

同一套索引,把 doc 里的表头去掉、只留行文本,干净子集从 0.8421 掉到 0.6974,14.5 个点。

原因很直白:行文本里全是数字和短名词,”5″”1.00″”0.0000″ 这类值 384 张表里到处都是,idf 接近 0;能区分的”版式””具体风险”全在表头里。我原本想只塞行文本省 token,实测被打回来了。

五、两段式的账:表级几乎不丢

看条件命中率:Gold 表所在页只要进了页面 top-10,表级检索 65/65 全中。而 Gold 页进 top-5 只有 61/114、进 top-10 只有 65/114(0.5702)。

也就是表级几乎没有损失,召回瓶颈全在页面。要继续优化该动页面检索,不是继续调表级参数。

六、坐标题在检索层是空白

12 道干净坐标题:页级 Recall@5 是 0.0,表级平坦 0.0,两段式 0.1667。

为什么?题面长这样:”这个表格去掉表头后,第 2 行、第 7 列的单元格内容是什么?”我在 384 张表的语料上数了一遍它能命中的词:数字 2 出现在 101 张表、”后” 84 张、数字 7 出现 73 张、”的” 44 张——idf 全趋零,BM25 排出来的名次等于随机。

那 0.1667 是哪来的?两段式里页内表级能到 11/12,但 12 道题里有 7 道落在只有一张表的页面上,选谁都对。这是白捡的,不是排出来的。

所以不是表级检索不行,是问法里没有可检索的内容。坐标题得走”表身份”这条别的路径:上游把”第 2 行第 7 列”翻译成内容描述,或保留上篇”整页 + 主表”的启发式,或依赖会话里已确定的那一页。

七、答题层:只带命中的表够不够

链路 121 道 剔废题 76 道
G_page 上篇 C 链路(带整页所有表) 0.8430 0.9868
O_table 只带 Gold 表(表检索上界) 0.8099 0.9737
R1_table 平坦表级 top-1 0.5124 0.7632
R2_table 两段式 top-1 0.4876 0.7632

第一,只带命中的那一张表,和带整页所有表几乎打平:干净子集 0.9737 对 0.9868,差的那一道是”值→列名”拿错表。而 prompt token 从 409.8 降到 257.9,少 37%——准确率打平、上下文少三成,那就带一张。

第二,端到端(页和表都靠检索)掉到 0.7632。76 道里 18 道失分:16 道拿错表、2 道表对答错。拿错表的 16 道 = 12 道坐标题 + 4 道”值→列名”——后者 Gold 表其实在 top-5 里,是我只喂 top-1 才丢的。

八、能交给程序就别交给模型

顺手试了个更省的路子:”值「X」属于哪一列”这类题,答案本来就在 (header, value) 索引里,不用检索也不用模型:全局索引直答 13/13。

把六种问法都写成解析器加索引直答:76 道里 64 道(84.2%)零模型、零检索搞定,零歧义。剩下 12 道全是坐标题,它们的检索信号恰好是 0。

说清楚:这是对我自己评测模板的解析,换成真实用户的自由提问,解析率会崩。真正的结论是”确定性查询从模型手里拿走”:按值找行、按值找列、按下标取值交给索引,模型只处理语义问题。

九、成本

环节 prompt / completion 费用(off-peak)
本轮三条答题链(121 题 × 3) 90,833 / 837 $0.0141
其中两段式 top-1 那一条 27,994 / 265 $0.0044
上篇 C2(带整页表,121 题) 55,410 / 401 $0.0086
表级索引 + 检索 + 按下标取值 0 / 0 $0

按 deepseek-flash 的 off-peak 价算(单位美元):未命中输入 0.15/1M、输出 0.6/1M。索引、检索、坐标取值都在本地,不花钱。

总结

一句话:把检索从页下沉到表是对的——干净 76 道 Recall@5 从 0.8026 到 0.8421,答题只带命中的一张表,准确率和带整页打平、token 少 37%;但坐标题在检索层没有信号,这不是检索能修的。

三条落地:

  1. 表级索引一定要带表头。只塞行文本,干净子集从 0.8421 掉到 0.6974。
  2. 两段式里表级几乎不丢(页在 top-10 内时 65/65),瓶颈在页面召回。
  3. 坐标题别指望检索。能程序化的——按值找行、按值找列、按下标取值——全部交给索引和下标,模型只处理语义问题。

下期预告

下篇我回头收拾页面级检索。这轮已经证明表级这段是全对的,Gold 页进 top-10 只有 0.5702(114 道里 65 道),锅在页面。我打算把页面检索从纯正文 BM25 换成分字段加权的混合召回——正文 + 标题 + 表头 + URL 路径词分别算分再加权,看能否把 Gold 页进 top-10 抬上去,顺带复盘这次 16 道拿错表的题。

参考文献

转载请注明:Falost的小窝 » 多模态 RAG 实测(五):把检索从页下沉到表——内容题 Recall@5 涨 4 个点,坐标题仍是 0

如果你觉得这篇文章不错或者对你有帮助,想请我喝一杯咖啡,可以打赏
喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址