RAG:使用 ChromaDB 和 Mistral
使用Mistral搭建本地RAG时,最简单的技术栈是Ollama(负责生成,并通过bge-m3计算嵌入向量)搭配文件模式的ChromaDB,无需服务器或PyTorch。模型方面,对于配备8至12 GB显存的显卡,ministral-3:8b(6.0 GB,Apache 2.0许可证,公布的上下文长度为256K)是一个不错的默认选择;16 GB显存可选择ministral-3:14b,更大显存则可选择mistral-small3.2:24b(15 GB)。有一项设置不能忘:增大Ollama的上下文窗口,确保提示词能容纳这些文段。
本指南使用两个 Python 脚本和一个在您电脑上运行的 Mistral 模型,构建完整的文档助手:您的 PDF 和文本文件会被切分并索引到 ChromaDB 中,随后检索到的段落会传给模型,由模型作答并引用来源。本指南还说明如何根据您的显存选择 Mistral 模型,以及哪些陷阱会导致 RAG 答非所问。
#我们要构建的系统:完全在本地运行的 Mistral RAG
RAG(检索增强生成)是指找出您的文档中与问题相关的片段,再将其放入模型的提示词中,让模型依据这些片段回答。这里预期得到的是一个小型命令行工具:一个脚本为文档文件夹建立索引;另一个脚本读取问题,在 ChromaDB 中检索最相近的五个片段,通过 Ollama 将这些片段连同问题发送给 Mistral 模型,然后显示回答,再列出查阅过的文件。任何数据都不会离开这台机器:Ollama 提供生成模型和嵌入模型的服务,ChromaDB 将向量存储在本地文件夹中。
“Mistral” 这个名称有两种用法:一是 Mistral AI 的开放权重模型,可以自行下载并运行(本指南讨论的对象);二是该公司托管的 API,会将您的文本片段发送到它的服务器。对于保密文档,只有前者符合“100% 本地”的要求。
#用于 RAG 时该选择哪个 Mistral 模型
你的文档,你的 AI:基于你的 PDF、笔记和邮件的可靠本地 RAG——无需向云端发送任何内容。
- 在线空间,终身可用
- PDF + 文件
- 30 天内退款
RAG 有其特殊需求:模型必须严格遵循指令(“仅根据这些文本片段回答”),能够阅读多个片段而不混淆信息,并用法语作答。与自由对话相比,模型规模没那么重要;但可用于上下文的内存则更加重要。下列大小均为 Ollama 模型库中显示的默认量化版本大小。
| 模型 | Ollama 模型大小 | 公布的上下文长度 | 适用人群 |
|---|---|---|---|
| ministral-3:3b | 3.0 GB | 256K | 没有独立 GPU 的机器;回答简单,对复杂指令的适应能力较弱 |
| ministral-3:8b | 6.0 GB | 256K | 对于配备 8–12 GB 显存的显卡或 16 GB 内存的笔记本电脑,这是合理的默认选择 |
| ministral-3:14b | 9.1 GB | 256K | 配备 16 GB 显存的显卡,或在上下文长度适中的情况下使用 12 GB 显存的显卡 |
| mistral-nemo (12B) | 查看 Ollama 页面 | 128K | 较早的替代方案,仍广泛使用 |
| mistral-small3.2:24b | 15 GB | 128K | 显存 24 GB 或统一内存 32 GB 及以上;在格式指令方面表现最稳定 |
| mistral(7B,0.3 版) | 4.4 GB | 32K | 旧模型:只建议用于资源极为有限的设备 |
Ministral 3 系列(3B、8B 和 14B)采用 Apache 2.0 许可证发布,Mistral 3 的公告对此有说明。Ollama 上的页面将该系列描述为面向边缘部署设计,能够在多种硬件上运行。Mistral Small 4 于 2026 年发布,根据其 Hugging Face 模型页面的名称,总参数量为 1190 亿,面向服务器硬件,不适合作为个人电脑上的模型选择。要大致估算所需内存,本站的显存计算器会给出模型本身加上上下文缓存所需的内存。
#技术栈
- 生成
- 由 Ollama 通过本地 HTTP API 端口 11434 提供的 Mistral 模型。
- Embeddings
- 通过 Ollama 运行 bge-m3:模型库页面将其描述为 BAAI 的通用、多语言、多粒度模型,拥有 5.67 亿参数。这种方式无需安装 PyTorch 和 sentence-transformers。
- 向量数据库
- ChromaDB 本地模式(PersistentClient):一个文件夹,无需服务器。Chroma 提供了名为 OllamaEmbeddingFunction 的封装,用于调用 Ollama 的嵌入 API。
- 文件读取
- pypdf用于包含文本的PDF文件,Markdown和纯文本则使用直接读取。扫描件PDF是图像:首先需要进行字符识别。
#准备环境
- 01安装 Ollama 并下载模型安装Ollama,然后使用以下两条命令分别下载生成模型和嵌入模型。
- 02创建 Python 环境Python 3.10 或更高版本。虚拟环境可隔离项目依赖。
- 03放置文档将您的 PDF、Markdown 文件和文本文件复制到与脚本位于同一目录的 docs/ 文件夹中。
#2. 在 ChromaDB 中索引文档
脚本读取每个文件,在段落边界处将文本切分为约 1,800 个字符的片段,然后交给 Chroma,由 Chroma 通过 Ollama 调用 bge-m3 来计算向量。有两个重要细节:每个片段都会在元数据中保留文件名(用于引用来源),而且内容按批次添加,而不是一次添加一个片段。
使用 upsert,并以文件名和文本片段编号构建标识符,可以让脚本重复运行:重新索引同一文件夹时,会更新文本片段,而不是生成重复项。不过请注意:如果文档变短,多余的旧片段仍会留在数据库中;如果发生重大变更,请删除 chroma_db 文件夹并重新索引。文本片段大小的选择详见分块策略指南。
#3. 提问:检索后生成
第二个脚本包含问题,检索最接近的五个段落并构建提示词。其中的指令至关重要:它要求仅根据这些段落作答,缺少信息时明确承认,并引用文件。num_ctx 参数用于增大上下文窗口:Ollama 文档指出,默认窗口为 4096 个 token,可通过 OLLAMA_CONTEXT_LENGTH 变量或 num_ctx 参数修改。五个段落各有 400 至 500 个 token,再加上指令和回答,4096 个 token 已接近极限:上下文窗口过小时,内容会被静默截断,模型会在没有读到您所提供段落末尾的情况下作答。
#在归咎于模型之前,先检查 ChromaDB 返回的内容
当回答质量不佳时,原因出在两个环节之一:检索没有找回正确的文本片段,或者模型没有正确使用该片段。无需调用模型,只要显示检索到的片段及其距离值,就能区分这两种情况。如果正确片段不在前五个结果中,请调整切分方式,增加关键词搜索或重排序器。如果正确片段在其中,但回答仍然错误,问题就出在提示词、被截断的上下文或模型上:在下结论之前,先尝试大一档的模型。
#内存预算:同时需容纳的内容
RAG 需要同时使用两个模型:一个负责生成,另一个负责计算向量,此外还需要第一个模型的上下文缓存。Ollama 按需加载各个模型,也可以卸载其中一个,为另一个腾出空间;如果内存余量不足,每次切换都会增加延迟。表格给出了三种配置的粗略估算;模型大小来自 Ollama 模型库,其余部分是计算所得的估值,可借助本站的 VRAM 计算器进一步细化。
| 配置 | 生成模型的大小 | 待添加 | 目标显卡 |
|---|---|---|---|
| ministral-3:8b + bge-m3 | 6.0 GB | 上下文缓存、嵌入模型(5.67 亿参数,半精度下略大于一个 Go)、系统余量 | 8至12 GB |
| ministral-3:14b + bge-m3 | 9.1 GB | 同上;在 12 GB 显存下,长上下文成为限制因素 | 12 到 16 GB |
| mistral-small3.2:24b + bge-m3 | 15 GB | 相同;需预留充足的余量 | 24 GB 或以上 |
#容易导致答非所问的陷阱
- 默认上下文长度过短
- 参见上文:如果没有调高 num_ctx,最后几个段落就会被截断。典型症状是:ChromaDB 确实检索到了正确答案,但模型却说找不到。
- 扫描的PDF文件
- pypdf 仅能读取已存在的文本。扫描文件将返回空内容:脚本会将其显示出来。请先使用 OCR 工具处理文档,相关说明见 Tesseract 指南。
- 缺乏上下文的文本片段
- 从文档中截取的段落(如「期限为30天」)未说明具体内容。每个段落前应添加文档或章节标题。
- 文档中无答案的问题
- 如果没有‘明确说明’这一指令,模型会凭借自身知识填补空白。请始终测试那些答案不在您文件中的问题。
- 精确标识与术语
- 仅靠嵌入向量很难准确检索到合同编号或档案编号:请按照混合检索指南中的说明,加入关键词检索。
#深入了解
| 优化 | 努力 | 适用场景 |
|---|---|---|
| 将检索返回的文本片段数量(k)从 5 增加到 8 | 一行 | 答案分散在多个段落中 |
| 按标题而非段落进行分块 | 中等 | 结构化文档(说明文档、按条款划分的合同) |
| BM25 + 向量混合搜索 | 中等 | 按标识符、缩写或专有名词提问 |
| 重排序模型(bge-reranker-v2-m3) | 中等 | 正确答案被检索到,但排名位于第 5 位之后 |
| 聊天界面(Open WebUI,FastAPI API) | 视情况而定 | 其他用户需要使用该工具 |
| 计划的备份与重新索引 | 较低 | 文档目录每周都会更新 |
每项改进都有对应的指南:请用 30 到 50 个真实问题,分别测量改进前后的召回率,而不是不断堆叠技术。如果您更喜欢无需编写代码的现成界面,无代码 RAG 指南介绍了 Open WebUI 和 AnythingLLM。
#使用 Mistral 实现 RAG 的常见问题
本地 RAG 应选用哪个 Mistral 模型?+
Ollama 是否可以代替 sentence-transformers 计算嵌入向量?+
为什么模型表示未找到答案,而答案实际上存在于我的文档中?+
能否用 Mistral API 替代 Ollama?+
如何添加新文档而无需重新索引全部内容?+
运行这个 RAG 需要 GPU 吗?+
- 使用 ChromaDB 和 Ollama 进行本地 RAG:Python 教程
- 分块策略
- BM25 + 向量混合搜索
- 在您的流水线中添加重排序器
- VRAM 计算器
- 使用 Ollama 实现本地 RAG,无需写代码
- 来源:Ollama,ministral-3
- 来源:Ollama,mistral-small3.2
- 来源:Ollama,bge-m3
- 来源:Chroma,Ollama嵌入模型
- 来源:Ollama 常见问题解答,上下文窗口
有反馈、发现了错误,或想补充说明?请告诉我们,让这份指南对每个人都更有帮助。