LangChain4j 新手入门实战教程(Java版)

前言

今天介绍一下LangChain怎么玩。本人学AI Agent不超过一个月,如有错误,欢迎批评指正。了解我的人都知道,最近三年,本人都在打磨产品,没有涉足AI领域。最近才开始杀入AI领域的开发。除了Java后端有些基础外,我基础不比新人强多少。

LangChain是什么?

LangChain是一个开源的大语言模型(LLM)应用开发框架,作用是把大模型、文档、向量库、各类工具API组装起来,快速搭建AI应用。

开始开发(基础使用)

由于本人不会Python,所以只介绍Java的开发。老规矩,在pom.xml中配置依赖。

xml 复制代码
<!-- 核心包,必须 -->
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j</artifactId>
</dependency>
<!-- 兼容openai协议的都可以使用它 -->
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-open-ai</artifactId>
</dependency>
<!-- 也可以用具体的模型的SDK的,比如千问的 -->

创建OpenAiChatModel

先创建OpenAiChatModel对象,我这里举三个例子。

阿里云百炼
scss 复制代码
val model = OpenAiChatModel.builder()
        .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
        .apiKey("sk-xxx") // 阿里云dashscope api key
        .modelName("qwen-turbo") // qwen-plus / qwen-max
        .temperature(0.7)
        .build();
DeepSeek
scss 复制代码
val model = OpenAiChatModel.builder()
        .baseUrl("https://api.deepseek.com")
        .apiKey("sk-xxx") // deepseek api key
        .modelName("deepseek-chat")
        .temperature(0.7)
        .returnThinking(true) // 开启reasoning_content思考内容解析
        .build();
火山方舟
scss 复制代码
val model = OpenAiChatModel.builder()
        .baseUrl("https://ark.cn-beijing.volces.com/api/v3")
        .apiKey("sk-xxx") //火山方舟api key
        .modelName("ep-xxxxxx") //火山方舟是endpoint id,不是模型名!
        .temperature(0.7)
        .build();

生成内容

ini 复制代码
String resp = model.chat("你好");

没错,就是这么一行代码,完成了。

RAG

在完成基础使用后,我们对Demo进行加强,使用到RAG。

什么是RAG?

RAG,Retrieval-Augmented Generation,检索增强生成。给大模型外接一个知识库,提问时先检索相关资料,再把资料连同问题一起交给大模型,让模型基于查到的材料来回答,而不是只靠模型自身预训练记忆。

为什么需要RAG?

使用RAG的目的是为了避免大模型出现幻觉,免得豆包等大模型一本正经的胡说八道。有人要问了,那我为什么不把知识库直接训练给大模型?好问题。原因如下:

  1. 模型训练需要时间,最新的知识无法实时更新

  2. 使用RAG就相当于外接一本书,回答可以附带引用原文片段,便于溯源与合规

  3. 解耦合,方便更新与更换

写一个RAG的Demo

创建Embedding模型

创建一个Embedding模型,这里以阿里的千问为例。

csharp 复制代码
// Embedding模型(同样OpenAI兼容)
private static EmbeddingModel createEmbeddingModel() {
    // 千问embedding
    return OpenAiEmbeddingModel.builder()
            .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
            .apiKey("sk-你的dashscope-key")
            .modelName("text-embedding-v1")
            .build();
}
在RAG里,Embedding起什么作用?

回忆 RAG 流程:文档切分成 chunk → Embedding → 存入向量库。 用户提问时:问题文本 → Embedding → 在向量库计算向量距离,召回最相似的文档片段。

文档切分,向量化
ini 复制代码
String docText = """
        Langchain4j 是Java版大模型应用开发框架。
        Langchain4j支持RAG检索增强生成,可以把私有文档内容交给大模型。
        Langchain4j支持对话记忆,可以记住多轮聊天上下文。
        作者:langchain4j社区。
        """;
Document document = Document.from(docText);
var splitter = DocumentSplitters.recursive(300, 30);
var segments = splitter.split(document);
EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
embeddingStore.addAll(embeddingModel.embedAll(segments).content(), segments);

先将文档拆分成很多Chunk ,这里使用的是DocumentSplitters拆分器,按300个字一组拆分,实际项目不会这么用。先使用InMemoryEmbeddingStore存到内存中,用Map保存,实际项目一般会存到Redis或Database。

定义Assistant接口
arduino 复制代码
interface Assistant {
    String chat(String userMessage);
}
召回记忆
ini 复制代码
// 对话记忆:消息窗口,最多保存10条消息
ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
创建检索增强器
scss 复制代码
var contentRetriever = EmbeddingStoreContentRetriever.builder()
        .embeddingStore(embeddingStore)
        .embeddingModel(embeddingModel)
        .maxResults(2) //最多召回2条
        .minScore(0.6)
        .build();
RetrievalAugmentor retrievalAugmentor = DefaultRetrievalAugmentor.builder()
        .contentRetriever(contentRetriever)
        .build();
Assistant发起对话
ini 复制代码
// 创建AI服务实例,绑定记忆+RAG
Assistant assistant = AiServices.builder(Assistant.class)
        .chatModel(createChatModel())
        .chatMemory(chatMemory)
        .retrievalAugmentor(retrievalAugmentor)
        .build();
// ====== 测试对话 ======
System.out.println("【第一轮提问】Langchain4j是什么?");
String resp1 = assistant.chat("Langchain4j是什么?");
System.out.println(resp1);
System.out.println("\n【第二轮提问】它支持哪些能力?");
String resp2 = assistant.chat("它支持哪些能力?");
System.out.println(resp2);
System.out.println("\n【第三轮提问】刚才我们聊的框架是谁开发的?");
String resp3 = assistant.chat("刚才我们聊的框架是谁开发的?");
System.out.println(resp3);

RAG的会话隔离

前面的Demo有什么问题?记忆是所有会话共享的。这样,无论什么信息你都写入长期记忆了,那会话多了是不是会爆炸💥。人的大脑还要睡眠处理信息,然后选择性遗忘呢!

定义使用MemoryId隔离记忆的Assistant
less 复制代码
interface AssistantUnique {
    /**
     * @param memoryId 会话唯一ID(userId / sessionId),不同id自动隔离记忆
     * @param userMessage 用户提问
     * @return LLM回答
     */
    String chat(@MemoryId String memoryId, @UserMessage String userMessage);
}

多个String参数,需要使用@UserMessage手动标注哪个是UserMessage。

使用ChatMemoryProvider提供记忆(关键)
ini 复制代码
ChatMemoryProvider memoryProvider = memoryId ->
        MessageWindowChatMemory.withMaxMessages(10);
完整实现流程
java 复制代码
package com.dora.agent.llm;

import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.rag.DefaultRetrievalAugmentor;
import dev.langchain4j.rag.RetrievalAugmentor;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;

public class RagUniqueMemoryDemo {

    private static OpenAiChatModel createChatModel() {
        // 千问 dashscope
        return OpenAiChatModel.builder()
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .apiKey("sk-xxx")
                .modelName("qwen-turbo")
                .temperature(0.7)
                .build();
    }
    private static EmbeddingModel createEmbeddingModel() {
        return OpenAiEmbeddingModel.builder()
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .apiKey("sk-xxx")
                .modelName("text-embedding-v1")
                .build();
    }
    
    interface AssistantUnique {
        /**
         * @param memoryId 会话唯一ID(userId / sessionId),不同id自动隔离记忆
         * @param userMessage 用户提问
         * @return LLM回答
         */
        String chat(@MemoryId String memoryId, @UserMessage String userMessage);
    }
    
    public static void main(String[] args) {
        // 1. 向量库、文档向量化(全局知识库,所有会话共用)
        EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
        EmbeddingModel embeddingModel = createEmbeddingModel();
        String docText = """
                Langchain4j 是Java版大模型应用开发框架。
                Langchain4j支持RAG检索增强生成,可以把私有文档内容交给大模型。
                Langchain4j支持对话记忆,可以记住多轮聊天上下文。
                """;
        Document document = Document.from(docText);
        var splitter = DocumentSplitters.recursive(300, 30);
        var segments = splitter.split(document);
        embeddingStore.addAll(embeddingModel.embedAll(segments).content(), segments);
        // 2. RAG检索器,全局共用
        var retriever = EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(embeddingModel)
                .maxResults(2)
                .minScore(0.6)
                .build();
        RetrievalAugmentor augmentor = DefaultRetrievalAugmentor.builder()
                .contentRetriever(retriever)
                .build();
        // 3.ChatMemoryProvider:根据memoryId自动创建独立记忆
        ChatMemoryProvider memoryProvider = memoryId ->
                MessageWindowChatMemory.withMaxMessages(10);
        // 4. 构建AiService,只构建1个实例,供所有会话复用
        AssistantUnique assistant = AiServices.builder(AssistantUnique.class)
                .chatModel(createChatModel())
                .chatMemoryProvider(memoryProvider) // 按id动态生成记忆
                .retrievalAugmentor(augmentor)
                .build();
        // ========== 测试:两个独立会话,记忆互不串 ==========
        String sessionA = "session_001";
        String sessionB = "session_002";
        System.out.println("==== 会话A(session_001) ====");
        System.out.println(assistant.chat(sessionA, "Langchain4j是什么?"));
        System.out.println(assistant.chat(sessionA, "它支持什么能力?"));
        System.out.println("\n==== 会话B(session_002) ====");
        System.out.println(assistant.chat(sessionB, "刚才我问了你什么?")); // B看不到A的对话,回答不知道
    }
}

总结

本文面向Java后端开发新手,从零完成了LangChain4j框架的入门学习与实操开发,完整讲解了Java体系下大模型应用的基础搭建与RAG核心能力落地。首先介绍了LangChain4j的核心定位,作为轻量化开源LLM开发框架,它可快速整合各类大模型、知识库与工具接口,适配Java技术栈的AI应用开发场景。

在基础开发部分,详细演示了核心依赖引入方式,并适配阿里云百炼、DeepSeek、火山方舟三大主流兼容OpenAI协议的大模型,提供了可直接复用的模型初始化代码,极简实现了大模型基础对话能力,降低了新手接入大模型的开发门槛。

同时,文章重点拆解了RAG检索增强生成技术的核心原理与应用价值,明确了RAG解决大模型幻觉、知识滞后、无法私有化部署等核心痛点的优势,并完整落地了RAG入门Demo,涵盖Embedding模型创建、文档切片、文本向量化、向量内存存储、检索增强器配置、对话记忆绑定等全流程核心步骤,清晰阐释了Embedding在语义检索中的关键作用。

最后针对基础RAG Demo的缺陷,优化实现了会话记忆隔离能力,通过MemoryId、ChatMemoryProvider实现多用户、多会话的记忆独立隔离,解决了全局记忆共享导致的信息混乱、内存溢出等线上问题,让RAG应用具备了初步生产可用能力。

整体教程从理论到实操、从基础功能到生产优化,循序渐进,无需深厚AI基础即可上手,完整覆盖了LangChain4j+RAG的核心入门知识点,为后续开发复杂AI Agent、私有化知识库问答、智能对话系统等高阶应用打下了扎实的基础。后续可基于本文案例,进一步替换Redis、数据库等持久化向量存储,优化文档切片规则与检索权重,适配正式项目开发场景。

相关推荐
蜗牛互联网43 分钟前
MongoDB Atlas Agent Engine之后,如何用版本门禁防止陈旧写入
java·数据库·人工智能·后端·mongodb
长弓三石44 分钟前
企业级智能体的权限到底怎么落地?以 BizBuddy 为例
java·人工智能·agent
栈知见1 小时前
04-让 Agent 会"用工具": Tool Calling 实战
agent
付威20231 小时前
Rust 生命周期:为什么要有它,实际代码里到底怎么用?
后端
海岳云舟1 小时前
spring使用kafka的三种方式(listener、container、stream)
后端
吃饱了得干活2 小时前
Agent 的架构、多智能体与落地:从 Demo 到生产系统
llm·agent
VIP_CQCRE2 小时前
Coze 接入大模型太麻烦?用 Ace Data Cloud 统一 OpenAI Responses API
ai·大模型·agent·coze·acedatacloud
谢亮_vipxieliang3 小时前
Spring Boot 自动配置原理:从 @SpringBootApplication 到自定义 Starter
java·spring boot·后端
10年前端老司机3 小时前
实战分享:基于 PyMuPDF+Qwen-VL 实现图文兼容的 PDF RAG 方案
人工智能·python·agent