RAG 入门实战:一个 Demo 讲清楚检索增强生成

一、先看一个问题:大模型为什么需要"查资料"?

假设你问 ChatGPT:

"知行科技 2025 年的年会主题是什么?"

如果你之前从没告诉过它这家公司的任何信息,它会怎么回答?大概率是一本正经地编一个------因为它的知识截止在训练数据日期,它不知道 2025 年的事,更不知道一家它没见过的公司。

这不是 ChatGPT 的问题。这是所有大语言模型的共同局限:它们只知道训练时见过的内容,不知道你手里的私有文档。

传统解决方案是微调(Fine-tuning)------把新知识"背"进模型参数。但微调有三个致命缺陷:每次更新知识都要重新训练、无法快速追加新数据、模型学会"编得更像真的"而不是"说不知道"。

RAG(Retrieval-Augmented Generation,检索增强生成)换了一个思路:不靠背,靠查。 让模型在回答问题之前,先去一个专门的知识库里检索相关文档,然后把查到的内容拼进 Prompt,再让模型基于这些资料回答。

这个思路的核心公式只有八个字:先查资料,再答题。


二、RAG 是怎么工作的?

RAG 的工作流程分为四个步骤:

步骤 做什么 类比
1. 索引(Indexing) 把文档切成段落,用 Embedding 模型转成向量,存入向量数据库 把书拆成纸条,贴上标签,放进分类柜
2. 检索(Retrieval) 用户提问时,把问题也转成向量,在向量数据库中找最相似的 Top-K 个段落 拿着关键词去柜子里翻出最相关的几条纸条
3. 增强(Augmentation) 把检索到的段落拼接到用户的原始问题后面,组成一个完整的 Prompt 把纸条贴在问题上,一起递给答题人
4. 生成(Generation) LLM 基于增强后的 Prompt 生成答案,可以标注引用来源 答题人看完纸条,给出有据可查的答案

为什么步骤 2 要用向量数据库而不是普通的关键词搜索?

因为向量相似度能理解"语义"。当你问"公司多少人"时,传统关键词搜索可能只匹配含"人"或"多少"的句子,但向量搜索能找出"团队规模"、"员工数量"这种用词不同但意思相同的段落。这是 RAG 区别于传统全文搜索的关键。

在实际项目中,有几个关键设计选择直接影响效果:

  • Chunk Size(分块大小):太小丢失上下文("根据第3条"------第3条是什么?),太大检索精度下降。典型值是 512-1024 个字符。
  • Embedding 模型:中文场景推荐 BGE/M3E 系列,英文推荐 text-embedding-3。维度越高表达能力越强,但检索速度越慢。
  • 检索策略:纯向量检索有精度损失,混合检索(向量 + BM25 关键词 + 重排序)是生产级 RAG 的标配。

三、一个能跑起来的 Demo:rag_demo

理论讲完了,我们看一个能真正跑起来的项目。代码在 https://gitee.com/XiaoYRecluse/rag_demo.git ,技术栈是 FastAPI + ChromaDB + 多提供商 LLM/Embedding

3.1 项目做了什么?

这个 Demo 实现了一个完整的 RAG 系统,把一份公司的员工手册(约 9000 字)做成了可问答的知识库。

核心特性:

  • FastAPI REST API :提供 /api/v1/ask(问答)、/api/v1/upload(文档上传)、/api/v1/health(健康检查)等接口
  • 多提供商架构:LLM 和 Embedding 都可以在 DeepSeek API / LM Studio / Ollama / SentenceTransformers 之间自由切换------本地跑还是用云端 API,改一个环境变量就行
  • ChromaDB 向量存储:持久化到本地文件夹,无需额外安装数据库服务
  • 64 题自动化测试套件:覆盖 8 个检索维度,可复现的量化评估

3.2 三层架构

复制代码
┌─────────────────────────────────────┐
│  API 层 (FastAPI)                    │  ← 接收 HTTP 请求
│  /ask  /upload  /docs  /health      │
└───────────────┬─────────────────────┘
                │
┌───────────────▼─────────────────────┐
│  业务逻辑层                          │
│  QueryPipeline  IngestionPipeline   │  ← 编排查询和摄入流程
└───────────────┬─────────────────────┘
                │
┌───────────────▼─────────────────────┐
│  核心服务层(多提供商)               │
│  LLMService  EmbeddingService       │  ← 适配 4 种 LLM + 4 种 Embedding
│  RetrievalService → ChromaDB        │
└─────────────────────────────────────┘

最巧妙的设计是provider 切换 ------只需要修改 .env 文件中的一个配置项:

场景 EMBEDDING_PROVIDER LLM_PROVIDER 网络
纯本地离线 sentence_transformers lm_studio 离线
本地 API ollama ollama 本地
云端 deepseek deepseek 需要

这种设计的实际意义:开发时用免费的本地模型调试,上线后切换到更精准的云端 API------代码一行不改。

3.3 真实测试数据

这个 Demo 不是"能跑就行"的玩具------它配了一套 64 题的测试集,覆盖精确事实、概括总结、多段落推理等 8 个维度。最新一轮测试结果:

指标 数值 解读
检索命中率 67.2% (43/64) 64 题中有 43 题找到了正确答案所在的段落
答案正确率 48.4% (31/64) 找到段落后,LLM 能正确回答的有 31 题
平均延迟 4057ms/题 本地 Qwen3.5-9B + RTX 5090

67.2% 的检索命中率暴露了 Naive RAG 的核心瓶颈:检索不到正确段落,后续的增强和生成都是空中楼阁。 这也是为什么生产级 RAG 需要混合检索 + 重排序------这些正是下文要谈的扩展方向。


四、从 Demo 到生产:五个扩展方向

这个 Demo 是一个干净的起点。如果你想让它在真实场景中可用,以下是五个递进的扩展方向。

扩展 1:混合检索(难度:低,效果:显著)

当前状态 :只用了向量相似度检索(ChromaDB query → Top-K 段落)。

问题 :纯向量检索对精确匹配(人名、日期、编号)不敏感------你问"第 3.2 条是什么",它可能返回完全不相关的段落。

方案 :加入 BM25 关键词检索作为补充,两路结果通过 RRF(Reciprocal Rank Fusion)合并,再用一个轻量级 Reranker 模型二次排序。

预期提升:检索命中率 67% → 85%+

扩展 2:文档格式支持(难度:低)

当前状态 :只支持 Markdown 文档摄入,按 ## 标题分块。

扩展:加入 PDF(PyMuPDF)、Word(python-docx)、网页抓取(trafilatura)的支持,覆盖更多真实文档来源。

扩展 3:对话历史记忆(难度:中)

当前状态 :每次问答独立,没有上下文记忆。用户追问"那第二条呢?",系统不知道"那"指什么。

方案:加入对话历史管理------将最近 N 轮对话压缩后注入 Prompt,同时支持"基于之前的回答继续追问"。这是从"单轮问答"到"对话式 RAG"的跨越。

扩展 4:多文档知识库(难度:中)

当前状态 :只有一个 collection(documents),所有文档混在一起。

扩展:支持创建多个 collection(如"员工手册"、"技术文档"、"规章制度"),用户提问时可以指定检索范围,或者让系统自动路由到最相关的 collection。

扩展 5:Agentic RAG(难度:高)

当前状态 :固定流程------提问 → 检索 → 拼接 Prompt → 生成。

Agentic RAG:让 LLM 自己决定检索策略。"这个问题需要去哪个知识库查?"、"第一次检索结果不够精确,换一个角度再查"、"用户问的是对比性问题,需要从两个知识库各取一段"------Agent 自主规划多步检索,而不是被动的单次查询。

这是 RAG 的最终形态:不是"给模型查资料",而是"模型自己去查资料"。


五、总结

RAG 解决的是一个朴素但关键的问题:大模型不知道怎么回答它没学过的东西。 与其让它背下来(微调),不如让它去查(检索增强)。

这个 Demo 把 RAG 的核心 pipeline 完整落地了------从文档分块到向量检索到 LLM 生成,所有环节都可配置、可测试。67.2% 的检索命中率不是终点,而是告诉你下一步该往哪走的起点。

如果你拿到这个 Demo,建议的改动优先级: 先加混合检索(让检索更准)→ 再支持 PDF/Word(让文档来源更广)→ 然后加对话记忆(让交互更自然)→ 最后探索 Agentic RAG(让系统更智能)。

以上的优化方向已经在项目中规划了,正在实施中,更强大的v2.0版本敬请关注;

下一篇,我们讲讲如何实现 Agentic RAG