RAG科普

9 阅读3分钟

RAG(Retrieval-Augmented Generation,检索增强生成)是大模型应用开发中最核心、落地最广的技术方案。

简单来说,如果把大模型(LLM)比作一个“饱读诗书但没有网、且记忆停留在两年前”的专家,那么 RAG 就是给这位专家配了一个可以随时查阅的“最新私人图书馆”。


1. 为什么需要 RAG?

大模型虽然强大,但在企业级应用中面临三个致命问题:

  1. 知识幻觉(Hallucination): 模型会一本正经地胡说八道。
  2. 时效性限制: 模型的训练数据有截止日期(Knowledge Cutoff),它不知道昨天的资讯。
  3. 私有数据缺失: 模型没有读过你公司的内部文档、代码库或你的个人笔记。

解决办法有两种:

  • 微调(Fine-tuning): 像让专家去考个研,把知识“背”进脑子里(成本高、更新慢)。
  • RAG: 像给专家发一本参考书,让他开卷考试(成本低、实时性强、准确度高)。

2. RAG 的核心工作流程

RAG 的实现可以分为两个阶段:数据准备(离线)检索生成(在线)

第一阶段:数据入库(Indexing)

这是将你的“私人文档”转化成大模型能“检索”的格式的过程:

  1. 文档加载(Load): 读取 PDF、Word、Markdown 或数据库记录。
  2. 文本切分(Chunking): 将长文章切成小段(比如每段 500 字),因为大模型上下文有限。
  3. 向量化(Embedding): 调用 Embedding 模型,将每一小段文字转化成一串数字向量。
  4. 向量存储(Vector Store): 存入向量数据库(如 Milvus、Pinecone、Elasticsearch)。

第二阶段:检索与生成(Retrieval & Generation)

当用户提问时,系统会执行以下步骤:

  1. 问题向量化: 把用户的提问也转成向量。

  2. 向量检索: 在数据库中寻找与提问向量最相似(通常用余弦相似度)的 Top-K 个文档片段。

  3. Prompt 增强(Augmentation): 将找回的片段和原始问题拼在一起。

    • Prompt 模板示例: “已知以下信息:{检索到的片段}。请根据这些信息回答问题:{用户提问}。”
  4. 模型生成: 大模型根据“参考资料”给出精准回答。


3. RAG vs. 微调(Fine-tuning)

对于开发者来说,选择哪种方案通常参考下表:

维度RAG (检索增强)Fine-tuning (微调)
知识更新速度秒级(更新数据库即可)慢(需要重新训练)
外部知识量理论上无限(取决于硬盘)有限(受模型参数限制)
准确性高(引用原始出处)中(容易产生幻觉)
实现难度较低(工程化为主)较高(需要算法和算力)
数据隐私易控制(权限管理)难控制(知识被模型吸收)

4. Java 开发者的 RAG 工具栈

作为主攻 Java 后端的同学,你可以通过 LangChain4j 快速搭建一套 RAG 系统。

核心组件映射:

  • Embedding 模型: OpenAiEmbeddingModel 或本地部署的 OllamaEmbeddingModel
  • 向量数据库: MilvusEmbeddingStoreRedisEmbeddingStore
  • 内容检索器: ContentRetriever(这是 LangChain4j 中负责“找资料”的核心接口)。

简单的代码实现逻辑:

Java

// 1. 创建向量库
EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();

// 2. 将文档片段存入(实际开发中会先切分文本)
TextSegment segment = TextSegment.from("阿离,Java后端开发者,擅长信息安全。");
Embedding embedding = embeddingModel.embed(segment).content();
embeddingStore.add(embedding, segment);

// 3. 构建 RAG 检索器
ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
        .embeddingStore(embeddingStore)
        .embeddingModel(embeddingModel)
        .maxResults(3) // 找最相关的 3 条
        .build();

// 4. 绑定到 AI Service
Assistant assistant = AiServices.builder(Assistant.class)
        .chatLanguageModel(model)
        .contentRetriever(contentRetriever) // 注入 RAG
        .build();

5. 进阶思考:RAG 的安全挑战

由于你专业是 信息安全,在设计 RAG 时需要额外考虑:

  1. 数据越权: 如果用户 A 检索到了只有用户 B 才有权限查看的文档片段,这就是严重的安全事故。

    • 对策: 在向量检索时增加 Filter(Metadata Filtering),确保只检索 userId 匹配的文档。
  2. Prompt 注入: 文档片段中如果包含恶意指令,可能会误导模型执行错误操作。


学习参考视频:www.bilibili.com/video/BV11z… and www.bilibili.com/video/BV1ae…