跳到主要内容

数据模型、富化与面向 RAG 的输出

30 秒导读: 前面几章讲的是「怎么把一份文件解析开」——入口分派、后端、流水线、逐阶段的模型。这一章讲产物端:所有路径最终都汇成同一个数据结构 ConversionResult,里面装着一个 DoclingDocument(统一文档表示)。这份统一表示可以被富化(往节点上贴描述、分类、公式),可以被导出成 Markdown/HTML/JSON/DocTags 等格式,也可以被**切块(chunking)**成带元数据的小块喂给 RAG 检索。理解了这一章,你就明白 Docling 为什么值钱:它把「一百种输入格式」统一成「一种可编程、可切块、可检索的文档对象」。

本章是本组文档的收束章。想先看全景,回到 index;想知道输入怎么进来,看 入口与分派后端层流水线层;想知道 PDF 上那些识别模型怎么跑,看 PDF 识别流水线。这一章接在它们后面:模型跑完之后,数据长什么样、怎么出去。


1. 这是什么(零基础也能懂)

一句话定义

Docling 的数据模型就是「一份文档在内存里被表示成什么」;输出端就是「这份表示怎么变成你能用的东西」。

用一个类比建立直觉

把一次转换想象成一条装配线的成品下线口:

  • 原料(PDF 字节、Word、网页……)从进料口进来,经过一节节工位(后端 → 各识别模型)。
  • 每一页先被组装成一个半成品托盘(Page + AssembledUnit)。
  • 所有托盘最后汇总、排好阅读顺序,压成一件统一成品——DoclingDocument
  • 成品连同它的质检报告(状态、错误、置信度、耗时)一起放进一个出货箱——ConversionResult
  • 出货箱到手后,你可以给成品再加工(富化)、换包装(导出成 md/html/json)、或切成零件(chunking)喂给检索。

为什么这件事重要

RAG(检索增强生成:先从你的资料里检索相关片段,再让大模型基于片段回答)最脏最累的活,是把各种格式的文档洗成结构化、可切块的文本。市面上大多数库要么只吃某一种格式,要么吐出一坨没有结构的纯文本。

Docling 的价值主张是:无论输入是什么格式,产物都是同一个 DoclingDocument——它有标题层级、有表格结构、有图片、有出处坐标(provenance)。有了这个统一表示,下游的富化切块就能对所有格式一视同仁地工作。这就是本章标题里「统一表示为何是 Docling 对 RAG 生态核心价值」的意思。


2. 顶层全景(数据怎么从「页」收敛成「文档」再出去)

怎么读这张图: 从上到下是时间顺序。左边是「每页各自的中间产物」,中间汇成「一份统一文档」,右边是「文档的三种去处」。

逐页处理(见 04 章)
┌───────────────────────────────┐
│ Page ① Page ② Page ③ ... │ 每页: size / predictions / assembled
│ └ AssembledUnit(该页元素) │ 元素 = TextElement / Table / FigureElement ...
└───────────────┬───────────────┘
│ _assemble_document(): 汇总所有页的 elements/headers/body

conv_res.assembled (AssembledUnit, 全篇打平的中间元素)
│ reading_order_model → heading_hierarchy_model

┌───────────────────────────────────────────────┐
│ DoclingDocument (统一表示) │ ← 来自外部 docling_core
│ 有阅读顺序 / 标题层级 / 表格 / 图片 / 出处坐标 │
└───────────────┬───────────────────────────────┘

┌────────────┼─────────────────────────┐
▼ ▼ ▼
① 富化 enrichment ② 导出 export ③ 切块 chunking
就地改写节点 save_as_markdown/html HybridChunker →
(贴描述/分类/公式) /json/doctags/vtt DocChunk(带 DocMeta 元数据)
│ │
▼ ▼
给人 / 存档 / 前端 喂给向量库 → RAG 检索

整件成品和它的质检报告,都装在 ConversionResult 这一个对象里。下表是这一章要拆解的几个关键部件:

部件是什么在哪
ConversionResult一次转换的总出货箱:输入 + 页 + 中间产物 + 最终文档 + 状态/错误/置信度datamodel/document.py:565
ConversionAssetsConversionResult 的父类,承载可序列化的产物(status/pages/document/...)datamodel/document.py:372
Page单页的容器:尺寸、解析结果、各模型预测、该页组装单元datamodel/base_models.py:431
AssembledUnit一批中间元素(文本/表/图)的打平集合datamodel/base_models.py:418
DoclingDocument最终统一文档(外部 docling_core 提供)来自 docling_core.types.doc,document.py:27 导入
ConversionStatus / ErrorItem / FailureCategory状态与错误模型datamodel/base_models.py:85 / 278 / 254
富化 _enrich_documentDoclingDocument就地改写节点pipeline/base_pipeline.py:111
导出 export_documents把文档存成各种格式cli/main.py:353
chunking把文档切成带元数据的块chunking/__init__.py(再导出 docling_core)

3. 核心数据模型(由外到里,逐层拆)

3.1 最外层:ConversionResult —— 一次转换的全部

每次转换产出一个 ConversionResult。它继承自 ConversionAssets,把「输入信息」和「可序列化的产物」分成两层。

先看产物层 ConversionAssets,它定义了转换到底产出了哪些东西(datamodel/document.py:372-384):

# 真实字段(datamodel/document.py:372),节选
class ConversionAssets(BaseModel):
status: ConversionStatus = ConversionStatus.PENDING # 成功/失败/部分成功...
errors: list[ErrorItem] = [] # 结构化错误清单
pages: list[Page] = [] # 逐页中间产物
timings: dict[str, ProfilingItem] = {} # 各阶段耗时
confidence: ConfidenceReport = Field(...) # 质量置信度报告
document: DoclingDocument = _EMPTY_DOCLING_DOC # ★ 最终统一文档

再看 ConversionResult 本身,它在产物之外补上输入与中间态(datamodel/document.py:565-572):

class ConversionResult(ConversionAssets):
input: InputDocument # 输入文档的元信息(路径/hash/格式/页数)
assembled: AssembledUnit = AssembledUnit() # 全篇打平的中间元素
_pdf_outline: Optional[list[_PdfOutlineItem]] = PrivateAttr(default=None)
# ↑ PDF 书签/目录,私有临时字段,不序列化;标题层级阶段消费完就置 None

一句话记住这套分层:

字段角色
输入input (InputDocument)我处理的是谁:路径、hash、格式、页数、大小、后端
中间pagesassembled半成品:逐页产物、打平后的元素
成品document (DoclingDocument)你真正要的那份统一文档
质检statuserrorsconfidencetimings转换得怎么样、哪里出错、多有把握、花了多久

ConversionAssets 还带了 save() / load()(document.py:409 / 481):把整箱产物打包成一个 ZIP(里面每个字段一份 JSON),文档部分用 document.export_to_dict() 保证 schema 稳定。这让「一次转换的完整结果」可以落盘、回读、复现。

3.2 单页容器:Page

DoclingDocument 是全篇的成品,而在成品成型之前,数据是按页攒的。Page 就是单页的容器(datamodel/base_models.py:431-447):

class Page(BaseModel):
page_no: int
size: Size | None = None # 页面尺寸
parsed_page: SegmentedPdfPage | None = None # 后端解析出的文本单元(cell)
predictions: PagePredictions = PagePredictions() # 各模型的预测挂这里
assembled: AssembledUnit | None = None # 本页组装好的元素

_backend: Optional["PdfPageBackend"] = None # 私有:PDF 页后端,组装后默认清空
_default_image_scale: float = 1.0
_image_cache: dict[float, Image] = {} # 私有:不同缩放比例的页图缓存

几个值得注意的设计:

  • predictions 是各识别模型的收件箱。 布局、表结构、图分类、公式、VLM 响应各占一个字段(PagePredictions,base_models.py:407)。04 章那些模型跑完,结果就落在这里。
  • cells 是只读视图。 page.cells 直接返回 parsed_page.textline_cells(base_models.py:449),没有解析页时返回空列表——不额外存一份,避免数据不一致。
  • 图片是懒加载 + 缓存。 get_image(scale)(base_models.py:457)按缩放比例从 _backend 取图并缓存进 _image_cache;后端一旦卸载,就只能吃缓存。_backend_image_cache 都是私有属性、默认在组装阶段被清掉,以免把整份 PDF 的像素都拖在内存里。

3.3 中间元素:Cluster / BasePageElement 及其家族

页要变成「文档」,得先把像素/文本聚成有语义的块。这一层的类型都在 base_models.py:

  • Cluster(base_models.py:297):最底层的「一坨」——一个 label(标题?表?图?)、一个 bbox(包围盒)、一个 confidence、下挂 cells(文本单元)和 children(可嵌套)。这是布局模型直接吐出来的东西。
  • BasePageElement(base_models.py:310):在 Cluster 之上包一层语义元素,带 label / id / page_no / cluster / text。它是下面这几类的共同基类。

具体的元素类型分成几种,共同点是都携带自己的 Cluster(即出处与坐标):

元素类型额外携带什么定义
TextElementtext、可选 hyperlinkbase_models.py:375
Tableotsl_seq(表结构序列)、num_rows/num_colstable_cellsbase_models.py:363
FigureElementannotationsprovenancepredicted_classconfidencebase_models.py:380
ContainerElement无(仅用于表单 / 键值区域的类型标注)base_models.py:357

这四种被并成一个联合类型 PageElement(base_models.py:415),而 AssembledUnit(base_models.py:418)就是它们的三个列表:

class AssembledUnit(BaseModel):
elements: list[PageElement] = [] # 全部元素
body: list[PageElement] = [] # 正文流
headers: list[PageElement] = [] # 页眉类

从「页」到「文档」的临门一脚在流水线里(pipeline/standard_pdf_pipeline.py:997-1009):_assemble_document() 把每页 assembledelements/headers/body 全部 extend 到一起,拼成 conv_res.assembled,然后交给两个模型收尾:

# standard_pdf_pipeline.py:1005
conv_res.assembled = AssembledUnit(elements=elements, headers=headers, body=body)
conv_res.document = self.reading_order_model(conv_res) # 排阅读顺序 → DoclingDocument
conv_res.document = self.heading_hierarchy_model(conv_res) # 建标题层级

关键理解: AssembledUnit 是「打平、无顺序」的中间态;reading_order_model 才把它排成有阅读顺序、有层级的 DoclingDocument(实际构造见 utils/glm_utils.py:70to_docling_document,通过 add_text / add_table / add_picture 往文档里塞节点)。

3.4 状态与错误模型:ConversionStatus / ErrorItem / FailureCategory

一次转换不是「成或不成」两态。Docling 把它拆得很细。

ConversionStatus(base_models.py:85)——转换整体走到哪一步 / 结果如何:

含义
PENDING / STARTED未开始 / 进行中
SUCCESS干净成功(且无错误)
PARTIAL_SUCCESS完成了,但记录了错误
FAILURE失败
SKIPPED跳过

这里有个诚实的小设计:流水线在 base_pipeline.py:86 明确规定「只要 errors 非空,就绝不报 SUCCESS」,而是降级成 PARTIAL_SUCCESS——避免「带病成功」骗过下游。

ErrorItem(base_models.py:278)——一条结构化错误,不只是一句话:

class ErrorItem(BaseModel):
component_type: DoclingComponentType # 谁出的错:后端/模型/组装器/用户输入/流水线
module_name: str
error_message: str
category: FailureCategory = FailureCategory.UNKNOWN # 语义分类,便于过滤
page_no: int | None = None # 定位到具体某页(可为空=文档级)

FailureCategory(base_models.py:254)——把错误按语义归类,这样「任务级」和「文档/页级」的错误能用同一套词汇表沟通(注释里点明:POLICY / SOURCE_UNAVAILABLE / TIMEOUT 是共享类别,BACKEND_FAILURE / INFERENCE_FAILURE 是文档/页级专有)。ConversionAssets 上还有一组便捷谓词:has_timeout_errors() / has_inference_errors() / has_parse_errors()(document.py:397-407),让下游一行判断「是不是超时/推理失败/解析失败」。

ConfidenceReport(base_models.py:607,继承 PageConfidenceScores at 537)是另一维质检:它对 parse / layout / table / ocr 四项打分,并算出 mean_grade / low_grade(QualityGrade 枚举:poor/fair/good/excellent)。RAG 场景里,这让你能按质量阈值筛掉解析得太差的文档,而不是照单全收。


4. 最终产物:DoclingDocument(外部依赖,统一表示的核心)

DoclingDocument 不在本仓库定义,而是从外部包 docling_core 引入的(document.py:27 显式 import,注释写明 DO NOT REMOVE; explicitly exposed from this location)。本仓库把它当作最终统一表示来产生和消费。(以下对其内部结构的描述属外部依赖,标 (inferred);本仓库只依赖它对外的方法。)

它对本章下游两件事至关重要:

4.1 iterate_items() —— 遍历文档节点的统一入口

富化和导出都靠它。这是 DoclingDocument 暴露的遍历器,产出「(节点, 层级)」序列 (inferred, 来自 docling_core)。本仓库到处这样用:

# base_pipeline.py:115(富化时遍历)
for doc_element, _level in conv_res.document.iterate_items():
...
# standard_pdf_pipeline.py:1028(生成图片时遍历)
for element, _level in conv_res.document.iterate_items():
...

为什么重要: 有了统一的 iterate_items(),任何「对文档里每个节点做点事」的逻辑——贴描述、抽图片、就地改写——都不用管这份文档最初是 PDF 还是 Word。这就是统一表示的红利。

4.2 导出方法 —— 换包装

DoclingDocument 自带一组导出/落盘方法,CLI 直接调用它们(见下一节)。它们把同一份文档渲染成不同格式:save_as_markdown / save_as_html / save_as_json / save_as_yaml / save_as_doctags / save_as_vtt / export_to_doclang / export_to_dict


5. 富化(enrichment):在文档上就地改写节点

5.1 它要解决的小问题

解析出的文档节点常常「有形无神」:一张图只知道位置,不知道画了什么;一段公式只是一坨文本,没有 LaTeX。富化就是在文档成型后,再跑一遍模型,往这些节点上补内容——图片描述、图片分类、公式识别、图表数据抽取等。

5.2 思路:统一遍历 + 批处理 + 就地改写

富化的骨架在 pipeline/base_pipeline.py:111_enrich_document,极简且通用:

# base_pipeline.py:111,节选
def _enrich_document(self, conv_res):
def _prepare_elements(conv_res, model):
for doc_element, _level in conv_res.document.iterate_items(): # ① 遍历每个节点
prepared = model.prepare_element(conv_res=conv_res, element=doc_element)
if prepared is not None: # ② 模型自己筛
yield prepared
for model in self.enrichment_pipe: # ③ 逐个富化模型
for element_batch in chunkify(_prepare_elements(conv_res, model),
model.elements_batch_size): # ④ 攒成批
for element in model(doc=conv_res.document,
element_batch=element_batch): # ⑤ 就地改写
pass # Must exhaust! ← 生成器必须被抽干,副作用才落到文档上

一句话概括这五步:遍历文档所有节点 → 每个富化模型挑出它能处理的 → 攒成批 → 把批喂给模型,模型直接在 DoclingDocument 上改节点。

注意那句 # Must exhaust!:模型的 __call__ 返回的是生成器,副作用(改写节点)发生在迭代过程中,所以外层用一个空 for 把它抽干,确保改写真的发生。

5.3 富化模型的契约:GenericEnrichmentModel

所有富化模型实现同一个抽象基类(models/base_model.py:146):

class GenericEnrichmentModel(ABC, Generic[EnrichElementT]):
elements_batch_size: int = settings.perf.elements_batch_size
def is_processable(self, doc, element) -> bool: ... # 这个节点我处理吗?
def prepare_element(self, conv_res, element): ... # 把节点转成我要的输入(否则 None)
def __call__(self, doc, element_batch): ... # 批量处理并改写

两个常用子类划出两种「输入形态」:

子类喂给模型的是什么定义
BaseEnrichmentModel直接是文档节点 NodeItembase_model.py:166
BaseItemAndImageEnrichmentModel节点 + 裁好的图片(ItemAndImageEnrichmentElement)base_model.py:175

后者的 prepare_element(base_model.py:181)会为图片类节点裁出图像一并打包——图片描述、图片分类这类需要「看图」的富化就走这条路。富化流水线本身在 ConvertPipeline.__init__ 里按选项拼装(base_pipeline.py:177 起,如 DocumentPictureClassifier 等)。


6. 导出:同一份文档,多种包装

富化之后,文档就可以出货了。CLI 的 export_documents(cli/main.py:353)是导出总入口。它按一组布尔开关,逐个调用 DoclingDocument 的导出方法:

输出格式调用的方法代码
JSONsave_as_jsonmain.py:382
YAMLsave_as_yamlmain.py:390
HTML / 分页 HTMLsave_as_html(split_page_view=…)main.py:398 / 422
纯文本save_as_markdown(strict_text=True)main.py:432
Markdownsave_as_markdownmain.py:442
DocTagssave_as_doctagsmain.py:465
WebVTTsave_as_vttmain.py:471
DocLangexport_to_doclang(手动写文件)main.py:478

这些开关不是散落的。cli/export_utils.py:28_export_flags_from_formats 把用户请求的 OutputFormat 列表展开成 export_* 布尔字典,再 splat 进 export_documents(main.py:9401236**export_flags)。本地 convert 与远程 convert-remote 共用这一个函数,保证两条命令输出选择完全一致。

OutputFormat 枚举本身在 base_models.py:122:MARKDOWN="md" / JSON / YAML / HTML / HTML_SPLIT_PAGE / TEXT / DOCTAGS / VTT / DOCLANG

一个值得留意的细节——图片嵌入。 不是所有格式都能内嵌图片。export_utils.py:8 定义了一个集合 _OUTPUT_FORMATS_NOT_SUPPORTING_IMAGE_EMBEDDING = {TEXT, DOCTAGS, VTT, DOCLANG};_should_generate_export_images(export_utils.py:18)据此决定:如果所有目标格式都不支持嵌图、或用户选了 PLACEHOLDER 模式,就干脆不生成导出图片,省一大笔开销。

另一个诚实兜底(main.py:445):Markdown 导出后会检查输出是否为空(_is_empty_output),空了就补一条 ErrorItem 并把状态降为 FAILURE——不让「悄悄导出个空文件」蒙混过关。


7. 面向 RAG 的输出:chunking

导出是「给人看 / 存档 / 喂前端」;chunking 才是给 RAG 检索用的产物端

7.1 它要解决的小问题

向量检索不能把一整篇文档塞进一个向量——太粗,检索不准。得切成语义连贯的小块(chunk),每块单独 embedding、单独入库。难点是:切块时既不能切碎语义,又要保留上下文(这块属于哪个章节、哪张表的标题是什么),否则检索到一段孤零零的文字,模型无从判断它讲的是什么。

7.2 Docling 的做法:复用 docling_core 的分层切块器

本仓库的 docling/chunking/__init__.py 本身不实现切块,而是把 docling_core 的切块器再导出,作为对外统一入口(chunking/__init__.py:6-12):

from docling_core.transforms.chunker.base import BaseChunk, BaseChunker, BaseMeta
from docling_core.transforms.chunker.hierarchical_chunker import (
DocChunk, DocMeta, HierarchicalChunker,
)
from docling_core.transforms.chunker.hybrid_chunker import HybridChunker

这几个类型的角色如下(实现属外部 docling_core,以下语义标 (inferred)):

类型角色
BaseChunker / BaseChunk / BaseMeta切块器与「块 / 块元数据」的抽象基类
HierarchicalChunker按文档层级切:利用 DoclingDocument 的标题/章节结构,让每块落在语义边界上
HybridChunker在层级切块之上再叠一层 token 感知:按 tokenizer 控制块大小,过长再切、过短合并
DocChunk一个切好的块:文本 + DocMeta
DocMeta块的元数据:所属标题路径、出处等,让块「自带上下文」

7.3 为什么这一步是核心价值

因为切块吃的正是那份统一表示。 HierarchicalChunker 之所以能「不切碎语义」,是因为它读的是 DoclingDocument 里已经建好的标题层级和结构(第 3.3、4 节讲的那套);DocMeta 之所以能「自带上下文」,是因为文档节点上本就带着出处和层级。

于是流程闭环成这样:

任意格式输入 ──► DoclingDocument(统一表示) ──► HybridChunker ──► DocChunk(文本 + DocMeta)

embedding → 向量库 → 检索 → 喂给 LLM

一句话: 前面所有章节费那么大劲把一百种格式解析成一份有结构、有出处、有层级DoclingDocument,最终的兑现点就在这里——切块器能直接吃它,产出带元数据、边界干净的块。没有这份统一表示,RAG 的切块要么丢结构、要么对每种格式各写一套。这就是 Docling 对 RAG 生态的核心价值。


8. 巧妙之处(可借鉴)

  • 产物与输入分层(ConversionAssets / ConversionResult)。 把「可序列化的产物」和「输入/中间态」分成父子两层,于是 save()/load() 只需管产物层,存档格式稳定(document.py:372 / 565)。
  • 私有临时字段用 PrivateAttr,不污染 schema。 _pdf_outlinePage._backendPage._image_cache 都是私有、不序列化,且在组装阶段主动清空重资源(document.py:572base_models.py:441-447)——内存友好。
  • cells 用只读 property 而非存储字段。 避免 parsed_pagecells 两份数据不一致(base_models.py:449)。
  • 错误是结构化 + 分类的,不是字符串。 ErrorItemcomponent_type / category / page_no,配合 FailureCategory 让下游能按语义过滤、精确定位到页(base_models.py:254 / 278)。
  • 「有错就不报 SUCCESS」。 状态判定强制降级为 PARTIAL_SUCCESS,杜绝带病成功(base_pipeline.py:86)。
  • 富化用「遍历 + 批 + 就地改写」的极简骨架。 一套 iterate_items + GenericEnrichmentModel 契约,适配所有富化模型;# Must exhaust! 一句点破副作用时机(base_pipeline.py:111)。
  • 导出开关集中派生、本地/远程共用。 _export_flags_from_formats 一处定义,convertconvert-remote 输出行为天然一致(export_utils.py:28)。

9. 边界与局限(诚实)

  • DoclingDocument 与全部切块器都在外部 docling_core 本仓库只生产和消费它们,不定义其内部结构;本章对它们内部字段的描述标了 (inferred),要看真章需去 docling_core
  • 富化会拖慢转换、且依赖额外模型。 图片描述/分类等是可选的富化模型,开启后要下载并运行模型,不是零成本(装配见 base_pipeline.py:177 起)。
  • 导出图片的成本被刻意规避,但也意味着某些格式天生不带图。 TEXT/DOCTAGS/VTT/DOCLANG 不嵌图(export_utils.py:8)——需要图就得选 md/html/json 等。
  • 切块质量最终受解析质量制约。 解析差(低 ConfidenceReport)→ 层级乱 → 切块也乱。confidence 提供了阈值筛选的手段,但 Docling 不替你决定阈值。

10. 横向对比(同 shelf 的 rag-retrieval 兄弟库)

Docling 在 rag-retrieval 区里占的格子是「文档理解 + 统一表示 + 结构感知切块」——它回答的是「把任意格式洗成一份可切块的结构化文档」。相邻的格子各管一段:

兄弟库在 RAG 流程里的位置与本章的关系
crawl4ai数据入口:把网页洗成干净文本上游进料;Docling 管的是把「已到手的文件」结构化
chonkie专职切块器与本章第 7 节直接对照:Docling 的切块靠 DoclingDocument 的结构层级,chonkie 是独立、更通用的 chunking 工具
r2r / agentset / llmware端到端 RAG 系统(检索/编排/生成)下游消费方:它们可以吃 Docling 切出来的 DocChunk

一句话定位: 别的库多数从「我已经有干净可切的文本了,怎么检索」起步;Docling 往前顶了一大步——先把一百种脏格式收敛成一份结构化文档,再把切块建在这份结构上。这一层统一表示,正是本章反复强调的核心价值。


11. 代码地图(导航索引)

主题文件路径符号名
转换总出货箱docling/datamodel/document.py:565ConversionResult
可序列化产物层 + save/loaddocling/datamodel/document.py:372ConversionAssets / ConversionAssets.save / .load
输入文档元信息docling/datamodel/document.py:120InputDocument
单页容器docling/datamodel/base_models.py:431Page / Page.get_image / Page.cells
各模型预测收件箱docling/datamodel/base_models.py:407PagePredictions
中间元素基类 / 聚类docling/datamodel/base_models.py:310 / 297BasePageElement / Cluster
文本/表/图/容器元素docling/datamodel/base_models.py:375 / 363 / 380 / 357TextElement / Table / FigureElement / ContainerElement
打平的中间单元docling/datamodel/base_models.py:418AssembledUnit
页→文档组装docling/pipeline/standard_pdf_pipeline.py:997StandardPdfPipeline._assemble_document
构造 DoclingDocumentdocling/utils/glm_utils.py:70to_docling_document
状态枚举docling/datamodel/base_models.py:85ConversionStatus
结构化错误 / 分类docling/datamodel/base_models.py:278 / 254ErrorItem / FailureCategory
置信度报告docling/datamodel/base_models.py:607ConfidenceReport
富化主循环docling/pipeline/base_pipeline.py:111BasePipeline._enrich_document
富化模型契约docling/models/base_model.py:146GenericEnrichmentModel
图像型富化输入docling/models/base_model.py:175BaseItemAndImageEnrichmentModel
导出入口docling/cli/main.py:353export_documents
导出开关派生docling/cli/export_utils.py:28_export_flags_from_formats
输出格式枚举docling/datamodel/base_models.py:122OutputFormat
不支持嵌图的格式docling/cli/export_utils.py:8_OUTPUT_FORMATS_NOT_SUPPORTING_IMAGE_EMBEDDING
切块器再导出(RAG)docling/chunking/__init__.py:6HierarchicalChunker / HybridChunker / DocChunk / DocMeta