基于 SpringBoot 整合 LangChain4j 实现完整的 RAG 流程,核心包括:自定义 ContentRetriever 加载知识库、配置阿里百炼文本向量模型、替换内存存储为 Pinecone 向量数据库,最终实现精准的知识库检索增强生成。

一、核心组件:ContentRetriever(检索器)

1.1 作用

ContentRetriever 是 LangChain4j 中 RAG 的核心检索组件,负责从向量存储中检索与用户查询最相似的文本片段,为大模型提供精准的外部知识。

1.2 自定义 ContentRetriever Bean(Spring 配置)

1.2.1 代码实现(XiaozhiAgentConfig.java)

import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.retriever.ContentRetriever;
import dev.langchain4j.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;
import java.util.List;

@Configuration
public class XiaozhiAgentConfig {

    /**
     * 自定义小智助手的内容检索器
     * 步骤:加载文档 → 初始化内存向量库 → 文档分割+向量化+入库 → 构建检索器
     */
    @Bean
    public ContentRetriever contentRetrieverXiaozhi() {
        // 1. 加载本地知识库文档(MD格式,使用默认TextDocumentParser解析)
        Document doc1 = FileSystemDocumentLoader.loadDocument("E:/knowledge/医院信息.md");
        Document doc2 = FileSystemDocumentLoader.loadDocument("E:/knowledge/科室信息.md");
        Document doc3 = FileSystemDocumentLoader.loadDocument("E:/knowledge/神经内科.md");
        List<Document> documents = Arrays.asList(doc1, doc2, doc3);

        // 2. 初始化内存向量存储(仅测试用,生产需替换为Pinecone)
        InMemoryEmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();

        // 3. 文档处理入库:分割 → 向量化 → 存入向量库(使用默认递归分割器+内置向量模型)
        EmbeddingStoreIngestor.ingest(documents, embeddingStore);

        // 4. 构建并返回基于向量库的检索器
        return EmbeddingStoreContentRetriever.from(embeddingStore);
    }
}
1.2.2 关键说明
  • FileSystemDocumentLoader:加载本地文件,默认使用 TextDocumentParser 解析纯文本(MD/TXT/HTML);
  • EmbeddingStoreIngestor.ingest():一站式完成「文档分割 + 文本向量化 + 向量入库」;
  • InMemoryEmbeddingStore:内存级向量存储,优点是无需部署、快速测试;缺点是重启后数据丢失,生产环境禁止使用

1.3 关联 AI 服务(XiaozhiAgent.java)

将自定义的 ContentRetriever 配置到 AI 服务中,让大模型生成时自动检索知识库:

import dev.langchain4j.service.AiService;
import static dev.langchain4j.service.WiringMode.EXPLICIT;

@AiService(
    wiringMode = EXPLICIT, // 显式指定依赖组件
    chatModel = "qwenChatModel", // 通义千问对话模型
    chatMemoryProvider = "chatMemoryProviderXiaozhi", // 对话记忆组件
    tools = "appointmentTools", // 自定义工具(预约挂号)
    contentRetriever = "contentRetrieverXiaozhi" // 关联自定义检索器
)
public class XiaozhiAgent {
    // AI 方法定义...
}

1.4 工具提示词优化(关键)

修改工具的 value 提示,引导模型优先从向量库检索信息:

java

运行

import dev.langchain4j.agent.tool.Tool;

@Tool(
    name = "预约挂号",
    value = "根据参数,先执行工具方法queryDepartment查询是否可预约,并直接给用户回答是否可预约,并让用户确认所有预约信息,用户确认后再进行预约。如果用户没有提供具体的医生姓名,请从向量存储中找到一位医生。"
)
public String appointmentRegistration(String department, String doctorName) {
    // 工具逻辑实现...
}

二、向量模型:阿里百炼 text-embedding-v3(通用文本向量)

2.1 核心介绍

  • 作用:将文本(文档片段 / 用户查询)转换为高维向量,向量维度越高,语义表达越精准,检索精度越高;
  • text-embedding-v3:阿里百炼通用文本向量模型,维度 1024,支持中文语义精准建模;
  • 依赖:需引入 langchain4j-community-dashscope(通义千问 / 百炼集成依赖)。

2.2 配置步骤

2.2.1 依赖(已引入可忽略)

xml

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-community-dashscope</artifactId>
    <version>0.32.0</version>
</dependency>
2.2.2 配置文件(application.yml/application.properties)

yaml

# 阿里百炼文本向量模型配置
langchain4j:
  community:
    dashscope:
      embedding-model:
        api-key: ${DASH_SCOPE_API_KEY} # 百炼API Key(替换为自己的)
        model-name: text-embedding-v3 # 向量模型名称
  • DASH_SCOPE_API_KEY:需在阿里百炼控制台申请,配置为环境变量或直接替换;
  • 模型默认输出 1024 维向量,无需额外配置维度。

2.3 测试向量模型(SpringBootTest)

java

运行

import dev.langchain4j.model.embedding.Embedding;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.output.Response;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class EmbeddingTest {

    @Autowired
    private EmbeddingModel embeddingModel; // 自动注入百炼向量模型

    @Test
    public void testEmbeddingModel() {
        // 文本向量化
        Response<Embedding> embedResponse = embeddingModel.embed("你好");
        Embedding embedding = embedResponse.content();

        // 输出结果
        System.out.println("向量维度:" + embedding.vector().length); // 输出1024
        System.out.println("向量内容:" + embedding.toString());
    }
}

三、向量存储:从内存存储到 Pinecone(生产级)

3.1 核心对比

表格

存储类型 优点 缺点 适用场景
InMemoryEmbeddingStore 无需部署、测试快 重启丢失、不支持分布式、容量小 本地测试 / 演示
Pinecone 持久化、分布式、支持高并发、相似度检索优化 需要注册、少量免费额度(2GB) 生产环境 / 正式部署

3.2 Pinecone 简介

  • 官方地址:https://www.pinecone.io/
  • 核心能力:专为向量检索设计的云原生数据库,支持余弦相似度 / 点积等多种相似度计算,提供 REST API 快速集成;
  • 免费额度:注册后默认 2GB 免费存储空间,满足中小规模场景。

3.3 Pinecone 使用前置步骤

  1. 注册 Pinecone 账号并登录;
  2. 创建 Index(索引):设置向量维度(需与 text-embedding-v3 一致,1024)、距离度量方式(余弦相似度);
  3. 获取 API Key 和环境 ID(Environment),配置到项目环境变量中。

3.4 核心概念:检索得分

  • 含义:查询向量与存储向量的相似度数值(如余弦相似度),得分越高,语义相关性越强;
  • 作用:ContentRetriever 会根据得分筛选 Top-K 最相似的文本片段,作为大模型的参考知识。

3.5 Pinecone 集成(替换内存存储)

3.5.1 添加依赖

xml

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-pinecone</artifactId>
    <version>0.32.0</version>
</dependency>
3.5.2 替换 ContentRetriever 中的向量存储

@Bean
public ContentRetriever contentRetrieverXiaozhi() {
    // 1. 加载文档(同之前)
    Document doc1 = FileSystemDocumentLoader.loadDocument("E:/knowledge/医院信息.md");
    List<Document> documents = Arrays.asList(doc1, doc2, doc3);

    // 2. 初始化Pinecone向量存储(替换InMemoryEmbeddingStore)
    PineconeEmbeddingStore<TextSegment> embeddingStore = PineconeEmbeddingStore.builder()
            .apiKey(System.getenv("PINECONE_API_KEY")) // 环境变量中的API Key
            .environment(System.getenv("PINECONE_ENV")) // Pinecone环境ID
            .indexName("xiaozhi-rag-index") // 自己创建的Index名称
            .dimension(1024) // 与text-embedding-v3维度一致
            .build();

    // 3. 文档入库(分割+向量化+存入Pinecone)
    EmbeddingStoreIngestor.ingest(documents, embeddingStore);

    // 4. 构建检索器(可配置返回Top-K片段,默认Top-5)
    return EmbeddingStoreContentRetriever.builder()
            .embeddingStore(embeddingStore)
            .embeddingModel(embeddingModel) // 注入百炼向量模型
            .maxResults(3) // 每次检索返回3个最相似片段
            .build();
}

四、完整测试流程

4.1 Controller 测试 RAG 效果

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RagController {

    @Autowired
    private XiaozhiAgent xiaozhiAgent;

    @GetMapping("/rag/query")
    public String ragQuery(@RequestParam String question) {
        // 调用AI服务,自动触发ContentRetriever检索知识库
        return xiaozhiAgent.chat(question);
    }
}

4.2 测试示例

  • 请求:/rag/query?question=神经内科有哪些可预约的医生
  • 预期效果:模型从向量库中检索「神经内科.md」的内容,结合工具逻辑返回精准答案,而非编造信息。

总结(核心关键点)

  1. ContentRetriever 是 RAG 检索的核心,需绑定到 AI 服务中,实现「查询→检索→生成」的闭环;
  2. 向量模型 决定文本向量化精度,优先选用生产级模型(如阿里 text-embedding-v3),维度需与向量数据库匹配;
  3. 向量存储:InMemoryEmbeddingStore 仅用于测试,生产必须替换为 Pinecone/Milvus 等专业向量数据库,保证数据持久化和检索性能。
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐