Java程序员接入AI的另一种姿势:LangChain4j

0 阅读3分钟

关注我的公众号:【编程朝花夕拾】,可获取首发内容。

01 引言

提起 LLM 应用开发,绝大部分的开发还是Python。虽然Spring AI已经正式发布,但是使用上总觉得差点东西。

LangChain4j很早就听人说了,但是一直没有来得及使用。这一节一起了解一下LangChain4j的简单使用。

02 简介

LangChain4jLangChainJava/JVM 版本。目标是让 Java 开发者能在自己的技术栈里,像 Python 开发者一样方便地构建 LLM 应用。不同的是,它不是简单移植,而是深度适配 Java 生态——QuarkusSpring Boot``、Helidon` 原生集成,依赖注入、接口代理,一切都是 Java 开发者熟悉的方式。

LangChain4j 是一个 Java 库,用于构建 LLM 驱动的应用程序。它提供:

  • 统一 API:对接市面上几乎所有主流 LLM(OpenAI、Anthropic、Google Gemini、国内的通义千问、智谱等)和向量数据库(Pinecone、Milvus、Weaviate、Chroma 等),无需关心各家的 SDK 差异。
  • Java 原生设计:不是从 Python 翻译过来,而是从零开始用 Java 思维设计,充分利用 Java 的接口、注解、泛型、依赖注入等特性。
  • 分层抽象:既有底层组件(ChatModelChatMessage)满足定制需求,也有高层抽象(AI Services、RAG)让你少写代码。

最低支持 JDK 17

官网地址:docs.langchain4j.dev/

GitHub地址:github.com/langchain4j…

03 入门

3.1 引入依赖

使用 Maven(推荐使用 BOM 管理版本):

dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>dev.langchain4j</groupId>
      <artifactId>langchain4j-bom</artifactId>
      <version>1.15.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

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

3.2 简单测试

没有 API Key?LangChain4j 还提供了一个 demo key,限制使用 gpt-4o-mini 模型,供快速体验:

OpenAiChatModel model = OpenAiChatModel.builder()
    .baseUrl("http://langchain4j.dev/demo/openai/v1")
    .apiKey("demo")
    .modelName("gpt-4o-mini")
    .build();

结果:

这就完成接入,就是这么直接。

3.3 接入其他厂商

管方默认提供了open-ai的案例,我们试试Ollama

langchain4j针对不同的尝试使用了不同的依赖,所以我们要继续引入ollama的依赖。

 <dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-ollama</artifactId>
</dependency>

测试案例:

@Test
void testOllama() {
    OllamaChatModel model = OllamaChatModel.builder()
            .baseUrl("http://10.100.213.26:11434")
            .modelName("modelscope.cn/unsloth/DeepSeek-R1-Distill-Qwen-1.5B-GGUF:latest")
            .build();

    String response = model.chat("你是什麽模型");
    System.out.println(response);
}

模型的名称,大家根据自己本地的那模型填写对应的名称。

结果:

我们可以看到完全独立,不依赖Spring生态。

04 进阶

AI Services:把 LLM 当服务写,这是 LangChain4j 最核心的高层抽象,也是体验最好的部分。

核心思路

参考 Spring Data JPARetrofit 的思路:你声明一个接口,框架通过动态代理生成实现类。接口里定义业务方法,框架负责处理 Prompt 构造、LLM 调用、输出解析等底层工作。

4.1 定义接口

public interface Assistant {

    String chat(String message);
}

4.2 调用

LangChain4j提供了dev.langchain4j.service.AiServices抽象类用来构建接口的实现。

@Test
void testAiService() {
    OllamaChatModel model = OllamaChatModel.builder()
            .baseUrl("http://10.100.213.26:11434")
            .modelName("modelscope.cn/unsloth/DeepSeek-R1-Distill-Qwen-1.5B-GGUF:latest")
            .build();

    Assistant assistant = AiServices.create(Assistant.class, model);
    String response = assistant.chat("hello");
    System.out.println(response);
}

单独的模型可以直接调用,而AiService则将调用抽象成方法,可以根据不同的模型构建不同的实现。

4.3 注入角色设定

我重新定义一个接口,注入角色设自定。

public interface Friend {

    @SystemMessage("你是我的朋友,总能给我提供情绪价值。")
    String chat(String userMessage);
}

@SystemMessage正是用来提供角色设定的关键注解。

我们直接看看调用结果:

05 SpringBoot集成

官方也提供了与SpringBoot的集成方式。

5.1 引入依赖

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-ollama-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-spring-boot-starter</artifactId>
</dependency>

5.2 接口改造

Spring Boot 中,配置好依赖后,AI Service 直接作为 Bean 注入即可,完全不需要手动调用 AiServices.create

@AiService
public interface Friend {

    @SystemMessage("你是我的朋友,总能给我提供情绪价值。")
    String chat(String userMessage);
}

其中@AiService是自动将接口作为Bean注入。

5.3 配置

因为直接使用框架,我们就需要配置ollama的参数。

langchain4j.ollama.chat-model.base-url=http://10.100.213.26:11434
langchain4j.ollama.chat-model.model-name=modelscope.cn/unsloth/DeepSeek-R1-Distill-Qwen-1.5B-GGUF:latest

5.4 调用

@SpringBootTest
class BootLangChain4jTests {

    @Autowired
    private Friend friend;

    @Test
    void contextLoads() {
        String response = friend.chat("我失恋了");
        System.out.println(response);
    }
}

结果展示:

06 小结

到这里就已经基本入门了,后面我们将继续探索更深层次的用法。总体感觉用起来不Spring AI要顺畅一些。