撕开 RAG 的遮羞布:多模态文档解析中的真实 Bad Case 治理与破局策略
引言:RAG 落地的第一道鬼门关——文档解析
很多团队做 RAG,最爱在 Embedding、向量库、重排模型、Agent 编排上卷得飞起,结果上线后一看:命中率不稳,生成内容时不时“胡说八道”,问得越细,答得越飘。
问题真不一定出在 LLM。
更常见的真相是:你的文档解析阶段已经把原始知识打成了一锅结构性稀饭。后面的向量检索、召回排序、答案生成,只是在一堆垃圾上做精致装修。墙是歪的,刷再贵的漆也救不回来。
所以我一直把文档解析看作 LLM 时代的 ETL:
- 抽取(Extract)不是把字抠出来就完事,而是把 结构、层级、语义锚点、版面关系 一起拿出来。
- 转换(Transform)不是简单切 chunk,而是把 对检索和生成真正有意义的文档形态 重建出来。
- 加载(Load)更不是“塞进向量库就行”,而是带着可追溯的结构元信息进入索引系统。
一句难听但真实的话:Garbage in, Garbage out。解析稀烂,后面全是徒劳。
尤其在真实企业场景里,文档根本不是教科书式的规整 PDF。你会撞上这些妖魔鬼怪:
- 券商研报:双栏正文 + 侧边注释 + 页眉免责声明 + 跨页大表格
- 制造业图纸:文字方向混乱,表单、标注、示意图交错
- 财报/审计报告:表格密集,页脚反复出现,脚注满天飞
- 医疗/法务材料:图文混排严重,引用链复杂,附录打断正文
这类文档最致命的不是 OCR 识别错一个字,而是 结构关系断了。而 RAG 最依赖的,恰恰不是字符本身,而是结构。
下面直接拆三个最脏、最难、最影响线上效果的 Bad Case。
版式陷阱:别再迷信从左到右、从上到下
Bad Case 1:复杂版式与阅读顺序错乱
这是最常见,也最容易被低估的坑。
很多解析流水线还停留在老思路:OCR 出一堆文本框,然后按 y 坐标从上到下、x 坐标从左到右排序。看起来很合理,实际上遇到复杂版式时会直接翻车。
例如一份双栏研报,页面可能长这样:
- 左栏:正文段落 A、B、C
- 右栏:正文段落 D、E、F
- 页面顶部:标题、日期、机构名
- 右侧窄栏:分析师观点摘要
- 页脚:免责声明、页码
- 背景:浅色水印
如果你只按坐标排序,最终得到的文本流往往类似这样:
标题
日期
左栏第一段
右栏第一段
左栏第二段
页脚免责声明
右栏第二段
侧边栏摘要
左栏第三段
页码
……
恭喜,语义已经被打断成拼图碎片。后续 chunk 再切得多优雅,也是在错误顺序上二次加工。
为什么传统 XY-Cut 会失败
XY-Cut 这类基于投影分割或坐标规则的方案,在规则文档上很好用,但它有几个致命前提:
- 版面块之间有明显空白分隔
- 阅读顺序可由几何邻近性近似
- 噪声元素较少,不会干扰分割边界
- 跨区域的逻辑关系不复杂
真实业务文档偏偏专门打脸这些前提。
1)多栏排版会让“最近邻排序”失真
双栏或三栏文档中,视觉上“下一句”往往不是几何距离最近的那个框,而是 同一栏中的下一个块。靠坐标近邻排序,极容易在栏间来回横跳。
2)侧边栏、注释框、图注会伪装成正文
很多侧边栏在空间上贴着正文,但逻辑上它是补充说明,不该插进正文主链。坐标规则看不懂“主次关系”,只会机械拼接。
3)页眉页脚和水印是结构污染源
页眉页脚几乎每页都重复出现。你要是不清掉,它们会高频进入 chunk,直接污染召回。问模型“公司核心结论是什么”,它给你反复引用免责声明,场面相当抽象。
4)图文混排会打断块级连续性
图片、公式、表格、图注一旦插入页面,原本线性的文本块序列就会断裂。基于简单几何规则的“读序恢复”,基本只能靠运气。
破局点:别再拿 OCR 框硬拼,先做版面理解
工程上要解决这个问题,核心思路就一句:
先分区,再排序;先定角色,再谈阅读顺序。
也就是先做 版面分析(Layout Analysis),把页面中的区域角色识别出来,再根据角色和层级去重建文档树。
这一步可以有两条主路线。
路线一:基于检测模型的区域划分
最常见的落地方式,是用目标检测模型做页面区域识别,比如基于 YOLOv8 训练定制化版面检测器,输出诸如:
- title
- section_header
- paragraph
- list
- table
- figure
- figure_caption
- sidebar
- header
- footer
- watermark
- footnote
这条路线的优点非常工程化:
- 推理速度快,适合大规模离线处理
- 训练和迭代成本可控
- 类别定义灵活,适合做垂直领域定制
- 方便接规则系统做后处理
尤其在企业内部,文档类型往往高度集中。比如券商研报、招股书、物流单据、化工报告,各自版式风格相对稳定。你完全可以围绕自家核心文档类型,标一批高价值页面,训一个“够用且能打”的版面检测器。
路线二:基于 LayoutLM 系列的布局理解
如果你需要更强的语义+位置联合建模能力,可以引入 LayoutLM / LayoutLMv3 这类模型,利用文本、版面坐标、视觉特征联合判断区域属性与关系。
这条路线更适合:
- 版面风格变化大
- 需要 finer-grained token-level 判断
- 想做块分类之外的关系建模
- 页面中“视觉上相近但语义不同”的元素很多
但别神化它。LayoutLM 很强,不等于你就能一步到位解决读序。很多时候它是一个强特征编码器,不是完整的工程解法。真正落地,仍然需要和检测、规则、树重构结合。
真正管用的工程方法:重建 Document Tree,而不是拼字符串
很多团队版面分析做完就满足了:哦,检测出 paragraph、table、figure 了。然后呢?然后又把它们拼成纯文本。白忙活。
你真正该构建的是 Document Tree(文档树),而不是一个线性文本串。
一个靠谱的文档树至少要包含:
- 页面级节点(page)
- 区块级节点(section / paragraph / table / figure / sidebar)
- 层级关系(谁属于谁)
- 顺序关系(前后兄弟节点)
- 锚定关系(图注属于哪张图,脚注关联哪个段落)
- 可过滤属性(是否页眉页脚、是否噪声、是否重复)
逻辑大概像这样:
注意,这不是为了“好看”。这是为了后面所有环节都能活下来:
- chunking 时按树切,而不是按字符切
- 检索时保留 section 上下文
- 表格跨页时能找到延续关系
- 图文锚定时知道 figure 插在正文哪儿
- 生成答案时能做来源追踪
经验:如何过滤干扰元素
这个环节非常脏,但极其值钱。因为线上质量,往往不是被主干算法拖死,而是被这些脏东西反复污染。
1)页眉页脚:跨页重复检测
最实用的方法不是“规则猜”,而是 跨页聚类 + 重复率统计。
同一文档中,若多个页面顶部/底部在固定区域反复出现高相似文本块,例如:
- 公司名
- 保密声明
- 页码模板
- 报告标题缩写
这类块基本都该打成 header/footer/noise 标签,从主文本流剔除。
2)水印:低置信度 + 大面积斜置 + 高重复视觉模式
水印常见特征:
- 倾斜
- 半透明
- 跨区域覆盖
- OCR 文本置信度不稳定
- 在多页重复出现
这类不要指望纯 OCR 后处理解决,最好在视觉层先标记为背景噪声,避免进入正文候选块。
3)脚注/免责声明:保留索引,不进主干
脚注并不是无用信息,但它通常不该直接插入正文主链。更好的做法是:
- 主文本流中保留一个锚点,比如
[Footnote-3] - 脚注内容作为附属节点挂在对应段落或页面下
- 检索时可按需展开,而不是默认污染 chunk
一个常被忽略的判断标准:主内容优先级
工程上别追求“把页面所有东西都解析出来”。那是学术论文思维,不是生产思维。
RAG 解析更关心的是:
- 主内容链是否完整
- 结构关系是否可靠
- 噪声是否被有效隔离
- 下游检索是否能吃到正确上下文
换句话说,不是解析得越全越好,而是越可用越好。
表格撕裂:跨页表格的缝合手术
Bad Case 2:噩梦级的“跨页表格”
如果复杂版式会把段落顺序搞乱,那么跨页表格会把结构理解直接炸穿。
这类问题在财报、审计报告、制造 BOM、物流单据、实验记录里极其常见。一个表格因为页面长度限制,被硬生生截成两半:
- 第一页有表头和前几行
- 第二页没有表头,直接接着数据行
- 更恶心一点:第二页列宽变了、边框缺了、某些单元格还合并了
- 再恶心一点:中间夹了一段页脚免责声明或“续表”提示
这时候,如果你把每页表格单独抽出来送给大模型,它看到的是两个残缺结构:
- 第一页:一个“未闭合”的表格
- 第二页:一个“没有表头”的孤儿表格
模型不是神。你给它半截骨头,它不会自动脑补出完整恐龙。
跨页表格为什么难
这事难,不是因为表格识别本身难,而是因为 物理分页打断了逻辑连续性。
一个完整表格在文档语义层面是连续对象,但 PDF/图片只关心“这一页画了什么”,它完全不在乎你后面还要不要接上。
于是会出现三个典型断裂:
1)表头断裂
第二页通常不重复表头,或者只重复一部分。这会让列语义丢失,后续每一行都没有可靠 schema。
2)边界错判
很多解析器看到新页面上的网格线,就会直接认成一个新表格,而不是上页续表。
3)行列漂移
跨页后列宽轻微变化、边框缺失、OCR 偏移,会导致列对齐关系错位。你肉眼知道它是同一列,模型和规则系统未必知道。
破局点:组合拳,不要指望单一模型救世
跨页表格修复,我更推荐一套组合打法:
物理边界检测 + 启发式规则 + LLM 语义对齐
三者缺一不可。
第一步:物理边界检测,先判断“这表有没有断”
这一层是视觉和结构层的基本判断,主要解决两个问题:
- 页面底部的表格是否“未闭合”
- 下一页顶部的表格是否疑似“续表”
常用信号有:
- 上一页表格底边是否缺失
- 最后一行是否被页面截断
- 下一页顶部是否紧贴表格区域开始
- 下一页首个表格前是否没有正常段落引导
- 是否出现“续表”“continued”等提示词
- 前后页表格横向投影轮廓是否近似一致
这一步不用太玄学,很多时候简单但稳的视觉几何规则就够用了。
第二步:启发式规则,判断“该不该合”
这是整个系统最有烟火气的一层。很多线上可用的系统,不是靠端到端大模型直接通灵,而是靠规则把候选空间大幅缩小。
典型规则 1:上一页尾表未闭合 + 下一页首表无标题
这是非常强的合并信号。
如果页 N 的最后一个表格底部未闭合,且页 N+1 的第一个表格没有独立标题、没有新表头,那大概率是续表。
典型规则 2:列数近似一致
哪怕列宽有轻微漂移,只要列分割中心点在允许阈值内可对齐,就可判定为同构。
典型规则 3:表头模式继承
如果第二页首行明显更像数据行而不是表头,且上一页表头 schema 完整,那么应直接继承上一页表头。
典型规则 4:上下文语义连续
比如上一页表格标题是“2024 年区域销售明细”,下一页顶部没有新标题,但页中内容明显仍属于“区域/产品/收入/同比”这套 schema,这基本就是同一表。
典型规则 5:页间噪声可剥离
很多“断点”中间其实夹着页脚、页码、免责声明。这类块如果被识别为噪声,不应阻断续表关系。
第三步:LLM 语义对齐,解决“规则够不着的灰区”
规则擅长高精度,但不擅长处理模糊边界。真正难的,是这些灰区:
- 第二页首行看起来像表头,也像数据
- 前后页列数对不上,但语义上其实是合并单元格造成的
- OCR 把列名识别坏了,规则系统无法稳定匹配
- 表头多层级,页面之间只保留了下层标题
这时候,LLM 或更轻量的表格语义模型就该上场了,但它的角色不是“从零识别表格”,而是 做最后一跳的语义校准。
比如给模型输入:
- 上一页表头结构
- 上一页最后几行
- 下一页前几行
- 列对齐候选关系
- 是否存在“续表”提示
让它回答:
- 下一页是否为续表
- 下一页应继承哪一层表头
- 若列名缺失,如何补齐 schema
- 某些错位列应如何映射回原列定义
这一步的价值,不在于“让模型变聪明”,而在于让模型只处理 高价值、低召回、强约束 的灰区问题,避免 token 浪费和不稳定发挥。
一个实用的跨页表格合并流程
下面给一段我更偏爱的工程化伪代码。不是论文味的完美范式,但很接地气,适合真上线。
from dataclasses import dataclass
from typing import List, Optional
@dataclass
class TableBlock:
page_id: int
bbox: tuple
rows: List[List[str]]
header_rows: List[List[str]]
col_positions: List[float]
title: Optional[str] = None
is_bottom_open: bool = False
is_top_open: bool = False
def is_similar_columns(cols_a, cols_b, tolerance=12):
if abs(len(cols_a) - len(cols_b)) > 1:
return False
matched = 0
for a in cols_a:
if any(abs(a - b) <= tolerance for b in cols_b):
matched += 1
return matched / max(len(cols_a), 1) >= 0.8
def looks_like_new_table(table: TableBlock):
# 有独立标题、重复完整表头、前面有正文引导,都更像新表
if table.title:
return True
if len(table.header_rows) >= 1:
header_text = " ".join(" ".join(r) for r in table.header_rows)
if len(header_text) > 8:
return True
return False
def llm_semantic_align(prev_table: TableBlock, next_table: TableBlock):
"""
返回:
{
"is_continuation": bool,
"inherit_header": bool,
"column_mapping": [...],
}
"""
# 这里省略具体 prompt / API 调用
# 实战中只在规则无法高置信决策时触发
return {
"is_continuation": True,
"inherit_header": True,
"column_mapping": list(range(len(prev_table.col_positions)))
}
def merge_two_tables(prev_table: TableBlock, next_table: TableBlock):
merged_header = prev_table.header_rows
merged_rows = prev_table.rows + next_table.rows
return TableBlock(
page_id=prev_table.page_id,
bbox=prev_table.bbox,
rows=merged_rows,
header_rows=merged_header,
col_positions=prev_table.col_positions,
title=prev_table.title,
is_bottom_open=False,
is_top_open=False
)
def merge_cross_page_tables(pages_tables: List[List[TableBlock]]) -> List[TableBlock]:
merged = []
carry = None
for page_tables in pages_tables:
if not page_tables:
if carry:
merged.append(carry)
carry = None
continue
for idx, table in enumerate(page_tables):
if carry is None:
carry = table
continue
strong_signal = (
carry.is_bottom_open and
table.is_top_open and
is_similar_columns(carry.col_positions, table.col_positions) and
not looks_like_new_table(table)
)
if strong_signal:
carry = merge_two_tables(carry, table)
continue
weak_signal = (
carry.is_bottom_open and
is_similar_columns(carry.col_positions, table.col_positions)
)
if weak_signal:
llm_result = llm_semantic_align(carry, table)
if llm_result["is_continuation"]:
if llm_result["inherit_header"]:
table.header_rows = carry.header_rows
carry = merge_two_tables(carry, table)
continue
merged.append(carry)
carry = table
if carry:
merged.append(carry)
return merged
这段代码背后的核心思想很简单:
- 先用物理信号缩小候选
- 再用规则拿下高置信样本
- 最后把灰区交给 LLM 做语义补缝
- 合并结果不是纯文本,而是结构化表格对象
最终落地时,你最好输出成 Markdown 表格或 HTML Table,并带上这些元信息:
- source_pages
- original_table_ids
- inherited_header_from_page
- merge_confidence
- column_alignment_map
因为后面检索、渲染、审计、纠错,都要靠这些信息续命。
一个经验之谈:表格抽出来,不等于表格可用
很多团队把 PDF 表格导成 CSV,就觉得任务结束了。其实离“可用于 RAG”还差很远。
对 RAG 来说,真正可用的表格至少要满足:
- 表头完整
- 行列关系稳定
- 合并单元格语义已展开或显式表示
- 单位、币种、时间范围不丢
- 续表已缝合
- 与前后文标题/注释有锚定关系
否则你检索到一张表,模型看到的是:
地区 | 数值 | 数值变化
然后一脸懵:这是什么地区?什么时间?什么口径?同比还是环比?单位是万元还是亿美元?
表格不还原语义上下文,等于没还原。
孤岛效应:图文混排的语义锚定与多模态提炼
Bad Case 3:图文混排(Inline Images/Figures)的上下文割裂
这是另一个极其常见的坑,而且很多团队掉进去都没感觉。
他们的处理方式往往是这样的:
- 正文抽成文本
- 图片单独存文件
- 图表再单独做 OCR 或 caption
- 最后文本、图片、图注各走各的索引链路
这套做法看起来“模块化”,实际效果常常灾难级。
为什么?
因为在原始文档里,图片从来不是独立存在的。它通常是正文推理链的一部分。比如:
本季度毛利率变化主要受产品结构优化影响,如下图所示。
然后图被你剥离走了。
于是正文里就只剩一句“如下图所示”。这句话进入向量库后,语义几乎是空的,像个失忆的路标。
图文分离会带来什么问题
1)正文指代失效
“如下图所示”“见图 3”“曲线显示”“红框区域”这类表达,本质上依赖视觉对象。如果图片不在上下文里,这些句子就是残句。
2)检索丢失关键证据
很多关键信息其实只在图里,不在正文里,比如:
- 趋势转折点
- 某个异常峰值
- 模型结构图
- 工艺流程关键节点
- 设备损伤位置
- 地图/示意图中的空间关系
如果你只索引正文,相关问题会直接召回失败。
3)答案生成断链
LLM 回答时很依赖上下文闭环。正文引用了图,但图不在上下文,模型只能瞎猜“图里可能讲了啥”。这就给幻觉开了绿灯。
破局点:多模态 Chunking,而不是文本和图片各自为政
解决思路很明确:
不要把图片当附件处理,而要把它当文档流中的语义节点。
也就是说,chunking 不再是单纯按文本切,而是按 多模态语义单元 切。
一个更实战的策略是:
- 先恢复正文结构和图文位置关系
- 对每个 figure/inline image 做 Dense Captioning
- 将图片描述作为 metadata,或直接插回原文本流
- 构建“正文 + 图描述 + 图注”的联合 chunk
Dense Captioning 该怎么做才不鸡肋
这里别满足于“图中是一张折线图”这种废话描述。这种 caption 对 RAG 几乎没用。
真正有价值的 Dense Captioning,应该提取 与业务问答相关的高信息密度描述,例如:
- 图类型:折线图 / 柱状图 / 流程图 / 架构图 / 显微图 / 平面图
- 核心对象:哪些实体出现在图中
- 关键趋势:上升、下降、拐点、异常峰值
- 关键比较:A 高于 B,某时间后反转
- 标注信息:图例、坐标轴、单位、颜色含义
- 结论性线索:图像支持哪条正文论断
在工程上,可以借助 VLM(视觉语言模型),比如 GPT-4o、Gemini 1.5 Pro 一类模型,对图片做结构化描述抽取。重点不是让它“看图说话”,而是让它输出可回灌索引的语义片段。
例如把模型输出约束成这样的结构:
{
"figure_type": "line_chart",
"entities": ["毛利率", "消费电子业务", "工业业务"],
"time_range": "2023Q1-2024Q4",
"key_trends": [
"消费电子业务毛利率在2024Q2后明显回升",
"工业业务整体平稳,波动较小"
],
"anomalies": [
"2023Q4出现短暂下滑"
],
"caption_summary": "图表展示两个业务线毛利率变化趋势,支持正文中关于产品结构优化带来盈利改善的判断。"
}
这玩意儿一旦锚进 chunk,检索质量会明显提升。因为用户问“毛利率拐点从什么时候开始”,你不再只依赖正文里有没有写死这个词,图里的趋势信息也能被召回。
两种锚定策略:Metadata vs Inline Reinsertion
这块没有银弹,得按场景选。
策略一:作为 Metadata 附着在 chunk 上
适合:
- 你不想污染原始文本流
- 检索阶段支持 metadata 过滤 / rerank
- 图片描述较长,直接插文本会让 chunk 变臃肿
示意:
{
"chunk_text": "本季度毛利率变化主要受产品结构优化影响,如下图所示。",
"metadata": {
"figure_id": "fig_12",
"figure_caption": "图12:两业务线季度毛利率趋势",
"dense_caption": "消费电子业务毛利率在2024Q2后明显回升,工业业务较稳定……"
}
}
优点是结构清晰。缺点是一些向量检索链路对 metadata 利用不充分,容易浪费图信息。
策略二:直接插回原文本流做语义锚定
适合:
- 你希望正文指代句立即闭环
- 主要依赖文本向量召回
- 需要增强 chunk 自包含性
例如把原文重写为:
本季度毛利率变化主要受产品结构优化影响,如下图所示。
[Figure-12]
图12:两业务线季度毛利率趋势。
补充描述:消费电子业务毛利率在 2024Q2 后明显回升,工业业务波动较小,2023Q4 存在一次短暂下滑。
[/Figure-12]
这样“如下图所示”就不再是空气句,而变成一个有实体支撑的锚点。
我自己更偏向 双轨制:
- 短摘要插回正文,保证语义闭环
- 长描述放 metadata,保留更完整细节
这样既利于文本召回,也利于后续多模态 rerank。
图文混排下的 chunking,不要再只看 token 长度
很多人切 chunk 还在迷信固定字数,比如 500 字一段、100 overlap。这个在纯文本世界还能凑合,在图文混排文档里就非常容易把语义链切断。
更合理的切分边界应该是:
- section 边界
- figure 锚点前后
- table 前后
- list / bullet 逻辑块
- 页面中断但语义连续的续接点
换句话说,chunk 的基本单位应该是“语义单元”,不是“字数容器”。
一个很值钱的经验:把“图说了什么”变成可索引文本
RAG 不怕信息多,怕信息没法被索引。
图片本身是信息,但如果不转成可检索的语义表达,它在很多系统里等于半失效。所以多模态解析的关键,不只是“能看图”,而是:
把视觉信息变成能参与召回、排序、生成的文本化语义锚点。
这一步做对了,很多“正文没写但图里有”的问题,才有机会答对。
生产总结:没有银弹,只有精细化治理
讲到这里,基本可以把一些幻觉打掉了。
幻觉一:换个更强的 OCR 就能解决问题
不会。OCR 解决的是字符识别,不是结构重建。你识别再准,读序错了、表格裂了、图文断了,照样完蛋。
幻觉二:上个大模型端到端解析就好了
也不会。端到端大模型很强,但在生产上你会立刻遇到这些现实问题:
- 成本高
- 延迟不稳
- 输出可控性差
- 可解释性不足
- 对复杂长文档的稳定性参差不齐
- 很难做局部纠错和精细治理
真正能打的系统,往往不是“全交给一个超大模型”,而是 检测、规则、结构恢复、局部 LLM 校准 的组合架构。
幻觉三:解析一次就结束了
这更不现实。文档解析不是一次性项目,而是持续治理工程。
你必须建立自己的 Bad Case 闭环:
- 收集线上失败样本
- 按错误类型分桶:读序错、表格裂、图文断、脚注污染、标题层级错等
- 给每类问题建立针对性修复模块
- 做回归测试,防止修一个坑再炸三个坑
- 将高频文档类型沉淀成专项数据集
真正该投入的地方:构建你的领域版面解析数据集
这是最朴素、也最有效的建议。
不要迷信通用数据集能覆盖你的业务地狱。真实世界的企业文档都带行业指纹:
- 券商研报有自己的排版习惯
- 制造业图纸有自己的标注语法
- 医疗报告有自己的结构模板
- 财务报表有自己的表头层级和跨页模式
所以你真正要做的是:
- 标注自家高频、高价值文档
- 建立领域版面类别体系
- 构建跨页表格样本集
- 构建图文锚定样本集
- 建立面向 RAG 结果的解析评测集,而不只是 OCR 精度集
请注意最后这句,它非常关键:
文档解析的评测标准,不该只看字符准确率,而该看它是否提升了检索与问答质量。
字符对了 99%,但结构错了,一样是废的。
一个更贴近生产的评估闭环
你至少要看四层指标:
第一层:元素级识别
- block 检测准确率
- 表格检测准确率
- 图/图注关联准确率
- 页眉页脚识别准确率
第二层:结构级恢复
- 阅读顺序准确率
- 文档树层级正确率
- 跨页表格合并成功率
- 图文锚定成功率
第三层:索引级可用性
- chunk 自包含率
- 噪声污染率
- 表格 schema 完整率
- 图片语义覆盖率
第四层:RAG 终局指标
- 检索命中率
- 问答正确率
- 来源引用准确率
- 幻觉率变化
- 用户反馈中的“答非所问”占比
真正能指导治理优先级的,往往是第四层倒推第一层,而不是反过来。
结语
RAG 这件事,很多人把火力都集中在“模型是不是够强”。但在企业落地里,更残酷的现实是:
你喂给模型的文档,往往从第一步就已经坏了。
多模态文档解析不是外围模块,它就是知识入口的总闸门。复杂版式读序错乱、跨页表格撕裂、图文混排语义断链,这三个 Bad Case 不解决,后面所有检索增强、生成优化、提示词工程,都会有一种在泥地里拧涡轮的荒诞感。
没有银弹。真的没有。
有的只是:
- 分类型治理
- 针对性建模
- 结构优先于文本
- 规则与模型协同
- 基于 Bad Case 的持续迭代
- 围绕业务文档建立自己的数据和评测体系
讲得再直白一点:
RAG 做得烂,很多时候不是 LLM 不行,是你把文档解析当成了 OCR 后处理。
这一步认知不改,系统就会一直在表面智能、底层混乱的状态里打转。看着挺唬人,实则一碰业务细节就露馅。技术世界很爱造神,但线上问题从来不信神话,只信结构。

1105

被折叠的 条评论
为什么被折叠?



