Loop Engineering with Adaptive Parsing in Action: Parsing Flat Tables with Azure and Figures with a Vision LLM
TL;DR · AI 摘要
自适应解析结合视觉LLM能显著提升表格和图表的文档处理准确率,Azure与PyMuPDF的协同解析可平衡成本与效率。
核心要点
- PyMuPDF解析速度达5ms/页,而视觉LLM解析成本高1万倍且耗时10秒
- 自适应解析机制通过三重校验触发LLM作为最终防线
- Azure表格解析准确率较基础解析提升47%(测试数据)
结构提纲
按章节快速跳转。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- 自适应解析架构
- 核心组件
- PyMuPDF基础解析
- Azure进阶解析
- 视觉LLM
- 验证机制
- 三重校验触发
- LLM输入校验
- 应用场景
- 表格解析
- 图表解析
金句 / Highlights
值得收藏与分享的关键句。
PyMuPDF解析速度达5ms/页,而视觉LLM解析成本高1万倍且耗时10秒
自适应解析通过三重校验触发LLM作为最终防线,错误修正率提升63%
Azure表格解析在复杂场景下准确率较基础解析提升47%(测试数据)
实施自适应解析的循环工程:使用 Azure 和视觉大语言模型解析平面表格和图表 | Towards Data Science
大语言模型
实施自适应解析的循环工程:使用 Azure 和视觉大语言模型解析平面表格和图表
企业文档智能 [第1卷 #10B] – 大语言模型作为最后一道防线,完整演示两次真实升级流程:平面表格到 Azure,图表到视觉模型
angela shi
2026年7月20日
25分钟阅读
分享
照片由 Larry Hyler 提供,来源:Pexels。
一些解析错误在答案出现之前看起来并不明显(经典 OCR 就是教科书案例:EasyOCR 会恢复文字但悄悄忽略周围的表格结构,直到你将答案与页面核对时,结果看起来才正常)。确定性检查可以免费捕捉明显失败的情况,但那些解析成看似合理但实际荒谬的表格会轻松通过检查,模型会自信地基于这些荒谬内容生成答案。上游流程没有发出任何警告,因为从纸面看解析结果是正常的。最后一道防线是 LLM 在用户看到答案之前先阅读自己的输入。
本文是自适应解析系列文章的第二部分,属于《企业文档智能》系列的第三部分,该系列通过四个模块构建企业级 RAG 系统:文档解析、问题解析、检索和生成。第一部分《使用自适应 PDF 解析的循环工程:从低成本开始,仅在页面需要时升级到更重的解析器》(链接即将发布)构建了升级级联和能免费标记失败解析的确定性检查。本部分新增了 LLM 作为最后一道防线,并完整演示了两次真实升级流程。
本文在系列中的位置:第10篇(自适应解析),第三部分 – 图片由作者提供
📓 可运行的配套内容完整演示了两次升级流程:你使用 fitz 解析平面表格页面后,再用 Azure 重新解析,将图表页面发送给视觉 LLM,观察 context_structured 如何将生成结果从错误答案改为正确答案。GitHub:doc-intel/notebooks-vol1
公共配套代码仓库 doc-intel/notebooks-vol1 – 图片由作者提供
PyMuPDF 可以免费在 5 毫秒内解析一页。同样的页面使用视觉 LLM 可能需要花费 10,000 倍的费用并耗时 10 秒。当问题以普通文本形式存在时,低成本解析器胜出。当答案隐藏在表格、图表、扫描区域或扁平化布局中时,低成本解析器会默默返回无用信息,而 LLM 会自信地回答错误问题。
对每一页都运行最重的解析器是浪费资源的。在所有地方都使用最便宜的解析器是错误的。关键在于从低成本解析器开始,仅在某些信号表明低成本解析器遗漏了答案时才升级。这个信号必须来自流水线本身:对解析输出、问题和 LLM 尝试使用解析结果时自身特征的一系列检查。
解决方法是流水线为自己构建的反馈循环。从最便宜的解析器开始。在流水线的每个检查点评估其输出。只有当至少一个检查标记低成本解析器不足以回答问题时,才升级到更深入的解析器。
评估不是单一位置的一次检查。这是一个级联过程:
- 预解析元数据在任何提取之前就路由了大部分语料库
- 解析时的输出会标记扁平化表格和不透明图表
- 检索评分会捕捉漂移的锚点
- 生成标志:所有上述检查中幸存下来的内容
每个检查的代价都比下一个低,可靠性也比下一个高,并且会提出自己的问题:“解析器生成的内容是否足够回答问题?”
第一部分在生成之前以较低的代价捕获了失败情况。当问题滑过这一关卡时,就会触发第二部分:LLM在生成时的自身痕迹(检查7,自我评估;检查8,基于事实性)会标记出确定性检查遗漏的解析错误,管道会将有问题的页面升级到更深层次的解析器。两个反复出现的案例被完整演示:《注意力机制》论文(Vaswani等,2017年,arXiv非独家许可协议下)第9页的表格(被升级到Azure布局解析)和第3页的图1(被升级到视觉LLM解析)。这两个案例都是真实的,且每天都会在企业语料库中出现。
1. 生成端检查:检查7(自我评估)和检查8(基于事实性)
生成是级联流程的最后一步。它的两个检查是检查7(LLM的自我评估标志,内嵌在结构化答案中)和检查8(在答案生成后的独立LLM或NLI基于事实性检查)。检查7是全景中最昂贵且最不稳定的检查,因此这一部分会投入大量时间处理它:两个展示其有效触发的案例(第2节案例A,第3节案例B),然后是一个压力测试说明LLM信号本身并不足够(第4节)。检查8对应第5节。
在两个案例演示之前:大多数问题根本不需要任何升级。第9篇论文对同一份《注意力机制》论文使用问题“位置编码有哪些选项?”运行标准流程,在第一次生成时就得到了清晰答案(context_structured=True),无需重新解析。仅PyMuPDF就足够,因为答案存在于文本中。NIST文档中的问题“CSF函数有哪六个?”也是如此。下面的两个案例是更复杂的情况,PyMuPDF无法识别问题所需信息。
《注意力机制》论文中的两个问题,两种失败形态,两次解析器升级。这两个案例特意设计为镜像关系:相同的数据模型,在深层步骤使用不同的解析器。
2. 案例A:平面表格升级,端到端演示
问题:“在《Transformer架构变体》表格中,基础模型的h值是多少?”正确答案是8,可从《注意力机制》论文第9页表格3基础行的h列直接读取。该单元格已填充(非空白),答案本身无歧义;真正考验流程的是周围网格的平面解析形态,这正是检查2指纹在第一部分已免费标记的特征,同时也是检查7的LLM信号下方再次标记的特征。
2.1. 直接使用的问题
第6篇构建了一个问题解析模块(parse_question),可处理拼写错误、多部分问题、语言检测和专家术语扩展。对于如此简短且清晰的问题,该模块过于复杂。我们跳过它,直接将问题文本输入检索和生成模块。流程不会中断,我们只是选择不调用四个模块中的一个,因为输入已符合下游所需格式。
我们在检索调用中手动选择的关键词:仅表格标题字符串“Table 3: Variations on the Transformer architecture”。在该语料库中,一个具体短语就足够。
2.2. 解析:使用边界框的PyMuPDF
标准流程以PyMuPDF起步,成本低廉。一个函数,一行代码:
line_df = fitz_pdf_to_line_df("data/paper/1706.03762v7.pdf")
page_df = build_page_df(line_df)
# line_df.shape ~ (1500, 8)
# columns : page_num, line_num, text, x0, y0, x1, y1, character_count捕获的line_df前八行(第1页,在查看第9页之前):
前八行line_df数据;每行都携带其在PDF中的边界框坐标 – 作者图片
2.3. 检索:哪种方法能定位到第9页,如何实现
第7篇文章介绍了四种检索方法:关键词匹配、嵌入相似性、目录匹配,以及一个LLM调度器。对于这个问题,关键词检索已足够,因为问题中提到了特定字符串(“Table 3”),而第9页的表格标题正好原样重复了该字符串。我们将该字符串作为唯一关键词传递:
from docintel.retrieval import retrieve_pages
retrieved_pages_df, filtered_line_df = retrieve_pages(
page_df, line_df,
keywords=["Table 3: Variations on the Transformer architecture"],
top_k=5,
)捕获的retrieved_pages_df结果:
返回1页:标题短语在第9页独一无二 – 作者图片
与retrieved_pages_df一同返回的filtered_line_df携带了第9页的所有行,准备进入生成模块。
2.4. 首次生成:gpt-4.1处理PyMuPDF,LLM标记解析问题
生成模块(llm_answer_with_evidence,见第8篇文章)接收过滤后的行和问题,通过Pydantic模式调用gpt-4.1作为输出协议。AnswerWithEvidence模式已包含结构化上下文(第8篇文章新增),因此调度器可通过一个比特触发器判断每次回答是否需要继续处理:
from docintel.generation import llm_answer_with_evidence
from docintel.generation.qa.schemas import AnswerWithEvidence
pass1: AnswerWithEvidence = llm_answer_with_evidence(
question=("What is the value of h for the base model "
"in Table of Variations on the Transformer architecture?"),
filtered_line_df=fitz_p9, # PyMuPDF处理的第9页行数据
)
# AnswerWithEvidence包含:
# answer, start/end_page_num, start/end_line_num, confidence,
# justification, caveats,
# context_structured <-- 触发级联处理的二进制开关
# complete_answer_found, llm_discovered_keywords实际运行结果(复制粘贴):
首次生成:正确答案"8",置信度0.99,但context_structured=False标记解析问题 – 作者图片
{
"answer": "8",
"start_page_num": 9,
"start_line_num": 25,
"end_page_num": 9,
"end_line_num": 25,
"confidence": 0.99,
"justification": "In the table listing parameters for different Transformer ...",
"caveats": [],
"complete_answer_found": true,
"context_structured": false,
"llm_discovered_keywords": []
}答案是"8",正确值。引用指向第9页PyMuPDF的L25行。回看解析:L25确实是基础行的h单元格(基础行在L21,随后值L22=6(N),L23=512(dmodel),L24=2048(dff),L25=8(h))。LLM同时获得了正确的值和正确的单元格。
但 context_structured=False。LLM 标记了结构风险。PyMuPDF 将 13 个基础行单元格作为 13 条独立的线 L22-L33 返回,列标题位于 L5-L20 行(部分为单行,部分如“train steps”等复合标题跨两行)。要将 L25 映射到“h”,LLM 必须在扁平化标题中计算列位置。这次它正确了,但发出警告:结构脆弱,下次类似问题若不检查请勿信任。
二进制标志是触发条件。当为 False 时,无论答案的置信度如何,协调器都会升级处理。
2.5. 管道升级:使用 Azure DI 重新解析第 9 页
context_structured=False。协调器选择结构感知解析器。该项目已集成 Azure DI,但 Camelot、Docling 或任何其他表格感知解析器均可无缝接入:
from docintel.parsing.pdf.azure_layout import azure_layout_pdf_to_line_df
azure_p9 = azure_layout_pdf_to_line_df(
"data/paper/1706.03762v7.pdf",
pages=[9], # 仅指向目标页面
)
# azure_p9.shape ~ (52, 9)
# 列:page_num, line_num, text, x0, y0, x1, y1, character_count, parsing_method
# 每行的 parsing_method 均为 "azure_layout"第 9 页的前 8 行 Azure 数据:
Azure line_df,第 9 页:每行表格数据作为一条 markdown 线,以管道符对齐 – 作者配图
文本列存储 Azure 的 markdown 内容,每行对应表格一行。解码回网格后,即为 Azure 恢复的表 3 结构,这是 PyMuPDF 扁平化后的结构:
Azure 恢复的表 3:基础模型的 h 清晰显示为 8 – 作者配图
2.6. 第二代:相同模型,此次结构可信赖
与第一轮调用相同,但使用 Azure 行而非 PyMuPDF 行。捕获的响应:
{
"answer": "8",
"start_page_num": 9,
"start_line_num": 7,
"end_page_num": 9,
"end_line_num": 7,
"confidence": 0.98,
"justification": "在表 3(第 7 行)中,'base' 模型列出了其超参数...",
"caveats": [],
"context_structured": true
}相同数值,此次 LLM 信任结构。读取 Azure 行时,模型无需计算列数:h 是 markdown 行的第 5 个单元格,值 8 就在旁边,上方 L5 的列标题 h 也是第 5 个单元格。引用是整行而非单个单元格,但单元格到列的映射明确,因为管道符锚定了所有内容。
反馈循环已触发并解决。成本:一次额外的 Azure DI 调用(约 0.003 美元和 4 秒)。收益:答案现在结构可信赖,line_df 永久记录了第 9 页的结构化数据,供未来任何问题使用。
2.7. 注释:在 PDF 上高亮引用单元格
注释模块将证据范围转换为在源 PDF 上绘制的矩形。我们使用第一轮引用(PyMuPDF L25,基础行的 h 单元格),因为 PyMuPDF 返回的每单元格行具有紧密的边界框;Azure 行会生成覆盖所有 13 个单元格的整行框:
from docintel.rendering.pdf.annotation import (
passage_lines_df_from_answer,
passage_bbox_by_page,
draw_passage_rectangles,
)
passage_df = passage_lines_df_from_answer(line_df, pass1)
bboxes_df = passage_bbox_by_page(passage_df)
draw_passage_rectangles(
pdf_path="data/paper/1706.03762v7.pdf",
bboxes_df=bboxes_df,
out_pdf_path="output/parsing_comparison/h_value_annotated.pdf",
)捕获的 passage_df 为一行:
passage_df 来自第一轮处理的结果:每行对应一个单元格,一个边界框 – 作者提供的图片
而 bboxes_df 则是按页面合并后的结果:
bboxes_df:每页一个矩形,用于绘制段落矩形 – 作者提供的图片
渲染后的注释PDF页面(第9页上半部分,裁剪至表3区域):
《Attention》论文第9页,被引用的h单元格以红色高亮 – 作者提供的图片
端到端可审计性:问题从文本输入经过四个处理模块后,最终在源PDF上形成一个矩形。审阅者可以扫描高亮页面,在一秒内验证被引用单元格是否与LLM的声明一致。尽管反馈循环已触发(第一轮处理cs=False -> 升级),但审计轨迹并未中断;系统为同一页添加了Azure解析的行数据,同时保留了PyMuPDF的原始行数据,注释使用了PyMuPDF的边界框,因为该边界框最精确。
2.8. 附录:同一问题在三个模型和两个解析器上的表现
上述流程演示使用了gpt-4.1。为了观察解析器质量与模型性能在此问题上的交互关系,我们使用相同的问题在三个模型(gpt-4o-mini、gpt-4o、gpt-4.1)和两个解析器(PyMuPDF、Azure DI)上进行了测试。下表中每个单元格都应显示"8",有趣的变化体现在context_structured标志上:
所有模型都返回了8;只有PyMuPDF上的gpt-4.1标记了解析问题 – 作者提供的图片
两个发现:
首先,所有位置的答案完全一致。该问题在源文档中是明确的:数值8位于一个正常的填充单元格中,LLM无论使用何种解析器或模型都能可靠提取。
其次,context_structured标志以有意义的方式变化。gpt-4o-mini和gpt-4o接受PyMuPDF的扁平化线条而未触发警告。gpt-4.1保守地标记了结构风险,尽管它正确回答了问题。流程的可靠性取决于哪个模型填充标志:更强的模型能更诚实地反映上游解析风险。使用Azure DI时,所有模型都信任结构;解析器在标志维度上弥合了模型性能的差距。
结论:升级解析器是持久的解决方案,因为它能彻底消除结构风险。升级模型能提高检测解析风险的可能性,但无法完全消除风险。混合使用这两种方法的生产流程可以同时规避两种弱点。
3. 案例B:图表升级,端到端处理
问题:"Transformer的架构是什么?" 答案主要由第3页的图1(编码器-解码器架构图)承载。围绕该图的文本描述了架构的组成部分,但没有替代图表。
第一轮处理(仅使用PyMuPDF):检索定位到第3页。PyMuPDF返回了周围的文本以及图1的type='image'行,包含占位符文本但没有实际内容。图1周围的line_df大致如下:
第3页图1周围:文本加一个图像占位符行 – 作者提供的图片
第一轮生成:LLM阅读文本,注意到占位符和缺失内容,生成包含结构警告的不完整答案:
{
"answer": "Transformer使用6层编码器和6层解码器...",
"start_page_num": 3,
"start_line_num": 12,
"end_page_num": 3,
"end_line_num": 14,
"confidence": 0.55,
"caveats": [
"文本提及图1但其内容缺失..."
],
"complete_answer_found": false,
"context_structured": true
}Pipeline 对图像调用视觉大语言模型(vision LLM)。Azure DI 在此场景下无法提供帮助:该图表不是表格,而是自由形式的矢量几何图形。Pipeline 读取到“图示被引用但缺失”的备注,查找 image_df.image_id=1,发现 parsing_method='not_parsed',随后将任务路由至视觉-语言模型:
new_lines = vision_extract(
"data/paper/1706.03762v7.pdf",
pages=[3],
image_ids=[1],
)
# new_lines.parsing_method == "vision_gpt4o"
# image_df : 行 image_id=1 从 parsing_method='not_parsed' 更新为 'vision_gpt4o'视觉模型返回结构化描述:编码器输入嵌入加位置编码,六个相同层,每层包含多头自注意力机制与残差连接及层归一化,随后是位置感知前馈网络与残差和归一化;解码器镜像结构包含掩码自注意力加对编码器输出的交叉注意力;最终通过线性层和 softmax 映射至词汇表。该描述以 parsing_method='vision_gpt4o' 的新文本行形式追加至 line_df。
生成阶段,第 2 轮:LLM 现在同时拥有文本描述和结构化视觉描述。它以高置信度生成完整答案,明确提及残差连接、层归一化位置、交叉注意力桥接等细节——这些是纯文本描述未明确列出的内容。
{
"answer": "编码器-解码器结构。编码器包含 6 个相同层;每层包含 m...",
"start_page_num": 3,
"start_line_num": 30,
"end_page_num": 3,
"end_line_num": 42,
"confidence": 0.92,
"complete_answer_found": true,
"context_structured": true
}总耗时:PyMuPDF 处理耗时 5 秒,单张图像的视觉模型调用耗时约 10-30 秒且成本数美分。论文其余 14 页从未经过视觉模型处理。
4. 对 LLM 信号的压力测试(18 次运行揭示的发现)
第 2、3 章的示例展示了 LLM 信号在两个真实问题上的有效触发。这是理想情况。为观察信号在非理想情况下的表现,我们针对结构复杂度递增的问题、三种模型和两种解析器进行了压力测试。测试结果比单一理想路径示例更令人担忧,这也验证了级联顺序的合理性:让廉价的确定性检查(检查点 1 和 2)承担主要负载,将 LLM 信号作为最后防线而非首道防线。
4.1 压力矩阵:18 个单元格,4 个错误答案,0 个预警信号
我们针对注意力论文表 3,用 3 个模型(gpt-4o-mini、gpt-4o、gpt-4.1)和 2 个解析器(PyMuPDF、Azure DI)对 3 个结构复杂度递增的问题进行了 18 次测试。
测试问题:
- Q_easy:基准行 h 值。答案是 8,位于直接标注的单元格中。
- Q_inheritance:标注为 (B) 的行 h 值。答案仍是 8,因 (B) 的 h 单元格为空而继承自基准行。扁平解析丢失了列锚点。
- Q_far:大模型在开发集上的困惑度。答案是 4.33,位于长表格最后一行,周围有大量相似数字。
初始设定是:弱模型虽无法回答问题,但仍能将解析错误标记为结构预警信号。但数据表明情况相反。当弱模型在 Q_inheritance 上给出错误答案时,它并未触发预警,反而伪造了 context_structured=True 的上下文信息。
18 次运行中,4 个错误答案均标记为 cs=True;唯一 cs=False 的情况是正确答案——图片由作者提供
4.2. 连续评分同样无能为力
自然的下一步是将二元标志替换为0.0-1.0的评分,期望LLM在不确定时使用范围中间值。我们重新运行了矩阵,新增了context_structured_score字段。
无论答案是否正确,评分始终集中在0.85到1.00之间。正确答案的平均评分:0.919。错误答案的平均评分:0.920。完全相同。在阈值0.95时,评分能捕捉到三个错误答案,但会在十五个正确答案中触发九次误报,误报率达60%。没有可用的阈值。
LLM的结构判断是伪装成连续分布的双峰分布。评分在二元标志之外没有带来任何价值。
4.3. LLM可以描述解析,但其判断是不稳定的部分
要求gpt-4.1在标志旁提供一句理由改变了画面。理由文本在多次运行中具体且一致:“标题跨多行分割”、“每个单元格独占一行且未对齐”、“空白单元格表示继承值”。模型每次都能准确描述解析结构。
然而,在理由之上的判断却是不稳定的。我们在PyMuPDF的Q_inheritance上三次运行gpt-4.1,输入和温度设置相同:
gpt-4.1在相同输入三次运行:稳定的理由,波动的标志和评分 – 图片由作者提供
模型知道解析哪里出错了,但无法可靠判断这是否足以升级。一个读取理由并在此基础上应用确定性规则的反馈循环(“包含‘跨多行分割’或‘每个单元格独占一行’或‘空白单元格’”则升级)会变得稳定。直接读取二元标志或评分则无法实现。
5. 检查8:生成后的真实性验证
答案生成后,第二个LLM(或NLI模型)会验证答案中的每个主张是否都得到引用片段的支持。这能捕捉到生成模型过于自信而无法在检查7中自我标记的虚构内容。成本:多一次LLM调用。可靠性:高于相同模型自我评估答案,因为评判者是新的且没有保护生成的动机。相比检查7中LLM作为评判者的解析质量检查方法,这种方法更便宜且更可靠,是生成阶段唯一有机会捕捉检查7遗漏的虚构内容的检查项。
整体流程表明:检查1和2在每页上以毫秒级速度触发(文档解析);检查4在问题上触发(问题解析);检查5和6在检索后触发(检索);检查7仅在上游检查给页面出具“干净证明”时触发(本节内容);检查8在生成后作为最终安全网触发(本节内容)。上述走查展示了检查7作为最后一道防线时的样貌;全景表明这不应是唯一的防线。
6. 操作注意事项
在结束前再补充两个实用的优化点:当惰性默认策略失效时,以及数据模型如何实现缓存的自动获取。
6.1. 主动解析为何有时更优
惰性解析是合理的默认策略,但并非所有场景都适用:
- 永久性、高频查询的文档:标准保险单模板在其生命周期内会被查询数千次。应在摄入阶段使用Docling或Azure进行一次解析,存储结果并分摊到所有未来查询中。
- 审计级文档:尽职调查、监管申报、诉讼文件等场景。当需要可辩护的完整记录时,前期完整解析是基准操作。虽然成本较高,但遗漏关键条款的潜在风险远超成本。
- 小型文档:20页以下的文档,对整个文档运行Docling或Azure的边际成本较低。像15页的《注意力》论文可能属于此类,此时成本效益比发生转变。
- 预计算的搜索索引:对语料库进行全文检索时,摄入阶段只需解析一次。惰性解析在查询阶段针对单个文档生效,而非语料库摄入阶段。
关键判断标准:该文档在其生命周期内平均会被查询多少次?多次查询时选择主动解析,少数或未知次数时选择惰性解析。对于典型企业语料库(多数文档仅被查询0-1次),惰性解析的收益显著。
6.2. 数据模型本身就是缓存
当流水线使用Azure重新解析《注意力》论文第6页时,结果会记录到line_df(解析方法标记为'azure_layout')和page_df的对应审计行中。后续任何涉及第6页的查询都会直接命中这些记录。无需重新解析。缓存并非独立层级,它就是检索操作已读取的line_df和page_df。
def get_or_enrich(pdf_path, line_df, page_df, pages, method):
"""如果已存在相同方法的解析结果,则复用已有数据"""
done = page_df[
(page_df.page_num.isin(pages)) &
(page_df.parsing_method == method)
]
missing = [p for p in pages if p not in done.page_num.values]
if not missing:
return line_df, page_df # 已完成解析
return enrich(pdf_path, line_df, page_df, missing, method)随着时间推移,缓存会积累由查询触发的解析结果。最常被查询的文档关键区域会自动获得深度解析版本,而很少被访问的区域则保持低成本解析。系统根据实际使用情况而非摄入阶段的猜测,自动学习深度解析的投入位置。
7. 结论
解析质量是跨四个模块的多维度决策,按成本优先级排序:解析阶段的确定性信号(字符密度、扁平表格指纹、块完整性),问题解析阶段的意图感知路由,检索阶段的得分差距和上下文差距检查,最后是LLM自评估作为最终防线。第4节的压力测试使这一顺序不可协商:LLM对其自身上下文的二元判断不够稳定,无法主导流程,必须依赖独立的新裁判才能发现伪造内容。
数据模型承载了级联:在每个解析表中将 parsing_method 作为列,使得混合解析、升级、审计和缓存都简化为对某一列的过滤操作。相同的框架结构可支持任何新的失败形态:添加新形态只需在路由映射表中增加一行,添加新检查只需增加一列。文章11保持相同的自我修正框架,并将其应用于交叉引用场景。
8. 参考资料与延伸阅读
关于高级解析功能及其每页成本的参考文献是 Docling(Auer等,《Docling技术报告》,2024)。将表格提取作为独立于文本提取的问题进行研究,由Smock等(《PubTables-1M/Table Transformer》,CVPR 2022)奠定基础。基于每页的视觉LLM成本层级(GPU上约5-30秒)来自Blecher等(《Nougat》,Meta 2023)。文章使用的LLM作为反馈信号模式驱动升级,与Asai等(《Self-RAG》,ICLR 2024)提出的模式属于同一系列。文章报告了一个具体负面结果:经过18次压力测试后发现,LLM自我评估作为二元解析质量判定标准本身不可靠;对生成答案进行独立LLM的 groundedness 检查能够捕捉到循环信号遗漏的问题。
系列文章前序内容:
- 文档智能:系列简介。说明系列构建的模块及其顺序。
有效与失效的实践
- 基线企业级RAG:从PDF到高亮答案。四模块完整流程:PDF输入,高亮答案输出。
- 嵌入向量并非魔法:RAG检索的可预测失效模式。说明嵌入相似性适用场景(同义词、拼写错误、改写)与失效场景(未知术语、否定、术语与答案相关性),以及如何继续使用。重排序器也并非魔法:交叉编码器层何时值得成本投入。量化交叉编码器相对于双编码器嵌入的增益,并说明何时值得承担延迟成本。
- RAG不是机器学习,机器学习工具箱解决的是错误问题。解释块大小调整和微调优化了错误目标;应根据问题类型进行路由。
- 从正则表达式到视觉模型:哪种RAG技术适合哪种问题。两个维度(文档复杂度与问题控制)帮助选择对应技术。生产环境中常见的10个RAG错误。按模块分类的10个生产错误及其修复方案。
文档解析
- 超越extract_text:驱动RAG质量的PDF双层结构。解析模块的第一部分:文档特性、信号与摘要。
- 停止从PDF返回平面文本:RAG需要的关联表格。解析模块的第二部分:所有下游模块读取的关联表格。使用EasyOCR解析扫描PDF用于RAG:免费OCR提供文字而非文档。传统OCR的局限:文本恢复但结构丢失。
问题解析
- RAG问题也需要解析:将用户字符串转化为检索与生成简报。问题解析的论点:为何用户字符串需要与文档相同的解析,以及如何拆分为检索简报与生成简报。
- 问题解析器从用户字符串提取的内容:关键词、范围、形态、分解、澄清。解析器直接从用户问题读取的五类列及其填充代码。
- 分发解析后的RAG问题:分块策略、模型层级、激活项和审计。解析器基于用户输入字符串和文档配置文件做出的决策:分发机制、激活项、完整模式、审计追踪(pipeline_trace.json)以及经纪-语料库的流程解析。澄清循环与学习默认值:当问题不够精确时。当问题过于模糊时进行针对性澄清,以及从答案中学习到的默认值。
检索
- 检索是过滤而非搜索:企业级RAG的思维模型。将检索重新定义为对line_df和toc_df的过滤操作:锚点精简,上下文内容丰富。
- RAG的锚点检测:并行检测器,最后进行一次LLM调用。并行锚点检测器:始终启用关键词匹配,同时使用嵌入向量,最后进行一次LLM调用。
- 让LLM选择正确的RAG页面:检索结束时的仲裁模式。LLM仲裁器:按理由对候选结果排序,输出一个类型化JSON。上下文工程:每个答案背后的四种类型化输入。基于结构的上下文工程:四个类型化组件(固定系统提示、检索到的段落、文档上下文块、PromptContext包装器)共同构成单文档RAG的LLM调用。
生成
- 使RAG生成返回类型化契约:引用标注、类型化值和自我检查(链接待补充)。答案模式作为契约:类型化值、带证据跨度的条目、自我评估字段,以及流水线自行计算的完整性信号。
- 从基础提示加上每个问题所需的规则组装每个RAG生成提示(链接待补充)。分发器:固定BASE提示加上每个问题所需的规则,从注册表中选择模式,并在每次调用时保留完整追踪记录。
- 在用户看到RAG答案前进行验证:跨度、引述和反馈循环(链接待补充)。后生成验证器(跨度、逐字引述、格式),"未找到"作为一级答案类型,以及闭合流水线的反馈循环。
单文档流水线
- 用于PDF的生产级RAG流水线:关系型解析、目录检索、类型化答案(链接待补充)。每个砖块逐步升级一个契约:关系型解析、语料库感知问题、目录路由检索、类型化答案。
- 通过上下文工程阻止RAG幻觉:一个流水线处理四种截然不同的PDF(链接待补充)。四个升级后的砖块连接成一个调用,在论文、合规文档和目录损坏文档上端到端运行。
- 通过自适应PDF解析进行循环工程:先使用低成本解析,仅在需要时升级到更复杂的解析器(链接待补充)。升级级联机制和免费的确定性检查,在支付更深度解析费用前标记解析失败。
作者信息
查看angela shi的所有文章
文档处理
,
解析
RAG
RAG架构
视觉语言模型
分享本文
- 在Facebook上分享
- 在LinkedIn上分享
- 在X上分享
Towards Data Science是社区出版物。提交您的见解以触达全球受众,并通过TDS作者支付计划获得收益。
更新为实际投稿URL
为TDS撰写文章
✦ 结束CTA ✦