Langflow Docling Bundle 实战指南:文档解析、分块与导出的完整链路
Langflow 的 Docling 扩展包(lfx-docling)将 IBM 的 Docling 文档解析能力封装为一组可拖拽的 Flow 组件,覆盖"文档转换 → 分块 → 导出"的完整链路。阅读本文后,你将掌握 4 个组件(Docling、Docling Serve、Chunk DoclingDocument、Export DoclingDocument)的安装方式、全部参数含义与适用场景,并能结合源码理解其子进程隔离、异步轮询与数据契约(DoclingDocument)等底层实现,从而在 Langflow 中搭出可复用的 RAG 文档预处理流程。
Bundle 概览与包元数据
Docling Bundle 是一个独立的 Langflow Extension Bundle,打包位置与组件注册关系可以直接从包元数据中确认:
- 包名
lfx-docling,当前版本0.1.4,MIT 协议,要求 Python>=3.10,<3.15(见 pyproject.toml); - 扩展清单 extension.json 中声明
id: lfx-docling、lfx 兼容级别"1",并注册了一个名为docling的 bundle,组件路径为components/docling; - 通过 entry point
langflow.extensions以lfx_docling包名注册,Langflow 启动时据此发现组件。
Bundle 内包含 4 个组件(见 init.py):
| 组件 display_name | 类名 | 职责 |
|---|---|---|
| Docling | DoclingInlineComponent |
在本地进程内运行 Docling 模型解析文档 |
| Docling Serve | DoclingRemoteComponent |
连接外部 Docling Serve 服务解析文档 |
| Export DoclingDocument | ExportDoclingDocumentComponent |
将 DoclingDocument 导出为 Markdown/HTML/Plaintext/DocTags |
| Chunk DoclingDocument | ChunkDoclingDocumentComponent |
将 DoclingDocument 切分为 chunks |
依赖设计上,基础依赖只包含 docling-core(提供 DoclingDocument 数据模式)、httpx 和 lfx。完整说明见 pyproject.toml 中的注释:即使转换发生在远端,Bundle 之间传递的也是 DoclingDocument 对象,所以 docling-core 必须随基础包安装,而重量级的本地转换/OCR 栈则被拆进可选 extras。
安装方式与可选依赖(Extras)
Bundle 随 Langflow 1.10 workspace 一起安装;若需要本地转换能力或分块能力,按需安装 extras(引自 README):
# 本地转换:完整 Docling 转换器 + OCR 栈
uv pip install "lfx-docling[local]"
# 分块能力:只装分块器与 tokenizer,不装本地转换器/OCR 栈
uv pip install "lfx-docling[chunking]"
# 图片描述能力:依赖 local,并额外安装 langchain-docling
uv pip install "lfx-docling[image-description]"
各 extra 的实际内容(来自 pyproject.toml):
| Extra | 依赖 | 说明 |
|---|---|---|
local |
docling>=2.36.1,<3.0.0(darwin x86_64 平台除外)、tesserocr、rapidocr-onnxruntime、ocrmac(仅 macOS)、torch>=2.6.0、torchvision>=0.21.0 |
完整本地转换栈;macOS Intel 平台需要参照 Docling 官方安装指南单独处理 |
chunking |
docling-core[chunking]>=2.36.1、tiktoken>=0.7.0 |
仅供 Chunk DoclingDocument 组件使用 |
image-description |
lfx-docling[local] + langchain-docling>=1.1.0 |
让 Pic Description 阶段可用 LLM 生成图片描述 |
all |
以上三者组合 | 全量安装 |
另外两点适用前提(来自官方文档页 bundles-docling.mdx):
- 若以包形式安装 Langflow,本地模型能力可用
uv pip install "langflow[docling]"获得; - Langflow Desktop 用户需在
.env中设置LANGFLOW_DOCLING=True以启用 Docling 依赖安装; - Windows 平台需先启用 Developer Mode(涉及
tesserocr等原生依赖)。
Docling 组件(本地解析):参数与子进程架构
Docling 组件(docling_inline.py)继承自 BaseFileComponent,输出带 DoclingDocument 数据的 files。它支持的输入扩展名与 Docling 官方支持格式对齐,覆盖 pdf、docx/docm、pptx/potx、xlsx/xls、html/xhtml、md、adoc/asciidoc、csv、json、txt、xml、tiff/png/jpeg/webp/bmp 等(源码中 VALID_EXTENSIONS 列表,共 31 种)。
核心参数(与 参数解析表 一一对应):
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| files | File | — | 待处理的文件,由 BaseFileComponent 提供 |
| pipeline | Dropdown | standard |
standard(传统 PDF 管道)或 vlm(视觉语言模型管道) |
| ocr_engine | Dropdown | None |
None/easyocr/tesserocr/rapidocr/ocrmac;None 表示禁用 OCR |
| do_picture_classification | Bool | False |
是否对文档内图片做类型分类 |
| pic_desc_llm | Handle(LanguageModel) | 未连接 | 连接后启用图片描述(需安装 image-description extra) |
| pic_desc_prompt | Str(高级) | Describe the image in three sentences. Be concise and accurate. |
图片描述的用户提示词 |
从源码结构看,这个组件有一个值得关注的工程设计:整个 Docling 转换在独立的操作系统子进程中执行(_CHILD_SCRIPT + subprocess.Popen)。源码注释给出了三条理由:
- 与 Read File 高级模式相同的
Popen模式在 Gunicorn 的 fork worker 下可靠运行; - 父进程事件循环保持空闲,SSE 心跳可以持续发送;
- 避免 multiprocessing 带来的 pickling 与信号处理冲突。
配套的健壮性细节包括:
- 依赖检查不触发导入:父进程仅用
importlib.util.find_spec("docling")检查包是否安装,真正导入 PyTorch/transformers 发生在子进程,否则会瞬间拉高内存并可能触发 OOM; - 管道缓冲防死锁:子进程 stdout/stderr 写入
tempfile.TemporaryFile()而非管道,因为 Docling 及其依赖可能产生大量输出,而 macOS 上约 16KB 的管道缓冲区一旦写满就会死锁; - 超时与心跳:
docling_timeout = 600秒(10 分钟),每 5 秒轮询一次子进程状态并输出Docling processing in progress (Ns elapsed)...心跳日志; - VLM 管道:
pipeline=vlm时使用VlmPipeline,macOS 上优先选择GRANITEDOCLING_MLX规格,导入失败则回退到GRANITEDOCLING_TRANSFORMERS; - 结果回收:子进程以 JSON 输出每个文件的
export_to_dict()结果,父进程用DoclingDocument.model_validate()重建对象后,通过rollup_data与原始文件列表对齐返回。
如果 docling 未安装,组件会抛出带安装提示的 ImportError(uv pip install 'langflow[docling]' 或 uv pip install 'lfx-docling[local]')。
Docling Serve 组件(远端解析):参数与轮询流程
当文档解析需要放到独立 GPU 服务上时,使用 Docling Serve 组件(docling_remote.py)。它连接自建的 Docling Serve 实例,走"上传 → 异步转换 → 轮询 → 取结果"的 REST 流程。
参数(源码 inputs 定义,第 64–133 行):
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| api_url | Str(必填) | — | Docling Serve 实例 URL |
| task_id | Str | — | 提供已有任务 ID 时忽略文件输入,直接轮询该任务结果 |
| max_concurrency | Int(高级) | 2 |
并发转换请求数上限 |
| max_poll_timeout | Float(高级) | 3600 秒 |
等待文档转换完成的最长时间 |
| api_headers | Table(高级) | 空 | 连接 Docling Serve 所需的自定义 HTTP 头(key/value 两列,value 支持从数据库加载) |
| docling_serve_opts | NestedDict(高级) | — | 透传给 Docling Serve 的附加转换选项 |
从源码看其工作流程:
- URL 处理:
transform_localhost_url(self.api_url)处理容器内 localhost 场景,最终拼接出{base}/v1前缀;HTTP 客户端由ssrf_protected_httpx_client_kwargs_for_url构造,带 SSRF 防护; - 上传:每个文件读取字节后 base64 编码,POST 到
/v1/convert/source/async,payload 为{"options": {...}, "sources": [{"kind": "file", "base64_string": ..., "filename": ...}]};默认 options 为to_formats: ["json"]、image_export_mode: "placeholder",再合并docling_serve_opts; - 并发:用
ThreadPoolExecutor(max_workers=self.max_concurrency)并发提交,按原始文件顺序回填结果; - 轮询:
GET /v1/status/poll/{task_id}每 2 秒一次,直至task_status为success或failure;期间超过max_poll_timeout则报错提示调大参数;5xx 响应最多容忍MAX_500_RETRIES = 5次; - 取结果:
GET /v1/result/{task_id},服务端返回失败时把errors中的error_message聚合成ValueError抛出;成功时用coerce_docling_document校验json_content,产出Data(data={"doc": doc, "file_path": ...})。
组件测试覆盖在 tests 目录 中,其中远端组件的上传/轮询/结果解析逻辑有专门的 test_docling_remote.py。
Chunk DoclingDocument:分块参数与输出结构
Chunk DoclingDocument 组件(chunk_docling_document.py)把 DoclingDocument 切成适合向量库入库的 chunks,依赖 chunking extra(缺失时抛出带安装命令的 ImportError,见 第 9–23 行)。
参数(update_build_config 会根据选择动态显隐字段):
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| data_inputs | Data/JSON/DataFrame/Table | — | 含文档的数据 |
| chunker | Dropdown | HybridChunker |
HybridChunker(按 token 预算切分)或 HierarchicalChunker(按文档层级切分) |
| provider | Dropdown(高级,仅 Hybrid 显示) | Hugging Face |
tokenizer 提供方,可选 OpenAI |
| hf_model_name | Str(高级) | sentence-transformers/all-MiniLM-L6-v2 |
HF tokenizer 模型名 |
| openai_model_name | Str(高级) | gpt-4o |
OpenAI tokenizer 模型名 |
| max_tokens | Int(高级) | 未设置 | HybridChunker 的最大 token 数;选 OpenAI 且未设置时代码内回退为 128 * 1024 |
| merge_peers | Bool(高级) | True |
合并共享相同元数据、尺寸不足的相邻 chunk |
| always_emit_headings | Bool(高级) | False |
空章节是否也输出标题 |
| doc_key | Str(高级) | doc |
文档对象所在列/字段名 |
输出为 Table(DataFrame),每个 chunk 是一行 Data,字段包括:text(经 chunker.contextualize 补充了层级上下文的文本)、document_id(取 doc.origin.binary_hash)、doc_items(该 chunk 覆盖的文档元素 self_ref 列表的 JSON)。对应的单元测试见 test_chunk_docling_document_component.py。
Export DoclingDocument:四种导出格式与图片模式
Export DoclingDocument 组件(export_docling_document.py)把 DoclingDocument 导出为文本格式,两个输出:Exported data(Data 列表)与 Table(DataFrame)。
参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| data_inputs | Data/JSON/DataFrame/Table | — | 待导出的数据 |
| export_format | Dropdown | Markdown |
Markdown/HTML/Plaintext/DocTags,分别调用 export_to_markdown/export_to_html/export_to_text/export_to_doctags |
| image_mode | Dropdown | placeholder |
placeholder 用占位字符串替换图片;embedded 以 base64 内嵌图片(映射到 docling_core 的 ImageRefMode) |
| md_image_placeholder | Str(高级,仅 Markdown 显示) | <!-- image --> |
Markdown 中的图片占位符 |
| md_page_break_placeholder | Str(高级,仅 Markdown 显示) | 空 | 页与页之间的占位符 |
| doc_key | Str(高级) | doc |
文档对象所在列/字段名 |
update_build_config 会根据 export_format 的实时选择显隐参数:选 Markdown 时三个图片/分页参数全部可见;选 HTML 时只有 image_mode 可见;选 Plaintext/DocTags 时三者都隐藏。
值得说明的是,导出结果不仅包含 text,还会保留 DoclingDocument 的元数据:name、origin.filename、origin.binary_hash(作为 document_id)、origin.mimetype,方便下游按来源文件去重或溯源。测试见 test_export_docling_document_component.py。
共享数据契约:DoclingDocument 的提取与强制转换
四个组件之间的"货币"是 DoclingDocument。Bundle 的组件统一复用 lfx 层的工具模块 docling_utils.py,其中两个函数值得理解:
coerce_docling_document(doc):输入已是文档对象(具有export_to_markdown/export_to_html/export_to_text方法)则原样返回;输入是 dict 则用DoclingDocument.model_validate重建;否则抛TypeError。这使得组件既能接收内存中的对象,也能接收跨节点序列化后的 JSON;extract_docling_documents(data_inputs, doc_key):统一从Data、list[Data]或DataFrame中提取文档。对 DataFrame,先精确匹配doc_key列(默认doc),匹配不到时回退扫描所有列寻找文档对象并给出警告(提示更新 Doc Key 参数);彻底找不到时,错误信息会列出可用列并给出三条排查建议,包括"改用 Docling 组件的 Data 输出而非 DataFrame 输出"。
chunking 路径上的分块器依赖(DocMeta、HierarchicalChunker、HybridChunker、HuggingFaceTokenizer、OpenAITokenizer)都在组件内延迟导入,未安装 chunking extra 时会得到明确指向 lfx-docling[chunking] 等安装命令的 ImportError。
实战:构建 PDF → Markdown → 向量库 的 Flow
官方文档页 bundles-docling.mdx 给出了一个典型链路,把 Docling 组件与检索侧组件串起来:
- Docling → Export DoclingDocument → Split Text:Docling 组件加载文档并解析,Export DoclingDocument 把
DoclingDocument转为 Markdown(图片用占位符表示),Split Text 再把 Markdown 切成 chunks; - Split Text 的 Chunks 输出 → Chroma DB:chunks 进入向量库;
- Embedding Model → Chroma DB 的 Embedding 端口:为向量库提供嵌入模型;同时接一个 Chat Output 组件用于查看导出后的
Table; - 在 Embedding Model 组件中配置模型与凭据;
- 在 Docling 组件中添加工件文件,点击 Playground 运行,切分后的文档即作为向量写入向量数据库。
对于"远端解析 + 分块"的组合,则替换为 Docling Serve → Chunk DoclingDocument → Chroma DB:远端组件输出 DoclingDocument,分块组件按 token 预算切片并附带上下文与文档 ID,无需在 Langflow 所在机器上部署任何本地模型。
开发与验证
在 Langflow 仓库内对该 Bundle 做扩展校验与测试,命令见 README:
# 扩展静态校验
uv run lfx extension validate src/bundles/docling/src/lfx_docling
# 运行 Bundle 测试
uv run pytest src/bundles/docling/tests
测试目录包含三个测试文件:远端组件(test_docling_remote.py)、分块组件(test_chunk_docling_document_component.py)与导出组件(test_export_docling_document_component.py),可分别作为远端协议、分块输出结构与导出元数据的行为基线参考。
小结
Docling Bundle 的设计要点可以归纳为三句话:
- 数据契约先行——所有组件围绕
DoclingDocument交换数据,docling-core作为基础依赖保证远端/本地两种链路产出同构; - 重量级依赖全部 optional——本地 OCR/模型栈、分块器、图片描述各自独立成 extra,按组件能力精确安装;
- 工程上隔离解析负载——本地组件用子进程 + 临时文件 + 心跳轮询把 Docling 的高内存、长耗时风险挡在 Langflow 主进程之外;远端组件则把并发与超时都做成可调参数(
max_concurrency、max_poll_timeout),适配自建 Docling Serve 集群。
掌握这条"转换 → 分块 → 导出"的组件链后,即可在 Langflow 中快速搭出面向向量检索的文档预处理流水线,并通过上文的源码路径进一步核对各参数的实现细节。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
