不想再拼凑本地RAG栈,我做了个100%离线企业级RAG脚手架

VaultRAG 将 Ollama、FastAPI、LangChain 与 React 封装为开箱即用的本地企业级 RAG 脚手架。
文章介绍了一个名为 VaultRAG 的开源企业级 RAG 脚手架,它源于开发者对本地 LLM 应用重复搭建基础设施的痛点。VaultRAG 以 Ollama 运行 LLM 与嵌入模型,FastAPI 提供异步后端,LangChain 负责 RAG 编排,React 加 Tailwind 构建前端,Docker Compose 统一部署,全链路本地运行、数据不出内网。文章拆解了文档摄取(PDF 解析、RecursiveCharacterTextSplitter 分块、嵌入存储)与检索生成(SSE 流式响应)的工作流程,并指出 Docker 网络配置和 chunk size/overlap 调参是两大实际难点。项目以脚手架形式开源,面向自由开发者、黑客松团队和隐私敏感的个人用户。
从折腾到封装:一个本地RAG开发者的真实痛点
本地跑一个大模型已经不算难事——Ollama 让模型部署变得像 ollama run 一样简单。但如果你想让非技术用户或企业客户真正用起来,还要保证数据不出内网,问题就来了:后端、前端、向量数据库、编排逻辑、Docker 配置……把这些拼成一个生产级全栈 RAG 应用,往往要花掉数天甚至数周。
开发者 toprakkbozbeyy 在几个月本地 LLM 实验后,决定把这些重复劳动封装成一个开箱即用的企业级 RAG 脚手架 VaultRAG,让开发者可以把时间花在业务逻辑而不是基础设施上。

技术栈选型:为异步与离线而生
VaultRAG 的选型思路很清晰——现代、异步、完全与互联网隔离。
LLM 与嵌入模型使用 Ollama 本地运行,文本生成主要测试 Llama 3.1 和 Qwen,嵌入模型选用 nomic-embed-text。这意味着整个推理链路不需要调用任何外部 API。
后端基于 Python 与 FastAPI,负责异步 API 路由和文档上传处理。FastAPI 的异步特性对 RAG 场景尤其重要——文档解析和向量检索都是 IO 密集型操作,同步框架很容易成为瓶颈。
RAG 编排交给 LangChain,涵盖 PDF 解析、文本分块和向量存储检索。前端用 React 搭配 Tailwind CSS,呈现出类似现代聊天工具的界面,降低企业用户的上手成本。部署则统一由 Docker Compose 管理,所有服务一键启动。
这套组合的取舍很务实:没有引入额外的消息队列或复杂微服务,保持了单一代码库的可维护性。
Ollama 是一个开源的大模型本地运行工具,它把模型权重下载、量化、推理引擎和 API 服务打包成一个命令行程序,支持 Llama、Qwen、Mistral 等主流开源模型。开发者只需 ollama pull 拉取模型、ollama run 启动对话,即可在本地获得一个兼容 OpenAI 接口风格的服务端点,从而让上层应用无需感知底层推理框架。
nomic-embed-text 是一款开源文本嵌入模型,专为检索场景设计,支持较长上下文输入,在向量检索基准上表现接近甚至超过部分闭源嵌入模型。它输出的向量可直接存入向量数据库用于相似度检索,且可完全本地运行,是私有化 RAG 方案中替代 OpenAI Embeddings 的常见选择。
底层工作流程拆解
文档摄取:从 PDF 到向量
用户在 React 界面上传 PDF 后,FastAPI 接收文件,LangChain 负责文本处理。这里用了 RecursiveCharacterTextSplitter 来切分文本块,目的是在分块的同时尽量保留上下文连贯性。随后通过 Ollama 生成嵌入向量,存储在本地向量库中。
整个流程没有任何数据离开本地环境,这也是企业场景最看重的特性。
RecursiveCharacterTextSplitter 是 LangChain 提供的文本切分器,它按一组分隔符(通常是段落、换行、句子、空格等)递归地尝试切分文本,直到每个块的长度落在设定的 chunk size 以内。这种策略相比按固定字符数硬切,能更好地保留段落和句子的完整性,减少语义断裂。同时它支持设置 overlap,让相邻块之间保留部分重叠内容,避免关键信息恰好落在切分边界上而被割裂,这也是后续提到的 chunk size 与 overlap 调参的由来。
检索与生成:SSE 驱动的流式响应
当用户提问时,后端先检索最相关的文本块,拼装成提示词,再通过 Server-Sent Events(SSE)从本地 LLM 流式返回响应。SSE 在这里不只是体验优化——本地模型推理速度受硬件限制,流式输出能让用户第一时间看到内容,感知延迟大幅降低。
这个架构选择值得注意:相比 WebSocket,SSE 更轻量,对于单向的文本流场景完全够用。
Server-Sent Events(SSE) 是一种基于 HTTP 的服务器推送技术,服务端通过保持一个长连接,持续向客户端发送 text/event-stream 格式的数据流。与 WebSocket 的全双工通信不同,SSE 是单向的(服务器到客户端),协议更简单,天然支持断线重连,且无需额外的握手升级过程。在 LLM 流式输出这类“客户端发一次请求、服务端持续返回 token”的场景中,SSE 能以更低的实现复杂度达到与 WebSocket 相近的体验,因此被大量聊天类 AI 应用采用。
踩过的坑:Docker 网络与分块参数
作者坦言,Docker 网络配置是最初的难点。让 FastAPI 容器与宿主机上的 Ollama 实例(或容器化的 Ollama)通信,需要特定的网络配置。这类问题在本地开发中很常见,但在 Docker Compose 编排下往往需要额外调试。
另一个关键点是 LangChain 的 chunk size 和 overlap 调参。太小,LLM 会丢失上下文;太大,本地硬件上的推理速度会显著下降。这是一个需要根据模型和硬件反复摸索的平衡点——没有万能参数,只有针对具体场景的调优。
Docker 网络方面,容器默认处于独立的桥接网络中,容器内的 localhost 指向容器自身而非宿主机。若 Ollama 运行在宿主机上,FastAPI 容器要访问它,通常需要使用 host.docker.internal(Docker Desktop)或在 Linux 上通过 --network=host、自定义 bridge 网络并指定宿主机网关 IP 来打通。若 Ollama 本身也容器化,则要让两个容器加入同一自定义网络,并通过服务名互相解析。这些差异正是本地 RAG 部署中网络调试频繁的原因。
chunk size 与 overlap 直接影响检索质量与推理开销:chunk 过小会导致单个块缺乏完整语义,检索到的上下文碎片化;chunk 过大则会让提示词迅速膨胀,超出模型有效上下文窗口,并显著拖慢本地硬件的推理速度。overlap 用于在块之间保留重叠文本以维持语义连续,但过大的 overlap 会造成冗余存储与重复检索。实践中需要结合文档类型、模型上下文长度和硬件算力反复实验来寻找平衡点。
适用场景与开源地址
VaultRAG 定位为脚手架而非成品,适合三类使用者:为客户端构建 AI 工具的自由开发者、参加黑客松需要快速搭建原型的团队、以及希望为自己的隐私文档部署私有 AI 的个人用户。
作者在 GitHub 上开源了部分组件和文档:github.com/toprakkbozbeyy/vaultrag-enterprise-starter-kit。文末还向社区抛出了一个问题:有没有更好的方式来处理本地向量存储,同时不让 Docker 镜像体积膨胀?这个问题击中了很多本地 RAG 部署的痛点——向量数据库的镜像大小和持久化策略,往往决定了整个方案的部署成本。
相关推荐

AI红利仅限科技圈?非科技行业难见回报
Apollo分析指出,AI的经济回报目前高度集中在科技行业,非科技领域尚无可量化收益迹象。本文梳理其核心论点、Hacker News上的分歧观点,以及对企业AI投入与衡量的实际启示。

AI时代,BBC《蓝色星球III》为何刻意保留“不完美”镜头?
BBC《蓝色星球III》在AI时代反其道而行,刻意保留不完美镜头以证明画面真实性。本文分析这一策略背后的信任逻辑,以及它对内容创作者在AI时代的启示。

FreeDNS:免费动态DNS服务的经典之选
FreeDNS 是一个提供免费动态 DNS 托管服务的平台,支持共享域名池和 HTTP 更新。本文介绍其核心功能、社区评价、适用场景及与其他 DNS 方案的对比。