项目概述
本文带你一步步构建一个能够处理表格、发片、文本和图表的多模态PDF文档问答系统,核心技术栈为Gemma 3 + Mistral OCR + RAG。我们先看最终效果:

在Streamlit应用中,通过侧边栏输入Mistral和Google API密钥,上传包含表格、发片、文本和图表的PDF文件,点击“处理PDF”后系统自动提取内容并构建索引,最后你可以在聊天窗口提问,系统基于文档上下文给出精准回答。
是什么让 Mistral OCR 与众不同?
Mistral AI 推出的 Mistral OCR 被誉为“全球最佳OCR模型”。与传统OCR不同,它擅长理解复杂的文档元素:
- 可输入图像和PDF文件,从有序交错的文本和图像中提取内容。
- 天然支持多语言和多模态,轻量设计使其每节点每分钟可处理高达2000页文档。
- 将读取的数据转换为Markdown格式,AI模型能轻松理解该格式,从而更好地解析文档数据。
- 支持本地部署,敏感数据触手可及。
关键优势:Mistral OCR是RAG系统处理多模态文档(如幻灯片、复杂PDF)的理想搭档。
是什么让 Gemma 3 与众不同?
Google发布的 Gemma 3 被宣称是“全球最佳单翻跟斗模型”,在单GPU主机上性能超越Meta、DeepSeek、OpenAI等对手。主要特点:
- 增强的视觉编码器,支持高分辨率和非方形图像。
- 开箱支持超过35种语言,预训练覆盖140种语言。
- 可无缝分析图像、文本和短视频。
- 128K token的巨大上下文窗口,一次处理并理解大量数据。
Gemma 3 是如何训练的?
Gemma 3 的训练融合了多项先进技术:
- 蒸馏技术:从更大指令模型提取知识。
- 预训练+后训练:通过强化学习和模型融合优化。
- 全新分词器:支持超140种语言。
- 训练基础设施:在Google TPU上使用JAX框架。
后训练阶段主要包含4个组件:
- 从更大指令模型提取到Gemma 3预训练检查点。
- RLHF(人类反馈强化学习)使模型预测符合人类偏好。
- RLMF(机器反馈强化学习)增强数学推理。
- RLEF(执行反馈强化学习)提升编码能力。
这些更新使Gemma 3在LMArena中获得1338分,显著提升了数学、编程和指令跟随能力。
开始编码:构建多模态文档问答系统
下面逐步实现核心功能。每个函数都配有详细注释和错误处理。
1. 上传PDF函数 (upload_pdf)
该函数负责安全地将PDF上传到Mistral OCR API并获取签名URL:
- 检查客户端对象是否为
None,若是则抛出ValueError。 - 创建临时目录,写入PDF内容,以
rb模式打开文件。 - 调用客户端上传,指定文件名、内容和目的为
"ocr"。 - 获取签名URL,若出错则捕获异常并抛出带清晰消息的
ValueError。 - 确保最后清理临时文件。
2. 替换Markdown中的图像 (replace_images_in_markdown)
此函数接受Markdown字符串和一个字典(图像名→base64编码):
- 遍历字典,对每个键(图像占位符)使用
.replace()方法。 - 将
替换为。 - 返回嵌入base64图像的更新后Markdown字符串。
3. 合并多页Markdown (get_combined_markdown)
处理多页OCR提取的Markdown及其相关图像:
- 创建空列表
markdowns存储每页处理后的内容。 - 遍历
ocr_response.pages,通过page.images提取图像ID和base64编码。 - 调用
replace_images_in_markdown替换占位符,将修改后的内容添加到列表。 - 使用
"\n\n".join(markdowns)合并所有部分,确保页面间清晰分隔。
4. 处理OCR (process_ocr)
根据文档来源类型调用Mistral OCR:
- 检查客户端是否存在,若不存在则抛出错误。
- 判断
document_source:若是"document_url",使用DocumentURLChunk;若是"image_url",使用ImageURLChunk。 - 指定模型
"mistral-ocr-latest",启用include_image_base64=True。 - 来源类型无法识别时抛出
ValueError。
5. 初始化Google Gemini并生成回答
配置Google Gemini API:
- 检查上下文是否为空或过短(少于10字符),若是则返回错误。
- 创建包含文档上下文和用户查询的提示。
- 使用温度、top_p和安全设置等参数配置模型。
- 调用
model.generate_content()生成响应,捕获异常并打印错误详情。
6. Streamlit应用界面
构建用户交互界面:
- 侧边栏输入Mistral和Google API密钥,验证成功后初始化客户端。
- 支持PDF、图像或URL上传文档。
- 点击“处理PDF”后,系统使用OCR提取内容并存储。
- 用户可提问,应用通过Google Gemini API生成回答。
- 所有聊天消息保存在会话状态中。
- 处理各种错误(如缺少密钥、处理失败),功能不完整时显示警告。
常见问题
- Q:处理大PDF时内存不足怎么办?
A:Mistral OCR分页处理,每页独立提取。建议将PDF拆分为多份(如每份100页),或使用流式处理方式。 - Q:Gemini API返回结果不准确?
A:检查上下文是否完整,尝试调整温度参数(降低至0.2~0.3)使回答更确定,同时确保提示中明确要求“基于文档内容回答”。 - Q:OCR提取的Markdown中图像丢失?
A:确认在process_ocr中启用了include_image_base64=True,并且替换函数正确处理了所有占位符。 - Q:Streamlit应用启动后侧边栏卡住?
A:检测API密钥有效性可能较慢,可适当添加加载动画(如st.spinner)提升用户体验。
