Java大模型开发入门 (5/15):开发利器 – 初识Java最流行的LLM框架LangChain4j

前言

在上一篇文章中,我们成功地将大模型能力封装成了一个标准的Spring Boot服务。我们有了Controller、Service,通过依赖注入管理着OpenAIClient。这是一个巨大的进步,我们的AI应用已经具备了企业级开发的雏形。

但是,当我们想实现更复杂的功能时,挑战也随之而来:

  • 多轮对话:如何让AI记住我们之前的谈话内容?我们需要手动管理一个List<ChatMessage>,并在每次请求时都把它传来传去,这非常繁琐且容易出错。
  • 结构化输出:如何确保AI返回的是一个我们可以直接转换为Java对象的JSON,而不是一段随心所欲的文本?
  • 连接外部知识:如何让AI回答关于我们自己公司产品文档的问题?
  • 调用工具:如何让AI在回答问题时,能去调用一个外部API(比如查询实时天气)?

只靠我们目前使用的官方SDK,要实现这些功能,需要编写大量复杂的“胶水代码”。幸运的是,社区已经为我们准备好了一个功能极其强大的“瑞士军刀”——LangChain4j

今天,我们将正式引入这个Java领域最流行的LLM应用开发框架,看看它是如何将我们从繁杂的底层逻辑中解放出来的。

第一步:什么是LangChain4j?它解决了什么问题?

我们可以用一个简单的类比来理解:

如果说官方SDK(如openai-java-client)是为我们提供了一台性能强劲的汽车引擎,那么LangChain4j就是为我们提供了整车的底盘、变速箱、方向盘和智能驾驶系统

它不是要替代SDK,而是构建于SDK之上,让我们能更轻松地“驾驶”AI,构建完整的、复杂的应用。

LangChain4j的核心思想是 “链(Chain)” ,也就是将与大模型交互的多个步骤串联起来,形成一个自动化的工作流。它将复杂的AI应用抽象为几个核心组件:

  • 语言模型 (Language Models):对不同AI服务商(如OpenAI, DeepSeek, Google Gemini)的统一接口。
  • 提示模板 (Prompt Templates):创建可复用、可动态填充的提示词。
  • 记忆 (Memory):为对话提供短期或长期的记忆能力。
  • 输出解析器 (Output Parsers):将模型的文本输出强制转换为结构化的Java对象。
  • 检索器 (Retrievers)文档 (Documents):用于实现RAG(检索增强生成),让AI能连接外部知识库。

今天,我们先从它最神奇、最简单的功能之一AiServices入手,直观感受它的威力。

第二步:在Spring Boot中集成LangChain4j

LangChain4j与Spring Boot的集成非常成熟,我们只需要引入它的spring-boot-starter

  1. 修改pom.xml
    pom.xml中,添加LangChain4j的Spring Boot Starter依赖。注意:你可以移除上一章添加的openai-java-client依赖

      <dependency>
         <groupId>dev.langchain4j</groupId>
         <artifactId>langchain4j-spring-boot-starter</artifactId>
         <version>1.0.1-beta6</version>
     </dependency>
    <dependency>
         <groupId>dev.langchain4j</groupId>
         <artifactId>langchain4j-open-ai</artifactId>
         <version>1.0.1</version>
    </dependency>
    
  2. 修改 application.properties
    LangChain4j的配置项遵循着清晰的命名空间。我们将之前的配置修改为LangChain4j的格式:

    # 服务器端口号
    server.port=8080
    
    # LangChain4j Configuration for DeepSeek
    langchain4j.open-ai.chat-model.api-key=${DEEPSEEK_API_KEY:}
    langchain4j.open-ai.chat-model.base-url=https://api.deepseek.com/v1/
    langchain4j.open-ai.chat-model.model-name=deepseek-chat
    langchain4j.open-ai.chat-model.temperature=0.7
    langchain4j.open-ai.chat-model.max-tokens=1024
    

    仅仅这样配置,LangChain4j的Starter就会自动为我们创建一个配置好的ChatLanguageModel Bean。我们已经不需要自己写AiClientConfig了!
    如何提示没有chatModel则需要自己创建一个。

    import dev.langchain4j.model.chat.ChatModel;
    import dev.langchain4j.model.openai.OpenAiChatModel;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class LangChain4jConfig {
    
        @Value("${langchain4j.open-ai.chat-model.api-key}")
        private String apiKey;
    
        @Value("${langchain4j.open-ai.chat-model.base-url}")
        private String baseUrl;
    
        @Value("${langchain4j.open-ai.chat-model.model-name}")
        private String modelName;
    
        @Value("${langchain4j.open-ai.chat-model.temperature}")
        private Double temperature;
    
        @Value("${langchain4j.open-ai.chat-model.max-tokens}")
        private Integer maxTokens;
    
        @Bean("openAiChatModel")
        public ChatModel openAiChatModel() {
            return OpenAiChatModel.builder()
                    .apiKey(apiKey)
                    .baseUrl(baseUrl)
                    .modelName(modelName)
                    .temperature(temperature)
                    .maxTokens(maxTokens)
                    .build();
        }
    }
    

第三步:代码重构 – 见证AiServices的魔力

现在,我们将重构上一章的ChatService,让你看看代码可以被简化到什么程度。LangChain4j提供了一个名为AiServices的工厂,它可以将一个Java接口,自动转换成一个可以与AI交互的实现类

  1. 创建一个AI助手接口
    service包下,创建一个新的接口Assistant.java

    package com.example.aidemoapp.service;
    import dev.langchain4j.service.SystemMessage;
    import dev.langchain4j.service.spring.AiService;
    
    @AiService(chatModel = "openAiChatModel")
    public interface Assistant {
    
        @SystemMessage("You are a polite assistant")
        String chat(String userMessage);
    }
    

    这是一个普通的Java接口,只有一个chat方法。

  2. 重构ChatService
    现在我们的ChatService变得异常简单:

    package com.example.aidemoapp.service;
    
    import lombok.RequiredArgsConstructor;
    import org.springframework.stereotype.Service;
    
    @Service
    @RequiredArgsConstructor
    public class ChatService {
    
        // 直接注入我们定义的Assistant接口
        private final Assistant assistant;
    
        public String getChatResponse(String userPrompt) {
            // 直接调用接口方法,就像调用一个普通的Java方法一样
            return assistant.chat(userPrompt);
        }
    }
    

    ChatController完全不需要任何改动!

    package com.example.aidemoapp.service.ChatService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class ChatController {
    
    
       @Autowired
       ChatService chatService ;
    
       @GetMapping("/chat")
       public String chat(String message) {
           return chatService.chat(message);
       }
    }
    

    Java大模型开发入门 (5/15):开发利器 - 初识Java最流行的LLM框架LangChain4j

第四步:对比与思考

我们来对比一下前后的变化:

  • 之前 (纯SDK):我们需要在ChatService中手动构建ChatCompletionCreateParams对象,然后调用client.chat().completions().create(),再从复杂的响应对象中解析出结果。
  • 现在 (用LangChain4j):我们只定义了一个接口Assistant,然后就像调用一个本地方法一样调用assistant.chat()。所有的API请求构建和响应解析都被LangChain4j在幕后优雅地处理了。

这到底发生了什么?

AiServices.create()是一个神奇的工厂。当你调用assistant.chat("你好")时,LangChain4j的代理实现会自动:

  1. 创建一个ChatMessage,角色是user,内容是"你好"
  2. 构建一个完整的API请求。
  3. 调用我们配置好的ChatLanguageModel(也就是DeepSeek模型)。
  4. 等待响应,并自动解析出内容。
  5. 将内容作为String返回。

这就是框架的力量:它让你能够用业务逻辑的语言(assistant.chat(...))来编程,而不是用技术实现的语言。

总结

今天我们只是揭开了LangChain4j神秘面纱的一角,但其强大的生产力已经可见一斑。通过AiServices,我们以一种前所未有的优雅方式重构了我们的AI服务。

我们不再需要自己去管理和创建OpenAIClient,也不再需要手动拼装请求参数。LangChain4j的Spring Boot Starter和AiServices工厂为我们处理了这一切。

但这仅仅是开始。LangChain4j真正的威力在于它那些可组合的模块。如何让我们的Assistant拥有记忆?如何让它返回一个Java对象而不是String


下一篇预告:
Java大模型开发入门 (6/15):对话的灵魂 – 深入理解LangChain4j中的模型、提示和解析器》—— 我们将深入LangChain4j的核心,学习如何通过提示模板(Prompt Templates)和输出解析器(Output Parsers)来驯服AI,让它按照我们的意愿进行思考和输出!

© 版权声明

相关文章

暂无评论

暂无评论...