RAG(检索增强生成):

  1. 把你的文档(PDF/Word/TXT/Excel)切成一段段
  2. 转成向量(Embedding)
  3. 存在向量库
  4. 用户提问时,先去向量库里检索相关内容
  5. 把检索到的内容丢给 AI,让 AI 只根据你的资料回答

准备

一、先拿 通义千问 API 信息

打开:https://dashscope.console.aliyun.com/
左侧 API-KEY 管理 → 创建并复制 API-KEY
通义的 Embedding 模型名固定:

text-embedding-v1

通义的 接口地址固定:

https://dashscope.aliyuncs.com/compatible-mode/v1

在这里插入图片描述
在这里插入图片描述

二、准备文本信息

新建文件:info.txt

公司名称:科技有限公司
成立时间:2025年
员工人数:50人
主营业务:AI软件开发、智能系统集成
创始人:张三

入门版RAG

手动拼接提示词、手动处理向量、手动检索

DEMO

pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 使用 Spring Boot 父项目,自动管理版本 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath/>
    </parent>

    <groupId>org.example</groupId>
    <artifactId>langchain4j-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <java.version>17</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <langchain4j.version>1.3.0</langchain4j.version>
    </properties>

    <dependencies>
        <!-- 1. Spring Boot 核心依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- 2. LangChain4j 核心依赖 -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j</artifactId>
        </dependency>

        <!-- 3. OpenAI 适配依赖 -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-open-ai</artifactId>
        </dependency>

        <!-- 4. 流式依赖       -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-reactor</artifactId>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>dev.langchain4j</groupId>
                <artifactId>langchain4j-bom</artifactId>
                <version>${langchain4j.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <!-- Spring Boot 打包插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

实现

package org.deepseek.demo09;

// ==================== 基础依赖 ====================
// 文档对象,代表一个完整的文件
import dev.langchain4j.data.document.Document;
// 文件加载器,用于从本地磁盘读取文件
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
// 文档切分工具,把大文件切成小段
import dev.langchain4j.data.document.splitter.DocumentSplitters;
// 向量对象,存储文本的向量表示
import dev.langchain4j.data.embedding.Embedding;
// 文本片段,切分后的每一小段文本
import dev.langchain4j.data.segment.TextSegment;

// ==================== 模型依赖 ====================
// 对话模型接口
import dev.langchain4j.model.chat.ChatModel;
// 向量生成模型接口
import dev.langchain4j.model.embedding.EmbeddingModel;
// DeepSeek 对话模型(OpenAI 兼容格式)
import dev.langchain4j.model.openai.OpenAiChatModel;
// 通义千问 向量模型(OpenAI 兼容格式)
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;

// ==================== 向量库依赖 ====================
// 向量匹配结果,包含匹配到的文本和分数
import dev.langchain4j.store.embedding.EmbeddingMatch;
// 向量搜索请求,构建搜索的参数
import dev.langchain4j.store.embedding.EmbeddingSearchRequest;
// 向量库顶层接口
import dev.langchain4j.store.embedding.EmbeddingStore;
// 内存版向量库(重启消失,适合学习)
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;

import java.util.List;

/**
 * 【RAG 入门版】
 * 功能:读取本地 info.txt 文件,构建知识库,根据文档内容准确回答问题
 * 解决:AI 胡说八道、无法回答私有数据问题
 */
public class SimpleRAGDemo {
    public static void main(String[] args) {

        // ==================== 步骤 1:初始化 对话模型(DeepSeek) ====================
        // 作用:负责理解问题 + 整理资料 + 生成最终回答
        ChatModel chatModel = OpenAiChatModel.builder()
                .apiKey("sk-xxxxxxxxxxxxx")       // 你的 API Key
                .baseUrl("https://api.deepseek.com")                  // DeepSeek 接口地址
                .modelName("deepseek-chat")                          // 对话模型名称
                .temperature(0.1)                                     // 温度越低,回答越严谨、稳定
                .build();

        // ==================== 步骤 2:初始化 向量模型(通义千问 Embedding) ====================
        // 作用:把【文本】转换成【向量】,让计算机能理解语义、做相似度匹配
        EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
                .apiKey("sk-xxxxxxxxxxxx")       // 阿里云 API Key
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1") // 通义兼容接口
                .modelName("text-embedding-v1")                      // 通义向量模型(固定)
                .build();

        // ==================== 步骤 3:加载本地文档 ====================
        // 从本地磁盘读取 txt 文件,封装成 Document 对象
        Document document = FileSystemDocumentLoader.loadDocument("D:\\Project\\public\\langchain4j\\demo\\info.txt");

        // ==================== 步骤 4:文档切分(核心!) ====================
        // 为什么要切分?
        // 1. 大模型有输入长度限制
        // 2. 检索更精准
        // 3. 向量计算更快
        var splitter = DocumentSplitters.recursive(300, 50);
        // 300:每一段最大长度
        // 50:段落重叠长度(防止语义被切断)
        List<TextSegment> segments = splitter.split(document);

        // ==================== 步骤 5:初始化向量库 ====================
        // 内存向量库:学习用,重启项目数据消失
        // 生产环境建议使用:Redis / Milvus / Chroma / Qdrant
        EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();

        // ==================== 步骤 6:批量生成向量并存入向量库 ====================
        // 把所有文本片段 → 转换成向量
        List<Embedding> embeddings = embeddingModel.embedAll(segments).content();
        // 把【向量】和【对应的文本】一起存入向量库
        embeddingStore.addAll(embeddings, segments);

        // ==================== 步骤 7:用户提问 → 生成查询向量 ====================
        String question = "公司创始人是谁?";
        // 把问题也变成向量,才能去向量库做“语义匹配”
        Embedding queryEmbedding = embeddingModel.embed(question).content();

        // ==================== 步骤 8:向量库检索(最核心) ====================
        // 构建搜索请求
        EmbeddingSearchRequest request = EmbeddingSearchRequest.builder()
                .queryEmbedding(queryEmbedding)      // 查询向量
                .maxResults(3)                       // 最多返回 3 条最相关的片段
                .build();

        // 执行搜索:根据向量相似度,找到最相关的文本片段
        var result = embeddingStore.search(request);
        List<EmbeddingMatch<TextSegment>> matches = result.matches();

        // ==================== 步骤 9:拼接检索到的内容 ====================
        StringBuilder context = new StringBuilder();
        for (EmbeddingMatch<TextSegment> match : matches) {
            TextSegment segment = match.embedded();
            if (segment != null) {
                context.append(segment.text()).append("\n");
            }
        }

        // ==================== 步骤 10:交给 AI,生成最终回答 ====================
        // 提示词:强制 AI 只根据资料回答,禁止编造
        String prompt = """
                请根据资料回答,不要编造。
                资料:%s
                问题:公司创始人是谁?
                """.formatted(context);

        // AI 生成回答
        String answer = chatModel.chat(prompt);
        System.out.println("AI 回答:" + answer);
    }
}

在这里插入图片描述

知识点

1. 什么是 RAG?

RAG = Retrieval Augmented Generation
检索增强生成。
作用:

  1. 让 AI 只能根据你提供的文档回答
  2. 解决 AI 胡说八道 问题
  3. 让 AI 能使用私有数据、内部文档

2. RAG 执行流程

  1. 加载文档(txt/pdf/word)
  2. 切分文档(split)
  3. 向量化(embedding)
  4. 存入向量库
  5. 用户提问
  6. 问题向量化
  7. 检索相关片段
  8. 拼接上下文
  9. 交给大模型回答

3. 什么是 Embedding(向量)?

把文字变成 一串数字
语义相似的文本,向量距离更近
是 RAG 能 “语义检索” 的基础

4. 为什么要切分文档?

大模型有最大输入长度
太长的文本向量会丢失信息
切分后检索更精准
切分参数:
maxSegmentSize:片段长度
overlapSize:重叠长度(防止切断语义)

5. 向量库是什么?

专门存储向量、提供相似度检索的数据库。
学习用:
InMemoryEmbeddingStore(内存)
生产用:
RedisMilvusQdrantChroma

6. 检索原理

用户问题向量 → 去库中匹配 最相似的文本向量
不是关键词匹配,是语义匹配

7. 为什么要用混合模型?

deepseek-chat:擅长对话、推理、总结
text-embedding-v1:擅长中文向量
LangChain4j 支持任意模型混用

8.提示词工程

请根据资料回答,不要编造。
资料:xxx
问题:xxx

作用:强制 AI 不能瞎编。

9. 温度参数(temperature)

0.1 ~ 0.3:RAG 专用,严谨、事实准确
0.7 ~ 1.0:创意写作、发散思考

10. 企业 RAG 优化方向

更好的切分策略
更好的 Embedding 模型
加入关键词混合检索
加入重排(Rerank)
加入会话记忆
加入元数据过滤

AiServices 优雅版 RAG

AiServices = 自动帮你做:检索 + 提示词拼接 + 对话 + 记忆

  1. 接收问题
  2. 自动去向量库检索
  3. 自动拼接提示词
  4. 自动调用大模型
  5. 自动返回结果

DEMO

  1. 接口
package org.deepseek.demo10;

import dev.langchain4j.service.SystemMessage;

public interface CompanyAssistant {
    @SystemMessage("你是公司智能助手,请严格根据提供的资料回答问题,绝对不能编造信息")
    String ask(String question);

}

  1. 实现
package org.deepseek.demo10;

import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;

import java.util.List;

/**
 * 【 AiServices 优雅版 RAG】
 * 企业标准写法:自动检索 + 自动提示 + 自动回答
 */
public class AiServicesRAGDemo {

    public static void main(String[] args) {
        // ========================= 1. 配置对话模型(DeepSeek) =========================
        ChatModel chatModel = OpenAiChatModel.builder()
                .apiKey("sk-xxxxxxxxxxxxxx")
                .baseUrl("https://api.deepseek.com")
                .modelName("deepseek-chat")
                .temperature(0.1)
                .build();

        // ========================= 2. 配置向量模型(通义千问) =========================
        EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
                .apiKey("sk-xxxxxxxxxxxxxxxxx")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .modelName("text-embedding-v1")
                .build();

        // ========================= 3. 加载并向量化文档(只执行一次!) =========================
        Document document = FileSystemDocumentLoader.loadDocument("D:\\Project\\public\\langchain4j\\demo\\info.txt");
        List<TextSegment> segments = DocumentSplitters.recursive(300, 50).split(document);

        EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
        embeddingStore.addAll(embeddingModel.embedAll(segments).content(), segments);

        // ========================= 4. 构建检索器 =========================
        ContentRetriever contentRetriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(embeddingModel)
                .maxResults(3)
                .build();

        // ========================= 5. 自动创建 AI 助手(自动集成 RAG) =========================
        CompanyAssistant assistant = AiServices.builder(CompanyAssistant.class)
                .chatModel(chatModel)
                .contentRetriever(contentRetriever) // 自动 RAG
                .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) // 自动记忆
                .build();

        // ========================= 7. 直接提问!RAG 全自动执行 =========================
        String answer = assistant.ask("公司创始人是谁?");
        System.out.println("AI 回答:" + answer);
    }
}

知识点

1. AiServices 是什么?

LangChain4j 核心大脑
动态代理生成 AI 实现类
自动整合:模型、RAG、记忆、工具

2. ContentRetriever 作用

封装所有检索逻辑
对接向量库
给 AiServices 提供检索能力

3. @SystemMessage 作用

设定 AI 角色
约束行为
RAG 必须加:禁止编造

4. 为什么这种写法更强?

代码量减少 70%
不用处理向量、Embedding、TextSegment
不用处理空指针
不用拼接提示词
支持流式输出、多轮对话、工具调用

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐