关键词:RAG、LangChain4j、向量检索、Embedding、AI 应用

一、为什么要 RAG?一张图看懂痛点

场景 仅 LLM LLM + RAG
时效性 停留在训练数据截止时间 实时检索最新文档
领域知识 通用语料,答非所问 私域文档精确回答
幻觉问题 一本正经地胡说 基于检索内容作答,可溯源
数据安全 上传云端训练 本地索引,完全隔离

一句话:RAG = 用搜索引擎给大模型开外挂。下面 30 分钟带你跑通“Easy RAG → Naive RAG → Advanced RAG”全链路。


二、Easy RAG:3 行代码跑通“Hello RAG”

2.1 引入依赖(Gradle 同理)

<!-- 一站式 Easy RAG,连 embedding 模型都打包好了 -->
<dependency>
  <groupId>dev.langchain4j</groupId>
  <artifactId>langchain4j-easy-rag</artifactId>
  <version>1.1.0-beta7</version>
</dependency>
<!-- OpenAI 客户端 -->
<dependency>
  <groupId>dev.langchain4j</groupId>
  <artifactId>langchain4j-open-ai</artifactId>
  <version>1.1.0-beta7</version>
</dependency>

2.2 3 行代码完成索引

// 1. 递归加载本地文档
List<Document> docs = FileSystemDocumentLoader.loadDocumentsRecursively("/data/docs");

// 2. 内存向量库(上线可换 PgVector/Milvus)
InMemoryEmbeddingStore<TextSegment> store = new InMemoryEmbeddingStore<>();

// 3. 一键入库:自动分段 + embedding + 存储
EmbeddingStoreIngestor.ingest(docs, store);

背后帮你做了啥?

  • Apache Tika 解析 PDF/Word/Markdown
  • bge-small-en-v1.5 量化模型本地跑,24 MB 不占内存
  • 300 token/段,重叠 30 token,科学分块不踩坑

2.3 开聊!

interface Assistant {
    String chat(String question);
}

Assistant assistant = AiServices.builder(Assistant.class)
        .chatModel(OpenAiChatModel.withApiKey(System.getenv("OPENAI_API_KEY")))
        .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
        .contentRetriever(EmbeddingStoreContentRetriever.from(store))
        .build();

String answer = assistant.chat("新人入职流程怎么走?");
System.out.println(answer);

输出示例:

请参照《新员工入职指引_v3.2.pdf》第 4 页:

  1. HR 系统提交入职申请
  2. IT 分配账号
  3. 领取工牌 …

三、Naive RAG:把方向盘握在自己手里

Easy RAG 是自动挡,Naive RAG 给你手动挡的快乐。核心 4 件套:

组件 自由配置点
DocumentLoader 指定解析器、过滤文件
DocumentSplitter 按段落/句子/正则切块
EmbeddingModel 自选 OpenAI、BGE、Onnx 等
EmbeddingStore 本地内存、PgVector、Chroma、Milvus

示例代码片段:

DocumentSplitter splitter = DocumentSplitters.recursive(1000, 200, new OpenAiTokenCountEstimator("gpt-4o-mini"));

EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
        .documentLoader(FileSystemDocumentLoader.builder()
                .documentParser(new ApachePdfBoxDocumentParser()) // PDF 专用
                .pathMatcher(FileSystems.getDefault().getPathMatcher("glob:**.pdf"))
                .build())
        .documentSplitter(splitter)
        .embeddingModel(new BgeSmallEnV15EmbeddingModel()) // 本地模型
        .embeddingStore(PgVectorEmbeddingStore.builder()
                .host("localhost")
                .port(5432)
                .database("rag")
                .user("postgres")
                .password("123456")
                .dimension(384) // 与模型一致
                .build())
        .build();

ingestor.ingest(docs);

四、Advanced RAG:企业级检索的 6 大杀器

场景:百万级文档、多租户、权限隔离、Web + 内部知识联合检索

4.1 架构全景图

UserMessage → Query → QueryTransformer → QueryRouter → 多路Retriever → ContentAggregator → ContentInjector → LLM

4.2 代码级示例

// 1. 查询改写(压缩历史对话)
QueryTransformer compressor = new CompressingQueryTransformer(chatModel);

// 2. 路由:技术文档走向量库,实时信息走 Google
QueryRouter router = new LanguageModelQueryRouter(chatModel, Map.of(
        "tech-docs", EmbeddingStoreContentRetriever.from(pgVectorStore),
        "web", WebSearchContentRetriever.builder()
                .webSearchEngine(GoogleCustomWebSearchEngine.builder()
                        .apiKey(System.getenv("GOOGLE_API_KEY"))
                        .csi(System.getenv("GOOGLE_CSI"))
                        .build())
                .maxResults(3)
                .build()
));

// 3. 重排序:Cohere 交叉编码器提升精度
ContentAggregator reRanker = new ReRankingContentAggregator(
        CohereScoringModel.withApiKey(System.getenv("COHERE_API_KEY")));

// 4. 组装
RetrievalAugmentor augmentor = DefaultRetrievalAugmentor.builder()
        .queryTransformer(compressor)
        .queryRouter(router)
        .contentAggregator(reRanker)
        .executor(Executors.newFixedThreadPool(8)) // 并行提速
        .build();

Assistant assistant = AiServices.builder(Assistant.class)
        .chatModel(chatModel)
        .retrievalAugmentor(augmentor)
        .build();

4.3 元数据过滤(权限隔离)

ContentRetriever retriever = EmbeddingStoreContentRetriever.builder()
        .embeddingStore(store)
        .filter(metadataKey("userId").isEqualTo("12345")
                .and(metadataKey("department").isIn(Set.of("IT", "HR"))))
        .build();

五、与 Spring Boot 整合最佳实践

直接贴生产级片段,CV 即可用

@Configuration
public class RagConfig {

    @Bean
    public EmbeddingStore<TextSegment> embeddingStore() {
        return PgVectorEmbeddingStore.builder()
                .host(pgHost).port(pgPort).database(pgDb)
                .user(pgUser).password(pgPwd)
                .table("embeddings").dimension(384).build();
    }

    @Bean
    public EmbeddingModel embeddingModel() {
        return new BgeSmallEnV15EmbeddingModel();
    }

    @Bean
    public RetrievalAugmentor retrievalAugmentor(EmbeddingStore<TextSegment> store,
                                                 EmbeddingModel model) {
        ContentRetriever retriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(store)
                .embeddingModel(model)
                .dynamicFilter(query -> {   // 根据登录用户动态过滤
                    String userId = SecurityContextHolder.getUserId();
                    return metadataKey("userId").isEqualTo(userId);
                })
                .build();
        return DefaultRetrievalAugmentor.builder()
                .queryTransformer(new CompressingQueryTransformer(chatModel()))
                .queryRouter(new DefaultQueryRouter(retriever))
                .build();
    }

    @Bean
    public Assistant assistant(RetrievalAugmentor augmentor) {
        return AiServices.builder(Assistant.class)
                .chatModel(chatModel())
                .retrievalAugmentor(augmentor)
                .build();
    }
}

六、避坑 & 性能调优清单

问题 症状 解法
检索为空 embedding 维度不一致 检查模型 & 库维度
回答截断 分块过大导致超 token 降低 maxResults 或 chunk size
速度慢 单线程 并行 Executor + 索引并发写
幻觉仍在 无上下文重叠 增加 overlap token 或 sentence-window
权限泄露 元数据过滤缺失 务必加 Filter 并审计日志

七、一键源码 & 线上体验

  • 完整 Demo:https://github.com/langchain4j/langchain4j-examples/tree/main/rag-examples
  • 在线文档:https://docs.langchain4j.dev/tutorials/rag

如果本文帮到你,欢迎点赞 + 收藏!评论区聊聊你在落地 RAG 时遇到的奇葩需求,一起交流~

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐