SpringAI入门:轻松集成AI模型到Spring生态!
首先依旧是简单介绍一下:SpringAI就是在Spring生态中集成人工智能能力,提供标准化的接口,支持开发者通过配置切换不同 AI 服务提供商。
最近在学习SpringAI相关的技术,之前也接触过一些,但并不是系统的了解和学习,今天分享一些个人学习的心得,也是个人整理出来的SpringAI的入门教程吧。话不多说,开始分享!
一、介绍
首先依旧是简单介绍一下:
SpringAI就是在Spring生态中集成人工智能能力,提供标准化的接口,支持开发者通过配置切换不同 AI 服务提供商。
二、准备
因为会演示SpringAI的优势,所以需要准备多个AI服务,分别感受。也可以不做,至少需要有一个。
1.DeepSeek模型
首先去官网 https://www.deepseek.com/ ,进入API开放平台,并进行登录。

点击API keys 进行命名创建,key要保存好后续会使用。刚开始注册会给体验金额的,如果早就注册但没有使用过可能是过期了,我就是,充了10块钱,自己用能用很久的。


2.Ollama模型
直接去ollama官网,Ollama,下载ollama。下载慢就去找教程就行很多的。

下载后试着安装几个ollama模型,首先要确认好自己电脑的显卡和内存配置。可以让AI给你智能推荐。我下了这几个模型,我的电脑没有独显就选一些小模型。

三、SpringAI使用
1.依赖引入(Spring Boot Starter)
<?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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.5</version>
<relativePath/>
</parent>
<groupId>com.Luoyi</groupId>
<artifactId>AITest</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<spring-ai.version>1.0.0</spring-ai.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- DeepSeek -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-deepseek</artifactId>
</dependency>
<!--Ollama -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
<!--会话记忆-->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-autoconfigure-model-chat-memory</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.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>
</plugin>
</plugins>
</build>
</project>
2.配置文件
- api-key 配置你自己的key
- model 可以更换deepseek的模型(deepseek-reasoner模型是深度思考模型)
- temperature 是模型温度,模型温度越低模型输出越规矩、稳定,温度越高输出越多变、富有惊喜,通常是0.5~0.8
- maxTokens 可以理解为字数上限,这个值越低消耗的token就越少,不过太低回答会被截断
- stop 就是输出截断,可以设置输出一行截断,输出敏感词截断等等
- base-url ollama的默认访问地址就是配置中的地址无需修改
spring:
ai:
#deepseek模型配置
deepseek:
api-key: deepseek-key
chat:
options:
model: deepseek-chat #deepseek模型
temperature: 0.5 #模型温度
max-tokens: 1000 #字数上限
stop:
- "党" #敏感词
#ollama模型配置
ollama:
chat:
model: gemma3:4b #ollama模型
base-url: http://localhost:11434
3.调用模型
DeepSeek模型
(1) 直接调用
创建一个测试类进行演示
@SpringBootTest
public class DeepseekTest {
@Autowired
private DeepSeekChatModel chatModel;
@Test
public void testChat(){
String call = chatModel.call("你是谁?");
System.out.println( call );
}
}
运行结果:
(2) 流式输出
我们平常使用AI时的输出都是几个字几个字输出而不是一下子全出来的
@Test
public void testChat2() {
Flux<String> stream = chatModel.stream("你是谁?");
// 阻塞输出
stream.toIterable().forEach(System.out::print);
}
(3) 思考推理
使用AI时会有深度思考或推理的功能如下:

通过代码进行演示:
@Test
public void deepSeekReasonerExample() {
Prompt prompt = new Prompt("讲一个睡前故事。");
ChatResponse res = chatModel.call(prompt);
DeepSeekAssistantMessage assistantMessage = (DeepSeekAssistantMessage)res.getResult().getOutput();
//思考
String reasoningContent = assistantMessage.getReasoningContent();
//内容
String content = assistantMessage.getText();
System.out.println("思考:" + reasoningContent);
System.out.println("===============================================");
System.out.println("回答:" + content);
}
如果没有切换思考模型就会没有思考只有输出:

在配置文件中切换模型:
spring:
ai:
#deepseek模型配置
deepseek:
chat:
options:
model: deepseek-reasoner #思考模型

也可进行流式输出:
@Test
public void deepSeekReasonerStreamExample() {
Prompt prompt = new Prompt("讲个睡前故事。");
Flux<ChatResponse> stream = chatModel.stream(prompt);
stream.toIterable().forEach(res -> {
DeepSeekAssistantMessage assistantMessage = (DeepSeekAssistantMessage)res.getResult().getOutput();
String reasoningContent = assistantMessage.getReasoningContent();
System.out.print(reasoningContent);
});
System.out.println("===============================================");
stream.toIterable().forEach(res -> {
DeepSeekAssistantMessage assistantMessage = (DeepSeekAssistantMessage)res.getResult().getOutput();
String content = assistantMessage.getText();
System.out.print(content);
});
}
Ollama模型
(1) 直接调用 流式输出
Ollama的响应响应速度取决你的配置,如果你的电脑配置不好使用的还是参数大的模型响应自然就慢,使用小模型响应就较快。
@SpringBootTest
public class OllamaTest {
@Test
public void Ollamatest(@Autowired OllamaChatModel chatModel){
String call = chatModel.call("你是谁?");
System.out.println( call );
}
@Test
public void testStream() {
Flux<String> stream = chatModel.stream("你是谁?");
// 阻塞输出
stream.toIterable().forEach(System.out::println);
}
}
(2) 多模态
这里我们选用能进行图片识别的进行测试,在ollama的模型中找到可以识别图片的模型或有视觉能力,就是 vision ,我这选用gemma3:4b 模型(大的带不动),这个模型对于手写的识别很一般,当然也是因为参数小换个大的就会好很多。

代码和示例图片如下:
@Test
public void testMultimodality() {
// 加载类路径下的图片资源
var imageResource = new ClassPathResource("img.png");
// 创建Media对象,指定图片的MIME类型为PNG
Media media = new Media(MimeTypeUtils.IMAGE_PNG, imageResource);
// 调用OllamaChatModel的多模态接口,传入图片和文本提示
ChatResponse response = chatModel.call(
new Prompt(
UserMessage.builder()
.media(media)
.text("识别图片")
.build()
)
);
// 输出结果
System.out.println(response.getResult().getOutput().getText());
}

运行结果:

使用ChatClient
使用ChatClient的优点:
1. 统一 API:简化不同模型的调用方式。
2. 多模型支持:动态切换 DeepSeek、Ollama 等模型。
3. 流式响应:支持实时数据流(如 `Flux`)。
4. Spring 集成:依赖注入和测试友好。
5. 代码简洁:链式调用,减少样板代码。
(1) ChatClient不能自动选择模型
当有多个模型时,直接使用chatclient会报错,因为没有默认设置模型。
@SpringBootTest
public class ChatClientTest {
/**
* @Description: 多模型无法自动选择
* @param builder
* @return void
*/
@Test
public void testChatClient(ChatClient.Builder builder) {
ChatClient chatClient = builder.build();
String content = chatClient.prompt()
.user("你是谁?")
.call()
.content();
System.out.println( content );
}
}
(2) ChatClient调用不同模型
@SpringBootTest
public class ChatClientTest {
@Autowired
private DeepSeekChatModel deepSeekChatModel;
@Autowired
private OllamaChatModel ollamaChatModel;
/**
* @Description: 指定模型deepseek
* @param
* @return void
*/
@Test
public void testChatOptions() {
ChatClient chatClient = ChatClient.builder(deepSeekChatModel).build();
String content = chatClient.prompt()
.user("你是谁")
.call()
.content();
System.out.println(content);
}
/**
* @Description: 模型ollama
* @param
* @return void
*/
@Test
public void testChatOptions1() {
ChatClient chatClient = ChatClient.builder(ollamaChatModel).build();
String content = chatClient.prompt()
.user("你是谁")
.call()
.content();
System.out.println(content);
}
/**
* @Description: 阻塞输出
* @param
* @return void
*/
@Test
public void testChatStream(){
ChatClient chatClient = ChatClient.builder(deepSeekChatModel).build();
Flux<String> content = chatClient.prompt()
.user("你能告诉我2025年1月ai界的大事吗")
.stream()
.content();
//阻塞输出
content.toIterable().forEach(System.out::print);
}
}
四、AIDemo
通过上面的了解我使用ChatClient做一个小Demo,主要实现切换不同的模型,后续会对这个Demo进行升级。
1.配置ChatClient
在application中增加日志配置
logging:
level:
org.springframework.ai.chat.client.advisor: debug # AI对话的日志级别
创建AIConfig配置类,其中.defaultAdvisors(new SimpleLoggerAdvisor()) 是增加了一个日志输出。
package com.Luoyi.config;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.ai.deepseek.DeepSeekChatOptions;
import org.springframework.ai.deepseek.api.DeepSeekApi;
import org.springframework.ai.model.ollama.autoconfigure.OllamaChatProperties;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.ai.ollama.api.OllamaApi;
import org.springframework.ai.ollama.api.OllamaOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Luoyi
* @description: 模型配置
*/
@Configuration
public class AIConfig {
@Autowired
private DeepSeekChatModel deepSeekChatModel;
@Autowired
private OllamaApi ollamaApi;
@Autowired
private OllamaChatProperties options;
/**
* @Description: deepseek模型
* @param
* @return org.springframework.ai.chat.client.ChatClient
*/
@Bean
public ChatClient deepseek(){
return ChatClient.builder(deepSeekChatModel)
.defaultAdvisors(new SimpleLoggerAdvisor())//记录日志
.build();
}
/**
* @Description: 本地ollama模型
* @param
* @return org.springframework.ai.chat.client.ChatClient
*/
@Bean
public ChatClient ollama() {
OllamaChatModel ollamaChatModel = OllamaChatModel.builder()
.ollamaApi(ollamaApi)
.defaultOptions(OllamaOptions.builder().model(options.getModel()).build())
.build();
return ChatClient.builder(ollamaChatModel)
.defaultAdvisors(new SimpleLoggerAdvisor())//记录日志
.build();
}
}
再编写一个控制类根据传入不同的参数使用不同的模型
@Controller
public class MultiModelsController {
//注册ChatClient的bean
@Autowired
private Map<String, ChatClient> chatClientMap;
/**
* @Description: 模型对话流式输出
* @param message 消息
* @param model 指定模型
* @return reactor.core.publisher.Flux<java.lang.String>
*/
@RequestMapping(value = "/chat", produces = "text/html;charset=utf-8")
Flux<String> generation(@RequestParam String message,
@RequestParam String model) {
ChatClient chatClient = chatClientMap.get(model);
Flux<String> content = chatClient.prompt()//创建聊天请求对象
.user(message)//设置用户输入信息
.stream()//开启流式响应并获取内容
.content();
return content;
}
}
运行结果:


五、后续会继续更新增加对话记忆(内存、redis和数据库存储)、会话隔离、使用工具和AIDemo升级等等
更多推荐


所有评论(0)