一、简介

官方文档:https://docs.langchain4j.dev/intro/
中文文档:https://docs.langchain4j.info/intro

LangChain4j 是专为 JVM 生态(Java/Kotlin/Scala) 设计的开源大模型应用框架,核心目标是让 Java 开发者以类型安全、原生适配的方式快速集成 LLM 能力,无需跨语言桥接。它并非 LangChain 官方 Java 版,但设计思想对齐,且更贴合企业级 Java 开发习惯。

二、使用

1、引包与配置

(1)我们以阿里的百炼大模型为例


<!--        使用springboot-starter之后,这个就不需要了-->
<!--        <dependency>-->
<!--            <groupId>dev.langchain4j</groupId>-->
<!--            <artifactId>langchain4j</artifactId>-->
<!--            <version>1.11.0</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-spring-boot-starter</artifactId>
            <version>1.11.0-beta19</version>
        </dependency>

        <!--阿里百炼大模型-->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
            <version>1.11.0-beta19</version>
        </dependency>

        <!-- mcp -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-mcp</artifactId>
            <version>1.11.0-beta19</version>
        </dependency>

(2)application.yaml配置(可选,不配置的话需要自己编码初始化)

langchain4j:
  community:
    dashscope:
      chat-model:
        model-name: qwen-max # 选择模型
        api-key: <You API Key here> # 你的api key

(3)编码方式实现ChatModel


import dev.langchain4j.community.model.dashscope.QwenChatModel;
import dev.langchain4j.model.chat.ChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
public class Config {

    @Bean
    public ChatModel chatModel() {
        ChatModel chatModel = QwenChatModel.builder()
                .apiKey("You API key here") // 改为你的api key
                .modelName("qwen-plus")
                .enableSearch(true)
                .temperature(0.7f)
                .maxTokens(4096)
                .stops(List.of("Hello"))
                .build();
        return chatModel;
    }

}

2、基本对话使用


import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import jakarta.annotation.Resource;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class TestChat implements ApplicationRunner {

    @Resource
    private ChatModel chatModel;

    /**
     * 1、简单模型对话测试
     */
    public void testSimpleChat() {
        String message = "请将下面内容翻译成英文:我叫张三,我今年18岁,我住在上海。";
        UserMessage userMessage = UserMessage.from(message);
        ChatResponse chatResponse = chatModel.chat(userMessage);
        AiMessage aiMessage = chatResponse.aiMessage();
        // AiMessage { text = "My name is Zhang San, I am 18 years old this year, and I live in Shanghai.", thinking = null, toolExecutionRequests = [], attributes = {} }
        System.out.println(aiMessage.toString());
    }

    /**
     * 2、使用系统提示词
     */
    public void testSystemMessage() {
        String SYSTEM_MESSAGE = "你是美食领域的专家,帮助用户解答美食制作相关问题,并给出建议。";
        SystemMessage systemMessage = SystemMessage.from(SYSTEM_MESSAGE);
        UserMessage userMessage = UserMessage.from("制作蛋炒饭");
        // 用户提示词+系统提示词
        ChatResponse chatResponse = chatModel.chat(systemMessage, userMessage);
        AiMessage aiMessage = chatResponse.aiMessage();
        System.out.println(aiMessage.toString());
    }


    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 1、简单对话测试
        //testSimpleChat();

        // 2、使用系统提示词
        //testSystemMessage();
    }
}


3、AI Service(常用)

import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.spring.AiService;

// Springboot中可以使用该注解自动注册
@AiService
public interface AiFoodieService {

	// 支持没有系统提示词
	String chatNoStstem(String userMessage);

    // 支持从注解中获取系统提示词
    @SystemMessage("你是一个三岁小姑娘,帮助用户解答美食制作相关问题,并给出建议,你给出的答案应该是胡乱回答的。")
    String chat(String userMessage);

    @SystemMessage("你是一个记忆大师。")
    String chatMemory(String userMessage);

    // 支持从资源文件中获取系统提示词(提示词过长时,建议使用这种方式)
    @SystemMessage(fromResource = "system-prompt.txt")
    String chat2(String userMessage);

}


import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.service.AiServices;
import jakarta.annotation.Resource;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class TestAiService implements ApplicationRunner {

    @Resource
    private ChatModel chatModel;


    /**
     * 1、AI Service 服务 :编程方式
     */
    public void testAiService() {
        // 创建一个AI服务 代理类
        AiFoodieService aiFoodieService = AiServices.create(AiFoodieService.class, chatModel);
        String result = aiFoodieService.chat("制作蛋炒饭");
        System.out.println(result);
    }

    /**
     * 2、AI Service 服务 :注解方式
     */
    @Resource
    private AiFoodieService aiFoodieService;

    public void testAiServiceAnnotation() {
        String result = aiFoodieService.chat("制作蛋炒饭");
        System.out.println(result);
    }


    @Override
    public void run(ApplicationArguments args) throws Exception {

        // 1、AI Service 服务 - 编程方式
        //testAiService();

        // 2、AI Service 服务 - 注解方式
        //testAiServiceAnnotation();
    }
}

4、会话记忆

import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.spring.AiService;

// Springboot中可以使用该注解自动注册
@AiService
public interface AiMemoryService {


    @SystemMessage("你是一个记忆大师,只会回答问题,不会说废话。")
    String chatMemory(String userMessage);

    /**
     * 多用户隔离的会话记忆
     */
    @SystemMessage("你是一个记忆大师,只会回答问题,不会说废话。")
    String chatMemoryByUser(@MemoryId int memoryId, @UserMessage String userMessage);

}

import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 自定义记忆存储器,可以考虑使用数据库
 */
public class MyChatMemoryStory implements ChatMemoryStore {
    // 模拟记忆存储
    private static final Map<Object, List<ChatMessage>> memory = new ConcurrentHashMap<>();

    /**
     * 获取记忆
     */
    @Override
    public List<ChatMessage> getMessages(Object memoryId) {
        return memory.getOrDefault(memoryId, new ArrayList<>());
    }

    /**
     * 更新记忆
     */
    @Override
    public void updateMessages(Object memoryId, List<ChatMessage> messages) {
        memory.put(memoryId, messages);
    }

    /**
     * 删除记忆
     */
    @Override
    public void deleteMessages(Object memoryId) {
        memory.remove(memoryId);
    }
}


import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.service.AiServices;
import jakarta.annotation.Resource;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.UUID;

@Component
public class TestMemory implements ApplicationRunner {

    @Resource
    private ChatModel chatModel;

    /**
     * 1、内存会话记忆
     */
    public void testMemory() {
        // 3轮会话记忆
        ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(3);
        AiMemoryService aiMemoryService = AiServices.builder(AiMemoryService.class)
                .chatModel(chatModel)
                .chatMemory(chatMemory)
                .build();
        String result = aiMemoryService.chatMemory("我是张三");
        System.out.println(result);
        System.out.println(aiMemoryService.chatMemory("我是谁?"));
        System.out.println(aiMemoryService.chatMemory("我是谁?"));
        System.out.println(aiMemoryService.chatMemory("我是谁?"));
        System.out.println(aiMemoryService.chatMemory("我是谁?"));
        System.out.println(aiMemoryService.chatMemory("我是谁?"));
    }
    /**
     * 2、持久化自定义 会话记忆
     */
    public void testStoreMemory() {
        // 10轮会话记忆
        ChatMemory chatMemory = MessageWindowChatMemory.builder()
                .id(UUID.randomUUID())
                .maxMessages(3)
                .chatMemoryStore(new MyChatMemoryStory())
                .build();
        AiMemoryService aiMemoryService = AiServices.builder(AiMemoryService.class)
                .chatModel(chatModel)
                .chatMemory(chatMemory)
                .build();
        String result = aiMemoryService.chatMemory("我是张三");
        System.out.println(result);
        System.out.println(aiMemoryService.chatMemory("我是谁?"));
        System.out.println(aiMemoryService.chatMemory("我是谁?"));
        System.out.println(aiMemoryService.chatMemory("我是谁?"));
        System.out.println(aiMemoryService.chatMemory("我是谁?"));
        System.out.println(aiMemoryService.chatMemory("我是谁?"));
    }

    /**
     * 3、多用户隔离的会话记忆
     */
    public void testMemoryUsers() {
        // 10轮会话记忆
        AiMemoryService aiMemoryService = AiServices.builder(AiMemoryService.class)
                .chatModel(chatModel)
                // 每个memberId单独记忆
                .chatMemoryProvider((memoryId) -> MessageWindowChatMemory.builder()
                        .id(memoryId)
                        .maxMessages(3)
                        .chatMemoryStore(new MyChatMemoryStory())
                        .build())
                .build();
        String result = aiMemoryService.chatMemoryByUser(1, "我是张三");
        System.out.println(result);
        String result22 = aiMemoryService.chatMemoryByUser(2, "我是张三");
        System.out.println(result22);
        System.out.println(aiMemoryService.chatMemoryByUser(1, "我是谁?"));
        System.out.println(aiMemoryService.chatMemoryByUser(1, "我是谁?"));
        System.out.println(aiMemoryService.chatMemoryByUser(1, "我是谁?"));
        System.out.println(aiMemoryService.chatMemoryByUser(1, "我是谁?"));
        System.out.println(aiMemoryService.chatMemoryByUser(1, "我是谁?"));

        System.out.println(aiMemoryService.chatMemoryByUser(2, "我是谁?"));
        System.out.println(aiMemoryService.chatMemoryByUser(2, "我是谁?"));
        System.out.println(aiMemoryService.chatMemoryByUser(2, "我是谁?"));
        System.out.println(aiMemoryService.chatMemoryByUser(2, "我是谁?"));
        System.out.println(aiMemoryService.chatMemoryByUser(2, "我是谁?"));
    }


    @Override
    public void run(ApplicationArguments args) throws Exception {

        // 1、内存会话记忆
        //testMemory();

        // 2、持久化自定义 会话记忆
        //testStoreMemory();

        // 3、多用户隔离的会话记忆
        testMemoryUsers();
    }
}

5、结构化输出

结构化输出是指将大模型返回的文本输出转换为结构化的数据格式,比如JSON、一个对象。

(1)方式一:使用提示词

通过提示词的方式,在用户的输入之前插入一段提示词,指定大模型强制输出json格式。

你是一个专业的信息提取助手。请从给定文本中提取人员信息,
并严格按照以下 JSON 格式返回结果:

{
    "name": "姓名",
    "age": 年龄,
    "sex": 男/女,
    "address": "住址"
}

重要规则:
1. 只返回 JSON 格式,不要添加任何解释
2. 如果信息不明确,使用 null
3. age 必须是数字,不是字符串
4. sex 必须是男或者女

以下是我提供的信息:
xxxxxxxx

(2)方式二:基于AI Service(推荐)

public record User(String name, int age, String sex, String address) {
}

import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.spring.AiService;

@AiService
public interface AiJsonService {
	// 自动对应相关字段
    @SystemMessage("你是一个专业的信息提取助手。请从给定文本中提取人员信息")
    User chatJson(String userMessage);

}

import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.service.AiServices;
import jakarta.annotation.Resource;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class TestJson implements ApplicationRunner {

    @Resource
    private ChatModel chatModel;

    /**
     * 提取json ,直接转为对象
     */
    public void testJson() {
        AiJsonService aiJsonService = AiServices.builder(AiJsonService.class)
                .chatModel(chatModel)
                .build();
        User user = aiJsonService.chatJson("我是张三,18岁男,住在青岛");
        System.out.println(user);//User[name=张三, age=18, sex=男, address=青岛]
    }


    @Override
    public void run(ApplicationArguments args) throws Exception {

        testJson();
    }
}

(3)方式三:基于json schema方式(精度最高,需要大模型支持)

ResponseFormat responseFormat = ResponseFormat.builder()
        .type(JSON) // type can be either TEXT (default) or JSON
        .jsonSchema(JsonSchema.builder()
                .name("Person") // OpenAI requires specifying the name for the schema
                .rootElement(JsonObjectSchema.builder() // see [1] below
                        .addStringProperty("name")
                        .addIntegerProperty("age")
                        .addNumberProperty("height")
                        .addBooleanProperty("married")
                        .required("name", "age", "height", "married") // see [2] below
                        .build())
                .build())
        .build();

UserMessage userMessage = UserMessage.from("""
        John is 42 years old and lives an independent life.
        He stands 1.75 meters tall and carries himself with confidence.
        Currently unmarried, he enjoys the freedom to focus on his personal goals and interests.
        """);

ChatRequest chatRequest = ChatRequest.builder()
        .responseFormat(responseFormat)
        .messages(userMessage)
        .build();

ChatModel chatModel = OpenAiChatModel.builder()
        .apiKey(System.getenv("OPENAI_API_KEY"))
        .modelName("gpt-4o-mini")
        .logRequests(true)
        .logResponses(true)
        .build();
// OR
ChatModel chatModel = AzureOpenAiChatModel.builder()
        .endpoint(System.getenv("AZURE_OPENAI_URL"))
        .apiKey(System.getenv("AZURE_OPENAI_API_KEY"))
        .deploymentName("gpt-4o-mini")
        .logRequestsAndResponses(true)
        .build();
// OR
ChatModel chatModel = GoogleAiGeminiChatModel.builder()
        .apiKey(System.getenv("GOOGLE_AI_GEMINI_API_KEY"))
        .modelName("gemini-1.5-flash")
        .logRequestsAndResponses(true)
        .build();
// OR
ChatModel chatModel = OllamaChatModel.builder()
        .baseUrl("http://localhost:11434")
        .modelName("llama3.1")
        .logRequests(true)
        .logResponses(true)
        .build();
// OR
ChatModel chatModel = MistralAiChatModel.builder()
        .apiKey(System.getenv("MISTRAL_AI_API_KEY"))
        .modelName("mistral-small-latest")
        .logRequests(true)
        .logResponses(true)
        .build();
// OR
ChatModel chatModel = WatsonxChatModel.builder()
        .baseUrl(System.getenv("WATSONX_URL"))
        .projectId(System.getenv("WATSONX_PROJECT_ID"))
        .apiKey(System.getenv("WATSONX_API_KEY"))
        .modelName("ibm/granite-4-h-small")
        .logRequests(true)
        .logResponses(true)
        .build();

ChatResponse chatResponse = chatModel.chat(chatRequest);

String output = chatResponse.aiMessage().text();
System.out.println(output); // {"name":"John","age":42,"height":1.75,"married":false}

Person person = new ObjectMapper().readValue(output, Person.class);
System.out.println(person); // Person[name=John, age=42, height=1.75, married=false]

(3)附:json-repair修复包

文末有java版本:
python修复json神器:json-repair包(用于大模型返回json不规范)

6、工具调用Tools

工具调用(Tool Calling)可以让AI大模型借用外部工具来完成它自己做不到的事情。

注意!要认真描写参数和参数描述!

(1)声明式工具

import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.spring.AiService;

@AiService
public interface AiToolService {

    @SystemMessage("你是一名专家")
    String chatTool(String userMessage);

}

import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;

public class WeatherTool {

    /**
     * 获取天气工具
     */
    @Tool(name = "获取天气", value = "获取某个城市的天气")
    public String searchInterviewQuestions(@P(value = "城市") String city) {
        return city + "的天气为:晴天";
    }
}


import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.service.AiServices;
import jakarta.annotation.Resource;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class TestTool implements ApplicationRunner {

    @Resource
    private ChatModel chatModel;

    /**
     * 使用工具
     */
    public void testTool() {
        AiToolService aiToolService = AiServices.builder(AiToolService.class)
                .chatModel(chatModel)
                .tools(new WeatherTool()) // 注册工具
                .build();
        String result = aiToolService.chatTool("我明天想去青岛,天气怎么样?需要穿什么衣服");
        System.out.println(result);
    }


    @Override
    public void run(ApplicationArguments args) throws Exception {

        testTool();
    }
}

(2)编程式工具(不常用)

7、MCP

(1)服务端

貌似不是很好用。。

(2)客户端

import dev.langchain4j.service.SystemMessage;
// 定义service
public interface BotService {

    // 亲测,如果同时调用多个mcp,可能第一个还没返回就调用了第二个,导致第一个mcp拿不到结果
    @SystemMessage("你是建议大师,如果调用mcp的话,需要等待上一个mcp完成之后再进行接下来的操作")
    String chat(String userMessage);
}


import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
import dev.langchain4j.mcp.client.transport.McpTransport;
import dev.langchain4j.mcp.client.transport.http.StreamableHttpMcpTransport;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.tool.ToolProvider;
import jakarta.annotation.Resource;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.List;
@Component
public class TestMcpClient implements ApplicationRunner {

    @Resource
    private ChatModel chatModel;


    public void testMcp() {
        // 现在都是基于Streamable的了
        McpTransport transport = new StreamableHttpMcpTransport.Builder()
                .url("http://127.0.0.1:8080/mcp")
                .timeout(Duration.ofSeconds(60))
                .logRequests(true)
                .logResponses(true)
                .build();

        // 定义mcp客户端
        McpClient mcpClient = new DefaultMcpClient.Builder()
                .transport(transport)
                .build();

        // 可以同时使用多个mcp客户端
        ToolProvider toolProvider = McpToolProvider.builder()
                .mcpClients(List.of(mcpClient))
                .build();

        BotService bot = AiServices.builder(BotService.class)
                .chatModel(chatModel)
                // 使用mcp
                .toolProvider(toolProvider)
                .build();
        try {
            // bot可复用
            String response = bot.chat("我需要下午5点到家,我还剩多长时间?到家需要穿什么衣服");
            System.out.println(response);
        } finally {
            try {
                mcpClient.close();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }


    @Override
    public void run(ApplicationArguments args) throws Exception {

        testMcp();
    }
}

8、RAG

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐