LangChain4J

LangChain4J

LangChain4j 是一个专为 Java 开发者设计的大语言模型 (LLM) 集成框架,旨在简化 Java 应用程序与各种 LLM 提供商的集成过程。该项目受到 Python 的 LangChain、Haystack、LlamaIndex 等框架的启发,为 Java 生态系统提供了强大而统一的 LLM 工具链。

官网:docs.langchain4j.dev

LLM模型为核心的开发框架的出现为自然语言处理(NLP)打开了一个新世界,我们可以用其创建各种应用程序,包括聊天机器人和智能问答工具。

大语言模型LLM应用技术架构

  • UI交互层:用户通过UI与LLM应用交互,如langflow是langchain的GUI,通过拖放组件和聊天框架提供一种轻松的实验和原型流程方式。
  • 服务层:将各种语言模型或外部资源整合,构建实用的LLM模型。【代表性框架】 Langchain是一个开源LLM应用框架,将LLM模型、向量数据库、交互层Prompt、外部知识、外部工具整合到一起,可自由构建LLM应用。
  • 模型层:用户选择需要调用的大语言模型,可以是OpenAI的GPT系列模型,Hugging Face中的开源LLM系列等。模型层提供最核心支撑,包括聊天接口、上下文QA问答接口、文本总结接口、文本翻译接口等。
  • 存储层:主要为向量数据库,用于存储文本、图像等编码后的特征向量,支持向量相似度查询与分析。在做文本语义检索时,通过比较输入文本的特征向量与底库文本特征向量的相似性,从而检索目标文本。

大模型开发分类:基础通用大模型、行业垂直大模型、超级个体+智能体

LangChain4j支持的各种大型语言模型(LLMs)

地址:https://docs.langchain4j.dev/integrations/language-models/

模型供应商:

OpenAl

GPT系列(如GPT-4),具备强大的文本生成与理解能力。

优势:灵活性高,适用于多种应用场景。YYDS 大模型界的事实标准。目前暂停对国服的API服务,需要通过 Azure 接入。

阿里百炼

提供多种大模型服务(如通义千问系列)。

优势:性能接近GPT-4,API价格较低,支持企业迁移解决方案。主要面向企业用户,所有新用户可获得超过5000万Tokens的免费额度及4500张图片生成额度,以鼓励更多企业使用。

DeepSeek

开源大模型,支持多语言。

优点:推理与编码任务表现优异,社区活跃,支持多样化应用。性价比高,输入价格(缓存命中,缓存未命中):1元/百万Tokens,敏感词封号严重。

智谱清言

基于GLM架构,支持多轮对话与复杂指令处理。

优点:指令理解能力强,支持多场景下的定制化解决方案。模型全面;在国庆月特别活动中,智谱清言宣布用户可以以最低1折调用所有模型,并每位用户将获赠1亿Tokens的额度。

硅基流动

专注于AI基础设施,提供SiliconCloud平台

优点:高效推理,多模态支持,降低使用门槛,提升开发效率。主要面向技术开发者。提供了一系列开源大模型的API服务,其中多个开源大模型如Qwen2、GLM4和Yi1.5均为永久免费,这使得开发者可以自由使用这些模型进行应用开发,而无需承担费用。

Ollama

支持本地部署,集成多种开源模型,隐私保护优先。

优点:强调用户隐私和自主性。需要较高的硬件配置以支持本地部署。

前提准备

阿里云百炼平台

阿里云百炼是阿里云推出的一站式大模型开发与应用平台,于 2023 年 10 月发布,后续历经多次升级,成为承载阿里云云 + AI 能力的核心平台,面向企业、开发者及 ISV 技术人员,提供从模型调用到应用构建的全链路服务。

官网:https://bailian.console.aliyun.com/

大模型调用三件套

步骤1:获取API-key

步骤2:获取模型名

在模型广场选择一个模型,复制code值。

步骤3:获取BaseUrl开发地址

DeepseekAPI开放平台

官方地址:https://www.deepseek.com/

调用API地址:https://api-docs.deepseek.com/zh-cn/

配置API-key、模型名、开发地址

创建项目

创建Project父工程

配置Pom

xml 复制代码
<?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>cn.good.yan</groupId>
    <artifactId>langchain4j-V5</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>langchain4j-V5-Maven父工程POM配置</name>

    <!-- 子工程,后面有很多 -->
    <modules>
        <module>xxxxx</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>17</java.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <!-- Spring Boot -->
        <spring-boot.version>3.5.0</spring-boot.version>
        <!-- Spring AI -->
        <spring-ai.version>1.0.0</spring-ai.version>
        <!-- Spring AI Alibaba -->
        <spring-ai-alibaba.version>1.0.0-M6.1</spring-ai-alibaba.version>
        <!-- langchain4j -->
        <langchain4j.version>1.0.1</langchain4j.version>
        <!-- langchain4j-community 引入阿里云百炼平台依赖管理清单-->
        <langchain4j-community.version>1.0.1-beta6</langchain4j-community.version>
        <!-- maven plugin -->
        <maven-deploy-plugin.version>3.1.1</maven-deploy-plugin.version>
        <flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version>
        <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
		<!-- <flatten-maven-plugin.version>1.4.1</flatten-maven-plugin.version> -->
    </properties>

    <!-- 子工程不需要写版本号了 -->
    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- Spring AI -->
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- Spring AI Alibaba -->
            <dependency>
                <groupId>com.alibaba.cloud.ai</groupId>
                <artifactId>spring-ai-alibaba-starter</artifactId>
                <version>${spring-ai-alibaba.version}</version>
            </dependency>
            <!-- langchain4j的依赖清单,加载BOM后所有langchain4j版本号可以被统一管理起来
                 参考配置:https://docs.langchain4j.dev/get-started -->
            <dependency>
                <groupId>dev.langchain4j</groupId>
                <artifactId>langchain4j-bom</artifactId>
                <version>${langchain4j.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- 引入阿里云百炼平台依赖管理清单
                 https://docs.langchain4j.dev/integrations/language-models/dashscope -->
            <dependency>
                <groupId>dev.langchain4j</groupId>
                <artifactId>langchain4j-community-bom</artifactId>
                <version>${langchain4j-community.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>${maven-deploy-plugin.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-compiler-plugin.version}</version>
                <configuration>
                    <release>${java.version}</release>
                    <compilerArgs>
                        <compilerArg>-parameters</compilerArg>
                    </compilerArgs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>flatten-maven-plugin</artifactId>
                <version>${flatten-maven-plugin.version}1.3.0</version>
                <inherited>true</inherited>
                <executions>
                    <execution>
                        <id>flatten</id>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>flatten</goal>
                        </goals>
                        <configuration>
                            <updatePomFile>true</updatePomFile>
                            <flattenMode>ossrh</flattenMode>
                            <pomElements>
                                <distributionManagement>remove</distributionManagement>
                                <dependencyManagement>remove</dependencyManagement>
                                <repositories>remove</repositories>
                                <scm>keep</scm>
                                <url>keep</url>
                                <organization>resolve</organization>
                            </pomElements>
                        </configuration>
                    </execution>
                    <execution>
                        <id>flatten.clean</id>
                        <phase>clean</phase>
                        <goals>
                            <goal>clean</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <!-- 如果阿里云下包失败,则去这里下载
         阿里云地址包搜索:https://maven.aliyun.com/mvn/search -->
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
        <repository>
            <id>aliyunmaven</id>
            <name>aliyun</name>
            <url>https://maven.aliyun.com/repository/public</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

有些包如果下载失败时,访问 Maven Central Repository 官网 (search.maven.org) 搜索JAR,搜索结果中常包含阿里云等镜像地址。需要模糊搜索或查看所有可用版本。

阿里云地址搜搜地址:https://maven.aliyun.com/mvn/search

手动下载JAR文件后,需要将其安装到本地Maven仓库,Maven才能识别。使用以下命令安装。

例子:

xml 复制代码
mvn install:install-file 
-Dfile=C:\Users\HW\Desktop\cc\spring-ai-alibaba-starter-1.0.0-M6.1.jar  -- 路径包含文件名称
-DgroupId=com.alibaba.cloud.ai          -- groupId值
-DartifactId=spring-ai-alibaba-starter  -- artifactId值
-Dversion=1.0.0-M6.1                    -- 版本号
-Dpackaging=jar

其他的yml文件与启动类,与之前SpringBoot项目一致,可直接参考我Gitee上的项目即可。

创建基本大模型项目

配置Pom

xml 复制代码
<?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>
    <parent>
        <groupId>cn.good.yan</groupId>
        <artifactId>langchain4j-V5</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>langchain4j-01helloworld</artifactId>
    <name>langchain4j-01helloworld入门案例</name>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- langchain4j-open-ai 基础-->
        <!-- 所有调用均基于 OpenAI 协议标准,实现一致的接口设计与规范LangChain4j 提供与许多 LLM 提供商的集成
             从最简单的开始方式是从 OpenAI 集成开始https://docs.langchain4j.dev/get-started -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-open-ai</artifactId>
        </dependency>
        <!-- langchain4j 高阶-->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j</artifactId>
        </dependency>
        <!-- lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

配置API-key,官方不建议配置明文,需要配置环境变量,配置完需要重启IDEA。

环境变量分别配置千问 的API-key和Deepseek的API-key。

编写大模型配置类

java 复制代码
package cn.good.yan.config;

import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * LLM的配置类
 * System.getenv("aliQwen-api")  获取环境变量里的值
 * 值是API Key,最好加密,放在环境变量中
 * @auther yan
 * @Date 2025-05-27 22:04
 * @Description: 知识出处 https://docs.langchain4j.dev/get-started
 */
@Configuration
public class LLMConfig {
    // 千问大模型
    @Bean
    public ChatModel chatModelQwen() {
        return OpenAiChatModel.builder()
                .apiKey(System.getenv("aliQwen-api"))
                .modelName("qwen3.6-plus")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .build();
    }

    // deepseek大模型,知识出处,https://api-docs.deepseek.com/zh-cn/
    @Bean(name = "deepseek")
    public ChatModel chatModelDeepSeek(){
        return OpenAiChatModel.builder()
                .apiKey(System.getenv("deepseek-api"))
                .modelName("deepseek-chat")
                //.modelName("deepseek-reasoner")
                .baseUrl("https://api.deepseek.com/v1")
                .build();
    }
}

调用大模型:

java 复制代码
package cn.good.yan.controller;

import dev.langchain4j.model.chat.ChatModel;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 多模型共存,
 * 访问1:千问大模型
 * 访问2:Deepseek大模型
 */
@RestController
@Slf4j
public class MultiModelController {

    @Resource(name = "qwen")
    private ChatModel chatModelQwen;

    @Resource(name = "deepseek")
    private ChatModel chatModelDeepSeek;

    // 访问:千问大模型 访问地址: http://localhost:9002/multimodel/qwen
    @GetMapping(value = "/multimodel/qwen")
    public String qwenCall(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt) {
        String result = chatModelQwen.chat(prompt);
        System.out.println("通过langchain4j调用模型返回结果:\n" + result);
        return result;
    }

    // 访问:deepseek大模型 访问地址:http://localhost:9002/multimodel/deepseek
    @GetMapping(value = "/multimodel/deepseek")
    public String deepseekCall(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt) {
        String result = chatModelDeepSeek.chat(prompt);
        System.out.println("通过langchain4j调用模型返回结果:\n" + result);
        return result;
    }

}

如果调用提示这个,代表免费额度是否已用完,需要充值。

json 复制代码
 {"error":{"message":"Insufficient Balance","type":"unknown_error","param":null,"code":"invalid_request_error"}

整合SpringBoot

官网地址:https://docs.langchain4j.dev/tutorials/spring-boot-integration

配置Pom

xml 复制代码
<!-- 1 LangChain4j 整合boot底层支持-->
<dependency>
     <groupId>dev.langchain4j</groupId>
     <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
</dependency>
<!-- 2 LangChain4j 整合boot高阶支持-->
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-spring-boot-starter</artifactId>
</dependency>

yml配置

yml 复制代码
langchain4j.open-ai.chat-model.api-key=${aliQwen-api}
langchain4j.open-ai.chat-model.model-name=qwen3.6-plus
langchain4j.open-ai.chat-model.base-url=https://dashscope.aliyuncs.com/compatible-mode/v1

调用大模型接口:

java 复制代码
@AiService
public interface ChatAssistant {
    String chat(String prompt);
}

进行访问大模型:

java 复制代码
@RestController
public class DeclarativeAIServiceController {
    @Resource
    private ChatAssistant chatAssistantQwen;
    // 访问:千问大模型
    @GetMapping(value = "/lc4j/boot/declarative")
    public String declarative(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt) {
        return chatAssistantQwen.chat(prompt);
    }
}

LangChain4J的低阶与高阶API

官网:https://docs.langchain4j.dev/get-started/

详细介绍API:https://docs.langchain4j.dev/tutorials/chat-and-language-models/

大模型的Token:用来表示自然语言文本的基本单位,也是我们的计费单元,可以直观的理解为"字"或"词";通常1个中文词语、1个英文单词、1个数字或1个符号计为1个token。

Web开发下的Token:在Web开发中,通常指的是用于认证和授权的一种加密字符串。它被用来确保用户身份的安全验证,如:JWT(JSON Web Token)。这类token一般由服务器生成,并发给客户端保存(例如存储在浏览器的本地存储或cookie中),之后每次请求都需要携带这个token来证明用户的身份。

区别:

  • 目的不同:大模型中的token是为了将文本分割成可处理的单元,便于进行计算;而Web开发中的token主要用于安全地传递用户身份信息。

  • 生成方式不同:前者通过特定的算法(如BPE)对文本进行分割得到;后者则通常是通过加密算法生成的唯一字符串。

  • 应用场景不同:前者应用于文本分析、机器翻译等NLP任务;后者多见于用户登录系统、API访问控制等领域。

低阶APIChatModel 是所有大模型入口程序,可以使用原生的这些接口(ChatModel、UserMessage、AiMessage、EmbeddingStore、Embedding等);支持自由组合使用各个组件但编码量比较高。

普通低阶API调用:与上面调用方式一致;

调用Token用量计算

一般情况下模型中 token 和字数的换算比例大致如下:

  • 1个英文字符≈0.3个token
  • 1个中文字符≈0.6个token
java 复制代码
package cn.good.yan.controller;

import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ChatMessageType;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.response.ChatResponse;
import dev.langchain4j.model.output.TokenUsage;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 低阶API,使用
 */
@RestController
@Slf4j
public class LowApiController {

    @Resource(name = "deepseek")
    private ChatModel chatModelQwen;

    /**
     * 普通低阶API调用,访问:deepseek大模型
     * @param prompt
     * @return {@link String }
     */
    @GetMapping(value = "/lowapi/api01")
    public String api01(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt) {
        String result = chatModelQwen.chat(prompt);
        System.out.println("通过langchain4j调用模型返回结果:" + result);
        return result;
    }

    /**
     * 普通低阶API调用,调用Token用量计算,
     * 相关文档:https://api-docs.deepseek.com/zh-cn/quick_start/token_usage
     */
    @GetMapping(value = "/lowapi/api02")
    public String api02(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt) {
        ChatResponse chatResponse = chatModelDeepSeek.chat(UserMessage.from(prompt));
        String result = chatResponse.aiMessage().text();
        System.out.println("通过调用大模型返回结果:" + result);
        TokenUsage tokenUsage = chatResponse.tokenUsage();     // Token 用量计算的底层api
        System.out.println("本次调用消耗的token:" + tokenUsage);
        result = result + "\t\n" + tokenUsage;
        return result;
    }

}

高阶API:程序员自己定义接口,通过AiServices类里面的方法实现,优点是api封装度比较高,减少了代码的复杂性,但仍可以进行灵活的微调。

官网:https://docs.langchain4j.dev/tutorials/ai-services

我们提出了另一种名为 AI 服务的解决方案,专为Java 量身定制。这个想法是将与LLM 和其他组件交互的复杂性隐藏在简单的 API后面。这种方法与 Spring Data JPA 或 Retrofit 非常相似:您以声明方式定义一个具有所需 API 的接口,而LangChain4j 提供了一个实现此接口的对象(代理)。您可以将AI 服务视为应用程序中服务层的一个组件。它提供AI服务。因此得名。

步骤1:定义AI接口

java 复制代码
public interface ChatAssistant {
    String chat(String prompt);
}

步骤2:LLMConfig配置类,调用交给高阶API

java 复制代码
@Configuration
public class LLMConfig {
    @Bean(name = "qwen")
    public ChatModel chatModelQwen() {
        return OpenAiChatModel.builder()
                .apiKey(System.getenv("aliQwen-api"))
                .modelName("qwen-plus")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .build();
    }

    /**
     * @Description: 知识出处,https://api-docs.deepseek.com/zh-cn/
     * @Auther: zzyybs@126.com
     */
    @Bean(name = "deepseek")
    public ChatModel chatModelDeepSeek() {
        return
                OpenAiChatModel.builder()
                        .apiKey(System.getenv("deepseek-api"))
                        .modelName("deepseek-chat")
                        //.modelName("deepseek-reasoner")
                        .baseUrl("https://api.deepseek.com/v1")
                        .build();
    }

    // High-Api(高阶API文档): https://docs.langchain4j.dev/tutorials/ai-services#simplest-ai-service
    // 注意:AiServices是类,@Qualifier("qwen") 指定使用哪个大模型,交给高阶API
    @Bean
    public ChatAssistant chatAssistant(@Qualifier("qwen") ChatModel chatModelQwen) {
        return AiServices.create(ChatAssistant.class, chatModelQwen);
    }

}

步骤3:对应接口调用

java 复制代码
package cn.good.yan.controller;

import cn.good.yan.service.ChatAssistant;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 高阶API,使用 自定义的接口
 */
@RestController
@Slf4j
public class HighApiController {

    // ChatAssistant 是自定义的,而不是ChatModel的
    @Resource
    private ChatAssistant chatAssistant;

    /**
     * 高阶API调用, 访问:千问大模型
     */
    @GetMapping(value = "/highapi/highapi")
    public String highApi(@RequestParam(value = "prompt", defaultValue = "你是谁") String prompt) {
        return chatAssistant.chat(prompt);
    }
    
}

模型参数配置

官网:https://docs.langchain4j.dev/tutorials/model-parameters

SpringBoot官网YML模型配置地址:https://docs.langchain4j.dev/integrations/language-models/open-ai/#spring-boot-1

日志配置

YML配置:只有日志级别调整为debug级别,同时配置以上langchain日志输出开关才有效。

yml 复制代码
# 只有日志级别调整为debug级别,同时配置以上 langchain 日志输出开关才有效
logging.level.dev.langchain4j = DEBUG

配置类:

java 复制代码
@Configuration
public class LLMConfig {
    @Bean(name = "qwen")
    public ChatModel chatModelQwen() {
        return OpenAiChatModel.builder()
                .apiKey(System.getenv("aliQwen-api"))
                .modelName("qwen-plus")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .logRequests(true)    // 日志级别设置为debug才有效
                .logResponses(true)   // 日志级别设置为debug才有效
                .build();
    }
}
监控

官网:https://docs.langchain4j.dev/tutorials/observability/#chat-model-observability

类似:AOP的环绕通知、异常通知

java 复制代码
/**
 * 用于大模型 监控   (自定义的监控器)
 *
 * @author shengren.yan
 * @create 2026/6/17
 * @Description: 知识出处,https://docs.langchain4j.dev/tutorials/spring-boot-integration#observability
 */
@Slf4j
public class TestChatModelListener implements ChatModelListener {

    // 请求:前处理
    @Override
    public void onRequest(ChatModelRequestContext requestContext) {
        // onRequest配置的k:v键值对,在onResponse阶段可以获得,上下文传递参数好用
        String uuidValue = IdUtil.simpleUUID();
        requestContext.attributes().put("TraceID", uuidValue);  // 本次调用的id
        log.info("请求参数requestContext:{}", requestContext + "\t" + uuidValue);
    }

    // 响应:后处理
    @Override
    public void onResponse(ChatModelResponseContext responseContext) {
        Object object = responseContext.attributes().get("TraceID"); // 本次调用的id
        log.info("返回结果responseContext:{}", object);
    }

    // 如果调用过程有异常,走这里:
    @Override
    public void onError(ChatModelErrorContext errorContext) {
        log.error("请求异常ChatModelErrorContext:{}", errorContext);
    }

}

配置类

java 复制代码
@Configuration
public class LLMConfig {
    @Bean(name = "qwen")
    public ChatModel chatModelQwen() {
        return OpenAiChatModel.builder()
                .apiKey(System.getenv("aliQwen-api"))
                .modelName("qwen-plus")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .logRequests(true)    // 日志级别设置为debug才有效
                .logResponses(true)   // 日志级别设置为debug才有效
                .listeners(List.of(new TestChatModelListener()))  // 监听器,(可以有多个)
                .build();
    }
}
重试机制

配置类

java 复制代码
@Configuration
public class LLMConfig {
    @Bean(name = "qwen")
    public ChatModel chatModelQwen() {
        return OpenAiChatModel.builder()
                .apiKey(System.getenv("aliQwen-api"))
                .modelName("qwen-plus")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .logRequests(true)    // 日志级别设置为debug才有效
                .logResponses(true)   // 日志级别设置为debug才有效
                .listeners(List.of(new TestChatModelListener()))  // 监听器,(可以有多个)
                .maxRetries(2)        // 重试2次
                .build();
    }
}
// 如果网络波动,请求失败,会重试2次进行访问大模型。
超时机制

配置类

java 复制代码
@Configuration
public class LLMConfig {
    @Bean(name = "qwen")
    public ChatModel chatModelQwen() {
        return OpenAiChatModel.builder()
                .apiKey(System.getenv("aliQwen-api"))
                .modelName("qwen-plus")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .logRequests(true)    // 日志级别设置为debug才有效
                .logResponses(true)   // 日志级别设置为debug才有效
                .listeners(List.of(new TestChatModelListener()))  // 监听器,(可以有多个)
                .maxRetries(2)        // 重试2次
                .timeout(Duration.ofSeconds(2))  // 访问大模型发送请求时,超过2秒就中断,如在指定时间内没有收到响应,会中断请求,报异常:报request timed out
                .build();
    }
}

多模态视觉理解

官网:https://docs.langchain4j.dev/tutorials/chat-and-language-models#multimodality

如何选择模型:

https://help.aliyun.com/zh/model-studio/models#850732b1aabs0

视觉理解

配置类:

java 复制代码
@Configuration
public class LLMConfig {
    @Bean
    public ChatModel ImageModel() {
        return OpenAiChatModel.builder()
                .apiKey(System.getenv("aliQwen-api"))
                //qwen3-vl-plus 是一个多模态大模型,支持图片和文本的结合输入,适用于视觉-语言任务。
                .modelName("qwen3-vl-plus")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .build();
    }
}

对应接口调用:

java 复制代码
package cn.good.yan.controller;

import dev.langchain4j.data.message.ImageContent;
import dev.langchain4j.data.message.TextContent;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.chat.response.ChatResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Base64;

/**
 * 访问:千问大模型, (视觉理解)
 */
@RestController
@Slf4j
public class ImageModelController {

    @Autowired
    private ChatModel chatModel;

    // 获取 static目录下的图片文件
    @Value("classpath:static/images/mi.jpg")
    private Resource resource; // 来源的包:import org.springframework.core.io.Resource;

    // 访问:千问大模型  : 将图片发送给大模型,并进行分析
    // 通过Base64编码将图片转化为字符串
    @GetMapping(value = "/image/call")
    public String readImageContent() throws IOException {
        String result = null;
        // 1,图片转码:通过Base64编码将图片转化为字符串
        byte[] byteArray = resource.getContentAsByteArray();
        String base64Data = Base64.getEncoder().encodeToString(byteArray);
        // 2,提示词指定:结合ImageContent和TextContent一起发送到模型进行处理。
        UserMessage userMessage = UserMessage.from(
                TextContent.from("从下面图片种获取来源网站名称,股价走势和1月30号股价"),
                ImageContent.from(base64Data, "image/jpg")
        );
        // 3,API调用:使用OpenAiChatModel来构建请求,并通过chat()方法调用模型。
        // 请求内容包括文本提示和图片,模型会根据输入返回分析结果。
        ChatResponse chatResponse = chatModel.chat(userMessage);
        // 4,解析与输出:从ChatResponse中获取AI大模型的回复,打印出处理后的结果。
        result = chatResponse.aiMessage().text();
        return result;
    }
}
通义万相-图像理解

LangChain4J引入第3方平台和自己整合,DashScope (Qwen)

官网:https://docs.langchain4j.dev/integrations/language-models/dashscope

修改父工程POM文件

xml 复制代码
 <!-- langchain4j-community 引入阿里云百炼平台依赖管理清单 (LangChain4J引入第3方平台和自己整合)-->
 <langchain4j-community.version>1.0.1-beta6</langchain4j-community.version>

 <!-- 子工程不需要写版本号了 -->
<dependencyManagement>
    <dependencies>
        <!--引入阿里云百炼平台依赖管理清单
            https://docs.langchain4j.dev/integrations/language-models/dashscope
        -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-community-bom</artifactId>
            <version>${langchain4j-community.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

修改子工程POM文件

xml 复制代码
<!-- DashScope (Qwen)接入阿里云百炼平台
	 https://docs.langchain4j.dev/integrations/language-models/dashscope
-->
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-community-dashscope-spring-boot-starter</artifactId>
</dependency>

通义万相(WanxlmageModel)-官网:https://docs.langchain4j.dev/integrations/language-models/dashscope#configurable-parameters

文生图模型

wanx2.1-t2i-turbo(通义万相)它支持通过一句话生成图像

官网:https://help.aliyun.com/zh/model-studio/text-to-image

修改配置类:

java 复制代码
@Configuration
public class LLMConfig {
    @Bean
    public ChatModel ImageModel() {
        return OpenAiChatModel.builder()
                .apiKey(System.getenv("aliQwen-api"))
                //qwen3-vl-plus 是一个多模态大模型,支持图片和文本的结合输入,适用于视觉-语言任务。
                .modelName("qwen3-vl-plus")
                .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
                .build();
    }

    /**
     * 测试通义万象来实现图片生成,  (文生图模型)
     * wanx2.1-t2i-turbo(通义万相)它支持通过一句话生成图像
     * 知识出处,https://help.aliyun.com/zh/model-studio/text-to-image
     */
    @Bean
    public WanxImageModel wanxImageModel() {
        return WanxImageModel.builder()
                .apiKey(System.getenv("aliQwen-api"))
                .modelName("wanx2.1-t2i-turbo")
                .build();
    }
}

对应接口调用:

java 复制代码
package cn.good.yan.controller;

import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisParam;
import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisResult;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.JsonUtils;
import dev.langchain4j.community.model.dashscope.WanxImageModel;
import dev.langchain4j.data.image.Image;
import dev.langchain4j.model.output.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

/**
 * 访问:千问大模型, (文生图模型)
 */
@RestController
@Slf4j
public class WanxImageModelController {

    // 通义万相-大模型
    @Autowired
    private WanxImageModel wanxImageModel;

    // 访问:通义万相大模型  : 文生图,通过一句话生成图像
    // 1. 访问地址:http://localhost:9005/image/create2
    @GetMapping(value = "/image/create2")
    public String createImageContent2() throws IOException {
        System.out.println(wanxImageModel);
        // 生成一个美女图片
        Response<Image> imageResponse = wanxImageModel.generate("美女");
        System.out.println(imageResponse.content().url());
        return imageResponse.content().url().toString(); // 返回的图片的url地址,浏览器可以下载该图片
    }

    // 访问:通义万相大模型  : 文生图,通过一句话生成图像(生成复杂图片)
    // 1. 访问地址:http://localhost:9005/image/create3
    @GetMapping(value = "/image/create3")
    public String createImageContent3() throws IOException {
        String prompt = "近景镜头,18岁的中国女孩,古代服饰,圆脸,正面看着镜头," +
                "民族优雅的服装,商业摄影,室外,电影级光照,半身特写,精致的淡妆,锐利的边缘。";
        ImageSynthesisParam param =
                ImageSynthesisParam.builder()
                        .apiKey(System.getenv("aliQwen-api")) // api的key
                        .model(ImageSynthesis.Models.WANX_V1)
                        .prompt(prompt)  // 提示词
                        .style("<watercolor>")
                        .n(1)
                        .size("1024*1024")  // 大小
                        .build();
        ImageSynthesis imageSynthesis = new ImageSynthesis();
        ImageSynthesisResult result = null;
        try {
            System.out.println("---sync call, please wait a moment----");
            result = imageSynthesis.call(param);
        } catch (ApiException | NoApiKeyException e) {
            throw new RuntimeException(e.getMessage());
        }
        System.out.println(JsonUtils.toJson(result));
        return JsonUtils.toJson(result);
        // 返回的是json对象,results下的url里的内容,是图片地址,浏览器可以下载该图片
    }
}