LangChain4j RAG 检索增强

LangChain4j RAG 检索增强

薛定谔的汪 Lv5

LangChain4j RAG 检索增强:构建文档问答机器人

一、什么是 RAG?

1.1 核心概念

RAG(Retrieval-Augmented Generation,检索增强生成) 是一种结合信息检索技术和 AI 内容生成的混合架构。

用一个形象的比喻:RAG 就像给 AI 配了一个”小抄本”。当用户提问时,AI 会先从你的知识库(小抄本)中查找相关信息,然后基于这些真实资料来回答问题,而不是凭空想象。

1.2 为什么需要 RAG?

大模型存在两个核心问题:

问题 说明 RAG 解决方案
知识时效性 训练数据截止于某个时间点,不知道最新信息 实时检索最新文档
幻觉问题 会”编造”不存在的答案(比如我问gpt3.5turbo三国演义中的典故,他答得都是错的) 强制基于检索到的真实内容回答

核心优势:让 AI 在回答问题前先查一查特定的知识库来获取知识,确保回答是基于真实资料而不是凭空想象。很多企业也基于 RAG 搭建了自己的智能客服,可以用自己积累的领域知识回复用户。

1.3 RAG 完整工作流程

阶段一:索引(离线)

1
2
PDF/Word/TXT  ──→  文档加载  ──→  文档分块  ──→  向量化  ──→  向量数据库  
(原始文档) (Document) (Chunk) (Embedding) (存储)

阶段二:检索与生成(在线)

1
2
用户问题  ──→  向量化  ──→  相似度检索  ──→  相关文档片段  ──→  最终答案 
(Query) (Embedding) (Search) (Context) LLM 生成

二、核心组件详解

2.1 文档加载器(Document Loader)

负责从各种来源加载文档(PDF、Word、TXT、网页等)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.parser.TextDocumentParser;

// 加载单个文档
Document document = FileSystemDocumentLoader.loadDocument(
Paths.get("docs/readme.txt"),
new TextDocumentParser()
);

// 加载整个目录
List<Document> documents = FileSystemDocumentLoader.loadDocuments(
Paths.get("src/main/resources/docs"),
new TextDocumentParser()
);

langchain4j 提供了多个文档解析器:

1
2
3
4
5
6
7
DocumentParser parser;
if ("txt".equals(extension)) {
parser = new TextDocumentParser();
} else {
// PDF、DOCX、XLSX等使用Apache Tika
parser = new ApacheTikaDocumentParser();
}

我项目中原来有 Elasticsearch,就直接复用了,节省资源。如果为了追求极致性能可以采用 Milvus,但会增加额外成本。

2.2 文档分块器(Document Splitter)

大模型有上下文长度限制(如 4K、8K、128K tokens),需要将长文档切成小块

1
2
3
4
import dev.langchain4j.data.document.splitter.DocumentSplitters;

// 递归分块:最大500字符,重叠100字符
DocumentSplitter splitter = DocumentSplitters.recursive(500, 100);

为什么需要重叠? 重叠可以保持块与块之间的上下文连贯性,避免关键信息被切在边界上。

2.3 嵌入模型计算向量(Embedding Model)

将文本转换成向量(一个长数组),用于语义相似度计算

1
2
// 本地离线模型(无需 API,开箱即用,适合测试)
EmbeddingModel embeddingModel = new AllMiniLmL6V2QuantizedEmbeddingModel();

也可以用AI厂商的,如openai

1
2
3
4
5
// 或者使用 OpenAI
EmbeddingModel openAiEmbeddingModel = OpenAiEmbeddingModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("text-embedding-ada-002")
.build();

2.4 向量数据库(Vector Store)

存储向量并提供相似度检索能力。LangChain4j 支持 30+ 种向量数据库

数据库 特点 适用场景
InMemoryEmbeddingStore 内存存储,重启丢失 测试、原型
Elasticsearch 支持混合检索(向量+全文),需企业版许可证 已有 ES 基础设施
Milvus 专用向量数据库,性能极致 大规模生产环境

目前我项目中用到了 elasticsearch和腾讯商业向量数据库,都是768 维度向量。

2.5 EmbeddingStoreIngestor:一键索引流水线

EmbeddingStoreIngestor 是 LangChain4j 提供的索引流水线工具,封装了分块、向量化、存储的完整流程

1
2
3
4
5
6
7
8
9
10
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;

EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
.documentSplitter(DocumentSplitters.recursive(500, 100)) // 分块器
.embeddingModel(embeddingModel) // 嵌入模型
.embeddingStore(embeddingStore) // 向量存储
.build();

// 一键处理所有文档
ingestor.ingest(documents);

实战:文档上传 + 异步索引 + Elasticsearch 存储

流程:

  1. 用户前端上传文档到云存储服务器。

  2. 后端存储 url,把 id发送消息队列,状态为”处理中”。

  3. 消息消费者

    1. 接收文档 id
    2. langchain4j 加载文档内容
    3. 文档分块(Chunking)
    4. 生成向量
    5. 存入 Elasticsearch,文档向量元数据包括 部门id、文档 id、文档名称等。
    6. 更新文档状态
  4. 用户问答服务:

    1. 用户提问
    2. 向量检索 + 元数据过滤
    3. LLM 生成回答
  • Title: LangChain4j RAG 检索增强
  • Author: 薛定谔的汪
  • Created at : 2025-05-30 18:01:54
  • Updated at : 2026-04-10 13:58:26
  • Link: https://www.zhengyk.cn/2025/05/30/ai/langchain4j_05_RAG/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments