资讯详情

文档→知识库一条龙:Docling 接上 LlamaIndex 与 LangChain,RAG 管线 10 分钟打通

📅 2026/10/10 19:04:27 | 华诺云谱 👁 阅读
文档→知识库一条龙:Docling 接上 LlamaIndex 与 LangChain,RAG 管线 10 分钟打通
文档→知识库一条龙Docling 接上 LlamaIndex 与 LangChainRAG 管线 10 分钟打通【免费下载链接】doclingGet your documents ready for gen AI项目地址: https://gitcode.com/GitHub_Trending/do/docling做 RAG 最耗时、最劝退的环节往往不是向量库调优也不是提示词工程而是文档进得来、结构出得去。PDF 里嵌套的表格被硬生生切成文本碎片、扫描件识别出来的文字乱序、Word 里的标题层级在 Markdown 导出后荡然无存——这些脏数据直接决定了检索召回的天花板。IBM 开源的 Docling 之所以能在短时间内收获数万 Star正是因为它把文档解析这件脏活累活做成了可编程、可插拔、可入链的标准件一次解析同时产出带语义标签与空间坐标的结构化对象、无损 JSON 与规整 Markdown再通过官方加载器平滑接入 LlamaIndex、LangChain 等框架。这篇文章从源码与官方示例出发讲清楚三件事如何用 Docling 产出AI 就绪的 Markdown/JSON、加载器在两个框架里的正确接法以及一个 10 分钟可跑通的可检索知识库样例。为什么解析层决定了 RAG 的下限先看一个反直觉的事实大部分 RAG 失败不是模型不行而是分块之前文档就已经坏了。传统 PDF 文本抽取得到的是按阅读顺序打乱的 token 流表格单元与行列关系丢失标题与正文的从属关系被压平。而 Docling 的思路是先把所有格式统一翻译成一种结构化中间表示DoclingDocument再基于它做导出与分块。在仓库中docling/datamodel/document.py 承载了ConversionResult与输入校验逻辑docling/document_converter.py 则是总入口——它按格式注册了 30 余种 backendPDF、DOCX、PPTX、XLSX、HTML、EPUB、Apple Pages/Numbers/Keynote、WAV/MP3、WebVTT、Box Notes、EML/MSG、图片、LaTeX、DocLang 乃至 USPTO/JATS/XBRL 等专用 XML schema见 docling/datamodel/base_models.py 中的InputFormat枚举。PDF 走StandardPdfPipeline布局分析 表格结构识别 阅读顺序 OCROffice 类格式走SimplePipeline直接读原生 XML图片与扫描件则叠上 OCR 与可选 VLM 理解。这一统一中间表示 按格式路由的架构可以用仓库内的处理流程图直观看到DoclingDocument本身是 pydantic 模型把内容项texts、tables、pictures、key_value_items与内容结构body正文树、furniture页眉页脚、groups容器分门别类所有条目通过 JSON 指针挂接父子关系阅读顺序就是body树的遍历顺序详见 docs/concepts/docling_document.md。也就是说解析结果天然自带标题层级、表格结构、图片位置与出处信息——这些正是后面分块与向量化最值钱的元数据。一次解析Markdown / JSON 双形态导出Docling 的导出 API 非常薄核心就一句话result.document之后想导出什么形态由你选。仓库 docs/examples/minimal.py 给出了最简用法from docling.document_converter import DocumentConverter source https://arxiv.org/pdf/2408.09869 # 本地路径或 URL 均可 converter DocumentConverter() result converter.convert(source) print(result.document.export_to_markdown())export_to_markdown()输出的不是裸文本而是保留标题层级、表格栅格、列表结构与代码块语义的 Markdown——这直接决定了后续MarkdownHeaderTextSplitter能否按章节切出高质量分块。需要无损保留时则走export_to_dict()可再序列化为 JSON/YAMLDoclingDocument中的坐标、出处、父子指针全部原样保留适合需要精确定位或做文档原生 grounding 的场景。批量场景下docs/examples/batch_convert.py 演示了convert_all()配合save_as_json / save_as_html / save_as_markdown / save_as_doctags等辅助方法一次导出多形态产物并显式处理SUCCESS / PARTIAL_SUCCESS / FAILURE三种转换状态docs/examples/run_with_formats.py 则展示了如何用allowed_formats白名单与format_options按格式覆盖 pipeline/backend——比如 PDF 指定StandardPdfPipeline PyPdfiumDocumentBackendDOCX 指定SimplePipeline。对文档→知识库流水线而言推荐的生产姿势是先导出无损 JSON 留档再导出 Markdown 供分块检索一次转换两处消费。分块别忘了 Docling 原生 chunker导出 Markdown 后接通用文本分割器只是玩法之一。Docling 的另一条路是直接基于DoclingDocument原生分块由 docling/chunking/init.py 导出的HybridChunker、HierarchicalChunker实现。二者的差别见 docs/concepts/chunking.mdHierarchicalChunker按文档元素逐一成块自动挂接标题、图注等上下文元数据HybridChunker在层级分块之上叠加token 感知精修——先对超限块拆分再把同标题、同图注下的过小相邻块合并merge_peers默认开启并支持repeat_table_header让跨块的表格每块都携带表头上下文。用法的关键细节是真正喂给 embedding 的是contextualize(chunk)的返回值而非chunk.text裸文本。以 docs/examples/hybrid_chunking.ipynb 为例一个关于 IBM 的条目在contextualize()后会补上所在章节标题1910s–1950s作为前缀from docling.chunking import HybridChunker chunker HybridChunker() chunk_iter chunker.chunk(dl_docdoc) for chunk in chunk_iter: embed_text chunker.contextualize(chunk) # 标题/上下文已注入这种文档结构感知 tokenizer 对齐 embedding 模型的分块方式是 Docling 在 RAG 场景里对比朴素文本切割的核心竞争力。接入 LlamaIndexDoclingReader 与两种导出路线LlamaIndex 侧由官方扩展llama-index-readers-docling与llama-index-node-parser-docling提供组件说明见 docs/integrations/llamaindex.mddocs/examples/rag_llamaindex.ipynb 给出了两条路线路线一Markdown 导出 通用解析器最轻量from llama_index.core import StorageContext, VectorStoreIndex from llama_index.core.node_parser import MarkdownNodeParser from llama_index.readers.docling import DoclingReader from llama_index.vector_stores.milvus import MilvusVectorStore reader DoclingReader() # 默认导出 Markdown node_parser MarkdownNodeParser() # 按 Markdown 标题切 node index VectorStoreIndex.from_documents( documentsreader.load_data(SOURCE), transformations[node_parser], storage_contextStorageContext.from_defaults(vector_storevector_store), embed_modelEMBED_MODEL, )路线二JSON 无损导出 DoclingNodeParser检索命中时能拿到文档级 groundingfrom llama_index.node_parser.docling import DoclingNodeParser reader DoclingReader(export_typeDoclingReader.ExportType.JSON) node_parser DoclingNodeParser() index VectorStoreIndex.from_documents( documentsreader.load_data(SOURCE), transformations[node_parser], storage_contextStorageContext.from_defaults(vector_storevector_store), embed_modelEMBED_MODEL, )注意两条路线查出来的source_nodes元数据差异路线一只有Header_2这类标题信息路线二的doc_items里则带着page_no、bbox边界框与headings数组——这就是文档原生 grounding答案不只告诉你在哪一页还精确到页内坐标。若想把 DoclingReader 混入既有目录扫描管线只需把它注册为SimpleDirectoryReader的file_extractordir_reader SimpleDirectoryReader( input_dirtmp_dir_path, file_extractor{.pdf: reader}, # PDF 交给 Docling 处理 )接入 LangChainDoclingLoader 的两种导出模式LangChain 侧对应官方扩展langchain-docling见 docs/integrations/langchain.mddocs/examples/rag_langchain.ipynb 展示了DoclingLoader的两种ExportTypeExportType.MARKDOWN每个输入文档导出为一条独立的 LangChain Document之后交给MarkdownHeaderTextSplitter自行切分ExportType.DOC_CHUNKS默认加载器内部直接调用 Docling 原生 chunker把每条 chunk 作为一条 LangChain Document 输出分块逻辑与 tokenizer 对齐。from langchain_docling import DoclingLoader from langchain_docling.loader import ExportType from docling.chunking import HybridChunker from docling_core.transforms.chunker.tokenizer.huggingface import HuggingFaceTokenizer from transformers import AutoTokenizer tokenizer HuggingFaceTokenizer( tokenizerAutoTokenizer.from_pretrained(EMBED_MODEL_ID) # 与 embedding 模型同款分词器 ) loader DoclingLoader( file_pathFILE_PATH, # 本地路径或 URL 列表 export_typeExportType.DOC_CHUNKS, chunkerHybridChunker(tokenizertokenizer), ) docs loader.load() # 每条即一个 chunk 的 LangChain Document随后无论是MarkdownHeaderTextSplitter二次切分MARKDOWN 模式还是直接把docs当作splitsDOC_CHUNKS 模式下游都是标准的 LangChain 套路。官方示例把Milvus.from_documents(...)与create_retrieval_chain(retriever, question_answer_chain)一接端到端问答就通了。10 分钟跑通一个可检索知识库的完整链路最后把两条官方路线浓缩成一个文档→知识库最小闭环。以下组合均来自仓库内可复现的官方示例LLM 可换成任意本地或远程推理端点向量库也可替换为其他 Milvus/FAISS 兼容实现# 1) 解析一次转换双形态留档 from docling.document_converter import DocumentConverter converter DocumentConverter() result converter.convert(https://arxiv.org/pdf/2408.09869) doc_json result.document.export_to_dict() # 无损 JSON供归档/调试 markdown result.document.export_to_markdown() # 结构化 Markdown供检索 # 2) 分块原生 chunker 注入文档结构上下文 from docling.chunking import HybridChunker from docling_core.transforms.chunker.tokenizer.huggingface import HuggingFaceTokenizer from transformers import AutoTokenizer chunker HybridChunker( tokenizerHuggingFaceTokenizer( tokenizerAutoTokenizer.from_pretrained(sentence-transformers/all-MiniLM-L6-v2) ) ) chunks [chunker.contextualize(c) for c in chunker.chunk(dl_docresult.document)] # 3) 入库embedding 向量存储LangChain 侧等价代码见 rag_langchain.ipynb from langchain_huggingface.embeddings import HuggingFaceEmbeddings from langchain_milvus import Milvus from langchain_core.documents import Document docs [Document(page_contentt) for t in chunks] vectorstore Milvus.from_documents( documentsdocs, embeddingHuggingFaceEmbeddings(model_namesentence-transformers/all-MiniLM-L6-v2), collection_namedocling_demo, connection_args{uri: docling.db}, # 本地轻量部署无需单独起服务 drop_oldTrue, ) # 4) 检索问答 retriever vectorstore.as_retriever(search_kwargs{k: 3})跑完这套流程后提问 Which are the main AI models in Docling?两条官方示例给出的答案都指向同一事实Docling 随包发布布局分析模型页面元素目标检测与 TableFormer表格结构识别两个模型——且命中的检索源都带着headings如 3.2 AI models与页码/坐标元数据。这就是结构化解析的价值答案可溯源到章节与版面位置而不是一段来源不明的文本碎片。小结从仓库源码与官方示例可以得出一个清晰的工程结论Docling 并不只是格式转换器而是一套把文档解析、结构化表示、感知型分块与框架集成串起来的完整管线基座。接入 LlamaIndex 时按需选 Markdown 轻量路线或 JSON 无损路线接入 LangChain 时用DoclingLoader的DOC_CHUNKS模式省去手工分块想要更高召回质量则务必使用contextualize()注入文档结构的 embedding 文本。把这四步固化下来文档→知识库从接文件到可问答确实可以在十分钟内打通——而后续要做的就是在解析质量与分块策略上持续打磨了。【免费下载链接】doclingGet your documents ready for gen AI项目地址: https://gitcode.com/GitHub_Trending/do/docling创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑