ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Haystack 集成指南:使用 Mistral OCR、Embedder 与 Chat Generator 构建生产级 LLM 应用

Haystack 集成指南:使用 Mistral OCR、Embedder 与 Chat Generator 构建生产级 LLM 应用 Haystack 集成指南使用 Mistral OCR、Embedder 与 Chat Generator 构建生产级 LLM 应用【免费下载链接】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 AI 的官方集成覆盖三个核心组件MistralOCRDocumentConverter文档 OCR 与结构化注解、MistralDocumentEmbedder/MistralTextEmbedder向量化、以及MistralChatGenerator对话生成。你将学会在索引与 RAG 管线中接入 Mistral 能力、理解每个组件的参数语义与底层实现并掌握流式输出、工具调用、结构化输出等实战要点直接用于构建可落地的语义搜索与问答系统。集成概览与安装Mistral 集成属于 Haystack 的官方核心集成之一以独立包mistral-haystack的形式分发。安装后即可在 Haystack 管线中以标准组件的方式使用pip install mistral-haystack所有组件统一通过MISTRAL_API_KEY环境变量读取 API Key也可用Secret在初始化时显式传入其完整 API 参考见 集成 API 参考对应的用户文档分散在 MistralOCRDocumentConverter、MistralDocumentEmbedder、MistralTextEmbedder 与 MistralChatGenerator。从源码结构看三个生成/嵌入组件分别继承自 Haystack 核心库中 OpenAI 系列的对应实现OpenAIChatGenerator、OpenAIDocumentEmbedder、OpenAITextEmbedder见 openai.py、openai_document_embedder.py、openai_text_embedder.py这意味着它们复用了 OpenAI SDK 的 HTTP 客户端、超时与重试机制仅将模型族与默认端点切换为 Mistral。MistralOCRDocumentConverter把任意文档变成可检索的 Markdown组件定位MistralOCRDocumentConverter位于索引管线的起点通常接在DocumentSplitter之前负责把图像、PDF、网页文档等非结构化输入转换为 HaystackDocument。它在管线中的典型位置是“第一个转换器”输出documents每个输入源一个文档与raw_mistral_responseMistral 原始响应。支持的输入源run 参数sources输入类型说明str/Path本地文件路径组件会自动上传到 Mistral 存储ByteStreamHaystack 内存数据对象DocumentURLChunk文档 URL公开或带签名的 PDF 等ImageURLChunk图片 URL公开或带签名FileChunkMistral 文件 ID此前已上传到 Mistral 的文件组件针对每个 source 返回一个Document其content为全部页面以换页符\f连接而成的 Markdown图片以img-id形式内嵌。这个设计保证了与 HaystackDocumentSplitter的split_bypage精确协同——按页切分与重叠处理都可正确工作。初始化参数__init____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, ) - Noneapi_keyMistral API Key默认读MISTRAL_API_KEY环境变量。modelOCR 模型默认mistral-ocr-2505SUPPORTED_MODELS还包含mistral-ocr-2512、mistral-ocr-latest、mistral-ocr-2503。include_image_base64是否在响应中包含图片的 base64 编码开启会显著增大响应体积并拉长处理时间默认False。pages0 起始的页码列表None表示处理全部页面。image_limit从文档中最多抽取的图片数。image_min_size被抽取图片的最小像素宽/高阈值。cleanup_uploaded_files是否在处理后自动删除上传到 Mistral 的本地文件仅影响str/Path/ByteStream来源FileChunk不会被删除默认True。基础用法处理多种来源本地文件、文档 URL、图片 URL、Mistral 文件 ID的混合列表from haystack.utils import Secret from haystack_integrations.components.converters.mistral import MistralOCRDocumentConverter from mistralai.models import DocumentURLChunk, ImageURLChunk, FileChunk converter MistralOCRDocumentConverter( api_keySecret.from_env_var(MISTRAL_API_KEY), modelmistral-ocr-2505, ) sources [ DocumentURLChunk(document_urlhttps://example.com/document.pdf), ImageURLChunk(image_urlhttps://example.com/receipt.jpg), FileChunk(file_idfile-abc123), ] result converter.run(sourcessources) documents result[documents] # 3 个 Document raw_responses result[raw_mistral_response] # 3 份原始响应仅处理本地文件时直接传Path(my_document.pdf)即可组件自动完成上传与清理受cleanup_uploaded_files控制。结构化注解bbox 与 document 两级 Schema这是该组件的特色能力。通过传入两个 Pydantic 模型可让 Mistral 的 Vision LLM 在 OCR 之后按你的 Schema 输出结构化数据bbox_annotation_schema对文档中每个图片区域bounding box输出结构化注解注解会以文字形式内联插入到 Markdown 中对应图片标签之后。document_annotation_schema对整篇文档输出结构化注解字段会以source_前缀解包进Document.meta例如source_language、source_chapter_titles、source_urls。注意文档级注解最多支持 8 页超过限制的文档不会进行该级注解。from typing import List from pydantic import BaseModel, Field from haystack_integrations.components.converters.mistral import MistralOCRDocumentConverter from mistralai.models import DocumentURLChunk class ImageAnnotation(BaseModel): image_type: str Field(..., descriptionThe type of image content) short_description: str Field(..., descriptionShort natural-language description) summary: str Field(..., descriptionDetailed summary of the image content) class DocumentAnnotation(BaseModel): language: str Field(..., descriptionPrimary language of the document) chapter_titles: List[str] Field(..., descriptionDetected chapter or section titles) urls: List[str] Field(..., descriptionURLs found in the text) converter MistralOCRDocumentConverter(modelmistral-ocr-2505) sources [DocumentURLChunk(document_urlhttps://example.com/report.pdf)] result converter.run( sourcessources, bbox_annotation_schemaImageAnnotation, document_annotation_schemaDocumentAnnotation, )处理流程先由 OCR 模型抽取文本与结构再由 Vision LLM 依据 Pydantic Schema 分析内容并生成结构化注解。run的meta参数支持单个字典附加到所有输出 Document或与 sources 等长的字典列表按序 zip便于为不同来源打上不同元数据。返回值结构documents每个 source 一个Document。content为以\f连接的 Markdownmeta为聚合元数据结构为{source_page_count: int, source_total_images: int, source_*: any}若启用了 document 注解则附加source_前缀字段。raw_mistral_response每个 source 一份的 Mistral 原始 OCR 响应含逐页详情、图片、注解与用量信息。生命周期与序列化组件提供warm_up()初始化 Mistral 客户端、close()关闭客户端、to_dict()/from_dict()序列化与反序列化与 Haystack 标准组件的生命周期契约一致可安全嵌入 Pipeline 与序列化 YAML。在索引管线中的完整示例将 OCR 结果按页切分并写入InMemoryDocumentStorefrom haystack import Pipeline from haystack.document_stores.in_memory import InMemoryDocumentStore from haystack.components.preprocessors import DocumentSplitter from haystack.components.writers import DocumentWriter from haystack.utils import Secret from haystack_integrations.components.converters.mistral import MistralOCRDocumentConverter document_store InMemoryDocumentStore() pipeline Pipeline() pipeline.add_component(converter, MistralOCRDocumentConverter( api_keySecret.from_env_var(MISTRAL_API_KEY), modelmistral-ocr-2505, )) pipeline.add_component(splitter, DocumentSplitter(split_bypage, split_length1)) pipeline.add_component(writer, DocumentWriter(document_storedocument_store)) pipeline.connect(converter, splitter) pipeline.connect(splitter, writer) pipeline.run({converter: {sources: [invoice.pdf, receipt.jpg, contract.pdf]}})这里DocumentSplitter(split_bypage, split_length1)依赖\f分隔符做按页切分——正是组件输出格式设计的初衷。官方文档另有一条重要提醒该组件输出 Markdown不要用默认配置的DocumentCleanerremove_extra_whitespacesTrue、remove_empty_linesTrue会压平换行、破坏标题/表格/图片标签如需清理请关闭上述选项或直接连接DocumentSplitter做按页分块。MistralDocumentEmbedder为文档批量生成向量MistralDocumentEmbedder用于索引阶段把文档列表编码为向量并写回每个Document.embedding字段通常置于DocumentWriter之前。其默认模型为mistral-embedSUPPORTED_MODELS包括SUPPORTED_MODELS: list[str] [ mistral-embed-2312, mistral-embed, codestral-embed, codestral-embed-2505, ]初始化参数__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, ) - Nonebatch_size单次编码的文档数默认 32是吞吐与延迟的权衡点。progress_bar是否显示进度条生产环境建议关闭以保持日志整洁。meta_fields_to_embed与文本一起参与编码的元数据字段列表embedding_separator默认\n用于拼接这些字段与正文。这在为文档附加作者、标签等语义信息时非常有用。timeout/max_retries未显式设置时分别回退到OPENAI_TIMEOUT环境变量默认 30 秒与OPENAI_MAX_RETRIES默认 5 次。从基类源码openai_document_embedder.py 的_client_kwargs逻辑可以看出该回退链是继承自 OpenAI 实现的行为。http_client_kwargs透传给自定义httpx.Client/httpx.AsyncClient的参数字典可用于代理、TLS 等高级配置。用法from haystack import Document from haystack.utils import Secret from haystack_integrations.components.embedders.mistral import MistralDocumentEmbedder doc Document(contentI love pizza!) embedder MistralDocumentEmbedder( api_keySecret.from_token(your-api-key), modelmistral-embed, ) result embedder.run([doc]) print(result[documents][0].embedding) # [-0.453125, 1.2236328, 2.0058594, 0.67871094, ...]索引管线示例from haystack import Pipeline from haystack.components.converters import HTMLToDocument from haystack.components.fetchers import LinkContentFetcher from haystack.components.preprocessors import DocumentSplitter from haystack.components.writers import DocumentWriter from haystack.document_stores.in_memory import InMemoryDocumentStore from haystack_integrations.components.embedders.mistral import MistralDocumentEmbedder document_store InMemoryDocumentStore() indexing Pipeline() indexing.add_component(fetcher, LinkContentFetcher()) indexing.add_component(converter, HTMLToDocument()) indexing.add_component(chunker, DocumentSplitter()) indexing.add_component(embedder, MistralDocumentEmbedder()) indexing.add_component(writer, DocumentWriter(document_storedocument_store)) indexing.connect(fetcher, converter) indexing.connect(converter, chunker) indexing.connect(chunker, embedder) indexing.connect(embedder, writer) indexing.run(data{fetcher: {urls: [https://mistral.ai/news/la-plateforme/]}})MistralTextEmbedder查询向量化的入口MistralTextEmbedder负责把单个字符串通常是用户查询编码为向量典型位置是 embedding Retriever 之前与MistralDocumentEmbedder形成“文档-查询”对称的编码链路。它的SUPPORTED_MODELS与 Document 版本一致默认模型同为mistral-embed。__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 , *, timeout: float | None None, max_retries: int | None None, http_client_kwargs: dict[str, Any] | None None, ) - None参数语义与 Document 版本一致无batch_size、progress_bar、meta_fields_to_embed等批量相关项。from haystack_integrations.components.embedders.mistral.text_embedder import MistralTextEmbedder embedder MistralTextEmbedder(api_key..., modelmistral-embed) result embedder.run(textHow can I use Mistral embedding models with Haystack?) print(result[embedding]) # [-0.0015687942504882812, 0.052154541015625, 0.037109375, ...] # result[meta] {model: mistral-embed, usage: {prompt_tokens: 4, total_tokens: 4}}MistralChatGenerator对话生成、工具调用与推理MistralChatGenerator是 Mistral 生成模型的对话入口默认模型为mistral-small-latest兼容 Mistral Chat Completion 端点。其SUPPORTED_MODELS覆盖 mistral-medium / mistral-large / codestral / devstral / magistral / voxtral / ministral / pixtral 等系列完整列表见 集成 API 参考 的SUPPORTED_MODELS段。初始化参数__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, ) - Nonegeneration_kwargs 常用参数generation_kwargs会原样透传给 Mistral 端点run时传入的同名参数按 key 与初始化时的合并run 级优先。常用项包括max_tokens输出最大 token 数。temperature采样温度创意任务可尝试 0.9有明确答案的任务用 0argmax。top_p核采样概率质量阈值如 0.1 表示只考虑概率最高的 10% token。stream是否以 server-sent events 流式返回结束标记为data: [DONE]。safe_prompt是否在对话前注入安全提示。random_seed随机采样种子。reasoning_effort控制推理 token 量取值high/none适用于mistral-small-latest、mistral-medium等可调推理模型。prompt_mode针对 magistral 原生推理模型设为reasoning使用默认推理系统提示。response_formatJSON Schema 或 Pydantic 模型强制约束响应结构模型返回工具调用时除外流式结构化输出必须传 JSON Schema 而非 Pydantic 模型。基础对话from haystack_integrations.components.generators.mistral import MistralChatGenerator from haystack.dataclasses import ChatMessage messages [ChatMessage.from_user(Whats Natural Language Processing?)] client MistralChatGenerator() response client.run(messages) # response[replies][0].text - 模型回复文本 # response[replies][0].meta - {model: mistral-small-latest, index: 0, finish_reason: stop, usage: {...}}run的messages也接受纯字符串自动包装为一条 user 消息。输入输出统一使用 HaystackChatMessage数据结构见 chat_message.py 中的ChatMessage类保证多轮对话与系统提示的规范化。推理内容Reasoning支持对于支持推理的模型组件会把思考内容抽取到ChatMessage的ReasoningContent字段源码对应 chat_message.py 中的ReasoningContent数据结构messages [ChatMessage.from_user(Solve: if x 3 7, what is x?)] client MistralChatGenerator( modelmistral-small-latest, generation_kwargs{reasoning_effort: high}, ) response client.run(messages) print(response[replies][0].reasoning) # 推理过程 print(response[replies][0].text) # 最终答案流式输出在初始化时传入streaming_callback接收StreamingChunk即可流式接收 token例如配合 Haystack 提供的print_streaming_chunkfrom haystack.components.generators.utils import print_streaming_chunk from haystack.dataclasses import ChatMessage from haystack_integrations.components.generators.mistral import MistralChatGenerator generator MistralChatGenerator( api_key..., modelmistral-small-latest, streaming_callbackprint_streaming_chunk, ) message ChatMessage.from_user(Whats Natural Language Processing? Be brief.) print(generator.run([message]))工具调用Function Calling通过tools参数支持灵活的工具配置可传入单个 Tool 列表、单个 Toolset或两者的混合列表from haystack.tools import Tool, Toolset from haystack_integrations.components.generators.mistral import MistralChatGenerator weather_tool Tool(nameweather, descriptionGet weather info, parameters..., function...) news_tool Tool(namenews, descriptionGet latest news, parameters..., function...) math_toolset Toolset([add_tool, subtract_tool, multiply_tool]) generator MistralChatGenerator(tools[math_toolset, weather_tool, news_tool])run阶段的tools会覆盖初始化时传入的toolstools_strict可开启工具调用的严格 Schema 遵循。异步场景使用run_asyncstreaming_callback需为协程其参数语义与run完全一致。多模态输入配合pixtral系列视觉模型可直接传入图片内容from haystack.dataclasses import ChatMessage, ImageContent from haystack_integrations.components.generators.mistral import MistralChatGenerator llm MistralChatGenerator(modelpixtral-12b-2409) image ImageContent.from_file_path(apple.jpg) user_message ChatMessage.from_user( content_parts[What does the image show? Max 5 words., image], ) response llm.run([user_message])[replies][0].text print(response) # Red apple on straw.RAG 管线示例from haystack import Pipeline from haystack.components.builders import ChatPromptBuilder from haystack.components.fetchers import LinkContentFetcher from haystack.components.converters import HTMLToDocument from haystack.dataclasses import ChatMessage from haystack_integrations.components.generators.mistral import MistralChatGenerator fetcher LinkContentFetcher() converter HTMLToDocument() prompt_builder ChatPromptBuilder(variables[documents]) llm MistralChatGenerator(modelmistral-small) message_template Answer the following question based on the contents of the article: {{query}}\n Article: {{documents[0].content}} \n messages [ChatMessage.from_user(message_template)] rag_pipeline Pipeline() rag_pipeline.add_component(fetcher, fetcher) rag_pipeline.add_component(converter, converter) rag_pipeline.add_component(prompt_builder, prompt_builder) rag_pipeline.add_component(llm, llm) rag_pipeline.connect(fetcher.streams, converter.sources) rag_pipeline.connect(converter.documents, prompt_builder.documents) rag_pipeline.connect(prompt_builder.prompt, llm.messages) question What are the capabilities of Mixtral? result rag_pipeline.run({ fetcher: {urls: [https://mistral.ai/news/mixtral-of-experts]}, prompt_builder: {template_variables: {query: question}, template: messages}, llm: {generation_kwargs: {max_tokens: 165}}, })完整链路从文档索引到语义问答把前三类组件串联起来即构成一个端到端的语义搜索 RAG 系统索引阶段用MistralOCRDocumentConverter消化扫描件与图片、MistralDocumentEmbedder向量化入库查询阶段用MistralTextEmbedder编码问题InMemoryEmbeddingRetriever召回相关片段最后由MistralChatGenerator基于检索结果生成答案。相关组件实现可继续查阅 DocumentSplitter、InMemoryEmbeddingRetriever 与 ChatPromptBuilder 的源码。最佳实践与注意事项环境变量优先所有组件均默认读取MISTRAL_API_KEY生产环境推荐以环境变量注入避免密钥硬编码。OCR 输出是 Markdown不要用默认DocumentCleaner清洗需要分块时直接接DocumentSplitter\f分页天然兼容确需清洗则关闭remove_extra_whitespaces与remove_empty_lines。文档级注解上限 8 页长文档可先用pages参数按页拆分处理或仅使用bbox_annotation_schema。流式结构化输出response_format配流式时必须用 JSON Schema而非 Pydantic 模型。超时与重试不显式设置timeout/max_retries时回退到OPENAI_TIMEOUT30 秒与OPENAI_MAX_RETRIES5 次http_client_kwargs可用于代理与自定义传输层。上传文件清理保持cleanup_uploaded_filesTrue默认以自动清理本地上传文件通过FileChunk传入的已有文件不受影响。【免费下载链接】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),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进