Haystack MarkItDownConverter 集成详解:用微软 MarkItDown 把 PDF、Office、HTML 等文件批量转换为 Markdown Documents
【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack
本文围绕 Haystack 2.21 版本的 MarkItDown 集成 API 参考展开,系统讲解MarkItDownConverter组件的初始化参数(store_full_path)、run方法的输入输出契约(sources/meta/documents)、在 Pipeline 中的典型接法,以及与DocumentCleaner搭配时的注意事项。读完后,你可以直接把多格式文件转换接入 Haystack 的索引管道,并理解 Markdown 输出为何不应经过默认配置的文本清洗。
组件定位:为什么需要 MarkItDown 集成
MarkItDownConverter属于 Haystack 生态中的converter类组件,位于haystack_integrations.components.converters.markitdown模块下。它的底层能力来自微软开源的 MarkItDown 库:把多种文件格式统一转换为 Markdown 文本,覆盖 PDF、Word(.docx)、PowerPoint(.pptx)、Excel(.xlsx)、HTML、图片、音频等类型,且全部在本地处理,不依赖任何外部 API(这一点在 API 参考文档 markitdown.md 中有明确说明)。
在 Pipeline 架构中,converter 的典型位置是索引管道(indexing pipeline)的最前端,或在 PreProcessors 之前:文件进来 → 转成Document列表 → 切分 → 嵌入 → 写入文档存储。这一点在组件使用说明 markitdownconverter.mdx 的“Most common position in a pipeline”一栏中有明确定义。组件一览可参考 converters.mdx,平台组件清单见 platform-components.mdx。
需要先说明一点边界:MarkItDownConverter的 Python 源码并不在本仓库的haystack/包内,而是由独立分发的集成包markitdown-haystack提供(组件文档中标注的包名即markitdown-haystack,实现位于 deepset 维护的 haystack-core-integrations 仓库的integrations/markitdown目录)。因此本文的实现细节分析以官方 API 参考和组件文档为准,结合本地环境可验证的信息进行佐证。
安装
在写入管道代码之前,先安装集成包:
pip install markitdown-haystack该包会拉取底层依赖markitdown。从本仓库本地环境验证的安装结果看,markitdown运行时依赖包括beautifulsoup4、magika(文件类型识别)、markdownify(HTML 转 Markdown)、charset-normalizer、defusedxml、requests等,这也解释了它为何能支持 HTML、Office 等多种格式的本地转换。
核心 API:__init__与store_full_path
API 参考中定义的构造器签名为:
__init__(store_full_path: bool = False) -> None只有一个参数,行为约定如下:
| 参数 | 类型 | 默认值 | 作用 |
|---|---|---|---|
store_full_path | bool | False | 为True时,把文件的完整路径写入生成Document的 metadata;为False时,metadata 中只保留文件名 |
这个参数看似简单,实际影响的是 RAG 场景下的溯源能力。索引阶段的 metadata 会一路传递到检索与生成阶段——如果只存文件名,多个目录下出现同名文件(例如specs/2024/design.md与specs/2025/design.md)时,回答中引用该文件将难以定位;设置为store_full_path=True后,metadata 里的路径信息可以支撑“答案引用了哪个文件”的审计与跳转。
# 只存文件名(默认行为) converter = MarkItDownConverter() # 存完整路径,便于检索后溯源 converter = MarkItDownConverter(store_full_path=True)核心 API:run方法的输入输出契约
run方法签名(摘自 API 参考):
run( sources: list[str | Path | ByteStream], meta: dict[str, Any] | list[dict[str, Any]] | None = None, ) -> dict[str, list[Document]]输入sources支持三种来源,这使它既能接磁盘文件,也能接上游组件传来的字节流:
str/Path:本地文件路径,如"document.pdf";ByteStream:Haystack 的核心数据类之一,承载字节内容与元数据(如文件路径、MIME 类型),定义见>from haystack_integrations.components.converters.markitdown import MarkItDownConverter converter = MarkItDownConverter() result = converter.run(sources=["document.pdf", "report.docx"]) documents = result["documents"]带 metadata 的完整形态:
converter = MarkItDownConverter(store_full_path=True) # 形态一:整批共享 metadata result = converter.run( sources=["document.pdf", "report.docx"], meta={"source": "quarterly_reports", "language": "en"}, ) # 形态二:逐文件对齐 metadata result = converter.run( sources=["document.pdf", "report.docx"], meta=[{"source": "pdf_batch", "page_count": 12}, {"source": "docx_batch", "author": "engineering"}], )在 Pipeline 中接入:完整的索引管道示例
组件文档给出了一个可直接复制的端到端示例:
MarkItDownConverter → DocumentSplitter → DocumentWriter,写入InMemoryDocumentStore:from haystack import Pipeline from haystack.components.preprocessors import DocumentSplitter from haystack.components.writers import DocumentWriter from haystack.document_stores.in_memory import InMemoryDocumentStore from haystack_integrations.components.converters.markitdown import MarkItDownConverter document_store = InMemoryDocumentStore() pipeline = Pipeline() pipeline.add_component("converter", MarkItDownConverter()) pipeline.add_component( "splitter", DocumentSplitter(split_by="sentence", split_length=5), ) pipeline.add_component("writer", DocumentWriter(document_store=document_store)) pipeline.connect("converter", "splitter") pipeline.connect("splitter", "writer") pipeline.run({"converter": {"sources": ["document.pdf", "report.docx"]}})几个可以按生产需要调整的点:
split_length=5是演示值。示例用“每 5 句切一块”只是为了快速跑通;真实 RAG 场景通常按word或page切分并调大窗口(例如split_by="word", split_length=200, overlap=20),具体取值应结合下游嵌入模型的上下文窗口决定。run的输入按组件名嵌套:管道输入是{"converter": {"sources": [...]}}结构,键名对应add_component注册时的实例名——这是 Haystack 2.x 管道的标准约定。DocumentWriter的写入策略默认为OVERWRITE,重复索引同一批文件时不会去重,如需幂等写入可在DocumentWriter上显式配置duplicate_documents参数。
由于
MarkItDownConverter的输入类型包含ByteStream,管道前端还可以挂接FileTypeRouter之类的路由组件,把不同 MIME 类型的文件分流到不同 converter(例如 PDF 走 MarkItDown,CSV 走CsvToDocument),实现多模态索引。关键注意事项:Markdown 输出不要过默认配置的 DocumentCleaner
这是使用
MarkItDownConverter时最容易被忽略的坑。该组件返回的是Markdown 格式内容,而DocumentCleaner的默认参数remove_extra_whitespaces=True和remove_empty_lines=True是为纯文本设计的:开启它们会合并换行、压平标题、表格、列表和图片标签,直接破坏 Markdown 结构。组件文档给出的官方建议是:
- 直接把 converter 输出接到下一个组件(如 splitter),不要中间插一个默认配置的
DocumentCleaner; - 如果确实需要自定义清洗,务必显式关闭这两个选项。
这一点在仓库的发布说明中也有印证:docs-cleaner-markdown-ocr-examples 明确更新了包括
MarkItDownConverter在内的多个 Markdown 产出型 converter 的示例管道,避免把 Markdown 内容路由经过默认 cleaner 配置;2.21 版本对应文档见 documentcleaner.mdx。换言之,这个注意事项不是个别版本的偶发问题,而是被持续维护的既定约定。版本适用性与参考路径
- 本文依据的是 Haystack 2.21 版本冻结的 API 参考 markitdown.md,其中
__init__与run的签名、参数表、返回值定义即为 2.21 的契约; - 组件的功能性使用说明(安装、独立调用、管道示例)见 markitdownconverter.mdx;
- 从仓库内
versioned_docs目录结构看,该组件的转换器页面自 2.26 版本开始纳入版本化文档,如果你锁定的是 2.21 运行环境,请以pip install markitdown-haystack当时发布的包版本为准; ByteStream数据类的字段与序列化语义见 contenteditable="false">【免费下载链接】haystackOpen-source AI orchestration framework for building context-engineered, production-ready LLM applications. Design modular pipelines and agent workflows with explicit control over retrieval, routing, memory, and generation. Built for scalable agents, RAG, multimodal applications, semantic search, and conversational systems.项目地址: https://gitcode.com/GitHub_Trending/ha/haystack
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考