Chroma + llama.cpp llama.cpp+ LangChain LangChain+ SQLite SQLite + Python 3.12++ CUDA 12.4++ Apple Silicon M-series+ Sentence Transformers+ Docker Compose

基于Markdown文档构建本地RAG对话机器人,支持多轮上下文记忆

✓ 本地部署无需外部API✓ 向量库支持增量更新省算力 ✕ 需较高硬件配置(GPU/Apple Si✕ LLM可能产生幻觉或错误信息

方案简介

本项目将 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 pip3which 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 原文。

方案出处
umbertogriffo/rag-chatbot:RAG (Retrieval-augmented generation) ChatBot that provides answers based on cont
442 star RAG (Retrieval-augmented generation) ChatBot that provides answers based on contextual information extracted from a collection of Markdown files.

本方案由真实开源项目挖掘整理,实施命令均来自其 README 原文,安装使用请遵循项目开源协议。