别再羡慕Python开发者了!Java生态终于有了完整的LLM开发框架,一文搞懂LangChain4j所有核心功能

别再羡慕Python开发者了!Java生态终于有了完整的LLM开发框架,一文搞懂LangChain4j所有核心功能

别再羡慕Python开发者了!Java生态终于有了完整的LLM开发框架,一文搞懂LangChain4j所有核心功能


为什么值得关注:Java开发者的LLM开发困境与破局之道

LLM浪潮下的语言之争

2023年开始,大语言模型(LLM)浪潮席卷整个科技行业。从ChatGPT到Claude,从GPT-4到各类开源模型,AI能力正在重塑软件开发的方式。然而,对于长期使用Java生态的开发者而言,这场AI革命似乎显得有些”遥远”。

当你想要在Java项目中集成LLM能力时,你会发现:

  • 官方SDK往往只提供Python版本
  • 现有的Java包装库功能残缺,很多只是简单的HTTP调用封装
  • 缺乏像LangChain这样的一站式解决方案
  • 内存管理、提示词模板、链式调用等高级功能需要从零实现
  • 流式输出、工具调用、代理等能力在Java世界几乎是空白

LangChain4j是什么

LangChain4j正是为解决这些问题而生。它是LangChain的Java实现,专为JVM生态设计。它不仅仅是一个API客户端,而是一套完整的LLM应用开发框架,提供了:

  • 统一的模型抽象:支持OpenAI、Anthropic、Google、Azure、HuggingFace等数十种LLM提供商
  • 丰富的组件库:包括提示词模板、对话记忆、链式调用、工具系统、代理机制等
  • 企业级特性:流式响应、异步处理、错误重试、熔断降级
  • RAG支持:内置嵌入模型、向量存储、检索增强生成完整支持
  • 活跃的社区:持续更新,积极响应开发者需求

截至目前,LangChain4j已经在GitHub上获得了大量star,被众多Java项目采用,是Java生态中最具影响力的LLM开发框架。


环境搭建:从零开始的完整指南

前置要求

在开始之前,请确保你的开发环境满足以下要求:

  • JDK 8或更高版本:推荐使用JDK 17或JDK 21,以获得更好的性能和最新的语言特性
  • 构建工具:Maven 3.8+ 或 Gradle 7+
  • IDE:IntelliJ IDEA(推荐)、Eclipse或VS Code均可

Maven项目配置

创建一个新的Maven项目,在pom.xml中添加LangChain4j的核心依赖。LangChain4j采用模块化设计,你需要根据实际需求引入相应的模块:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>langchain4j-tutorial</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <langchain4j.version>1.0.0-beta1</langchain4j.version>
    </properties>

    <dependencies>
        <!-- 核心模块:必需 -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>

        <!-- OpenAI模块:如果使用OpenAI API -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-open-ai</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>

        <!-- 流式响应支持 -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-open-ai</artifactId>
            <version>${langchain4j.version}</version>
            <classifier>bleeding-edge</classifier>
        </dependency>

        <!-- JSON处理 -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.10.1</version>
        </dependency>

        <!-- 日志框架 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.9</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.14</version>
        </dependency>

        <!-- 单元测试 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.10.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.12.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Gradle项目配置

如果你更喜欢使用Gradle,配置同样简洁:

plugins {
    id 'java'
    id 'application'
}

group = 'com.example'
version = '1.0.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    // 核心模块
    implementation 'dev.langchain4j:langchain4j:1.0.0-beta1'

    // OpenAI支持
    implementation 'dev.langchain4j:langchain4j-open-ai:1.0.0-beta1'

    // JSON处理
    implementation 'com.google.code.gson:gson:2.10.1'

    // 日志
    implementation 'org.slf4j:slf4j-api:2.0.9'
    runtimeOnly 'ch.qos.logback:logback-classic:1.4.14'

    // 测试
    testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1'
}

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

application {
    mainClass = 'com.example.App'
}

tasks.named('test') {
    useJUnitPlatform()
}

配置API密钥

LangChain4j支持多种LLM提供商,你需要配置相应的API密钥。最常见的是OpenAI:

public class ApiKeyConfig {

    // 方式一:通过环境变量(推荐方式)
    // 设置环境变量 OPENAI_API_KEY=sk-xxxxxx

    // 方式二:在代码中直接配置(仅用于演示,生产环境请勿使用)
    public static final String OPENAI_API_KEY = System.getenv("OPENAI_API_KEY");

    // 方式三:通过配置文件管理
    // 创建config.properties文件,内容如下:
    // openai.api.key=sk-xxxxxx
    // 然后通过Properties类加载

    private static final String CONFIG_FILE = "config.properties";

    public static String getApiKey() {
        // 优先使用环境变量
        String apiKey = System.getenv("OPENAI_API_KEY");
        if (apiKey != null && !apiKey.isEmpty()) {
            return apiKey;
        }

        // 次优方案:从配置文件读取
        try {
            java.util.Properties props = new java.util.Properties();
            props.load(new java.io.FileInputStream(CONFIG_FILE));
            return props.getProperty("openai.api.key");
        } catch (java.io.IOException e) {
            throw new RuntimeException("请设置OPENAI_API_KEY环境变量或创建config.properties文件", e);
        }
    }
}

创建日志配置文件

在src/main/resources目录下创建logback.xml:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 调整LangChain4j日志级别以查看详细请求响应 -->
    <logger name="dev.langchain4j" level="debug"/>

    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

核心概念与架构:深入理解LangChain4j的设计哲学

整体架构概览

LangChain4j的设计遵循了LangChain的核心思想,但在Java生态中做了大量适配和优化。其架构可以分为以下几个层次:

第一层:模型抽象层

这是整个框架的基础。LangChain4j定义了一系列接口来抽象不同类型的模型:

  • ChatLanguageModel:对话模型接口
  • StreamingChatLanguageModel:流式对话模型接口
  • EmbeddingModel:嵌入模型接口
  • ImageModel:图像模型接口

这种抽象设计使得你可以在不修改业务代码的情况下,切换不同的模型提供商。

第二层:组件层

建立在模型抽象之上的各种组件:

  • PromptTemplate:提示词模板,用于构建动态提示词
  • ChatMemory:对话记忆,管理对话历史
  • Tool:工具/函数调用扩展
  • OutputParser:输出解析器,将模型输出转换为结构化数据

第三层:编排层

将各种组件组合成完整的应用逻辑:

  • Chain:链式调用接口
  • Agent:代理,智能决策和执行
  • Service:AI服务,自动组装各种组件

核心接口详解

让我们深入了解几个最重要的接口:

// 对话模型的抽象接口
public interface ChatLanguageModel {

    // 同步调用,返回完整响应
    AiMessage sendMessages(List<ChatMessage> messages);

    // 带系统提示的便捷方法
    default AiMessage sendUserMessage(String userMessage) {
        return sendMessages(List.of(UserMessage.from(userMessage)));
    }
}

// 消息类型定义
public interface ChatMessage {
    // 用户消息
    record UserMessage(String text) implements ChatMessage {}

    // AI回复
    record AiMessage(String text) implements ChatMessage {}

    // 系统提示
    record SystemMessage(String text) implements ChatMessage {}
}

// 流式响应的接口
public interface StreamingChatLanguageModel {

    void sendMessages(
        List<ChatMessage> messages,
        StreamingResponseHandler<AiMessage> handler  // 流式处理器
    );
}

设计模式的应用

LangChain4j大量使用了设计模式来实现灵活性和可扩展性:

建造者模式:几乎所有配置类都使用建造器模式

ChatLanguageModel model = OpenAiChatModel.builder()
    .apiKey("your-api-key")
    .modelName("gpt-3.5-turbo")
    .temperature(0.7)
    .maxTokens(1000)
    .timeout(Duration.ofSeconds(30))
    .build();

策略模式:不同的模型提供商实现相同的接口,可以自由切换

装饰器模式:可以通过装饰器添加缓存、重试、熔断等功能

ChatLanguageModel originalModel = OpenAiChatModel.builder()
    .apiKey(apiKey)
    .build();

// 添加缓存装饰器
ChatLanguageModel cachedModel = CachingChatLanguageModel.builder()
    .delegate(originalModel)
    .cache(TokenCache.byToken(8192))
    .build();

// 添加重试装饰器
ChatLanguageModel retryingModel = RetryingChatLanguageModel.builder()
    .delegate(cachedModel)
    .maxAttempts(3)
    .delayBeforeRetry(Duration.ofSeconds(1))
    .build();

AI Service:最简化的使用方式

什么是AI Service

AI Service是LangChain4j提供的高级抽象,它简化了与LLM交互的复杂度。对于大多数场景,使用AI Service是最佳选择。它会自动处理:

  • 提示词模板的构建
  • 对话历史的维护
  • 输出的解析和转换
  • 工具的注册和调用

基本用法

首先定义一个接口来描述AI的能力:

import dev.langchain4j.service.Agent;
import dev.langchain4j.service.tool.Tool;

// 定义AI服务接口
public interface Assistant {

    // 简单对话
    String chat(String userMessage);

    // 带流式响应的对话
    String chatStreaming(String userMessage);
}

然后使用注解和建造器创建实现:

import dev.langchain4j.service.AIServiceArguments;
import dev.langchain4j.service.AIServiceForStreaming;
import dev.langchain4j.service.spring.ai.AiServices;

public class AssistantExample {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        Assistant assistant = AiServices.builder(Assistant.class)
            .chatLanguageModel(OpenAiChatModel.builder()
                .apiKey(apiKey)
                .modelName("gpt-3.5-turbo")
                .temperature(0.7)
                .build())
            .build();

        // 使用AI服务
        String response = assistant.chat("什么是Java?");
        System.out.println(response);
    }
}

带记忆的对话

通过添加ChatMemory来实现多轮对话:

// 首先定义带记忆的接口
public interface ChattyAssistant {
    String chat(String userMessage);
}

// 创建记忆实现
ChatMemory memory = MessageWindowChatMemory.withMaxMessages(20);

ChattyAssistant assistant = AiServices.builder(ChattyAssistant.class)
    .chatLanguageModel(OpenAiChatModel.builder()
        .apiKey(apiKey)
        .modelName("gpt-3.5-turbo")
        .build())
    .chatMemory(memory)  // 添加记忆组件
    .build();

// 多轮对话
System.out.println(assistant.chat("我叫张三"));           // 第一轮
System.out.println(assistant.chat("我叫什么名字?"));      // 第二轮,应该记住"张三"
System.out.println(assistant.chat("再说一遍我的名字"));    // 第三轮

LangChain4j提供了多种记忆实现:

// 消息窗口记忆:只保留最近N条消息
ChatMemory windowMemory = MessageWindowChatMemory.withMaxMessages(10);

// 基于Token的记忆:按Token数量限制
ChatMemory tokenMemory = TokenWindowChatMemory.withMaxTokens(500);

// 文件持久化记忆:重启后仍能记住对话
ChatMemory persistentMemory = FileChatMemory.builder()
    .directory(Path.of("./chat-memory"))
    .maxMessages(100)
    .build();

带工具调用的AI服务

这是LangChain4j最强大的功能之一。你可以让AI调用自定义的工具来扩展其能力:

// 定义工具类
public class WeatherService {

    // 工具注解标记此方法可以被AI调用
    @Tool("查询指定城市的当前天气")
    String getWeather(@P("city") String city) {
        // 实际项目中这里会调用天气API
        return switch (city) {
            case "北京" -> "北京今天天气晴朗,温度15-25°C";
            case "上海" -> "上海今天多云,温度18-28°C";
            case "广州" -> "广州今天有雨,温度22-30°C";
            default -> "未知的城市";
        };
    }
}

// 定义工具类
public class Calculator {

    @Tool("计算两个数字的加减乘除")
    String calculate(@P("a") double a, 
                     @P("b") double b, 
                     @P("operation") String operation) {
        return switch (operation) {
            case "加", "+" -> String.valueOf(a + b);
            case "减", "-" -> String.valueOf(a - b);
            case "乘", "*" -> String.valueOf(a * b);
            case "除", "/" -> b != 0 ? String.valueOf(a / b) : "除数不能为零";
            default -> "不支持的操作";
        };
    }
}

// 定义支持工具调用的AI接口
public interface SmartAssistant {

    // content参数会显示工具调用的结果
    @UserMessage("{message}")
    String chat(@V("message") String message);
}

// 创建带有工具的AI服务
SmartAssistant assistant = AiServices.builder(SmartAssistant.class)
    .chatLanguageModel(OpenAiChatModel.builder()
        .apiKey(apiKey)
        .modelName("gpt-3.5-turbo-1106")  // 需要支持工具调用的模型
        .build())
    .tools(new WeatherService(), new Calculator())  // 注册工具
    .build();

// AI会根据对话内容自动决定是否调用工具
String response = assistant.chat("北京现在多少度?");  // 会调用天气工具
System.out.println(response);

提示词模板:构建动态提示词的利器

PromptTemplate基础

PromptTemplate用于构建动态的提示词,支持变量替换、条件逻辑等功能:

import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.input.variables.StringVariable;

public class PromptTemplateExample {

    public static void main(String[] args) {
        // 定义模板,使用{{variableName}}作为变量占位符
        PromptTemplate template = PromptTemplate.from(
            "请为以下产品写一段营销文案:\n" +
            "产品名称:{{productName}}\n" +
            "产品特点:{{features}}\n" +
            "目标用户:{{targetAudience}}\n\n" +
            "语气要求:{{tone}}"
        );

        // 填充变量
        Prompt prompt = template.apply(Map.of(
            "productName", "LangChain4j",
            "features", "简单易用、功能强大、企业级支持",
            "targetAudience", "Java开发者",
            "tone", "专业且富有激情"
        ));

        System.out.println(prompt.text());
        // 输出:
        // 请为以下产品写一段营销文案:
        // 产品名称:LangChain4j
        // 产品特点:简单易用、功能强大、企业级支持
        // 产品用户:Java开发者
        // 语气要求:专业且富有激情
    }
}

条件模板

支持if/else条件逻辑:

PromptTemplate conditionalTemplate = PromptTemplate.from(
    "{{#if isVIP}}尊敬的大客户您好!{{/if}}" +
    "{{#if isVIP}}作为VIP用户,您将享受专属折扣。{{else}}您当前是普通用户。{{/if}}"
);

// VIP用户场景
Prompt vipPrompt = conditionalTemplate.apply(Map.of(
    "isVIP", true
));
System.out.println(vipPrompt.text());
// 输出:尊敬的大客户您好!作为VIP用户,您将享受专属折扣。

// 普通用户场景
Prompt normalPrompt = conditionalTemplate.apply(Map.of(
    "isVIP", false
));
System.out.println(normalPrompt.text());
// 输出:您当前是普通用户。

列表和循环

支持处理列表类型的变量:

PromptTemplate listTemplate = PromptTemplate.from(
    "请评价以下产品:\n" +
    "{{#each products}}" +
    "- {{name}}:{{description}}\n" +
    "{{/each}}"
);

Prompt prompt = listTemplate.apply(Map.of(
    "products", List.of(
        Map.of("name", "产品A", "description", "高品质"),
        Map.of("name", "产品B", "description", "高性价比"),
        Map.of("name", "产品C", "description", "创新设计")
    )
));

System.out.println(prompt.text());
// 输出:
// 请评价以下产品:
// - 产品A:高品质
// - 产品B:高性价比
// - 产品C:创新设计

高级模板技巧

// 支持默认值的变量
PromptTemplate templateWithDefault = PromptTemplate.from(
    "为{{name}}{{#if age}}({{age}}岁){{/if}}写一句生日祝福"
);

// 省略可选参数
Prompt p1 = templateWithDefault.apply(Map.of("name", "张三"));
System.out.println(p1.text());
// 输出:为张三写一句生日祝福

// 提供可选参数
Prompt p2 = templateWithDefault.apply(Map.of(
    "name", "李四", 
    "age", 30
));
System.out.println(p2.text());
// 输出:为李四(30岁)写一句生日祝福

// 支持日期、数字格式化
PromptTemplate dateTemplate = PromptTemplate.from(
    "今天是{{date date 'yyyy年MM月dd日'}}"
);

LocalDate today = LocalDate.now();
Prompt datePrompt = dateTemplate.apply(Map.of(
    "date", today
));
System.out.println(datePrompt.text());
// 输出:今天是2024年01月15日

对话记忆:让AI记住上下文

记忆的重要性

在多轮对话场景中,如果每次都只发送当前消息,AI就无法理解对话的上下文。例如:

// 没有记忆的情况
ChatLanguageModel model = OpenAiChatModel.builder()
    .apiKey(apiKey)
    .build();

// 第一轮
model.sendMessages(List.of(
    UserMessage.from("我叫张三")
));

// 第二轮(没有上下文)
model.sendMessages(List.of(
    UserMessage.from("我叫什么名字?")  // AI不知道上一轮说了什么
));

简单记忆实现

public class SimpleMemoryExample {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .build();

        // 使用ArrayList存储对话历史
        List<ChatMessage> conversationHistory = new ArrayList<>();

        // 第一轮对话
        conversationHistory.add(UserMessage.from("我叫张三"));
        AiMessage response1 = model.sendMessages(conversationHistory);
        conversationHistory.add(response1);
        System.out.println("AI: " + response1.text());

        // 第二轮对话
        conversationHistory.add(UserMessage.from("我叫什么名字?"));
        AiMessage response2 = model.sendMessages(conversationHistory);
        conversationHistory.add(response2);
        System.out.println("AI: " + response2.text());
        // 这次AI能正确回答"张三"

        // 第三轮对话
        conversationHistory.add(UserMessage.from("再说一遍"));
        AiMessage response3 = model.sendMessages(conversationHistory);
        System.out.println("AI: " + response3.text());
    }
}

消息窗口记忆

使用MessageWindowChatMemory可以限制保留的消息数量,防止超出模型的上下文窗口:

public class WindowMemoryExample {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .build();

        // 限制最多保留10条消息
        ChatMemory memory = MessageWindowChatMemory.withMaxMessages(10);

        // 模拟多次对话
        for (int i = 1; i <= 15; i++) {
            String userMessage = "这是第" + i + "轮对话";
            memory.add(UserMessage.from(userMessage));

            AiMessage response = model.sendMessages(memory.messages());
            memory.add(response);

            System.out.println("轮次 " + i + " - 消息数量: " + memory.messages().size());
        }

        // 当超过10条消息时,最早的消息会被移除
        // 只保留最近的10条
    }
}

Token计数记忆

更精确的控制是使用基于Token数量的限制:

ChatMemory tokenMemory = TokenWindowChatMemory.withMaxTokens(
    4096,  // 最大Token数
    new OpenAiTokenizer("gpt-3.5-turbo")  // 指定模型以正确计算Token
);

// 或者更简单的创建方式
ChatMemory autoTokenMemory = ChatMemory.builder()
    .maxTokens(4096)
    .build();

记忆持久化

对于需要跨会话保留记忆的场景,可以使用文件存储:

public class PersistentMemoryExample {

    public static void main(String[] args) throws Exception {
        String apiKey = ApiKeyConfig.getApiKey();

        // 指定存储目录
        Path memoryDirectory = Path.of("./data/chat-memory");

        // 创建持久化记忆,自动保存和加载
        PersistentChatMemory memory = PersistentChatMemory.builder()
            .directory(memoryDirectory)
            .maxMessages(100)
            .build();

        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .build();

        // 第一次运行:添加记忆
        memory.add(UserMessage.from("我叫王五"));
        memory.add(UserMessage.from("我是一名Java开发工程师"));

        AiMessage response = model.sendMessages(memory.messages());
        memory.add(response);

        // 记忆会自动保存到文件
        System.out.println("记忆已保存,当前消息数: " + memory.messages().size());

        // 第二次运行:加载记忆继续对话
        // PersistentChatMemory会自动从目录加载之前的对话
    }
}

链式调用:组合多个处理步骤

Chain接口

Chain是LangChain4j中用于组合多个处理步骤的核心抽象。一个Chain接收输入,通过一系列转换后产生输出:

public interface Chain<I, O> {
    O execute(I input);
}

内置Chain类型

LangChain4j提供了多种预置的Chain实现:

TransformationChain:数据转换链

import dev.langchain4j.chain.TransformationChain;

public class TransformationChainExample {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .build();

        // 创建转换链:输入文本 -> 翻译成英文 -> 情感分析
        Chain<String, String> translateAndAnalyze = TransformationChain.builder()
            .inputTransformer(userInput -> 
                "请将以下中文翻译成英文:\n" + userInput
            )
            .chatLanguageModel(model)
            .outputParser(new StringOutputParser())
            .build();

        // 第一步:翻译
        String translated = translateAndAnalyze.execute("今天天气真好");
        System.out.println("翻译结果: " + translated);

        // 第二步:情感分析
        Chain<String, String> sentimentChain = TransformationChain.builder()
            .inputTransformer(text -> 
                "分析以下英文文本的情感(正面/负面/中性):\n" + text
            )
            .chatLanguageModel(model)
            .outputParser(new StringOutputParser())
            .build();

        String sentiment = sentimentChain.execute(translated);
        System.out.println("情感分析: " + sentiment);
    }
}

ConversationChain:带记忆的对话链

import dev.langchain4j.chain.ConversationChain;

public class ConversationChainExample {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .build();

        ChatMemory memory = MessageWindowChatMemory.withMaxMessages(20);

        ConversationChain chain = ConversationChain.builder()
            .chatLanguageModel(model)
            .chatMemory(memory)
            .build();

        // 多轮对话
        String response1 = chain.execute("我想学习Java");
        System.out.println("AI: " + response1);

        String response2 = chain.execute("有什么推荐的学习资源吗?");
        System.out.println("AI: " + response2);
        // AI会记住之前的"我想学习Java"

        String response3 = chain.execute("能详细说说第一点吗?");
        System.out.println("AI: " + response3);
    }
}

SummarizingChain:文本摘要链

import dev.langchain4j.model.input.PromptTemplate;
import dev.langchain4j.model.input.variables.StringVariable;

public class SummarizingChainExample {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .build();

        // 创建摘要提示模板
        PromptTemplate summarizeTemplate = PromptTemplate.from(
            "请用简洁的语言总结以下文本的核心内容,不超过50字:\n\n{{text}}"
        );

        Chain<String, String> summarizingChain = Chain.builder()
            .promptTemplate(summarizeTemplate)
            .chatLanguageModel(model)
            .outputParser(new StringOutputParser())
            .build();

        String longText = """
            人工智能(AI)是计算机科学的一个分支,致力于开发能够模拟、延伸和扩展人类智能的理论、方法、技术及应用系统。
            它包括机器学习、自然语言处理、计算机视觉、机器人技术等多个子领域。
            近年来,随着深度学习技术的发展,AI在图像识别、语音识别、自然语言生成等方面取得了突破性进展。
            AI技术已经广泛应用于医疗诊断、金融风控、自动驾驶、智能客服等众多领域。
            """;

        String summary = summarizingChain.execute(longText);
        System.out.println("摘要: " + summary);
    }
}

自定义Chain

你也可以创建自己的Chain:

import dev.langchain4j.chain.Chain;

// 定义一个专门处理代码审查的Chain
public class CodeReviewChain implements Chain<CodeReviewRequest, CodeReviewResult> {

    private final ChatLanguageModel model;
    private final PromptTemplate template;

    public CodeReviewChain(ChatLanguageModel model) {
        this.model = model;
        this.template = PromptTemplate.from(
            "请审查以下Java代码,重点关注:\n" +
            "1. 代码风格和命名规范\n" +
            "2. 潜在的Bug和安全问题\n" +
            "3. 性能优化建议\n" +
            "4. 设计模式的使用\n\n" +
            "代码:\n" +
            "{{code}}\n\n" +
            "语言:{{language}}"
        );
    }

    @Override
    public CodeReviewResult execute(CodeReviewRequest request) {
        // 构建提示词
        Prompt prompt = template.apply(Map.of(
            "code", request.code(),
            "language", request.language()
        ));

        // 发送给模型
        AiMessage response = model.sendMessages(List.of(
            SystemMessage.from(prompt.text())
        ));

        // 解析结果(实际项目中应该使用专门的解析器)
        return new CodeReviewResult(response.text(), LocalDateTime.now());
    }
}

// 数据类
public record CodeReviewRequest(String code, String language) {}
public record CodeReviewResult(String review, LocalDateTime timestamp) {}

// 使用自定义Chain
public class CustomChainExample {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .build();

        CodeReviewChain chain = new CodeReviewChain(model);

        CodeReviewRequest request = new CodeReviewRequest(
            """
            public int calculateSum(List<Integer> numbers) {
                int sum = 0;
                for (int i = 0; i <= numbers.size(); i++) {
                    sum += numbers.get(i);
                }
                return sum;
            }
            """,
            "Java"
        );

        CodeReviewResult result = chain.execute(request);
        System.out.println("审查结果:\n" + result.review());
    }
}

Chain组合

多个Chain可以组合成更复杂的流程:

public class ChainCompositionExample {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .build();

        // Chain 1: 问题分类
        Chain<String, String> classifier = TransformationChain.builder()
            .inputTransformer(input -> 
                "将以下问题分类为:技术问题、投诉、咨询、其他\n" +
                "问题:" + input + "\n\n只输出分类结果"
            )
            .chatLanguageModel(model)
            .outputParser(new StringOutputParser())
            .build();

        // Chain 2: 技术问题处理
        Chain<String, String> techSupport = TransformationChain.builder()
            .inputTransformer(input -> 
                "作为技术支持工程师,请回答:\n" + input
            )
            .chatLanguageModel(model)
            .outputParser(new StringOutputParser())
            .build();

        // Chain 3: 投诉处理
        Chain<String, String> complaintHandler = TransformationChain.builder()
            .inputTransformer(input -> 
                "作为客服经理,请处理以下投诉并提供安抚方案:\n" + input
            )
            .chatLanguageModel(model)
            .outputParser(new StringOutputParser())
            .build();

        // 根据分类结果选择不同的处理Chain
        String userQuestion = "我的程序运行很慢,怎么优化?";

        String category = classifier.execute(userQuestion).trim();
        System.out.println("问题分类: " + category);

        String response;
        if (category.contains("技术")) {
            response = techSupport.execute(userQuestion);
        } else if (category.contains("投诉")) {
            response = complaintHandler.execute(userQuestion);
        } else {
            response = "感谢您的提问,我们会尽快回复您。";
        }

        System.out.println("回复: " + response);
    }
}

RAG实战:构建智能问答系统

RAG概述

检索增强生成(Retrieval-Augmented Generation,RAG)是当前最流行的LLM应用架构之一。它通过从外部知识库检索相关信息,然后让LLM基于检索结果生成回答,有效解决了LLM的”幻觉”问题和知识时效性问题。

LangChain4j提供了完整的RAG支持,包括:

  • 文档分割
  • 嵌入模型
  • 向量存储
  • 检索器
  • 答案生成

完整的RAG实现

import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.splitter.DocumentSplitters;
import dev.langchain4j.data.embedding.Embedding;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.model.embedding.OpenAiEmbeddingModel;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;

public class RAGExample {

    public static void main(String[] args) throws Exception {
        String apiKey = ApiKeyConfig.getApiKey();

        // ========================================
        // 步骤1:准备知识库文档
        // ========================================

        String knowledgeContent = """
            LangChain4j入门指南

            什么是LangChain4j?
            LangChain4j是一个Java库,旨在简化大语言模型应用的开发。
            它提供了统一的API来对接多种LLM提供商,包括OpenAI、Google、HuggingFace等。

            主要特性
            1. 统一的模型抽象层
            2. 丰富的组件库
            3. 支持RAG(检索增强生成)
            4. 工具调用和代理功能
            5. 对话记忆管理

            安装方法
            在Maven项目中添加依赖:
            <dependency>
                <groupId>dev.langchain4j</groupId>
                <artifactId>langchain4j</artifactId>
                <version>1.0.0-beta1</version>
            </dependency>

            快速开始
            第一步:创建ChatLanguageModel实例
            第二步:使用AiServices创建AI服务
            第三步:调用chat方法进行对话

            注意事项
            1. 请妥善保管API密钥
            2. 注意控制Token使用量
            3. 合理设置温度参数
            """;

        Document document = Document.from(knowledgeContent);

        // ========================================
        // 步骤2:分割文档
        // ========================================

        // 将文档分割成小块,便于检索
        List<TextSegment> segments = DocumentSplitters
            .recursive(500, 50)  // 每块最大500字符,重叠50字符
            .splitDocument(document);

        System.out.println("文档已分割为 " + segments.size() + " 个片段");
        segments.forEach(seg -> 
            System.out.println("- [" + seg.text().length() + "字符] " + 
                             seg.text().substring(0, Math.min(50, seg.text().length())) + "...")
        );

        // ========================================
        // 步骤3:创建嵌入模型
        // ========================================

        EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
            .apiKey(apiKey)
            .modelName("text-embedding-ada-002")
            .build();

        // ========================================
        // 步骤4:生成嵌入并存入向量存储
        // ========================================

        EmbeddingStore<TextSegment> embeddingStore = new InMemoryEmbeddingStore<>();

        List<Embedding> embeddings = embeddingModel.embedAll(
            segments.stream().map(TextSegment::text).toList()
        ).content();

        // 为每个片段生成嵌入并存储
        List<Embedded<TextSegment>> embedded = new ArrayList<>();
        for (int i = 0; i < segments.size(); i++) {
            embedded.add(Embedded.of(segments.get(i), embeddings.get(i)));
        }
        embeddingStore.addAll(embedded);

        System.out.println("\n知识库已建立,共存储 " + embedded.size() + " 个嵌入向量");

        // ========================================
        // 步骤5:创建检索器和生成模型
        // ========================================

        EmbeddingStoreRetriever retriever = EmbeddingStoreRetriever.from(
            embeddingStore,
            embeddingModel
        );

        ChatLanguageModel chatModel = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .modelName("gpt-3.5-turbo")
            .temperature(0.3)  // RAG场景建议降低温度以提高准确性
            .build();

        // ========================================
        // 步骤6:实现RAG问答
        // ========================================

        String userQuestion = "如何安装LangChain4j?";

        // 6.1 检索相关文档
        List<TextSegment> relevantSegments = retriever.retrieve(userQuestion, 3);

        System.out.println("\n检索到 " + relevantSegments.size() + " 个相关片段:");
        for (TextSegment seg : relevantSegments) {
            System.out.println("- " + seg.text().substring(0, Math.min(100, seg.text().length())) + "...");
        }

        // 6.2 构建RAG提示词
        String context = relevantSegments.stream()
            .map(TextSegment::text)
            .collect(Collectors.joining("\n\n"));

        String ragPrompt = """
            你是一个问答助手,请根据以下参考资料回答用户的问题。

            参考资料:
            %s

            问题:%s

            要求:
            1. 只根据参考资料回答,不要编造信息
            2. 如果参考资料中没有相关信息,请说明"我没有足够的信息来回答这个问题"
            3. 回答要简洁明了
            """.formatted(context, userQuestion);

        // 6.3 生成回答
        AiMessage response = chatModel.sendMessages(List.of(
            SystemMessage.from(ragPrompt)
        ));

        System.out.println("\n回答: " + response.text());
    }
}

使用RAG AI服务

LangChain4j还提供了更简洁的RAG实现方式:

import dev.langchain4j.service.AIServices;
import dev.langchain4j.service.RetryableAiService;
import dev.langchain4j.service.tool.ToolSpecification;

public class RAGServiceExample {

    public interface KnowledgeBaseAssistant {

        // 用户问题会被自动用于检索
        @Retain
        String answer(@UserMessage String question);
    }

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        // 创建组件
        EmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
            .apiKey(apiKey)
            .modelName("text-embedding-ada-002")
            .build();

        EmbeddingStore<TextSegment> embeddingStore = createEmbeddingStore();

        ChatLanguageModel chatModel = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .modelName("gpt-3.5-turbo")
            .temperature(0.3)
            .build();

        // 创建AI服务,自动配置RAG
        KnowledgeBaseAssistant assistant = AIServices.builder(KnowledgeBaseAssistant.class)
            .chatLanguageModel(chatModel)
            .chatMemory(MessageWindowChatMemory.withMaxMessages(10))
            .contentRetriever(EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore)
                .embeddingModel(embeddingModel)
                .maxResults(3)
                .build())
            .build();

        // 直接使用,检索和回答自动完成
        String answer = assistant.answer("LangChain4j支持哪些LLM提供商?");
        System.out.println(answer);
    }

    private static EmbeddingStore<TextSegment> createEmbeddingStore() {
        // 实际项目中这里会初始化真正的向量存储
        // 例如:Pinecone、Weaviate、Milvus等
        return new InMemoryEmbeddingStore<>();
    }
}

支持多种向量存储

LangChain4j支持多种向量存储后端:

// InMemory:内存存储,适合小规模数据和测试
EmbeddingStore<TextSegment> inMemoryStore = new InMemoryEmbeddingStore<>();

// Chroma:本地向量数据库
EmbeddingStore<TextSegment> chromaStore = ChromaEmbeddingStore.builder()
    .baseUrl("http://localhost:8000")
    .collectionName("my_collection")
    .build();

// Pinecone:云端向量数据库
EmbeddingStore<TextSegment> pineconeStore = PineconeEmbeddingStore.builder()
    .apiKey("your-api-key")
    .environment("gcp-starter")
    .index("my-index")
    .build();

// Weaviate
EmbeddingStore<TextSegment> weaviateStore = WeaviateEmbeddingStore.builder()
    .scheme("http")
    .host("localhost:8080")
    .apiKey("your-api-key")
    .indexName("MyClass")
    .build();

// Qdrant
EmbeddingStore<TextSegment> qdrantStore = QdrantEmbeddingStore.builder()
    .host("localhost")
    .port(6334)
    .collectionName("my_collection")
    .build();

工具与代理:构建自主行动的AI

工具系统概述

工具(Tools)是扩展AI能力的关键机制。通过注册工具,AI可以执行实际操作,如查询数据库、调用API、操作文件系统等。

定义工具

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

// ========================================
// 搜索引擎工具
// ========================================
public class SearchEngine {

    @Tool("搜索互联网获取相关信息")
    String search(@P("searchQuery") String searchQuery) {
        // 实际项目中这里会调用真实的搜索引擎API
        // 例如:Google Search API、Bing Search API等

        // 模拟搜索结果
        return switch (searchQuery.toLowerCase()) {
            case String s when s.contains("java") -> 
                "Java是一种广泛使用的编程语言,由Sun Microsystems于1995年发布...";
            case String s when s.contains("python") -> 
                "Python是一种高级编程语言,以其简洁易读的语法著称...";
            case String s when s.contains("langchain") -> 
                "LangChain是一个用于构建LLM应用的框架,支持Python和Java...";
            default -> 
                "关于'" + searchQuery + "'的搜索结果暂无记录";
        };
    }
}

// ========================================
// 日历工具
// ========================================
public class CalendarService {

    @Tool("查询指定日期范围的日程安排")
    List<String> getEvents(
        @P("startDate") String startDate,
        @P("endDate") String endDate
    ) {
        // 实际项目中会连接日历服务API
        return List.of(
            "2024-01-15 10:00 团队周会",
            "2024-01-16 14:00 项目评审",
            "2024-01-18 09:00 代码审查"
        );
    }

    @Tool("创建新的日程事件")
    String createEvent(
        @P("title") String title,
        @P("dateTime") String dateTime,
        @P("description") String description
    ) {
        return "日程已创建:" + title + ",时间:" + dateTime;
    }
}

// ========================================
// 文件操作工具
// ========================================
public class FileOperations {

    @Tool("读取指定路径的文件内容")
    String readFile(@P("filePath") String filePath) {
        try {
            return Files.readString(Path.of(filePath));
        } catch (IOException e) {
            return "读取文件失败:" + e.getMessage();
        }
    }

    @Tool("在指定路径创建新文件")
    String writeFile(
        @P("filePath") String filePath,
        @P("content") String content
    ) {
        try {
            Files.writeString(Path.of(filePath), content);
            return "文件创建成功:" + filePath;
        } catch (IOException e) {
            return "创建文件失败:" + e.getMessage();
        }
    }
}

创建代理

import dev.langchain4j.agent.ToolSpecifications;

public class AgentExample {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        // 创建工具实例
        SearchEngine searchEngine = new SearchEngine();
        CalendarService calendarService = new CalendarService();
        FileOperations fileOperations = new FileOperations();

        // 创建聊天模型(需要支持函数调用)
        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .modelName("gpt-3.5-turbo-1106")  // 支持函数调用
            .temperature(0.3)
            .build();

        // 从工具类生成工具规范
        List<ToolSpecification> toolSpecs = ToolSpecifications.toolSpecificationsFrom(
            searchEngine, 
            calendarService, 
            fileOperations
        );

        // 创建内存
        ChatMemory memory = MessageWindowChatMemory.withMaxMessages(50);

        // 使用Agent构建器创建代理
        Agent agent = Agent.builder()
            .chatLanguageModel(model)
            .chatMemory(memory)
            .toolSpecifications(toolSpecs)
            .tools(searchEngine, calendarService, fileOperations)
            .build();

        // 演示代理执行任务
        demonstrateAgent(agent, "帮我搜索Java的最新资讯");
        demonstrateAgent(agent, "查看这周有什么日程安排");
        demonstrateAgent(agent, "帮我整理一份LangChain4j的学习计划");
    }

    private static void demonstrateAgent(Agent agent, String task) {
        System.out.println("\n" + "=".repeat(50));
        System.out.println("任务: " + task);
        System.out.println("=".repeat(50));

        String response = agent.execute(task);
        System.out.println("结果: " + response);
    }
}

代理执行流程详解

代理的执行过程是一个循环:

// 伪代码展示代理的执行流程
public String agentExecutionLoop(Agent agent, String userTask) {

    // 1. 将用户任务添加到记忆
    memory.add(UserMessage.from(userTask));

    while (true) {
        // 2. 获取当前对话历史
        List<ChatMessage> messages = memory.messages();

        // 3. 发送给LLM,让它决定是否调用工具
        AiMessage response = model.sendMessages(messages);
        memory.add(response);

        // 4. 检查是否有函数调用
        if (response.hasToolCalls()) {
            // 5. 执行工具调用
            for (ToolCall toolCall : response.toolCalls()) {
                String toolName = toolCall.name();
                Map<String, Object> args = toolCall.args();

                // 调用实际工具
                String toolResult = executeTool(toolName, args);

                // 6. 将工具结果添加为工具消息
                memory.add(ToolMessage.from(toolResult, toolCall.id()));
            }

            // 7. 继续循环,让LLM基于工具结果生成回答
            continue;
        }

        // 8. 没有工具调用,返回最终回答
        return response.text();
    }
}

流式响应:实时展示AI输出

为什么需要流式响应

传统的API调用需要等待模型生成完整响应后才能返回。对于长文本,这可能导致用户等待数十秒。流式响应通过逐块返回生成的内容,显著改善了用户体验。

实现流式响应

import dev.langchain4j.model.StreamingResponseHandler;
import dev.langchain4j.model.output.Response;

public class StreamingExample {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        // 创建流式聊天模型
        StreamingChatLanguageModel streamingModel = OpenAiStreamingChatModel.builder()
            .apiKey(apiKey)
            .modelName("gpt-3.5-turbo")
            .temperature(0.7)
            .build();

        // 演示基本流式输出
        System.out.println("开始流式输出演示:\n");
        System.out.println("AI: ", "");

        streamingModel.sendMessages(
            List.of(UserMessage.from("给我讲一个关于人工智能的简短故事")),
            new StreamingResponseHandler<>() {

                private StringBuilder fullResponse = new StringBuilder();

                @Override
                public void onPartialToken(String token) {
                    // 每个token到达时调用
                    System.out.print(token);
                    fullResponse.append(token);
                }

                @Override
                public void onComplete(Response<AiMessage> response) {
                    // 流式输出完成
                    System.out.println("\n\n--- 流式输出完成 ---");
                    System.out.println("完整响应: " + fullResponse);
                }

                @Override
                public void onError(Throwable error) {
                    System.err.println("发生错误: " + error.getMessage());
                }
            }
        );

        // 等待流式输出完成
        try {
            Thread.sleep(30000);  // 等待最多30秒
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

带进度显示的流式响应

public class ProgressStreamingExample {

    private static final char[] LOADING_CHARS = {'|', '/', '-', '\\'};
    private static int loadingIndex = 0;

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        StreamingChatLanguageModel model = OpenAiStreamingChatModel.builder()
            .apiKey(apiKey)
            .modelName("gpt-3.5-turbo")
            .build();

        String userMessage = """
            请详细解释什么是微服务架构,包括:
            1. 定义和核心概念
            2. 主要优势
            3. 常见挑战
            4. 最佳实践
            """;

        System.out.println("问题: " + userMessage);
        System.out.println("\nAI回答: ");

        final int[] tokenCount = {0};
        final boolean[] isComplete = {false};

        // 启动进度显示线程
        Thread progressThread = new Thread(() -> {
            while (!isComplete[0]) {
                System.out.print("\r[处理中] " + LOADING_CHARS[loadingIndex++ % 4] + 
                               " 已生成 " + tokenCount[0] + " 个token");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    break;
                }
            }
        });
        progressThread.start();

        model.sendMessages(
            List.of(UserMessage.from(userMessage)),
            new StreamingResponseHandler<>() {

                private final StringBuilder response = new StringBuilder();

                @Override
                public void onPartialToken(String token) {
                    response.append(token);
                    tokenCount[0]++;
                    // 可以选择性地显示部分内容
                    if (tokenCount[0] % 10 == 0) {
                        System.out.print("●");
                    }
                }

                @Override
                public void onComplete(Response<AiMessage> response) {
                    isComplete[0] = true;
                    System.out.println("\r" + " ".repeat(50));  // 清除进度行
                    System.out.println("\n" + "=".repeat(50));
                    System.out.println("生成完成!共 " + tokenCount[0] + " 个token");
                }

                @Override
                public void onError(Throwable error) {
                    isComplete[0] = true;
                    System.out.println("\n错误: " + error.getMessage());
                }
            }
        );

        // 等待完成
        synchronized (StreamingExample.class) {
            try {
                StreamingExample.class.wait();
            } catch (InterruptedException e) {
                // 忽略
            }
        }
    }
}

在AI服务中使用流式

public interface StreamingAssistant {

    // 使用@UserMessage指定用户消息
    // 配合流式模型自动支持流式响应
    void chat(@UserMessage String message, StreamingResponseHandler<String> handler);
}

public class StreamingServiceExample {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        // 使用支持流式的模型
        StreamingChatLanguageModel streamingModel = OpenAiStreamingChatModel.builder()
            .apiKey(apiKey)
            .modelName("gpt-3.5-turbo")
            .build();

        // 转换为普通ChatLanguageModel以便与AiServices配合
        ChatLanguageModel model = StreamingChatLanguageModel.toChatModel(streamingModel);

        StreamingAssistant assistant = AiServices.builder(StreamingAssistant.class)
            .chatLanguageModel(streamingModel)  // 传入流式模型
            .build();

        System.out.println("请描述你最喜欢的编程语言:");

        assistant.chat("请详细描述Java语言的特点和应用场景", new StreamingResponseHandler<>() {

            private StringBuilder fullText = new StringBuilder();

            @Override
            public void onPartialToken(String token) {
                System.out.print(token);
                fullText.append(token);
            }

            @Override
            public void onComplete(Response<AiMessage> response) {
                System.out.println("\n\n回答完成!");
            }

            @Override
            public void onError(Throwable error) {
                System.out.println("发生错误: " + error.getMessage());
            }
        });
    }
}

实战项目:构建企业级AI助手

项目概述

让我们构建一个综合性的企业AI助手项目,整合本教程中学到的所有功能:

// ========================================
// 企业AI助手 - 完整实现
// ========================================

// 主接口定义
public interface EnterpriseAssistant {

    // 智能对话(带记忆)
    String chat(String message);

    // 流式对话
    void chatStreaming(String message, StreamingResponseHandler<String> handler);

    // 文档问答(基于RAG)
    String answerFromKnowledgeBase(String question);

    // 执行任务(使用工具)
    String executeTask(String task);
}

// 工具类定义
public class EnterpriseTools {

    static class DateTimeTools {

        @Tool("获取当前日期和时间")
        String getCurrentDateTime() {
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
            return "当前时间:" + now.format(formatter);
        }
    }

    static class CalculatorTools {

        @Tool("执行数学计算")
        double calculate(
            @P("expression") String expression
        ) {
            // 使用ScriptEngine进行简单计算
            try {
                ScriptEngineManager manager = new ScriptEngineManager();
                ScriptEngine engine = manager.getEngineByName("JavaScript");
                Object result = engine.eval(expression);
                return Double.parseDouble(result.toString());
            } catch (Exception e) {
                throw new RuntimeException("计算错误: " + e.getMessage());
            }
        }
    }

    static class WeatherTools {

        private static final Map<String, String> weatherData = Map.of(
            "北京", "晴,15-25°C,空气质量良好",
            "上海", "多云,18-28°C,有轻微雾霾",
            "广州", "小雨,22-30°C,建议带伞",
            "深圳", "晴,23-31°C,适宜户外活动",
            "杭州", "阴,16-24°C,温度适宜"
        );

        @Tool("查询城市天气")
        String getWeather(@P("city") String city) {
            return weatherData.getOrDefault(city, 
                "未找到" + city + "的天气数据");
        }
    }
}

// 知识库管理
public class KnowledgeBaseManager {

    private final EmbeddingStore<TextSegment> embeddingStore;
    private final EmbeddingModel embeddingModel;
    private final EmbeddingStoreContentRetriever contentRetriever;

    public KnowledgeBaseManager(String apiKey) {
        this.embeddingModel = OpenAiEmbeddingModel.builder()
            .apiKey(apiKey)
            .modelName("text-embedding-ada-002")
            .build();

        this.embeddingStore = new InMemoryEmbeddingStore<>();
        this.contentRetriever = EmbeddingStoreContentRetriever.builder()
            .embeddingStore(embeddingStore)
            .embeddingModel(embeddingModel)
            .maxResults(5)
            .build();
    }

    public void addDocument(String content, String metadata) {
        Document doc = Document.from(content + "\n[来源: " + metadata + "]");

        List<TextSegment> segments = DocumentSplitters
            .recursive(500, 50)
            .splitDocument(doc);

        List<Embedding> embeddings = embeddingModel.embedAll(
            segments.stream().map(TextSegment::text).toList()
        ).content();

        List<Embedded<TextSegment>> embedded = new ArrayList<>();
        for (int i = 0; i < segments.size(); i++) {
            embedded.add(Embedded.of(segments.get(i), embeddings.get(i)));
        }

        embeddingStore.addAll(embedded);
        System.out.println("已添加文档片段: " + segments.size());
    }

    public List<String> retrieve(String query, int maxResults) {
        return contentRetriever.retrieve(query, maxResults)
            .stream()
            .map(TextSegment::text)
            .collect(Collectors.toList());
    }
}

// AI服务实现
public class EnterpriseAssistantImpl implements EnterpriseAssistant {

    private final ChatLanguageModel chatModel;
    private final StreamingChatLanguageModel streamingModel;
    private final ChatMemory chatMemory;
    private final KnowledgeBaseManager knowledgeBase;
    private final Agent agent;

    public EnterpriseAssistantImpl(String apiKey) {
        // 初始化聊天模型
        this.chatModel = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .modelName("gpt-3.5-turbo")
            .temperature(0.7)
            .maxTokens(2000)
            .build();

        // 初始化流式模型
        this.streamingModel = OpenAiStreamingChatModel.builder()
            .apiKey(apiKey)
            .modelName("gpt-3.5-turbo")
            .temperature(0.7)
            .build();

        // 初始化记忆
        this.chatMemory = MessageWindowChatMemory.withMaxMessages(50);

        // 初始化知识库
        this.knowledgeBase = new KnowledgeBaseManager(apiKey);

        // 初始化工具
        List<Object> tools = List.of(
            new EnterpriseTools.DateTimeTools(),
            new EnterpriseTools.CalculatorTools(),
            new EnterpriseTools.WeatherTools()
        );

        // 初始化代理
        this.agent = Agent.builder()
            .chatLanguageModel(chatModel)
            .chatMemory(chatMemory)
            .toolSpecifications(ToolSpecifications.toolSpecificationsFrom(tools))
            .tools(tools)
            .build();

        // 初始化知识库内容
        initializeKnowledgeBase();
    }

    private void initializeKnowledgeBase() {
        // 添加企业知识库文档
        knowledgeBase.addDocument(
            """
            公司成立于2010年,专注于人工智能技术研发。
            主要产品包括智能客服系统、数据分析平台、AI开发工具。
            公司价值观:创新、协作、责任、卓越。
            """,
            "公司简介"
        );

        knowledgeBase.addDocument(
            """
            员工福利政策:
            1. 五险一金全额缴纳
            2. 弹性工作制
            3. 年度体检
            4. 培训发展机会
            5. 带薪年假15天起
            """,
            "人事政策"
        );

        knowledgeBase.addDocument(
            """
            技术栈包括:
            - 后端:Java、Spring Boot、Kotlin
            - 前端:React、Vue.js
            - 大数据:Hadoop、Spark
            - 机器学习:TensorFlow、PyTorch
            - 云服务:AWS、阿里云
            """,
            "技术文档"
        );

        System.out.println("知识库初始化完成!");
    }

    @Override
    public String chat(String message) {
        chatMemory.add(UserMessage.from(message));

        AiMessage response = chatModel.sendMessages(chatMemory.messages());
        chatMemory.add(response);

        return response.text();
    }

    @Override
    public void chatStreaming(String message, StreamingResponseHandler<String> handler) {
        chatMemory.add(UserMessage.from(message));

        StringBuilder fullResponse = new StringBuilder();

        streamingModel.sendMessages(
            chatMemory.messages(),
            new StreamingResponseHandler<>() {

                @Override
                public void onPartialToken(String token) {
                    fullResponse.append(token);
                    handler.onPartialToken(token);
                }

                @Override
                public void onComplete(Response<AiMessage> response) {
                    chatMemory.add(response.content());
                    handler.onComplete(Response.from(fullResponse.toString()));
                }

                @Override
                public void onError(Throwable error) {
                    handler.onError(error);
                }
            }
        );
    }

    @Override
    public String answerFromKnowledgeBase(String question) {
        // 检索相关文档
        List<String> relevantDocs = knowledgeBase.retrieve(question, 5);

        if (relevantDocs.isEmpty()) {
            return "抱歉,知识库中没有找到相关信息。";
        }

        // 构建RAG提示词
        String context = relevantDocs.stream()
            .collect(Collectors.joining("\n\n---\n\n"));

        String prompt = """
            请基于以下参考资料回答用户的问题。如果资料中没有相关信息,请说明。

            参考资料:
            %s

            用户问题:%s
            """.formatted(context, question);

        AiMessage response = chatModel.sendMessages(
            List.of(SystemMessage.from(prompt))
        );

        return response.text();
    }

    @Override
    public String executeTask(String task) {
        return agent.execute(task);
    }
}

// 主程序入口
public class EnterpriseAssistantDemo {

    public static void main(String[] args) {
        String apiKey = ApiKeyConfig.getApiKey();

        System.out.println("=".repeat(50));
        System.out.println("企业AI助手演示");
        System.out.println("=".repeat(50));

        EnterpriseAssistant assistant = new EnterpriseAssistantImpl(apiKey);

        // ========================================
        // 演示1:普通对话(带记忆)
        // ========================================
        System.out.println("\n【演示1:智能对话】");
        System.out.println("- - - - - - - - - - - - - - - - - - -");

        String response1 = assistant.chat("我叫张三,是一名Java开发工程师");
        System.out.println("用户: 我叫张三,是一名Java开发工程师");
        System.out.println("AI: " + response1);

        String response2 = assistant.chat("我的工号是多少?");
        System.out.println("\n用户: 我的工号是多少?");
        System.out.println("AI: " + response2);

        String response3 = assistant.chat("刚才我说我是什么职位?");
        System.out.println("\n用户: 刚才我说我是什么职位?");
        System.out.println("AI: " + response3);

        // ========================================
        // 演示2:知识库问答
        // ========================================
        System.out.println("\n\n【演示2:知识库问答】");
        System.out.println("- - - - - - - - - - - - - - - - - - -");

        String q1 = "公司有哪些员工福利?";
        String a1 = assistant.answerFromKnowledgeBase(q1);
        System.out.println("问题: " + q1);
        System.out.println("回答: " + a1);

        String q2 = "公司的技术栈是什么?";
        String a2 = assistant.answerFromKnowledgeBase(q2);
        System.out.println("\n问题: " + q2);
        System.out.println("回答: " + a2);

        // ========================================
        // 演示3:工具调用
        // ========================================
        System.out.println("\n\n【演示3:智能任务执行】");
        System.out.println("- - - - - - - - - - - - - - - - - - -");

        String task1 = "现在几点了?顺便告诉我北京的天气";
        String result1 = assistant.executeTask(task1);
        System.out.println("任务: " + task1);
        System.out.println("执行结果: " + result1);

        String task2 = "帮我计算 (15 + 25) * 2 等于多少?";
        String result2 = assistant.executeTask(task2);
        System.out.println("\n任务: " + task2);
        System.out.println("执行结果: " + result2);

        // ========================================
        // 演示4:流式响应
        // ========================================
        System.out.println("\n\n【演示4:流式响应】");
        System.out.println("- - - - - - - - - - - - - - - - - - -");

        assistant.chatStreaming(
            "请介绍一下人工智能的发展历史",
            new StreamingResponseHandler<>() {

                private int tokenCount = 0;

                @Override
                public void onPartialToken(String token) {
                    System.out.print(token);
                    tokenCount++;
                }

                @Override
                public void onComplete(Response<String> response) {
                    System.out.println("\n\n流式输出完成!共 " + tokenCount + " 个token");
                }

                @Override
                public void onError(Throwable error) {
                    System.out.println("错误: " + error.getMessage());
                }
            }
        );

        // 等待流式输出
        try {
            Thread.sleep(60000);
        } catch (InterruptedException e) {
            // 忽略
        }
    }
}

常见使用场景与最佳实践

场景一:智能客服系统

public class CustomerServiceBot {

    private final ChatLanguageModel model;
    private final ChatMemory memory;
    private final Agent orderAgent;
    private final Agent refundAgent;

    public CustomerServiceBot(String apiKey) {
        this.model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .modelName("gpt-3.5-turbo")
            .temperature(0.5)
            .build();

        // 按客户会话隔离记忆
        this.memory = MessageWindowChatMemory.withMaxMessages(30);

        // 初始化订单查询工具
        this.orderAgent = Agent.builder()
            .chatLanguageModel(model)
            .chatMemory(memory)
            .tools(new OrderQueryTool())
            .build();

        // 初始化退款处理工具
        this.refundAgent = Agent.builder()
            .chatLanguageModel(model)
            .chatMemory(memory)
            .tools(new RefundTool())
            .build();
    }

    public String handleCustomer(String customerId, String message) {
        // 根据意图路由到不同的处理逻辑
        String intent = detectIntent(message);

        return switch (intent) {
            case "order_query" -> orderAgent.execute(message);
            case "refund" -> refundAgent.execute(message);
            default -> generalResponse(message);
        };
    }

    private String detectIntent(String message) {
        // 意图识别逻辑
        String lowerMessage = message.toLowerCase();

        if (lowerMessage.contains("订单") || lowerMessage.contains("物流") 
            || lowerMessage.contains("发货")) {
            return "order_query";
        }

        if (lowerMessage.contains("退款") || lowerMessage.contains("退货")) {
            return "refund";
        }

        return "general";
    }

    private String generalResponse(String message) {
        String prompt = """
            你是一个专业的电商客服,请礼貌地回复客户的问题。

            客户消息:%s

            回复要求:
            1. 礼貌友好
            2. 简洁明了
            3. 如无法解决问题,引导客户联系人工客服
            """.formatted(message);

        return model.sendMessages(List.of(
            SystemMessage.from(prompt)
        )).text();
    }
}

场景二:代码助手

public class CodeAssistant {

    private final ChatLanguageModel model;
    private final PromptTemplate codeReviewTemplate;
    private final PromptTemplate codeExplainTemplate;
    private final PromptTemplate codeOptimizeTemplate;

    public CodeAssistant(String apiKey) {
        this.model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .modelName("gpt-3.5-turbo")
            .temperature(0.3)  // 代码场景使用低温度
            .build();

        this.codeReviewTemplate = PromptTemplate.from(
            "请审查以下%s代码,重点检查:\n" +
            "1. 代码规范和风格\n" +
            "2. 潜在Bug和安全问题\n" +
            "3. 性能优化建议\n" +
            "4. 错误处理是否完善\n\n" +
            "代码:\n```%s\n%s\n```"
        );

        this.codeExplainTemplate = PromptTemplate.from(
            "请详细解释以下%s代码的功能和工作原理:\n\n" +
            "代码:\n```%s\n%s\n```\n\n" +
            "请包含:\n" +
            "1. 整体功能说明\n" +
            "2. 主要方法和类的作用\n" +
            "3. 关键逻辑的执行流程"
        );

        this.codeOptimizeTemplate = PromptTemplate.from(
            "请优化以下%s代码,在保持功能不变的前提下:\n\n" +
            "代码:\n```%s\n%s\n```\n\n" +
            "优化目标:\n" +
            "1. 提高性能\n" +
            "2. 改善可读性\n" +
            "3. 增强可维护性\n\n" +
            "请同时提供优化建议和优化后的代码。"
        );
    }

    public String reviewCode(String language, String code) {
        String prompt = codeReviewTemplate.apply(Map.of(
            "language", language,
            "language2", language,
            "code", code
        )).text();

        return model.sendMessages(List.of(SystemMessage.from(prompt))).text();
    }

    public String explainCode(String language, String code) {
        String prompt = codeExplainTemplate.apply(Map.of(
            "language", language,
            "language2", language,
            "code", code
        )).text();

        return model.sendMessages(List.of(SystemMessage.from(prompt))).text();
    }

    public String optimizeCode(String language, String code) {
        String prompt = codeOptimizeTemplate.apply(Map.of(
            "language", language,
            "language2", language,
            "code", code
        )).text();

        return model.sendMessages(List.of(SystemMessage.from(prompt))).text();
    }
}

场景三:数据提取与分析

public class DataExtractor {

    private final ChatLanguageModel model;
    private final OutputParser<ExtractedData> jsonParser;

    public DataExtractor(String apiKey) {
        this.model = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .modelName("gpt-3.5-turbo")
            .temperature(0.1)  // 数据提取使用极低温度
            .build();

        this.jsonParser = new GsonOutputParser<>(ExtractedData.class);
    }

    public ExtractedData extractFromText(String text, String schema) {
        String prompt = """
            请从以下文本中提取信息,并按照指定的JSON Schema格式输出。

            文本内容:
            %s

            JSON Schema:
            %s

            要求:
            1. 只输出JSON,不要包含任何其他文字
            2. 如果某字段在文本中找不到对应信息,使用null
            3. 日期格式使用ISO 8601标准
            """.formatted(text, schema);

        AiMessage response = model.sendMessages(List.of(
            SystemMessage.from(prompt)
        ));

        // 解析JSON响应
        try {
            return jsonParser.parse(response.text());
        } catch (Exception e) {
            throw new RuntimeException("解析失败: " + e.getMessage(), e);
        }
    }
}

// 数据类
public record ExtractedData(
    String name,
    String email,
    String phone,
    String company,
    String title,
    List<String> skills
) {}

// 自定义JSON解析器
public class GsonOutputParser<T> implements OutputParser<T> {

    private final Class<T> clazz;
    private final Gson gson = new Gson();

    public GsonOutputParser(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public T parse(String text) {
        // 尝试提取JSON部分
        String json = extractJson(text);
        return gson.fromJson(json, clazz);
    }

    private String extractJson(String text) {
        // 移除markdown代码块标记
        text = text.trim();
        if (text.startsWith("```json")) {
            text = text.substring(7);
        } else if (text.startsWith("```")) {
            text = text.substring(3);
        }
        if (text.endsWith("```")) {
            text = text.substring(0, text.length() - 3);
        }
        return text.trim();
    }
}

最佳实践总结

提示词工程

// 实践1:使用结构化提示词
PromptTemplate structuredPrompt = PromptTemplate.from(
    """
    任务:{{task}}

    角色:{{role}}

    输出格式:
    - 标题:[提取的标题]
    - 要点:[提取的要点列表]
    - 建议:[相关建议]

    内容:
    {{content}}
    """
);

// 实践2:Few-shot示例
PromptTemplate fewShotPrompt = PromptTemplate.from(
    """
    你是一个文本分类器。

    示例:
    输入:"这个产品太棒了!"
    输出:正面

    输入:"服务态度很差"
    输出:负面

    输入:"今天天气不错"
    输出:中性

    现在请分类:
    输入:"{{input}}"
    输出:
    """
);

// 实践3:链式思考提示
PromptTemplate cotPrompt = PromptTemplate.from(
    """
    问题:{{question}}

    请按以下步骤思考:
    1. 理解问题的核心要求
    2. 分析相关因素
    3. 制定解决方案
    4. 给出最终答案

    你的思考过程:
    """
);

性能优化

// 优化1:使用批量API减少网络开销
public class BatchOptimization {

    public List<String> batchProcess(List<String> inputs, ChatLanguageModel model) {
        // 将多个请求合并为一个提示词
        String combinedPrompt = inputs.stream()
            .map(input -> "任务" + (inputs.indexOf(input) + 1) + ": " + input)
            .collect(Collectors.joining("\n\n"));

        // 单次API调用
        String response = model.sendMessages(List.of(
            SystemMessage.from("请依次完成以下任务:\n" + combinedPrompt)
        )).text();

        // 解析结果
        return parseBatchResults(response, inputs.size());
    }
}

// 优化2:使用缓存减少重复调用
public class CachingExample {

    public static ChatLanguageModel createCachedModel(String apiKey) {
        ChatLanguageModel baseModel = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .build();

        // 使用内存缓存
        return CachingChatLanguageModel.builder()
            .delegate(baseModel)
            .cache(Cache.builder()
                .maximumSize(1000)
                .expireAfterWrite(Duration.ofMinutes(30))
                .build())
            .build();
    }
}

// 优化3:合理设置Token限制
public class TokenOptimization {

    public static ChatLanguageModel createOptimizedModel(String apiKey) {
        return OpenAiChatModel.builder()
            .apiKey(apiKey)
            .maxTokens(500)  // 根据实际需求设置
            .build();
    }
}

错误处理与重试

public class ResilientExample {

    public static ChatLanguageModel createResilientModel(String apiKey) {
        ChatLanguageModel baseModel = OpenAiChatModel.builder()
            .apiKey(apiKey)
            .build();

        return RetryingChatLanguageModel.builder()
            .delegate(baseModel)
            .maxAttempts(3)
            .delayBeforeRetry(Duration.ofSeconds(1))
            .retryOn(List.of(
                RateLimitException.class,
                HttpStatusException.class
            ))
            .build();
    }
}

高级特性与扩展

自定义模型集成

如果需要集成LangChain4j不支持的LLM提供商,可以实现自定义模型接口:

public class CustomModelExample {

    // 实现自定义聊天模型
    public static class MyCustomChatModel implements ChatLanguageModel {

        private final String apiKey;
        private final String baseUrl;

        public MyCustomChatModel(String apiKey, String baseUrl) {
            this.apiKey = apiKey;
            this.baseUrl = baseUrl;
        }

        @Override
        public AiMessage sendMessages(List<ChatMessage> messages) {
            // 将LangChain4j消息格式转换为你的API格式
            MyRequest request = convertToRequest(messages);

            // 调用自定义API
            HttpResponse response = HttpClient.newHttpClient()
                .send(
                    HttpRequest.newBuilder()
                        .uri(URI.create(baseUrl + "/chat"))
                        .header("Authorization", "Bearer " + apiKey)
                        .header("Content-Type", "application/json")
                        .POST(HttpRequest.BodyPublishers.ofString(toJson(request)))
                        .build(),
                    HttpResponse.BodyHandlers.ofString()
                );

            if (response.statusCode() != 200) {
                throw new RuntimeException("API调用失败: " + response.statusCode());
            }

            // 解析响应并转换为LangChain4j格式
            MyResponse myResponse = fromJson(response.body(), MyResponse.class);
            return AiMessage.from(myResponse.getContent());
        }

        private MyRequest convertToRequest(List<ChatMessage> messages) {
            // 实现消息格式转换逻辑
            return new MyRequest(/* 转换后的数据 */);
        }

        // Builder模式
        public static Builder builder() {
            return new Builder();
        }

        public static class Builder {
            private String apiKey;
            private String baseUrl;

            public Builder apiKey(String apiKey) {
                this.apiKey = apiKey;
                return this;
            }

            public Builder baseUrl(String baseUrl) {
                this.baseUrl = baseUrl;
                return this;
            }

            public MyCustomChatModel build() {
                return new MyCustomChatModel(apiKey, baseUrl);
            }
        }
    }

    // 使用自定义模型
    public static void main(String[] args) {
        MyCustomChatModel customModel = MyCustomChatModel.builder()
            .apiKey("your-api-key")
            .baseUrl("https://api.your-provider.com")
            .build();

        Assistant assistant = AiServices.builder(Assistant.class)
            .chatLanguageModel(customModel)
            .build();

        String response = assistant.chat("你好");
        System.out.println(response);
    }
}

与Spring Boot集成

// Spring Boot配置类
@Configuration
public class LangChain4jConfig {

    @Value("${openai.api.key}")
    private String openaiApiKey;

    @Bean
    public ChatLanguageModel chatLanguageModel() {
        return OpenAiChatModel.builder()
            .apiKey(openaiApiKey)
            .modelName("gpt-3.5-turbo")
            .temperature(0.7)
            .build();
    }

    @Bean
    public StreamingChatLanguageModel streamingChatLanguageModel() {
        return OpenAiStreamingChatModel.builder()
            .apiKey(openaiApiKey)
            .modelName("gpt-3.5-turbo")
            .temperature(0.7)
            .build();
    }

    @Bean
    public ChatMemory chatMemory() {
        return MessageWindowChatMemory.withMaxMessages(50);
    }

    @Bean
    public Assistant assistant(
            ChatLanguageModel chatLanguageModel,
            ChatMemory chatMemory) {
        return AiServices.builder(Assistant.class)
            .chatLanguageModel(chatLanguageModel)
            .chatMemory(chatMemory)
            .build();
    }
}

// Spring Boot控制器
@RestController
@RequestMapping("/api/ai")
public class AiController {

    private final Assistant assistant;

    public AiController(Assistant assistant) {
        this.assistant = assistant;
    }

    @PostMapping("/chat")
    public Map<String, String> chat(@RequestBody Map<String, String> request) {
        String message = request.get("message");
        String response = assistant.chat(message);
        return Map.of("response", response);
    }

    @PostMapping("/chat/stream")
    public Flux<ServerSentEvent<String>> chatStream(
            @RequestBody Map<String, String> request,
            HttpServletResponse response) {

        String message = request.get("message");

        return Flux.create(emitter -> {
            assistant.chat(message, new StreamingResponseHandler<>() {

                @Override
                public void onPartialToken(String token) {
                    emitter.next(ServerSentEvent.<String>builder()
                        .data(token)
                        .build());
                }

                @Override
                public void onComplete(Response<String> response) {
                    emitter.complete();
                }

                @Override
                public void onError(Throwable error) {
                    emitter.error(error);
                }
            });
        });
    }
}

总结与资源推荐

核心要点回顾

通过本教程,我们详细探讨了LangChain4j的各个方面:

  • 为什么值得关注:LangChain4j填补了Java生态在LLM应用开发领域的空白,提供了完整的一站式解决方案
  • 环境搭建:通过Maven或Gradle可以快速集成,配合简单的配置即可开始开发
  • AI Service:最高层次的抽象,通过接口定义和注解即可快速构建AI应用
  • 提示词模板:提供了强大的模板引擎,支持变量、条件、循环等复杂逻辑
  • 对话记忆:支持多种记忆实现,可以根据场景选择合适的方案
  • Chain系统:灵活的链式调用机制,可以组合出复杂的业务逻辑
  • RAG支持:完整的检索增强生成支持,可以构建知识密集型应用
  • 工具与代理:让AI能够执行实际操作,实现真正的智能自动化
  • 流式响应:提升用户体验,特别适合长文本生成场景

LangChain4j与其他框架对比

特性 LangChain4j Spring AI Direct API
学习曲线 中等 较高
功能完整性 完整 一般 需自行实现
多模型支持 丰富 一般
RAG支持 完善 一般 需自行实现
社区活跃度 活跃 一般
文档质量 优秀 一般

推荐的延伸学习方向

  1. 深入学习LLM原理:了解Transformer架构、注意力机制等
  2. 提示词工程:学习高级提示技巧,如CoT、ReAct等
  3. 向量数据库:学习使用Pinecone、Weaviate等生产级向量存储
  4. Agent架构:探索更复杂的Agent设计模式
  5. 性能优化:学习Prompt压缩、KV Cache等技术

相关资源链接

官方资源

  • GitHub仓库:https://github.com/langchain4j/langchain4j
  • 官方文档:https://docs.langchain4j.dev/
  • 示例项目:https://github.com/langchain4j/langchain4j-examples
  • Maven中央仓库:https://central.sonatype.com/artifact/dev.langchain4j/langchain4j

模型提供商

  • OpenAI API:https://platform.openai.com/
  • Anthropic Claude:https://www.anthropic.com/
  • Google AI Studio:https://aistudio.google.com/
  • HuggingFace:https://huggingface.co/

向量数据库

  • Pinecone:https://www.pinecone.io/
  • Weaviate:https://weaviate.io/
  • Qdrant:https://qdrant.tech/
  • Milvus:https://milvus.io/

展望未来

LLM应用开发正在快速发展,LangChain4j也在持续迭代。未来值得期待的方向包括:

  • 更好的多模态支持(图像、音频、视频)
  • 更强大的Agent框架
  • 更丰富的RAG优化
  • 与更多Java生态框架的深度集成
  • 性能优化和资源管理改进

无论你是Java老手还是新人,LangChain4j都为你打开了一扇通往AI应用开发的大门。现在就开始你的LangChain4j之旅吧!

祝你编码愉快!
“`

如果内容对您有帮助,欢迎打赏

您的支持是我继续创作的动力

前往打赏页面

评论区

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注