ARTICLE · 1298218
使用 Raggae 构建面向复杂文档的 RAG 解析流程:版面分析、阅读顺序与区域关联
点击上方“Deephub Imba”,关注公众号,好文章不错过 !
读文档时,我们会自然地把价格对应到表格中的物品,把图注和图片联系起来,也能分清处于同一高度、却分别属于两栏的段落。文档中的这些空间关系对理解内容很有帮助。 但是目前文档处理流程一般情况下都是分块之前就把全部内容展平成一个字符串,原有的空间关系可能随之丢失。
例如,用户向 RAG 系统提出这样的问题:
“我们在运输标签上花了多少钱?”
答案虽然写在原始文档里,但如果摄取时价格与物品名称脱离了对应关系,系统即使检索到正确页面,也可能向模型提供错误证据。
版面分析的作用是找出文档中的内容区域及其位置。
RAG 流水线可以利用这份版面映射,让不同读取器分别处理段落、表格和图像,再根据位置关系拼接上下文,避免完全依赖文件内部字节的存储顺序。
下面会以具体文档为例,介绍表格和插图定位、阅读顺序推断,以及重复页眉识别等任务。
示例使用 Python SDK Raggae。它将文档处理任务拆分为独立的工作器,其中的版面分析模块可以完成上述工作。
pip install raggae同时包含分栏、表格和插图的 PDF
段落、表格、图片和图注往往混排在同一份文档中。正文可能分成两栏,表格横跨两栏,图表则出现在下一页。
展平处理容易打乱栏间顺序,让表格数值与列标题失去对应关系,甚至漏掉图表。若将全部内容同时送往文本和表格读取器同一张表还可能被提取两次。
示例文件 complex-report.pdf 共两页。第一页交替出现分栏正文和跨栏表格;第二页包含图表、图注及后续文字。

NativePdfLayoutAnalyzer 根据 PDF 内部的字符、线条和光栅图像位置,把文字划分为候选文本块,找出带表格线的区域,并记录图表图像的坐标。
from raggae.documents.layout_analysis import NativePdfLayoutAnalyzer pdf_worker = NativePdfLayoutAnalyzer()
from collections import Counter pdf_layout = pdf_worker.analyze("complex-report.pdf") print(pdf_layout.outcome) print("pages:", len(pdf_layout.surfaces)) print("regions:", dict(Counter(region.kind for region in pdf_layout.regions))) for region in pdf_layout.regions: if region.kind in ("table", "image"): print(region.id, region.kind, region.bbox)
结果如下
success pages: 2 regions: {'text': 22, 'table': 1, 'image': 1} page-1-r8 table (48.0, 312.0, 564.0, 420.0) page-2-r5 image (48.0, 180.0, 564.0, 402.0)
结果列出了供后续处理的文本块、一张表和一张图。表格单元格里的文字不会重复纳入普通文本区域,因此文本和表格两条处理路径不会重复提取这些内容。
可以用 Raggae 的 DocumentRegionRenderer 在原始页面上画出区域框。它会为每页生成带标注的 Pillow 图像,显示图像仍需由调用方完成。先安装 PDF 渲染依赖:
pip install 'raggae[layout-visual]' from raggae.documents import DocumentRegionRenderer renderer = DocumentRegionRenderer()
在 Jupyter Notebook 中:
from IPython.display import display previews = renderer.render(pdf_source, layout=pdf_layout) try: for page_number, preview in previews.items(): print(f"Page {page_number}") display(preview) finally: for preview in previews.values(): preview.close()
Notebook 的display 用来显示图像。其他程序也可以先调用 preview.save("page.png") 保存,再关闭预览对象。
图中的蓝框对应文本,绿框对应表格,橙框对应图像。

区域的类型和坐标会随结果一同保留,读取器可以据此选定处理范围。 有了区域位置,还可以推断阅读顺序,并尝试关联图片及其附近的说明文字。
下一个应该读取哪个区域?
定位框只能说明内容在哪里。为了正确读取这份报告,还需要确定双栏文字、跨栏表格以及下一页图片之间的先后关系。
GeometricReadingOrderResolver 直接读取已有的版面结果,根据矩形之间的空隙建立先后链接,无须重新解析 PDF:
from raggae.documents.layout_analysis import GeometricReadingOrderResolver resolver = GeometricReadingOrderResolver()
order = resolver.resolve_order(pdf_layout, direction="ltr") print(order.outcome, "links:", len(order.edges)) print("unresolved:", len(order.unresolved_region_ids)) for edge in order.edges: if edge.before_region_id in ("page-1-r8", "page-2-r5"): print(edge.before_region_id, "->", edge.after_region_id, edge.basis)
结果如下:
success links: 23 unresolved: 0 page-1-r8 -> page-1-r9 horizontal_gap page-2-r5 -> page-2-r6 horizontal_gap
比如,结果建议先读图片区域 page-2-r5,再读附近的文字 page-2-r6。该链接的依据是 horizontal_gap(水平间距)。这里推断的是顺序,并未判定文字就是图片的图注。
接着用 DocumentReadingOrderRenderer 绘制这些链接:
from raggae.documents import DocumentReadingOrderRenderer order_renderer = DocumentReadingOrderRenderer()
from raggae.documents import DocumentReadingOrderRenderer order_previews = order_renderer.render( pdf_source, layout=pdf_layout, order=order, ) try: display(order_previews[2]) finally: for preview in order_previews.values(): preview.close()
图中箭头表示区域之间的先后链接,数字表示该页建议的读取次序。

图片和文字仍保留为两个区域,链接只负责记录它们之间的关系。 组装提取结果时,应用可以参考这些链接安排内容顺序。
常见的 PDF 版面形式
位于普通段落之间的采购表格
在这份采购报告中,带边框的表格位于介绍段落与交付说明之间,其中有一条 Shipping labels / 600 / $90(运输标签/600/90 美元)的记录。表格需要整体保留,不能把前后的普通段落一并纳入。

Raggae 将表格圈定为独立区域,保留前后段落的边界。后续读取器便能同时看到物品、数量和金额列。
通栏引言下方的三栏正文
这一页先是通栏引言,中间分三栏介绍不同团队的进展,最后又回到通栏结语。按文字高度直接拼接,会把不同团队的内容交错混排。

Raggae 会分别归组各栏文字,引言与结语也各有自己的区域,便于后续按原有结构读取。
旋转后的页面
这页 PDF 的底层页面方向为纵向,显示时却旋转成了横向,因此返回的内容坐标必须以旋转后的页面为准。

Raggae 会把旋转因素计入计算,让区域框对齐页面上实际显示的文本和表格。
两张各自带有附近说明文字的插图
页面里有两张嵌入式图表,旁边各有一段说明。两张图必须分别定位,文字标签也需要由文本读取器单独处理。

Raggae 为两张图分别生成图像区域,也标出附近文字的位置。后续处理时,可以依照这些坐标提取图像,并寻找对应说明。
版面映射究竟记录了什么?
内容发现工作器统一返回 LayoutAnalysisResult,其中几个字段的含义如下:
surfaces:承载内容的载体,例如 PDF 页面、幻灯片、工作表、图像帧或连续的文档正文。regions:识别出的内容区域,每个区域都有 ID、类型及原始文件中的位置。bbox:在存在物理坐标时表示矩形区域,依次记录左、上、右、下四个边界。findings:有关识别覆盖缺失、处理限制或问题的说明。
PDF 的矩形坐标以显示页面左上角为原点,单位是点(point);图像坐标使用像素。未经渲染的 Word 文档和工作表只有结构化元素位置,不能硬套页面坐标。
版面映射记录的是区域和位置,不含最终提取的段落正文或独立图像文件。区域 ID 也不表示阅读顺序。要让后续读取器准确找到原始元素,需要将版面映射和源文件一并保存。
图片嵌在表格里的 Word 报告
采购报告可能含有标题、说明、费用表,还可能在参考表中嵌套另一张表和图片。如果只遍历 Word 正文最外层的段落,会漏掉表内信息;如果把每个单元格的段落都递归当成正文处理,又会重复提取。
示例文件 receiving-report.docx 的第一页是一张采购表;第二页的参考表左边嵌套了小表格,右边嵌入图片。图中的青绿色矩形代表示例图片。

第一页:采购表格位于普通段落之间。

第二页:图片位于右侧表格单元格内。
Word 原本就把这些内容保存为结构化元素。DocxLayoutAnalyzer 可以沿文档结构定位,无须根据渲染后的像素猜测。
from raggae.documents.layout_analysis import DocxLayoutAnalyzer analyzer = DocxLayoutAnalyzer()
word_layout = analyzer.analyze("receiving-report.docx") print(word_layout.outcome) print(dict(Counter(region.kind for region in word_layout.regions))) for region in word_layout.regions: if region.kind in ("table", "image"): print(region.id, region.kind, region.location.child_indexes)
结果如下:
success {'heading': 2, 'text': 3, 'table': 2, 'image': 1} body-r3 table (2,) body-r6 table (6,) body-r7 image (6, 2, 1, 2, 0, 0)
下图用高亮区域对应分析结果中的元素 ID。输出中给出的源位置,是元素在原始文档中的路径。

两张顶层表各自保留为一个表格区域,单元格段落和嵌套表不会再额外成为正文区域。第二张表里的图片则有独立的精确位置。
例如,路径 (2,) 指正文中的第三个元素;更长的图片路径会继续深入表格的子元素。位置数据还包含内部部件名称 word/document.xml,其他读取器因此可以定位到同一个文档元素。
分析结果将 Word 正文视作连续的 flow。其中的元素路径能够跨过显式分页符,保留文档原有结构。
其他 Word 场景
使用自定义标题样式的员工手册:内置标题样式及其派生样式会被识别为
heading,为后续文本块组装保留章节边界。表格里带图片的参考资料:表格和内嵌图片均保留精确位置,方便表格读取器和图像读取器分别处理。
存在重复措辞的报告:元素路径直接指向原始段落或表格,后续读取器无需通过搜索相同文字来区分不同位置。
形状排列顺序不等于阅读顺序的演示文稿
发货简报里有标题、引言、库存表、图片和图片下方的备注。只提取文字会遗漏图片和表格结构。按文件中形状对象的存储列表依次读取也不可靠:对象的堆叠顺序不一定等于演示时的阅读顺序。
图中是根据 shipment-briefing.pptx 第一张幻灯片的原始形状绘制的示意图,其中有文字、表格和蓝色示例图片。第二张幻灯片会用于后面的阅读顺序示例。

PptxLayoutAnalyzer 同时返回形状在源文件中的位置路径,以及它们在幻灯片上的坐标:
from raggae.documents.layout_analysis import PptxLayoutAnalyzer analyzer = PptxLayoutAnalyzer()
slide_layout = analyzer.analyze("shipment-briefing.pptx") print(slide_layout.outcome) print("slides:", len(slide_layout.surfaces)) print(dict(Counter(region.kind for region in slide_layout.regions))) for region in slide_layout.regions: if region.kind in ("table", "image"): print(region.id, region.kind, region.bbox)
结果:
success slides: 2 {'heading': 1, 'text': 4, 'table': 1, 'image': 1} slide-1-s2 table (40.0, 200.0, 340.0, 340.0) slide-1-s3 image (400.0, 200.0, 580.0, 320.0)

这些示意图在相同的幻灯片布局上标出了返回的矩形框和区域 ID。
表格和图片各有单独的位置数据,供对应读取器使用。每个区域也记录源幻灯片部件和形状路径。例如(3, 1) 指第四个形状(组合对象)里的第二个子元素。
形状框坐标以幻灯片左上角为原点,阅读顺序建议则另行保存。
其他演示文稿场景
组合、缩放或镜像后的图形。 子元素坐标以所在组合为参照。镜像组合的示例中,第一个子元素最终落在右侧,坐标为 (380, 200, 580, 260),第二个落在左侧。工作器会先计算包含嵌套组合在内的各种变换,再返回幻灯片坐标。结果只保留末端的内容区域,不额外添加重叠的组合容器框。
下方文本框比上方文本框先创建。 第二张幻灯片保留了两个文本框的源位置和实际坐标。几何解析器可以据此建议先读上方文本框,不受创建先后影响。
跨多页的演示文稿。 每张幻灯片都有自己的内容载体和形状坐标,表格和图片即使分属不同页面,也不会被混在一起。
包含多个独立内容区域的工作簿
仓库工作簿的一张表中,左侧可能是库存,右侧是费用,下方还有一个合并单元格标签。若直接把整片使用区域当作单张表格,三个内容区和中间的空列都会被混在一起。
示例 stock-and-costs.xlsx 的 Warehouse 工作表左侧存放库存,右侧记录费用,下方是合并单元格中的发货标签。第二张表包含一块数据网格和两个分布在对角位置的标签。

原始工作表内容。
from raggae.documents.layout_analysis import XlsxLayoutAnalyzer analyzer = XlsxLayoutAnalyzer()
sheet_layout = analyzer.analyze("stock-and-costs.xlsx") print(sheet_layout.outcome) print(dict(Counter(region.kind for region in sheet_layout.regions))) for region in sheet_layout.regions: print(region.kind, region.location.sheet_name, region.location.cell_range)
结果
success {'table': 1, 'unknown': 5} table Warehouse A1:B4 unknown Warehouse A7:D7 unknown Warehouse F2:G4 unknown No declared table A1:B3 unknown No declared table F1 unknown No declared table G2

声明过的表格保留 table 类型,其余有内容的区域标记为 unknown。每个区域同时记录单元格范围,供后续读取器判断具体内容。
分析结果将库存、费用和合并标签分开;合并标签只出现一次,对角位置的两个标签也各自独立。区域还会注明工作表名称,因此不同工作表中的同一单元格地址不会混淆。
其他电子表格场景
锚定在 E6 的 Logo:图像区域的位置记录工作表、图像索引和锚定单元格,方便图像读取器继续处理。
A1 中存有
0,Excel 最后一个单元格中存有False:这一稀疏表格示例只返回两处非空内容区域,无须扫描中间的每个单元格。两个值都属于有效内容,只有格式而没有值的单元格会被忽略。包含空白工作表的工作簿:空表仍保留自己的内容载体,但不会凭空生成内容区域,从而保留原有工作簿结构。
工作表使用单元格范围及绘图对象引用表示位置,不采用页面矩形框。
结构信息已经写在标签里的网页文章
保存的网页文章通常已经通过 HTML 标签标明标题、正文、表格和图片说明。过早去掉所有标签,会让读取器失去原本可以直接利用的结构信息。
warehouse-report.html 的预览包含两级标题、库存表、图片引用、图注和结尾文字。示意图根据文件里保存的 HTML 元素绘制。

HtmlLayoutAnalyzer 直接检查这些元素,不抓取图片,也不运行网页脚本:
from raggae.documents.layout_analysis import HtmlLayoutAnalyzer analyzer = HtmlLayoutAnalyzer()
html_layout = analyzer.analyze("warehouse-report.html") print(html_layout.outcome) for region in html_layout.regions: print(region.kind, region.location.tag, region.location.child_indexes)
结果
success heading h1 (0, 1, 0, 0) text p (0, 1, 0, 1) heading h2 (0, 1, 0, 2, 0) table table (0, 1, 0, 2, 1) image img (0, 1, 0, 3, 0) caption figcaption (0, 1, 0, 3, 1) text p (0, 1, 0, 4)

轮廓框显示了预览中的元素类型和 ID。对应的原始位置,是上面输出的 HTML 元素路径。
表格及其自带的标题一起归入表格区域,图片的 figcaption 单独保留以供后续判断关联关系。元素路径从解析后文档的根节点起,按元素子节点计数,与屏幕坐标无关。读取器可以凭路径直接找到表格,无须再次搜索整个网页。
其他 HTML 场景
包含多个标题层级的文章。 标题标签能保留主标题和章节标题之间的区别,普通段落则成为文本区域。
同时包含段落和图片的表格。 表格及其单元格内容作为一个区域保留;内嵌图像元素也可以拥有独立位置,供图像读取器使用。
HTML 片段而非完整网页。 保存的文章片段也可以直接分析,其元素路径仍从解析结果的文档根节点开始。
整页内容都是一张图的扫描报告
扫描 PDF 的外观可能和普通 PDF 没有差别,但页面里的文字、表格、图表可能全部以像素形式存放在一张图里。此时,原生分析器找不到可直接读取的文本框或表格线。
OCR 能识别图中的文字,却不能据此确定哪些区域该交给表格读取器、哪些是图表。还需要视觉版面检测来划分区域。
示例 scanned-report.pdf 的第一页保留原生 PDF 内容,第二页把类似报告存成整页图片。两页看上去都有标题、正文、表格、图表、图注和页脚。下图展示第二页:

VisualLayoutAnalyzer 渲染 PDF 页面或打开图像文件,并把像素发送给指定的本地检测服务。检测服务预测带类别的区域框,工作器再把坐标转换到文档的坐标系。
可选服务包括使用 Paddle 版面检测器,以及使用 Docling Heron 模型等等不同的实现。两者上游项目都将版面检测用于定位和分类内容区域;各自完整的文档处理流程还包括其他步骤。
安装需要的后端:
pip install 'raggae[layout-visual,layout-docling]' # Alternative: pip install 'raggae[layout-visual,layout-paddle]'
模型权重需要事先从对应模型仓库下载。环境变量 RAGGAE_DOCLING_MODEL_DIR 应指向已经存在的本地 Heron 模型目录,实例化服务不会触发下载。推理过程在本地完成。
import os from raggae.documents.layout_analysis import ( DoclingLayoutService, VisualLayoutAnalyzer, ) service = DoclingLayoutService( model_path=Path(os.environ["RAGGAE_DOCLING_MODEL_DIR"]), device="cpu", ) visual_worker = VisualLayoutAnalyzer(service=service)
scan_pdf = Path("scanned-report.pdf") visual_layout = visual_worker.analyze(scan_pdf) print(visual_layout.outcome) for surface in visual_layout.surfaces: kinds = Counter( region.kind for region in visual_layout.regions if region.surface_id == surface.id_ ) print(surface.id_, dict(kinds))
结果
success page-1 {'table': 1, 'text': 5, 'image': 1, 'caption': 1, 'heading': 1} page-2 {'text': 5, 'table': 1, 'image': 1, 'caption': 1, 'heading': 1}
这两页都能得到候选文本、表格和图像区域,其中一页虽然没有原生文字,仍可以开展后续提取。

如果改用 Paddle,只需要替换注入的检测服务,无须修改工作器接口:
from raggae.documents.layout_analysis import PaddleLayoutService paddle_service = PaddleLayoutService( model_path=Path(os.environ["RAGGAE_PADDLE_MODEL_DIR"]), device="cpu", ) paddle_layout = VisualLayoutAnalyzer(service=paddle_service).analyze(scan_pdf)
替换检测服务不会改变工作器接口和返回结构,因此下游读取器、渲染器可以继续使用,应用只需选择合适的本地后端。 扫描页里的文本、表格和图像被划为不同区域后,相应读取器便能按坐标提取内容。
其他视觉分析场景
以 PNG 格式提供的收据或报告。 可以直接使用同一个工作器,无须先把图片封装成 PDF:
image_layout = visual_worker.analyze("scanned-page.png") surface = image_layout.surfaces[0] print(image_layout.outcome, surface.kind, surface.unit)
结果
success image px多帧 TIFF 或混合原生页与扫描页的 PDF。 工作器逐帧或逐页分析。视觉检测可以覆盖整个输入,但属于原生内容发现之外的可选方案,不会自动对每份 PDF 再跑一遍。
复用本地检测服务。 一次初始化后,可以将同一个服务对象传给多次分析任务,避免每处理一份文档就重新加载模型。
被错误拼接的双栏正文
定位所有文本块仍不足以确定阅读顺序。研究文章通常要先读完左栏,再接着读右栏;若只按纵向坐标排序,就可能在两栏之间反复跳转。
可以从区域之间的空白推断顺序:竖向空白带通常用于分隔栏,横向间距可以区分标题与正文。GeometricReadingOrderResolver 基于现有版面映射返回区域先后关系建议,无须重新打开文件。
前面处理复杂报告时,我们已经用它保持表格的整体性,并将图片排在邻近文字之前。原始区域的位置没有改变。
其他阅读顺序场景
先创建下方文本框的幻灯片。 在简报的第二张幻灯片中,下方文本框先于上方文本框存入源文件。解析器可以根据实际坐标重新提出阅读顺序:
slide_order = resolver.resolve_order(slide_layout) for edge in slide_order.edges: if edge.before_region_id.startswith("slide-2-") and edge.after_region_id.startswith("slide-2-"): print(edge.before_region_id, "->", edge.after_region_id)
slide-2-s1 -> slide-2-s0返回的链接从上方文本框指向下方文本框,与两个对象的创建时间无关。

从右向左阅读的分栏。 传入 direction="rtl",即可指定各栏按从右到左的顺序读取。这项版面约定由调用方明确设置。
正文之间的宽表格。 阅读顺序中仍将表格看作一个整体,避免单元格与周围段落交错。
跨多页的文档。 页面间的链接把有内容的页面连起来,供后续按页序组装。
每个文本块都混入手册标题的问题
一本 100 页的手册可能反复出现公司名称、内部使用声明和页码。若每次分块时都把这些文字收入正文,它们会占用文本块的容量,还可能打断连续内容。 但也不能见到重复文字就删除。“始终记录货运单号”可能是作者有意在不同章节反复提醒的操作要求。
示例 handbook.pdf 有两页:章节标题不同,手册页眉和内部使用页脚重复出现,页码随页变化,正文中部还重复了一条提醒。识别时需要结合文字和位置。

from raggae.documents.layout_analysis import PdfRepeatedMarginDetector analyzer = NativePdfLayoutAnalyzer()
handbook_pdf = Path("handbook.pdf") handbook_layout = analyzer.analyze(handbook_pdf) margins = PdfRepeatedMarginDetector().detect(handbook_layout, handbook_pdf) for group in margins.groups: print(group.kind, group.basis, len(group.region_ids))
结果
header repeated_text 2 footer repeated_text 2 footer page_number 2

图中的绿框是检测器提出的候选页边分组。正文中的提醒被排除在外;虚线标出默认的页面上下边缘带。
工作器从创建版面映射的同一份 PDF 读取少量原生文本,比较文字内容和跨页相对位置,并识别符合规则的变化页码。
这些分组只作为候选结果单独保存,不修改原始文本。后续组装时可以选择忽略正文中的重复页边元素或将其写入元数据、单独标注。
其他重复页边内容场景
变化的页码与发票编号。Page 1 of 2 和 Page 2 of 2 在示例中被识别为一组页码,Invoice 1001 和 Invoice 1002 则不会匹配。工作器不会抹去所有数字来凑出重复项;Release 2026 这样的固定标签仍可作为普通文本匹配。
重复出现在正文中的提醒。 两页都有同一条要求,但它位于页面中部,因此没有落入页眉页脚分组。是否重复以及出现在哪里,需要一起判断。
尺寸不同但位置相近的页眉。 比较位置时使用的是相对于各页尺寸的比例,不要求所有页面具有相同宽高。
让图表与解释文字保持关联
一张柱状图有四根柱子,图下方有一行说明,另一个较远的段落则讨论不同内容。把图下文字与图表对应起来,可以在后续组装内容时保留必要上下文。
在 caption-report.pdf 中,第一页的说明位于图表下方,第二页的说明位于表格上方。

RuleBasedRegionRelationshipDetector 利用已有版面结果,根据距离和对齐程度提出图注关联候选;对于包含关系,则参考元素结构路径或外接矩形。
from raggae.documents.layout_analysis import RuleBasedRegionRelationshipDetector caption_layout = pdf_worker.analyze("caption-report.pdf") relationship_worker = RuleBasedRegionRelationshipDetector() links = relationship_worker.detect(caption_layout) print(links.outcome) for link in links.relationships: print(link.kind, link.source_region_id, "->", link.target_region_id, link.basis)
结果
success caption_candidate page-1-r5 -> page-1-r4 proximity caption_candidate page-2-r4 -> page-2-r5 proximity

检测器能为图表或表格上下方的邻近说明建立对应链接。输出中的 proximity 表明判断依据是空间接近,供后续组装阶段进一步使用。
将这些功能组合使用
前面把各项功能分开调用,是为了展示工作器各自负责的任务。在常规摄取流程里可以统一调度这些步骤。
DocumentLayoutAnalyzer 先选定内容发现工作器,再按配置运行适用于当前版面的分析:
from raggae.documents.layout_analysis import DocumentLayoutAnalyzer report = DocumentLayoutAnalyzer().analyze(handbook_pdf) print(report.outcome) print("regions:", len(report.layout.regions)) print("margin groups:", len(report.repeated_margins.groups))
结果
success regions: 16 margin groups: 3
最终报告包括原始 layout 和独立的 reading_order、relationships、repeated_margins。它们针对同一份版面映射分别计算。比如检测出页眉后,也不会在阅读顺序解析之前悄悄删去页眉区域。

默认根据扩展名选择 PDF、DOCX、PPTX、XLSX 或 HTML 分析器。输入为原始字节时,可用 source_format="pdf" 明确指定 PDF 类型。
如果只关心内容的位置,可以关闭后续分析:
discovery_only = DocumentLayoutAnalyzer().analyze( handbook_pdf, reading_order=False, relationships=False, repeated_margins=False, )
处理图像文件时,需要设置 visual_service=service。对扫描版 PDF 采用视觉检测,则需要直接注入相应分析器:
scan_report = DocumentLayoutAnalyzer( analyzer=VisualLayoutAnalyzer(service=service), ).analyze(scan_pdf, repeated_margins=False)
表格边界、段落在页面上的位置、幻灯片中形状的坐标,以及图注可能对应的对象,都无法仅靠一串纯文本完整保留。版面分析会记录这些信息。 后续读取器便能各司其职:从文本区域读取文字,从表格区域提取表格,从图像区域处理图片,再借助位置数据将结果重新关联。 接下来的处理阶段可以提取实际内容,参照阅读顺序和区域关系进行组装,再把上下文放入可检索的文本块。
先定位证据,随后提取内容,再依据语义组织各部分。 文档结构如果在摄取阶段得到保留,RAG 系统回答问题时就更容易找到正确的依据。
作者:Okan Yenigün
如果你希望把模型、工具、状态、权限、执行环境和插件生命周期放在同一张架构图里理解,可以继续阅读:
《DeepSeek Harness 技术入门与架构原理》
本书适合 AI 应用工程师、Agent 开发者,以及希望从“模型调用”继续深入到 Agent Runtime 的技术读者。
喜欢就关注一下吧:
点个 在看 你最好看!















































































