Haystack 集成 Mistral 完全指南:OCR 文档转换、文本嵌入与对话生成
2026/9/14 1:19:27 网站建设 项目流程

Haystack 集成 Mistral 完全指南:OCR 文档转换、文本嵌入与对话生成

【免费下载链接】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 仓库中的 Mistral 集成参考文档(docs-website/reference_versioned_docs/version-2.20/integrations-api/mistral.md),系统讲解四个核心组件:MistralOCRDocumentConverter(OCR 文档转换)、MistralDocumentEmbedder(文档嵌入)、MistralTextEmbedder(文本嵌入)与MistralChatGenerator(对话生成)。读完本文,你将掌握如何在 Haystack 管道中集成 Mistral 的 OCR、Embedding 与 Chat Completion API,完成从 PDF/图片解析、向量化到对话式 RAG 的完整链路。

概览:Mistral 集成提供了什么

Haystack 的 Mistral 集成(haystack-integrations-mistral)由四个组件构成,覆盖了 LLM 应用中最常见的三个环节:

组件所属模块职责
MistralOCRDocumentConvertercomponents.converters.mistral调用 Mistral OCR API,从 PDF、图片、URL、ByteStream 等来源提取文本,并支持结构化标注
MistralDocumentEmbeddercomponents.embedders.mistral基于 Mistral 嵌入模型,为Document列表计算向量并写入embedding字段
MistralTextEmbeddercomponents.embedders.mistral基于 Mistral 嵌入模型,为单个文本字符串计算向量
MistralChatGeneratorcomponents.generators.mistral.chat基于 Mistral 对话模型,使用ChatMessage格式进行文本生成,支持流式、工具调用与推理内容

其中嵌入器和生成器分别继承自 Haystack 核心库中的OpenAIDocumentEmbedder(见 haystack/components/embedders/openai_document_embedder.py)、OpenAITextEmbedder(见 haystack/components/embedders/openai_text_embedder.py)与OpenAIChatGenerator(见 haystack/components/generators/chat/openai.py),这保证了与 Haystack 官方 OpenAI 组件一致的使用体验、序列化能力和错误处理逻辑。

所有组件默认从MISTRAL_API_KEY环境变量读取密钥,底层统一使用haystack.utils.Secret管理凭据(见 haystack/utils/auth.py),无需在代码中硬编码。

环境准备与密钥管理

安装集成包后,先在环境中导出 Mistral API 密钥:

export MISTRAL_API_KEY=your-mistral-api-key

组件默认通过Secret.from_env_var("MISTRAL_API_KEY")读取密钥,因此无需在构造函数中显式传入。如需在代码中显式指定,可这样写:

from haystack.utils import Secret converter = MistralOCRDocumentConverter(api_key=Secret.from_env_var("MISTRAL_API_KEY"))

适用前提:以上组件均依赖 Mistral 云端 API,需要有效的 Mistral 账号与 API 密钥;MistralOCRDocumentConverter的标注功能还需要额外的 Vision LLM 服务。

MistralOCRDocumentConverter:把文档交给 Mistral OCR

MistralOCRDocumentConverter是 Haystack 中调用 Mistral OCR API 的官方组件。它接收多种文档来源,通过 Mistral OCR 服务返回识别文本,并把每个来源包装成一个 HaystackDocument

支持的输入来源

run()sources参数接受混合类型列表,每种类型对应一种文档来源:

类型含义
str本地文件路径
Pathpathlib.Path对象
ByteStreamHaystack 内存中的字节流数据(见 haystack/dataclasses/byte_stream.py)
DocumentURLChunk文档 URL(签名或公开 URL,指向 PDF 等)
ImageURLChunk图片 URL(签名或公开 URL)
FileChunk已上传到 Mistral 的文件 ID

本地文件(strPathByteStream三种来源)会被自动上传到 Mistral 的存储;上传文件在默认情况下处理完毕后会被自动删除(见下文cleanup_uploaded_files参数)。

基本使用示例

from haystack.utils import Secret from haystack_integrations.mistral import MistralOCRDocumentConverter from mistralai.models import DocumentURLChunk, ImageURLChunk, FileChunk converter = MistralOCRDocumentConverter( api_key=Secret.from_env_var("MISTRAL_API_KEY"), model="mistral-ocr-2505" ) # 一次处理多个来源 sources = [ DocumentURLChunk(document_url="https://example.com/document.pdf"), ImageURLChunk(image_url="https://example.com/receipt.jpg"), FileChunk(file_id="file-abc123"), ] result = converter.run(sources=sources) documents = result["documents"] # List of 3 Documents raw_responses = result["raw_mistral_response"] # List of 3 raw responses

run()返回字典包含两个键:

  • documents:每个来源一个Document。其content为 Markdown 格式的全部页面文本,页面之间以换页符\f连接;
  • raw_mistral_response:Mistral API 的原始响应列表(每个来源一条),包含逐页详情、图片信息、标注结果和 token 用量。

构造函数参数详解

MistralOCRDocumentConverter的构造函数签名如下:

__init__( api_key: Secret = Secret.from_env_var("MISTRAL_API_KEY"), model: str = "mistral-ocr-2505", include_image_base64: bool = False, pages: list[int] | None = None, image_limit: int | None = None, image_min_size: int | None = None, cleanup_uploaded_files: bool = True, ) -> None

各参数含义:

参数类型默认值说明
api_keySecretMISTRAL_API_KEY环境变量Mistral API 密钥
modelstr"mistral-ocr-2505"OCR 模型,必须是SUPPORTED_MODELS之一
include_image_base64boolFalseTrue时在响应中包含 base64 编码的图片,会显著增大响应体积并拖慢处理
pageslist[int] \| NoneNone要处理的页号列表(0 起始);None表示处理全部页面
image_limitint \| NoneNone从文档中最多提取的图片数量
image_min_sizeint \| NoneNone提取图片的最小宽高(像素)
cleanup_uploaded_filesboolTrue是否在处理后自动删除上传到 Mistral 的文件。仅影响本地来源(strPathByteStream)上传的文件;FileChunk方式提供的文件不会被删除

SUPPORTED_MODELS列表为:

SUPPORTED_MODELS: list[str] = [ "mistral-ocr-2512", "mistral-ocr-latest", "mistral-ocr-2503", "mistral-ocr-2505", ]

如需获取 Mistral 完整模型列表,可向https://api.mistral.ai/v1/models发送 GET 请求。

结构化标注(Structured Annotations)

当提供bbox_annotation_schema(按图像区域的边界框标注)或document_annotation_schema(整篇文档标注)时,OCR 模型会先抽取文本和结构,随后调用一个 Vision LLM 根据你定义的 Pydantic schema 生成结构化标注。

from pydantic import BaseModel, Field from haystack_integrations.mistral import MistralOCRDocumentConverter # 图像区域的结构化标注 schema class ImageAnnotation(BaseModel): image_type: str = Field(..., description="The type of image content") short_description: str = Field(..., description="Short natural-language description") summary: str = Field(..., description="Detailed summary of the image content") # 整篇文档的结构化标注 schema class DocumentAnnotation(BaseModel): language: str = Field(..., description="Primary language of the document") chapter_titles: List[str] = Field(..., description="Detected chapter or section titles") urls: List[str] = Field(..., description="URLs found in the text") converter = MistralOCRDocumentConverter(model="mistral-ocr-2505") sources = [DocumentURLChunk(document_url="https://example.com/report.pdf")] result = converter.run( sources=sources, bbox_annotation_schema=ImageAnnotation, document_annotation_schema=DocumentAnnotation, ) documents = result["documents"] raw_responses = result["raw_mistral_response"]

标注行为的两个关键细节:

  • 使用bbox_annotation_schema时,文档content中的图片标签(Markdown 图像标签)会被替换为你定义的中文/自然语言描述;
  • document_annotation_schema最多处理 8 页,超出该限制的文档不会被做文档级标注。

元数据与分页设计

run()meta参数可以给生成的Document附加元数据:传单个字典则应用于所有文档,传列表则按顺序与sources一一对应(列表长度必须与来源数量一致)。

每个Documentmeta会自动聚合为如下结构:

{"source_page_count": int, "source_total_images": int, "source_*": any}

其中source_*前缀字段来自文档级标注——例如提供了document_annotation_schema时,languagechapter_titlesurls字段会以source_languagesource_chapter_titlessource_urls的形式进入元数据。

所有页面文本以换页符\f连接,是刻意为之的兼容性设计:Haystack 的DocumentSplitter支持按page切分,即按换页符\f分割(见 haystack/components/preprocessors/document_splitter.py)。因此 OCR 转换结果可以直接接入DocumentSplitter(split_by="page"),实现准确的逐页切分、重叠(split_overlap)与阈值控制,避免跨页内容粘连。这也是典型的「PDF 转文档 → 分页切分 → 嵌入 → 检索」索引管道的第一个环节。

生命周期方法

  • warm_up():初始化 Mistral 客户端,在管道运行时由 Haystack 自动调用;
  • close():关闭 Mistral 客户端,释放资源。

这两个方法配合 Haystack 的组件资源生命周期管理,确保长生命周期服务中客户端被正确复用与释放。

MistralDocumentEmbedder 与 MistralTextEmbedder:文本向量化

两个嵌入器组件分别负责「文档列表」与「单个文本」的向量化,计算得到的向量写入Document.embedding字段或随返回字典输出。

MistralDocumentEmbedder

from haystack import Document from haystack_integrations.components.embedders.mistral import MistralDocumentEmbedder doc = Document(content="I love pizza!") document_embedder = MistralDocumentEmbedder() result = document_embedder.run([doc]) print(result['documents'][0].embedding) # [0.017020374536514282, -0.023255806416273117, ...]

MistralTextEmbedder

from haystack_integrations.components.embedders.mistral.text_embedder import MistralTextEmbedder text_to_embed = "I love pizza!" text_embedder = MistralTextEmbedder() print(text_embedder.run(text_to_embed)) # output: # {'embedding': [0.017020374536514282, -0.023255806416273117, ...], # 'meta': {'model': 'mistral-embed', # 'usage': {'prompt_tokens': 4, 'total_tokens': 4}}}

两个组件共同支持的SUPPORTED_MODELS

SUPPORTED_MODELS: list[str] = [ "mistral-embed-2312", "mistral-embed", "codestral-embed", "codestral-embed-2505", ]

构造函数参数详解

MistralDocumentEmbedder的构造函数:

__init__( api_key: Secret = Secret.from_env_var("MISTRAL_API_KEY"), model: str = "mistral-embed", api_base_url: str | None = "https://api.mistral.ai/v1", prefix: str = "", suffix: str = "", batch_size: int = 32, progress_bar: bool = True, meta_fields_to_embed: list[str] | None = None, embedding_separator: str = "\n", *, timeout: float | None = None, max_retries: int | None = None, http_client_kwargs: dict[str, Any] | None = None ) -> None

MistralTextEmbedder的构造函数为上述参数的精简版(去掉了batch_sizeprogress_barmeta_fields_to_embedembedding_separator,其余相同)。

参数默认值说明
api_keyMISTRAL_API_KEY环境变量Mistral API 密钥
model"mistral-embed"使用的嵌入模型名称
api_base_url"https://api.mistral.ai/v1"Mistral API 基础地址,可覆盖以对接代理或自建网关
prefix/suffix""拼接到每段文本开头/结尾的字符串,可用于加入指令式提示
batch_size32每次批量编码的Document数量(仅文档嵌入器)
progress_barTrue是否显示进度条;生产环境建议关闭以保持日志干净(仅文档嵌入器)
meta_fields_to_embedNone需要与文档正文一同编码的元数据字段列表(仅文档嵌入器)
embedding_separator"\n"拼接元数据字段与正文的分隔符(仅文档嵌入器)
timeout环境变量或 30 秒Mistral 客户端调用超时;未设置时回退到OPENAI_TIMEOUT环境变量,再回退到 30 秒
max_retries环境变量或 5 次内部错误后重试最大次数;未设置时回退到OPENAI_MAX_RETRIES环境变量,再回退到 5 次
http_client_kwargsNone自定义httpx.Client/httpx.AsyncClient的关键字参数,用于配置代理、证书等

两个组件均提供to_dict()/from_dict()序列化方法,可无缝用于 Haystack 管道的 YAML/JSON 序列化与反序列化。

基类实现要点

从源码结构看,这两个组件直接继承 Haystack 核心库的OpenAIDocumentEmbedder/OpenAITextEmbedder基类,因而继承了批量编码、进度条、元数据拼接、超时重试等完整行为(见 haystack/components/embedders/openai_document_embedder.py)。在典型 RAG 管道中,两者配合使用:MistralDocumentEmbedder在索引阶段对文档库编码,MistralTextEmbedder在查询阶段对用户问题编码,确保二者处于同一向量空间。

MistralChatGenerator:对话生成与推理内容

MistralChatGenerator继承自OpenAIChatGenerator,与 Mistral Chat Completion 端点兼容,支持流式响应、工具调用、结构化输出与推理(reasoning)内容提取。它使用 Haystack 的ChatMessage数据结构组织输入输出。

基本用法

from haystack_integrations.components.generators.mistral import MistralChatGenerator from haystack.dataclasses import ChatMessage messages = [ChatMessage.from_user("What's Natural Language Processing?")] client = MistralChatGenerator() response = client.run(messages) print(response) >>{'replies': [ChatMessage(_role=<ChatRole.ASSISTANT: 'assistant'>, _content=[TextContent(text= >> "Natural Language Processing (NLP) is a branch of artificial intelligence >> that focuses on enabling computers to understand, interpret, and generate human language in a way that is >> meaningful and useful.")], _name=None, >> _meta={'model': 'mistral-small-latest', 'index': 0, 'finish_reason': 'stop', >> 'usage': {'prompt_tokens': 15, 'completion_tokens': 36, 'total_tokens': 51}})]}

run()返回字典的replies键包含生成的ChatMessage列表,每条消息的_meta携带模型名、结束原因与 token 用量。

推理(Reasoning)内容

对于支持可调推理的模型(如mistral-small配合reasoning_effort参数,以及 magistral 系列模型),生成的内容会被解析并存储到ChatMessage的推理字段中:

from haystack_integrations.components.generators.mistral import MistralChatGenerator from haystack.dataclasses import ChatMessage messages = [ChatMessage.from_user("Solve: if x + 3 = 7, what is x?")] client = MistralChatGenerator( model="mistral-small-latest", generation_kwargs={"reasoning_effort": "high"}, ) response = client.run(messages) print(response["replies"][0].reasoning) # 访问推理内容 print(response["replies"][0].text) # 访问最终答案

Haystack 的ChatMessage数据类原生支持ReasoningContent(见 haystack/dataclasses/chat_message.py),通过reasoning属性可取得第一条推理内容,reasonings属性可取得全部推理内容(见 haystack/dataclasses/chat_message.py)。这让「先推理、后作答」类模型的中间思考过程不再被丢弃。

构造函数参数详解

__init__( api_key: Secret = Secret.from_env_var("MISTRAL_API_KEY"), model: str = "mistral-small-latest", streaming_callback: StreamingCallbackT | None = None, api_base_url: str | None = "https://api.mistral.ai/v1", generation_kwargs: dict[str, Any] | None = None, tools: ToolsType | None = None, *, timeout: float | None = None, max_retries: int | None = None, http_client_kwargs: dict[str, Any] | None = None ) -> None
参数默认值说明
api_keyMISTRAL_API_KEY环境变量Mistral API 密钥
model"mistral-small-latest"使用的对话模型名称
streaming_callbackNone流式回调函数,每个新 token 到达时被调用,接收StreamingChunk参数
api_base_url"https://api.mistral.ai/v1"Mistral API 基础地址
generation_kwargsNone透传给 Mistral 端点的生成参数(见下文)
toolsNoneTool/Toolset对象列表,或单个Toolset,供模型准备调用;每个工具名称必须唯一
timeout环境变量或 30 秒API 调用超时,回退链同嵌入器
max_retries环境变量或 5 次内部错误重试次数,回退链同嵌入器
http_client_kwargsNone自定义httpx.Client配置

generation_kwargs支持的主要生成参数:

参数说明
max_tokens输出文本的最大 token 数
temperature采样温度;更高值更富创造性(可试 0.9),0 为贪心采样(argmax)适合答案明确的场景
top_p核采样;0.1 表示仅考虑概率质量前 10% 的 token
stream是否流式返回增量;若开启,token 以 server-sent events 到达,并以data: [DONE]结束
safe_prompt是否在对话前注入安全提示
random_seed随机采样种子
reasoning_effort控制推理 token 数量,可接受值"high""none",适用于mistral-small-latestmistral-medium等支持可调推理的模型
prompt_mode面向原生推理模型(magistral 系列);设为"reasoning"使用默认推理系统提示,省略则走模型默认行为
response_formatJSON schema 或 Pydantic 模型,强制模型输出结构;提供后输出总会经过格式校验(模型返回工具调用时除外)。注意:结构化输出配合流式使用时,response_format必须是 JSON schema 而非 Pydantic 模型

支持的模型列表

MistralChatGeneratorSUPPORTED_MODELS覆盖了 Mistral 当前主流与实验性模型:

SUPPORTED_MODELS: list[str] = [ "mistral-medium-2505", "mistral-medium-2508", "mistral-medium-latest", "mistral-medium", "mistral-vibe-cli-with-tools", "open-mistral-nemo", "open-mistral-nemo-2407", "mistral-tiny-2407", "mistral-tiny-latest", "codestral-2508", "codestral-latest", "devstral-2512", "mistral-vibe-cli-latest", "devstral-medium-latest", "devstral-latest", "mistral-small-2506", "mistral-small-latest", "labs-mistral-small-creative", "magistral-medium-2509", "magistral-medium-latest", "magistral-small-2509", "magistral-small-latest", "voxtral-small-2507", "voxtral-small-latest", "mistral-large-2512", "mistral-large-latest", "ministral-3b-2512", "ministral-3b-latest", "ministral-8b-2512", "ministral-8b-latest", "ministral-14b-2512", "ministral-14b-latest", "mistral-large-2411", "pixtral-large-2411", "pixtral-large-latest", "mistral-large-pixtral-2411", "devstral-small-2507", "devstral-medium-2507", "labs-devstral-small-2512", "devstral-small-latest", "voxtral-mini-2507", "voxtral-mini-latest", "voxtral-mini-2602", ]

run 与 run_async

run()方法签名:

run( messages: list[ChatMessage] | str, streaming_callback: StreamingCallbackT | None = None, generation_kwargs: dict[str, Any] | None = None, *, tools: ToolsType | None = None, tools_strict: bool | None = None ) -> dict[str, list[ChatMessage]]
  • messagesChatMessage列表;也可以直接传字符串,内部会转换为一条user角色的消息;
  • generation_kwargs:按 key 与初始化时的generation_kwargs合并,运行时传入的 key 优先,初始化时独有且未在运行时覆盖的 key 保留;
  • tools:若传入,会覆盖初始化时的tools设置;
  • tools_strict:是否对工具调用启用严格 schema 遵循。

组件还提供run_async()异步版本,签名与run()一致,适合与 Haystack 异步管道配合;异步模式下streaming_callback必须是协程(coroutine)。

实战:用 Mistral 构建 PDF 文档问答管道

将上述组件串联起来,即可构建一个典型的「上传 PDF → OCR 提取 → 分页切分 → 向量化 → 检索 → 对话生成」的 RAG 管道:

from haystack import Pipeline from haystack.components.preprocessors import DocumentSplitter from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever from haystack.document_stores.in_memory import InMemoryDocumentStore from haystack_integrations.components.converters.mistral import MistralOCRDocumentConverter from haystack_integrations.components.embedders.mistral import MistralDocumentEmbedder, MistralTextEmbedder from haystack_integrations.components.generators.mistral import MistralChatGenerator from mistralai.models import DocumentURLChunk document_store = InMemoryDocumentStore() # 1. 索引管道:OCR → 按页切分 → 嵌入 → 写入文档库 indexing = Pipeline() indexing.add_component("ocr", MistralOCRDocumentConverter()) indexing.add_component("splitter", DocumentSplitter(split_by="page", split_length=1, split_overlap=0)) indexing.add_component("embedder", MistralDocumentEmbedder()) indexing.add_component("writer", DocumentWriter(document_store=document_store)) indexing.connect("ocr.documents", "splitter.documents") indexing.connect("splitter.documents", "embedder.documents") indexing.connect("embedder.documents", "writer.documents") indexing.run({"ocr": {"sources": [DocumentURLChunk(document_url="https://example.com/report.pdf")]}}) # 2. 查询管道:问题嵌入 → 检索 → 对话生成 query = Pipeline() query.add_component("query_embedder", MistralTextEmbedder()) query.add_component("retriever", InMemoryEmbeddingRetriever(document_store=document_store)) query.add_component("prompt", PromptBuilder(template="根据以下文档回答:\n{% for doc in documents %}{{ doc.content }}{% endfor %}\n问题:{{ question }}")) query.add_component("llm", MistralChatGenerator(model="mistral-small-latest")) query.connect("query_embedder.embedding", "retriever.query_embedding") query.connect("retriever.documents", "prompt.documents") query.connect("prompt", "llm") result = query.run({"query_embedder": {"text": "这份报告的核心结论是什么?"}, "prompt": {"question": "这份报告的核心结论是什么?"}}) print(result["llm"]["replies"][0].text)

关键设计要点:

  • OCR 输出的\f分页符与DocumentSplitter(split_by="page")天然契合(见 haystack/components/preprocessors/document_splitter.py);
  • 索引与查询阶段分别使用MistralDocumentEmbedderMistralTextEmbedder,保证嵌入空间一致;
  • MistralChatGeneratorgeneration_kwargs可在初始化或run()时按需覆盖,例如{"temperature": 0.2, "max_tokens": 512}
  • 如需结构化答案,可在generation_kwargs中传入response_format(JSON schema 或 Pydantic 模型)。

常见问题与使用限制

  • 密钥未配置:组件默认读取MISTRAL_API_KEY环境变量,未设置时初始化会失败;也可在构造函数中通过Secret显式传入。
  • OCR 文件清理cleanup_uploaded_files=True(默认)时,本地来源上传的文件处理完即被删除;如需保留,可显式设为False
  • 文档级标注页数上限document_annotation_schema仅处理前 8 页,超长文档不会进行文档级标注。
  • 流式 + 结构化输出response_format配合流式时必须使用 JSON schema,不能用 Pydantic 模型。
  • 异步流式回调run_asyncstreaming_callback必须是协程。
  • 模型可用性:组件内置的SUPPORTED_MODELS为文档生成时的快照;完整模型列表可通过GET https://api.mistral.ai/v1/models实时获取。

参考路径

  • Mistral 集成参考文档:docs-website/reference_versioned_docs/version-2.20/integrations-api/mistral.md
  • 嵌入器基类实现:haystack/components/embedders/openai_document_embedder.py 与 haystack/components/embedders/openai_text_embedder.py
  • 生成器基类实现:haystack/components/generators/chat/openai.py
  • ChatMessage与推理内容:haystack/dataclasses/chat_message.py
  • 换页符分页支持:haystack/components/preprocessors/document_splitter.py
  • 密钥管理与字节流数据类:haystack/utils/auth.py 与 haystack/dataclasses/byte_stream.py

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询