很多团队都在问同一个问题:
能不能让 AI 基于公司的内部资料回答问题,但数据一页都不出内网?
我最近把这个问题做成了一个可以实际部署的开源项目:LocalRAG。
它不是演示截图,也不是只跑通一半的脚手架。当前 v0.1.0 已经完成真实 Docker 环境验证:
- 上传文档
- 自动解析、切块、向量化
- Qdrant 检索
- Ollama 本地生成
- 返回答案和来源引用
- 全链路无云端 AI API
仓库地址:
一、为什么又做一个 RAG?
RAG 本身不是新东西。
Dify、RAGFlow、FastGPT、AnythingLLM 都已经很成熟了。既然如此,为什么还要做 LocalRAG?
原因不在于"再造一个功能更复杂的系统",而在于一个很具体的场景:
有些团队不是想不想用 AI,而是不能把资料交给公有云。
律所、诊所、财税、制造业、涉密单位都有类似问题:
- 案件材料涉密
- 患者隐私受法规保护
- 客户财务数据敏感
- 工艺配方是核心资产
- 内网环境物理隔离
这些场景需要的不是"更大的模型",而是:
- 数据边界清楚
- 部署方式简单
- 答案可以追溯
- 出了问题能自己维护
- 后续可以替换模型和组件
LocalRAG 的第一版目标就是把这个最小闭环做扎实。
二、当前架构
LocalRAG 由三个容器组成:
text
浏览器
│
▼
FastAPI Backend
├── 文档解析 / 切块
├── RAG 编排
└── REST API + 静态前端
│
├──────────────► Qdrant(向量库)
│
└──────────────► Ollama(嵌入模型 + 大模型)
技术选型:
| 层 | 选型 | 原因 |
|---|---|---|
| 后端 | FastAPI | 轻量、易改、Python 生态成熟 |
| 向量库 | Qdrant | 一个容器即可启动,API 清晰 |
| 嵌入 | bge-m3 | 中文和多语言表现稳定,走 Ollama |
| 生成 | Qwen2.5 | 可从小模型逐步升级 |
| 前端 | 原生 HTML/CSS/JS | 无构建步骤,降低部署门槛 |
| 部署 | Docker Compose | 一条命令启动三个服务 |
架构图和详细说明已经放在仓库:
docs/architecture.mddocs/architecture.svg
三、两条核心流水线
索引流水线
text
文档 → 解析 → 切块 → bge-m3 向量化 → 写入 Qdrant
目前支持:
- 文本型 PDF
- DOCX
- TXT
- Markdown
问答流水线
text
问题 → 向量化 → Top-K 检索
→ 拼接参考片段 → 本地 LLM 生成
→ 返回答案 + 来源
这里有一个重要设计:
回答必须基于检索到的片段,而且来源要在前端显示出来。
来源引用不是装饰。它决定了用户能不能判断答案是否可靠,也决定了系统能否进入企业场景。
四、实际验证结果
我用下面的环境完成了端到端验证:
- Docker Desktop 4.95.0
- Ollama 0.11.3
- Qdrant
bge-m3嵌入qwen2.5:3b生成
测试过程:
- 上传一份虚构的员工手册
- 自动切分为 3 个文本块
- 提问"正式员工每年有多少天年假?"
- 返回"15 天"
- 前端显示命中的文档和相似度
健康检查返回:
json
{
"status": "ok",
"qdrant": "ok",
"ollama": "ok",
"llm_model": "qwen2.5:3b",
"embed_model": "bge-m3"
}
演示视频和截图都在仓库里:
text
demo/video/localrag-demo.mp4
docs/screenshots/
五、部署过程中踩到的坑
1. Ollama latest 镜像太大
ollama/ollama:latest 本地展开接近 9GB,国内网络首次拉取非常痛苦。
我最终把镜像固定到 0.11.3,体积明显下降,同时对当前模型兼容。
这件事说明:
部署体验不是"代码写完"就自动有的,镜像体积、下载源和版本兼容都属于产品的一部分。
2. Docker Hub 慢,不等于 Docker 坏了
国内环境里 Docker Hub 拉取慢很常见。最后采用镜像加速、断点拉取和本地模型导入的方式解决问题。
这部分我没有把脚本写死成某个国内镜像,而是把它记录成可替换的部署方案,避免和某个第三方源强绑定。
3. 流式回答一开始没有来源
最初流式接口只返回文本,非流式接口才返回来源。
但演示时用户看到的只有答案,来源没有显示,这和企业场景的核心卖点不一致。
现在的实现是:
- 后端在响应头里返回来源元数据
- 前端流式读取答案
- 答案结束后渲染来源卡片
这是第一版里很小但很关键的一处产品修正。
4. 小模型会不稳定
1.5B 模型在短资料上能回答,但资料稍长时可能出现"既给答案又说无法回答"的矛盾输出。
最终演示切换到 3B,并收紧提示词和推理参数。
结论很简单:
本地部署不等于模型越小越好。模型大小要和机器、场景、回答质量一起权衡。
六、当前明确不做什么
v0.1.0 不是生产级系统,当前没有:
- 扫描件 OCR
- 多知识库隔离
- 多用户权限
- 审计日志
- Reranker
- 可视化 Agent 编排
这不是藏着不谈,而是第一阶段不应该同时做太多。
先把"文档上传 → 检索 → 基于资料回答 → 返回来源"做稳,再扩展其他能力。
七、接下来优先改进什么
v0.1.0 先把核心链路做通,下一步会继续围绕技术体验改进:
- 完善 PDF 和 DOCX 解析
- 优化文档切块策略与检索评估
- 改进流式回答和来源展示
- 增加端口、模型和数据目录检查
- 补充备份、恢复和升级文档
- 逐步提供更清晰的本地部署指引
在部署、模型管理和本地部署体验没有继续打磨好之前,我不会急着堆叠更多模块。
八、如何运行
bash
git clone https://github.com/Pingredsai/local-rag.git
cd local-rag
cp .env.example .env
docker compose up -d
docker exec localrag-ollama ollama pull qwen2.5:3b
docker exec localrag-ollama ollama pull bge-m3
然后打开:
text
http://localhost:8080
首次安装需要联网拉取 Docker 镜像和模型。初始化完成后,运行时不需要调用公有云 AI API。
九、欢迎反馈
LocalRAG 目前还是一个持续迭代的开源项目,当前版本也不覆盖所有企业场景。
如果你在做本地部署、RAG 或离线 AI 相关工作,欢迎通过 GitHub Issue 提建议、报告问题,或者提交改进。
仓库:
我会优先处理可复现的 Bug、部署问题和文档改进,也希望这个项目能为更多需要数据留在本地的场景提供一个可运行的起点。