llama.cpp+
LangChain+
SQLite + Python 3.12++ CUDA 12.4++ Apple Silicon M-series+ Sentence Transformers+ Docker Compose基于Markdown文档构建本地RAG对话机器人,支持多轮上下文记忆
方案简介
本项目将 llama.cpp 与 Chroma 的能力结合,构建两类聊天机器人:具有对话记忆的聊天机器人(类似 ChatGPT 的体验)以及 RAG(检索增强生成)聊天机器人。
RAG 聊天机器人以一组 Markdown 文件作为输入,当用户提问时,基于这些文件提供的上下文给出对应答案。整个流程完全本地化:Memory Builder 组件加载 docs 文件夹中的 Markdown 页面,将页面切分为更小的段落,用 Sentence Transformers 的语义搜索模型计算嵌入向量,并保存到名为 Chroma 的嵌入数据库中备用。用户提问时,机器人从嵌入数据库中检索最相关的段落作为上下文,再用本地语言模型生成最终答案。由于原始问题未必最适合检索,项目会先让 LLM 重写问题,再进行检索增强阅读。
此外,聊天机器人会保存聊天历史并考虑之前对话的相关上下文,以提供更准确的回答。向量数据库以增量方式构建:文档变化时只更新对应的 chunk,而非重建整个索引,通过 SQLite 中的映射表精确删除旧 chunk。
该方案适合希望在本地、无外部 API 依赖的情况下基于私有文档构建问答机器人的开发者。
亮点与能力
- 具有对话记忆的聊天机器人(类 ChatGPT 体验)
- RAG 检索增强生成聊天机器人,以 Markdown 文件集合为知识源
- 提问前先由 LLM 重写问题以优化检索
- 保存聊天历史并结合之前对话的相关上下文给出更准确的回答
- 针对上下文溢出的两种处理策略:Create And Refine the Context(顺序综合所有检索内容生成回答)和 Hierarchical Summarization of Context(每段独立作答后分层合并)
- 向量数据库增量更新:文档变化时只更新对应 chunk,通过文档级元数据(来源 doc ID + 版本哈希)精确替换
- 通过 SQLite 中的 doc_id → chunk_ids 映射表精确处理文档删除
- 从 LangChain 提取并重构了 RecursiveCharacterTextSplitter 类,无需引入 LangChain 依赖即可有效切分 Markdown
组成与分工
- llama.cpp:C++ 后端,高效运行 transformer 模型,支持 CPU 或 GPU,使用 GGML/GGUF 格式的量化模型;通过 Docker Compose 在本地启动 llama.cpp 服务器
- Chroma:嵌入(向量)数据库,存储文档段落的向量表示,供检索时使用
- Sentence Transformers:提供语义搜索模型,用于计算文档段落的嵌入向量
- LangChain(仅参考实现):提取其 RecursiveCharacterTextSplitter 类用于切分 Markdown,不作为依赖引入
- SQLite:维护 doc_id → chunk_ids 映射表,支持精确删除过期 chunk
- Docker Compose:在本地启动 llama.cpp 服务器
- Poetry / Make:依赖管理与服务编排,前后端一键启动
- 前端(Node/Yarn):提供聊天 UI,通过 VITE_API_URL 指向后端
前置要求
硬件与系统要求(代码已在以下环境测试):
- Ubuntu 22.04.2 LTS(Lenovo Legion 5 Pro,12th Gen Intel® Core™ i7-12700H,NVIDIA GeForce RTX 3060)
- MacOS Sonoma 14.3.1(MacBook Pro M1, 2020)
软件依赖:
- Python 3.12+
- 支持 CUDA 12.4+ 的 GPU 或 Apple Silicon M 系列
- Poetry 2.3.0+
- Docker 24.0.6+ 和 Docker Compose 5.0.2+
- NVIDIA Container Toolkit(可选,用于 CUDA 支持)
UI 前端要求:
- Node 22.12+
- Yarn 1.22+
注意:如果使用其他操作系统或不同硬件导致无法加载模型,请参考官方 llama.cpp 的 GitHub issue。
实施步骤
1. 环境初始化
项目提供了 Makefile 一键安装依赖并启动服务。首次运行(或 Clean 之后)必须先运行 Setup:
shell
make check
用于检查 which pip3 和 which python3 指向正确的路径。
NVIDIA CUDA 加速环境安装:
shell
make setup_cuda
macOS Metal GPU 加速环境安装:
shell
make setup_metal
两者都会通过 Docker compose 在本地启动 llama.cpp 服务器。
2. 配置环境变量
复制 .𝐞𝐧𝐯.𝐞𝐱𝐚𝐦𝐩𝐥𝐞 → .𝐞𝐧𝐯 并填写;同样复制 /frontend/.𝐞𝐧𝐯.𝐞𝐱𝐚𝐦𝐩𝐥𝐞 → .𝐞𝐧𝐯 并填写。
3. 安装前端依赖
shell
cd frontend
nvm use
npm install -g yarn
yarn
Create .env file
echo "VITE_API_URL=http://localhost:8000" > .env
4. 启动 llama.cpp 服务器(可选单独启动)
CUDA 环境:
shell
make start_llama_server_cuda
Metal 环境:
shell
make start_llama_server_metal
服务器将运行在 http://0.0.0.0:8080(会显示 llama-ui)。
5. 启动前后端
shell
make start
同时启动后端和前端,并确保后端就绪后再启动前端。
使用与配置要点
- 将 Markdown 文档放入 docs 文件夹,Memory Builder 会自动加载并构建向量索引
- llama.cpp 服务器默认监听 http://0.0.0.0:8080,前端通过 VITE_API_URL=http://localhost:8000 连接后端
- 日常更新依赖:make update
- 代码格式化与检查:make tidy(运行 Ruff check and format)
- 运行测试:make test(使用 pytest)
- 停止 llama.cpp 服务器:make stop_llama_server
- 清理环境与缓存:make clean(移除环境和所有缓存文件)
- 后续改进计划见仓库的 todo list(notes/todo.md)
注意事项与常见问题
- 重要:大型语言模型有时会生成幻觉或虚假信息
- 切换嵌入模型后必须从头重建向量库,因为向量空间不兼容,应尽早规划这一点
- 增量更新依赖文档级版本哈希:文档变化时只为该文档重新生成 chunk,通过元数据过滤器删除旧的,插入新的,远比重建整个索引便宜
- 若使用其他操作系统或硬件无法加载模型,请查阅 llama.cpp 官方 GitHub issue
- Metal 加速仅适用于 macOS 系统
- NVIDIA Container Toolkit 为可选安装项,仅在需要 CUDA 支持时需要
优缺点
- ✓ 本地部署无需外部API
- ✓ 向量库支持增量更新省算力
- ✕ 需较高硬件配置(GPU/Apple Si
- ✕ LLM可能产生幻觉或错误信息
出处
本方案挖掘自开源项目 umbertogriffo/rag-chatbot,方案内容与实施命令均来自其 README 原文。
本方案由真实开源项目挖掘整理,实施命令均来自其 README 原文,安装使用请遵循项目开源协议。