1. 什么是 LangChain4j

LangChain4j 是一个面向 Java 生态的 LLM(大语言模型)应用开发框架,其设计灵感来自 Python 生态中广受欢迎的 LangChain。它旨在为 Java 开发者提供一套简洁、统一的 API,用于构建基于大语言模型的应用程序,例如聊天机器人、文档问答、智能体(Agent)和 RAG(检索增强生成)应用。

LangChain4j 的核心价值在于:它把与大模型交互、提示词管理、记忆存储、工具调用、文档切分、向量检索等常见能力封装成开箱即用的组件,让 Java 开发者无需深入底层细节,就能快速搭建生产可用的 AI 应用。

2. 环境准备

在开始编写代码之前,我们需要准备好开发环境。LangChain4j 基于 Java 17 及以上版本,并使用 Maven 或 Gradle 作为构建工具。同时,你需要一个可用的 LLM API Key,例如 OpenAI、Azure OpenAI、智谱 GLM 或本地部署的 Ollama。

2.1 环境要求

  • JDK:17 或更高版本。
  • 构建工具:Maven 3.8+ 或 Gradle 7.5+。
  • LLM 服务:OpenAI、Azure OpenAI、智谱 GLM、Ollama 等任选其一。
  • 网络:能够访问所选的 LLM 服务端点。

2.2 创建 Maven 项目并添加依赖

首先,创建一个标准的 Maven 项目,然后在 pom.xml 中添加 LangChain4j 的核心依赖。这里以 OpenAI 为例,同时引入核心模块和 OpenAI 模块。

<dependencies>
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j</artifactId>
        <version>0.35.0</version>
    </dependency>
    <dependency>
        <groupId>dev.langchain4j</groupId>
        <artifactId>langchain4j-open-ai</artifactId>
        <version>0.35.0</version>
    </dependency>
</dependencies>

如果你使用的是 Gradle,则在 build.gradle 中添加如下依赖:

dependencies {
    implementation 'dev.langchain4j:langchain4j:0.35.0'
    implementation 'dev.langchain4j:langchain4j-open-ai:0.35.0'
}

如果你希望使用智谱 GLM 或本地 Ollama,只需将 langchain4j-open-ai 替换为对应的模块即可,核心 API 用法保持一致。

3. 第一个对话程序

依赖配置完成后,我们来编写第一个 LangChain4j 程序:一个最简单的聊天对话。下面的代码创建了一个 OpenAI 聊天模型,并向模型发送一条消息,然后打印模型的回复。

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.message.ChatMessage;
import dev.langchain4j.message.UserMessage;

public class HelloLangChain4j {

    public static void main(String[] args) {
        // 1. 创建聊天模型实例
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("gpt-4o-mini")
                .temperature(0.7)
                .build();

        // 2. 构造用户消息
        ChatMessage userMessage = UserMessage.from("用一句话介绍 LangChain4j");

        // 3. 发送消息并获取回复
        String answer = model.generate(userMessage);

        // 4. 输出结果
        System.out.println(answer);
    }
}

运行上述程序前,请确保环境变量 OPENAI_API_KEY 已正确设置。程序运行后,控制台会输出模型生成的回答。

4. 提示词模板(Prompt Template)

在实际应用中,我们通常不会直接发送裸文本,而是使用提示词模板来构造结构化的请求。LangChain4j 提供了 PromptTemplate,支持占位符替换,让提示词更易维护和复用。

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.model.input.Prompt;
import dev.langchain4j.model.input.PromptTemplate;

import java.util.Map;

public class PromptTemplateExample {

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("gpt-4o-mini")
                .build();

        // 定义提示词模板,使用 {{name}} 和 {{topic}} 作为占位符
        PromptTemplate template = PromptTemplate.from(
                "你好,{{name}}!请用三句话介绍{{topic}}。"
        );

        // 填充模板变量
        Prompt prompt = template.apply(Map.of(
                "name", "小明",
                "topic", "Java 编程"
        ));

        // 发送提示词并打印回复
        String answer = model.generate(prompt.text());
        System.out.println(answer);
    }
}

使用提示词模板的好处是:提示词与业务逻辑分离,后续调整文案时无需修改 Java 代码,只需改动模板字符串即可。

5. 流式输出(Streaming)

对于聊天机器人等交互式应用,逐字返回结果能显著提升用户体验。LangChain4j 提供了流式接口 StreamingChatLanguageModel,通过回调函数实时接收增量内容。

import dev.langchain4j.model.chat.StreamingChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.model.output.Response;
import dev.langchain4j.message.ChatMessage;
import dev.langchain4j.message.UserMessage;
import reactor.core.publisher.Flux;

public class StreamingExample {

    public static void main(String[] args) throws InterruptedException {
        StreamingChatLanguageModel model = OpenAiStreamingChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("gpt-4o-mini")
                .build();

        ChatMessage userMessage = UserMessage.from("请写一首关于春天的短诗");

        // 订阅流式响应
        Flux<String> flux = model.generate(userMessage);
        flux.subscribe(
                token -> System.out.print(token),   // 每个增量片段
                error -> System.err.println("出错: " + error),
                () -> System.out.println("\n[完成]")
        );

        // 等待流式输出完成
        Thread.sleep(15000);
    }
}

流式输出非常适合用于打字机效果的聊天界面。需要注意的是,流式接口基于 Reactor 的 Flux,因此项目需要引入 Reactor 依赖。

6. 对话记忆(Memory)

多轮对话需要维护上下文记忆。LangChain4j 提供了 ChatMemoryMessageWindowChatMemory,可以自动保存历史消息,让模型理解对话上下文。

import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.UserMessage;

public class MemoryExample {

    // 定义一个 AI 服务接口
    interface Assistant {
        String chat(String userMessage);
    }

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("gpt-4o-mini")
                .build();

        // 创建窗口大小为 10 的对话记忆
        ChatMemory memory = MessageWindowChatMemory.builder()
                .maxMessages(10)
                .build();

        // 通过 AiServices 绑定模型和记忆
        Assistant assistant = AiServices.builder(Assistant.class)
                .chatLanguageModel(model)
                .chatMemory(memory)
                .build();

        // 第一轮对话
        String answer1 = assistant.chat("我叫小明,我喜欢 Java。");
        System.out.println("AI: " + answer1);

        // 第二轮对话,模型应能记住上文
        String answer2 = assistant.chat("我叫什么名字?");
        System.out.println("AI: " + answer2);
    }
}

通过 AiServices,LangChain4j 把模型、记忆和工具调用整合到一个类型安全的接口中,这是构建复杂 Agent 应用的基础。

7. 工具调用(Function Calling)

工具调用让模型能够调用外部函数,例如查询数据库、调用 REST API 或执行计算。LangChain4j 通过 @Tool 注解将 Java 方法暴露给模型。

import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;

import java.time.LocalDateTime;

public class ToolCallingExample {

    // 定义一个工具类
    static class DateTimeTools {
        @Tool("获取当前日期和时间")
        public String currentDateTime() {
            return LocalDateTime.now().toString();
        }

        @Tool("计算两个整数的和")
        public int add(int a, int b) {
            return a + b;
        }
    }

    // AI 服务接口
    interface Assistant {
        String chat(String userMessage);
    }

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("gpt-4o-mini")
                .build();

        Assistant assistant = AiServices.builder(Assistant.class)
                .chatLanguageModel(model)
                .tools(new DateTimeTools())
                .build();

        // 模型会自动决定是否调用工具
        String answer1 = assistant.chat("现在几点了?");
        System.out.println("AI: " + answer1);

        String answer2 = assistant.chat("请计算 123 加 456 等于多少?");
        System.out.println("AI: " + answer2);
    }
}

当模型认为需要调用工具时,LangChain4j 会自动执行对应的 Java 方法,并把结果返回给模型,最终生成自然语言回复。这一机制是构建智能体的核心能力。

8. RAG 检索增强生成实战

RAG(Retrieval-Augmented Generation)是当前最热门的应用模式之一。它通过把文档切分、向量化并存储到向量数据库中,在回答问题时先检索相关片段,再交给模型生成答案,从而让模型基于私有知识库回答问题。

8.1 添加向量存储依赖

这里我们使用内存向量存储 InMemoryEmbeddingStore 作为演示,无需额外部署数据库。在 pom.xml 中补充以下依赖:

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-easy-rag</artifactId>
    <version>0.35.0</version>
</dependency>

8.2 构建 RAG 问答系统

import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
import dev.langchain4j.data.segment.TextSegment;
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.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;

import java.nio.file.Path;
import java.nio.file.Paths;

public class RagExample {

    interface Assistant {
        String chat(String userMessage);
    }

    public static void main(String[] args) {
        // 1. 初始化模型
        OpenAiChatModel chatModel = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("gpt-4o-mini")
                .build();

        EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("text-embedding-3-small")
                .build();

        // 2. 加载文档并切分
        Path documentPath = Paths.get("docs/company_manual.txt");
        Document document = FileSystemDocumentLoader.loadDocument(documentPath);

        // 3. 创建内存向量存储并导入文档
        EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();
        EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                .documentSplitter(new dev.langchain4j.data.document.splitter.RecursiveDocumentSplitter(500, 100))
                .embeddingModel(embeddingModel)
                .embeddingStore(embeddingStore)
                .build();
        ingestor.ingest(document);

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

        // 5. 组装 AI 服务
        Assistant assistant = AiServices.builder(Assistant.class)
                .chatLanguageModel(chatModel)
                .chatMemory(MessageWindowChatMemory.withMaxMessages(20))
                .contentRetriever(retriever)
                .build();

        // 6. 提问
        String answer = assistant.chat("公司的年假政策是什么?");
        System.out.println("AI: " + answer);
    }
}

在上述代码中,我们完成了文档加载、切分、向量化、存储和检索的完整链路。当用户提问时,系统会先从向量库中检索最相关的文档片段,再结合这些片段生成回答,从而显著提升回答的准确性和针对性。

9. 结构化输出(Structured Output)

在很多业务场景中,我们希望模型返回结构化的 JSON 数据,而不是自由文本。LangChain4j 支持将模型输出直接映射为 Java 对象。

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.UserMessage;

public class StructuredOutputExample {

    // 定义数据结构
    record Person(String name, int age, String city) {}

    interface PersonExtractor {
        @UserMessage("从文本中提取人物信息:{{text}}")
        Person extractPerson(String text);
    }

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName("gpt-4o-mini")
                .build();

        PersonExtractor extractor = AiServices.builder(PersonExtractor.class)
                .chatLanguageModel(model)
                .build();

        Person person = extractor.extractPerson("张三今年28岁,住在上海。");
        System.out.println("姓名: " + person.name());
        System.out.println("年龄: " + person.age());
        System.out.println("城市: " + person.city());
    }
}

通过定义 Java record 或 POJO,LangChain4j 会自动引导模型输出符合结构的 JSON,并完成反序列化。这大大简化了信息抽取、表单填充等场景的开发。

10. 总结与进阶方向

本文从零开始介绍了 LangChain4j 的核心用法,包括环境搭建、基础对话、提示词模板、流式输出、对话记忆、工具调用、RAG 检索增强生成和结构化输出。掌握这些能力后,你已经可以构建大多数常见的 LLM 应用。

接下来,你可以从以下几个方向继续深入:

  • 多模态模型:探索图片输入和视觉理解能力。
  • 复杂智能体:结合多个工具和记忆,构建自主决策的 Agent。
  • 生产级向量数据库:将内存向量存储替换为 Milvus、PGVector 或 Elasticsearch。
  • 模型评估:使用 LangChain4j 的评估模块对回答质量进行自动化评测。
  • Spring Boot 集成:LangChain4j 提供了 langchain4j-spring-boot-starter,可无缝融入 Spring 生态。

希望这篇入门指南能帮助你快速上手 LangChain4j,开启 Java AI 应用开发之旅。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐