背景
无疑最近的最火的技术就是大模型,作为一个传统的java 程序,如何接入大模型呢?
要使用spring ai项目,必须使用jdk17,所以前提必须jdk升级下
直接上代码
pom文件 引入依赖
加入了TTS(文字转语音) 和STT(语音识别),没有需要的话,可以去掉
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>ai-openai-helloworld</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ai-openai-helloworld</name>
<description>Simple AI Application using OpenAPI Service</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-server-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>io.github.whitemagic2014</groupId>
<artifactId>tts-edge-java</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version> <!-- 最新稳定版 -->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alphacephei</groupId>
<artifactId>vosk</artifactId>
<version>0.3.45</version> <!-- 检查最新版本 -->
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.24</version>
</dependency>
<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>
<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>central-portal-snapshots</id>
<name>Central Portal Snapshots</name>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
application.yml 配置文件
需要向deepseek 申请api key
spring: ai: # DeepSeek配置 # 或OpenAI配置 deepseek: api-key: 你的apikey base-url: https://api.deepseek.com/v1 chat: options: model: deepseek-chat max-tokens: 1000 server: servlet: encoding: charset: UTF-8 enabled: true
MyTools.java 使用大模型的tool属性,让大模型理解,并回调这些函数
模型可能会调用的 tool 的列表。目前,仅支持 function 作为工具。使用此参数来提供以 JSON 作为输入参数的 function 列表。最多支持 128 个 function。
package org.example.tools;
import cn.hutool.core.util.RandomUtil; import lombok.extern.log4j.Log4j2; import org.springframework.ai.tool.annotation.Tool; import org.springframework.context.i18n.LocaleContextHolder;
import java.time.LocalDateTime;
@Log4j2 public class MyTools { @Tool(description = "以用户时区,获取时间和日期") String getCurrentDateTime() { return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString(); }
@Tool(description = "打开或者关闭的某个地方的灯,第一个参数地方:比如:卧室,第二参数操作灯的状态,比如: 打开关闭") void switchLamp(String place, String state) { log.info("place:{},state:{}", place, state); } @Tool(description = "获取一个随机数,参数为数字类型的长度") String getRandom(Integer len) { return RandomUtil.randomString(len); }
}
AiApplication.java 启动类
package org.example;
import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.deepseek.DeepSeekChatModel; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean;
import java.io.IOException;
@SpringBootApplication public class AiApplication {
public static void main(String[] args) throws IOException { SpringApplication.run(AiApplication.class, args); } @Bean public ChatClient openAiChatClient(DeepSeekChatModel chatModel) { return ChatClient.create(chatModel); }
}
ChatController.java 测试类入口
package org.example.controller;
import jakarta.annotation.Resource; import org.example.tools.MyTools; import org.springframework.ai.chat.client.ChatClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;
@RestController public class ChatController {
@Resource private ChatClient chatClient; // 统一接口支持 OpenAI/DeepSeek/通义千问等:cite[2]:cite[7] @GetMapping(value = "/stream") public Object generateText(@RequestParam("text") String text) { return chatClient.prompt() .user(u -> u.text(text)).tools(new MyTools()).call().content(); }
}
测试
- http://localhost:8080/stream?text=昨天是几号
昨天是2025年6月13日。
2.http://localhost:8080/stream?text=下个星期3是几号
下个星期三(2025年6月18日)是18号。
- http://localhost:8080/stream?text=给我一个10位的随机数
生成的10位随机数是:5r9N8QxKoL
- http://localhost:8080/stream?text=生成一个5位的随机数和一个3位的随机数
生成的随机数如下: - 5位随机数:q4LIj
- 3位随机数:Gdw
- http://localhost:8080/stream?text=打开卧室的灯
place:卧室,state:打开
卧室的灯已经打开了。 - http://localhost:8080/stream?text=关闭卧室和客厅的灯
2025-06-14T21:41:01.211+08:00 INFO 2727 --- [nio-8080-exec-6] org.example.tools.MyTools : place:卧室,state:关闭
2025-06-14T21:41:01.213+08:00 INFO 2727 --- [nio-8080-exec-6] org.example.tools.MyTools : place:客厅,state:关闭
卧室和客厅的灯已经关闭。
总结
spring ai+ spring boot,可以做很多事情,完全可以颠覆传统开发模式,一种新的革命开始了