news 2026/7/22 11:17:10

Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)

最近在学习 Java AI 应用开发,先用 Spring Boot 搭了一个最小项目,完成了大模型调用,然后在这个基础上继续接入 AI Service 和 Tool Calling。

这篇文章记录整个实现过程,也把中间遇到的几个配置问题整理出来。

本文最终实现的效果是:

用户发送自然语言请求 ↓ Spring Boot 接收请求 ↓ 大模型判断是否需要调用工具 ↓ LangChain4j 执行指定的 Java 方法 ↓ 工具返回业务数据 ↓ 大模型整理后回复用户

目前使用固定数据模拟查询,后续可以把 Tool 接到 Service、MyBatis 和 MySQL。


一、项目环境

本文使用的环境如下:

JDK 17 Spring Boot 3.5.x Maven LangChain4j 1.18.0-beta28

一开始使用的是:

JDK 8 Spring Boot 2.6.13

项目可以正常启动,但无法正常使用当前版本的 LangChain4j Spring Boot Starter,自动配置也没有生效。因此学习项目建议直接使用 JDK 17 和 Spring Boot 3。


二、创建 Spring Boot 项目

创建一个 Maven 类型的 Spring Boot 项目,依赖先选择:

Spring Web

项目创建后,确认pom.xml中的 Java 版本为 17:

<properties> <java.version>17</java.version> </properties>

完整的核心依赖如下:

<dependencies> <!-- Spring MVC、Controller、内置 Tomcat --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- OpenAI 兼容模型支持 --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId> <version>1.18.0-beta28</version> </dependency> <!-- AI Service、Tool Calling 等 Spring 集成能力 --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-spring-boot-starter</artifactId> <version>1.18.0-beta28</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>

这两个 LangChain4j 依赖的作用不同。

langchain4j-open-ai-spring-boot-starter

负责读取模型配置并创建ChatModel

langchain4j-spring-boot-starter

负责支持@AiService、Tool Calling 等更高层能力。

添加完成后,刷新 Maven 依赖。


三、配置大模型

在下面位置创建配置文件:

src/main/resources/application.yml

配置内容如下:

server: port: 8080 langchain4j: open-ai: chat-model: base-url: http://langchain4j.dev/demo/openai/v1 api-key: demo model-name: gpt-4o-mini temperature: 0.3 log-requests: true log-responses: true

几个配置项需要分开理解。

base-url

base-url: http://langchain4j.dev/demo/openai/v1

这是模型服务的接口地址,不是具体模型。

api-key

api-key: demo

这是接口调用凭证。当前使用的是演示配置,只适合本地学习。

model-name

model-name: gpt-4o-mini

这一项才是具体使用的模型名称。

整体关系可以理解为:

base-url:请求发到哪个模型服务 api-key:用什么凭证调用 model-name:具体调用哪个模型

四、先完成最简单的模型调用

创建 Controller:

package com.hsw.langchain4jdemo.controller; import dev.langchain4j.model.chat.ChatModel; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/ai") public class AiController { private final ChatModel chatModel; public AiController(ChatModel chatModel) { this.chatModel = chatModel; } @GetMapping("/chat") public String chat(@RequestParam String message) { return chatModel.chat(message); } }

启动项目后访问:

http://localhost:8080/api/ai/chat?message=请介绍一下Java

如果可以正常返回内容,说明下面这条链路已经打通:

Controller ↓ ChatModel ↓ LangChain4j ↓ 大模型接口 ↓ 返回文本

ChatModel 是什么

ChatModel并不是大模型本身,而是 LangChain4j 对聊天模型能力定义的统一接口。

代码中注入的是:

ChatModel chatModel

Spring 容器中实际创建的对象一般是对应模型的具体实现,例如:

OpenAiChatModel

可以类比:

List<String> list = new ArrayList<>();

List是接口,ArrayList是具体实现。

ChatModel的作用就是屏蔽不同模型服务之间的请求细节,让业务代码统一使用:

chatModel.chat(message);

五、使用 AI Service

直接调用ChatModel适合验证模型连接,但后面要做系统提示词、对话记忆、Tool Calling 和 RAG,通常会使用 AI Service。

创建接口:

com.hsw.langchain4jdemo.assistant.Assistant

代码如下:

package com.hsw.langchain4jdemo.assistant; import dev.langchain4j.service.SystemMessage; import dev.langchain4j.service.spring.AiService; @AiService public interface Assistant { @SystemMessage(""" 你是一名Java学习助手。 回答尽量准确、清晰。 遇到不确定的数据时不要编造。 """) String chat(String message); }

这里没有编写AssistantImpl

LangChain4j 会在项目启动时为这个接口创建代理对象,并把它注册到 Spring 容器中。

调用过程类似:

Assistant 接口 ↓ LangChain4j 动态代理 ↓ ChatModel ↓ 大模型

Controller 可以改成:

package com.hsw.langchain4jdemo.controller; import com.hsw.langchain4jdemo.assistant.Assistant; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/ai") public class AiController { private final Assistant assistant; public AiController(Assistant assistant) { this.assistant = assistant; } @GetMapping("/assistant") public String assistant(@RequestParam String message) { return assistant.chat(message); } }

测试地址:

http://localhost:8080/api/ai/assistant?message=线程池是什么

六、添加第一个 Tool

普通模型只能根据已有知识生成内容,无法直接查询项目中的数据库或业务接口。

例如用户输入:

帮我查询用户1001的信息

模型并不知道项目里的用户数据。如果直接回答,很可能会编造。

Tool Calling 的作用就是让模型在需要真实数据时,调用后端提供的 Java 方法。

创建工具类:

com.hsw.langchain4jdemo.tool.UserTool

代码如下:

package com.hsw.langchain4jdemo.tool; import dev.langchain4j.agent.tool.Tool; import org.springframework.stereotype.Component; @Component public class UserTool { @Tool("根据用户ID查询用户信息") public String queryUser(Long userId) { // 暂时使用固定数据模拟数据库查询 if (Long.valueOf(1001L).equals(userId)) { return """ 用户ID:1001 用户名:张三 年龄:25 会员等级:黄金会员 """; } return "没有找到对应的用户"; } }

这里的@Tool不是 Controller 接口,也不要求它是 HTTP 接口。

它就是一个普通 Java 方法,只不过通过@Tool告诉大模型:

系统拥有一个根据用户ID查询用户信息的能力

真实项目中一般会写成:

UserTool ↓ UserService ↓ UserMapper ↓ MySQL

例如:

@Component public class UserTool { private final UserService userService; public UserTool(UserService userService) { this.userService = userService; } @Tool("根据用户ID查询用户信息") public UserDTO queryUser(Long userId) { return userService.getById(userId); } }

七、把 Tool 注册到 AI Service

修改Assistant

package com.hsw.langchain4jdemo.assistant; import dev.langchain4j.service.SystemMessage; import dev.langchain4j.service.spring.AiService; @AiService( tools = "userTool" ) public interface Assistant { @SystemMessage(""" 你是一个用户信息查询助手。 查询用户信息时必须调用工具, 不允许自行编造用户数据。 """) String chat(String message); }

这里写的是:

tools = "userTool"

而不是:

tools = UserTool.class

因为当前版本中,tools属性接收的是 Spring Bean 名称。

工具类是:

@Component public class UserTool

Spring 默认会把它注册成:

userTool

所以 AI Service 中填写:

tools = "userTool"

如果手动指定 Bean 名称:

@Component("userQueryTool") public class UserTool { }

对应配置也需要改成:

@AiService( tools = "userQueryTool" )

八、测试 Tool Calling

启动项目后访问:

http://localhost:8080/api/ai/assistant?message=帮我查询用户1001的信息

完整流程如下:

用户输入: 帮我查询用户1001的信息 ↓ Assistant 接收消息 ↓ 大模型分析用户意图 ↓ 模型决定调用 queryUser ↓ LangChain4j 执行 UserTool.queryUser(1001) ↓ Java 方法返回用户数据 ↓ 工具结果再次交给大模型 ↓ 大模型整理后返回最终答案

需要注意,大模型并没有直接执行 Java 方法。

实际分工是:

大模型:决定调用哪个工具以及传递什么参数 LangChain4j:解析调用请求并执行 Java 方法 Java 业务代码:真正查询数据库或调用业务服务

九、wiringMode 是什么

在配置 AI Service 时,可能会看到下面这种写法:

@AiService( wiringMode = AiServiceWiringMode.EXPLICIT, tools = "userTool" )

wiringMode控制 AI Service 的依赖如何装配。

自动装配

默认情况下,LangChain4j 会从 Spring 容器中查找合适的模型和其他依赖。

@AiService( tools = "userTool" )

对于当前只有一个ChatModel的学习项目,使用自动装配比较简单。

显式装配

wiringMode = AiServiceWiringMode.EXPLICIT

表示不再自动选择,而是要求开发人员明确指定所使用的模型、工具等 Bean。

它适合以下场景:

项目中存在多个 ChatModel 不同 Agent 使用不同模型 不同 Agent 只能使用指定工具 需要严格控制依赖关系

如果写了:

wiringMode = AiServiceWiringMode.EXPLICIT

却只指定了 Tool,没有指定 ChatModel,就可能出现:

Please specify either chatModel or streamingChatModel

对于当前项目,直接删除EXPLICIT,使用自动装配即可:

@AiService( tools = "userTool" )

十、常见问题

1. 找不到 ChatModel Bean

报错:

required a bean of type 'dev.langchain4j.model.chat.ChatModel' that could not be found

优先检查以下内容。

配置文件是否放在:

src/main/resources/application.yml

配置前缀是否正确:

langchain4j: open-ai: chat-model:

依赖是否使用了 Starter:

<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>

而不是只添加普通的模型依赖。

还需要检查 JDK、Spring Boot 和 LangChain4j 版本是否匹配。


2. tools 属性类型错误

错误写法:

@AiService( tools = UserTool.class )

IDEA 会提示需要String[],实际提供的是Class<UserTool>

正确写法:

@AiService( tools = "userTool" )

这里填写的是 Spring Bean 名称。


3. 提示必须指定 chatModel

报错:

Please specify either chatModel or streamingChatModel

通常是因为使用了:

wiringMode = AiServiceWiringMode.EXPLICIT

但没有明确指定模型。

初学阶段可以先使用自动装配:

@AiService( tools = "userTool" )

4. 找不到名为 chatModel 的 Bean

报错:

required a bean named 'chatModel' that could not be found

通常是手动写了:

chatModel = "chatModel"

这里要求 Spring 容器里必须存在一个名称正好为chatModel的 Bean。

但自动配置生成的模型 Bean 不一定叫这个名字。

如果当前只有一个模型,直接删除 Bean 名称配置,让 LangChain4j 按类型自动装配更合适。


十一、当前项目结构

完成后,项目结构大致如下:

src/main/java/com/hsw/langchain4jdemo ├── LangChain4jDemoApplication.java ├── assistant │ └── Assistant.java ├── controller │ └── AiController.java └── tool └── UserTool.java src/main/resources └── application.yml

当前调用关系:

AiController ↓ Assistant ↓ ChatModel ↓ 大模型 ↓ 判断是否调用 UserTool ↓ UserTool ↓ 返回业务数据 ↓ 大模型生成最终回答

十二、这算不算 Agent

只调用:

chatModel.chat(message);

属于普通的大模型接入,还不能算 Agent。

加入 Tool Calling 后,模型已经可以:

理解用户需求 选择工具 生成工具参数 获取工具执行结果 根据结果继续回答

这已经具备了基础 Agent 能力。

不过距离完整业务 Agent 还有一些内容:

多轮对话记忆 多个工具连续调用 数据库真实查询 RAG 知识库 权限校验 高风险操作二次确认 幂等控制 工具调用日志 异常重试和超时处理

下一步可以把当前的固定用户数据替换成:

Spring Boot + MyBatis-Plus + MySQL + UserTool

让模型真正查询数据库中的用户信息。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/22 11:13:45

TM4C1292NCZAD模拟比较器:从原理到实战的嵌入式电压监控方案

1. 项目概述与核心价值在嵌入式系统开发&#xff0c;尤其是涉及模拟信号监控、电源管理或电机控制的场景里&#xff0c;我们经常需要判断一个电压是否超过了某个预设的阈值。你可能会想到用一颗外部的电压比较器芯片&#xff0c;比如LM393&#xff0c;配合电阻分压网络来实现。…

作者头像 李华
网站建设 2026/7/22 11:13:22

乙方外包考PMP,真的能顺利转甲方吗?2026职场大实话

做IT外包、项目乙方的小伙伴&#xff0c;心里大概率都藏着同一个终极目标&#xff1a;早日逃离乙方&#xff0c;跳槽进甲方。谁不想摆脱无休止的加班、甲方随意提需求、出问题先背锅的窘境&#xff1f;谁不想换个节奏稳定、话语权更强、发展更稳的工作&#xff1f;但很多人熬了…

作者头像 李华
网站建设 2026/7/22 11:12:08

数据分析能力怎么证明?别再只写一句 “熟练 Excel”

运营、市场、销售、HR、财务等业务人想靠数据分析加分跳槽&#xff0c;简历上一句单薄的 “熟练 Excel” 早已失去竞争力。HR 每天浏览数十份简历&#xff0c;几乎人人都会标注 Office 技能&#xff0c;无法区分你只会基础制表&#xff0c;还是能用数据 AI 解决业务问题。在 A…

作者头像 李华
网站建设 2026/7/22 11:09:48

AI移动工作站怎么选最好

AI工作站笔记本选购全指南&#xff1a;从需求匹配到硬件避坑&#xff0c;一文选对AI生产力本 随着本地大模型部署、AI绘画、视频AI生成、AI代码开发、模型微调、智能体搭建等需求爆发&#xff0c;普通轻薄本、游戏本已经很难胜任长时间AI算力负载&#xff0c;AI工作站笔记本成为…

作者头像 李华
网站建设 2026/7/22 11:09:38

springboot贵州行

Spring Boot贵州行选题背景贵州省作为中国西南地区的重要省份&#xff0c;近年来在数字经济、大数据产业、乡村振兴、文化旅游等领域取得了显著成就。随着国家“西部大开发”和“数字中国”战略的深入推进&#xff0c;贵州凭借得天独厚的自然条件、政策优势和产业布局&#xff…

作者头像 李华
网站建设 2026/7/22 11:09:26

EDMA3链接传输机制详解:实现乒乓与循环缓冲的自动化数据流

1. 项目概述 在嵌入式系统开发&#xff0c;尤其是涉及实时信号处理、高速数据采集或流媒体传输的场景里&#xff0c;如何高效、稳定地搬运数据&#xff0c;同时最大限度地解放CPU&#xff0c;是每个工程师都会面临的挑战。直接内存访问&#xff08;DMA&#xff09;技术是解决这…

作者头像 李华