1.简介
Spring AI 是 Spring 框架在⼈⼯智能领域的延伸,它旨在帮助开发者更⾼效地构建和部署 AI 应⽤。作为 Spring ⽣态系统的⼀部分,Spring AI 继承了 Spring 框架的诸多优点,如轻量级、松耦合、易于测试等,同时为 AI 应⽤开发提供了专⻔的⽀持和优化。
Spring AI 的核⼼理念是提供⾼度抽象化的组件,作为开发 AI 应⽤程序的基础。这些抽象化组件 具备多种实现,使得开发者能够以最少的代码改动便捷地交换和优化功能模块。 具体⽽⾔, Spring AI 提供了⽀持多种主流模型提供商的功能,包括 OpenAI 、 Microsoft 、 Amazon 、 Google 和 Hugging Face 。⽀持的模型类型涵盖了从聊天机器⼈到⽂本⽣成、图像处 理、语⾳识别等多个领域。⽽其跨模型提供商的可移植 API 设计,不仅⽀持同步和流式接⼝,还提 供了针对特定模型功能的灵活选项。 此外, Spring AI 还⽀持将 AI 模型输出映射为 POJO ,以及与主流向量数据库提供商⽆缝集成的 能⼒。其功能不仅局限于模型本身,还包括了数据⼯程中的 ETL 框架和各种便利的函数调⽤,使得 开发 AI 应⽤程序变得更加⾼效和可靠。
2.应用场景
⾃然语⾔处理
Spring AI 提供了丰富的⾃然语⾔处理⼯具,开发⼈员可以利⽤这些⼯具来处理⽂本数据、执⾏情 感分析、实现语⾳识别等功能。例如,你可以使⽤ Spring AI 构建⼀个智能客服系统,⾃动回答⽤ 户的问题,提⾼客户服务效率。
图像生成
在图像⽣成与处理⽅⾯, Spring AI 同样发挥着重要作⽤。以设计和⼴告⾏业为例,设计师可以利 ⽤ Spring AI 集成图像⽣成模型,如 OpenAI 的 DALL - E 模型或 StableDiffusion 模型。当 设计师需要为⼀个新产品设计宣传海报时,只需输⼊相关的⽂字描述,如 "⼀张充满科技感的智能⼿ 机宣传海报,⼿机位于画⾯中⼼,周围环绕着蓝⾊的光线和抽象的科技元素",模型就能快速⽣成相 应的图像。这不仅⼤⼤节省了设计时间,还能为设计师提供更多的创意灵感,帮助他们快速将创意转 化为视觉图像。
数据分析与预测
在⾦融⾏业,利⽤ Spring AI 可以快速构建⻛险评估模型。通过集成机器学习模型,如逻辑回归、 决策树等,对⽤户的信⽤数据、交易数据等进⾏分析,预测⽤户的信⽤⻛险,为⾦融机构的贷款审 批、信⽤卡发放等业务提供决策⽀持。 在电商领域, Spring AI 可以帮助企业进⾏销售预测。通过分析历史销售数据、⽤户⾏为数据、市 场趋势数据等,使⽤时间序列分析模型、神经⽹络等,预测未来的销售情况,帮助企业合理安排库 存、制定营销策略。
知识图谱和智能问答
在智能搜索场景中,利⽤ Spring AI 构建知识图谱,将各种领域的知识进⾏结构化表示。当⽤户输 ⼊查询关键词时,系统不仅能够进⾏传统的⽂本匹配搜索,还能通过知识图谱理解关键词的语义和相 关知识,提供更精准、全⾯的搜索结果。在智能客服场景中,知识图谱可以帮助客服机器⼈更好地理 解⽤户问题,结合图谱中的知识和业务逻辑,给出更准确、智能的回答。 例如,在⼀个电⼦产品售后客服场景中,当⽤户询问某款⼿机的电池续航问题时,客服机器⼈可以通 过知识图谱快速定位到该⼿机型号的电池参数、续航优化建议等相关知识,为⽤户提供详细的解决⽅ 案。
3.入门案例
基于 Spring AI 与 Ollama 的 DeepSeek-R1 构建本地 API 服务。开发代码前请务必启动 Ollama 。
SpringBoot 的版本建议为 3.5.3 。
3.1引入依赖
创建springai父类导入父类依赖
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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.3</version>
<relativePath/>
</parent>
<groupId>com.jiazhong.mingxing.ai</groupId>
<artifactId>jiazhong-ai</artifactId>
<packaging>pom</packaging>
<modules>
<module>ai-ollama-deepseek</module>
<module>ai-siliconflow-glm</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.boot.version>3.5.3</spring.boot.version>
<spring.ai.version>1.0.0</spring.ai.version>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
创建子项目引入依赖
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>com.jiazhong.mingxing.ai</groupId>
<artifactId>jiazhong-ai</artifactId>
<version>3.5.3</version>
</parent>
<groupId>com.jiazhong.mingxing.ai.ollama.deepseek</groupId>
<artifactId>ai-ollama-deepseek</artifactId>
<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>
<!--本地依赖-->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>
</dependencies>
</project>
3.2配置yml文件
XML
server:
port: 8001 //端口号
spring:
application:
name: ai-ollama-deepseek //大模型名字(复制)
ai:
ollama:
base-url: http://localhost:11434 //大模型端口号(默认)
chat:
model: deepseek-r1:7b //大模型下载版本
options:
temperature: 0.7 //温度 越低越准确
模型温度 温度参数( Temperature )是控制模型输出随机性的⼀个数值,其取值范围为0到2。以下是 温度参数的核心作用:
- 低温(接近0):模型输出更确定、保守,适合需要精准回答的任务。
- 中温(接近1):模型输出在确定性和创造性之间取得平衡,适合通⽤任务。
- ⾼温(接近2):模型输出更随机、多样化,适合需要⾼创意或灵活性的任务。
通俗理解:
- 温度=0:模型会选择最可能的回答,输出⾮常确定。
- 温度=1:模型会在多种可能的回答中随机选择,输出较为平衡。
- 温度=2:模型会尝试更多⾮主流的选择,输出更具创意和多样性。
3.3创建配置类
创建config包,编写ChatClientConfig类
java
package com.jiazhong.mingxing.ai.ollama.deepseek.config;
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//对话客户端
@Configuration
public class ChatClientConfig {
@Resource
private OllamaChatModel ollamaChatModel;
@Bean("ollamaChatClient")
public ChatClient ollamaChatModel(){
//return ChatClient.builder(ollamaChatModel).build();
return ChatClient.create(ollamaChatModel).mutate().build();
}
@Bean("ollamaChatClient1")
public ChatClient ollamaChatClient2(ChatClient.Builder chatClientBuilder){
return chatClientBuilder.build();
}
}
3.4编写控制类
创建controller包,编写DeepseekController类
java
package com.jiazhong.mingxing.ai.ollama.deepseek.controller;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
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;
import reactor.core.publisher.Flux;
@Slf4j
@RestController
@RequestMapping("/deepseek")
public class DeepseekController {
@Resource
private ChatClient ollamaChatClient;
@Resource
private ChatModel ollamaChatModel;
//流式输出 ChatClient
@GetMapping(value = "/stream",produces = "text/html;charset=utf-8")
public Flux<String> stream(@RequestParam("question") String question){
return ollamaChatClient.prompt()
.user(question)//问题 你要给大模型提交的问题
.stream().content();//以流式返回内容
}
//普通输出 ChatClient(二次封装,二次优化的)
@GetMapping(value = "/call",produces = "text/html;charset=utf-8")
public String call(@RequestParam("question") String question){
return ollamaChatClient.prompt()//链式
.user(question)//问题 你要给大模型提交的问题
.call().content();//以流式返回内容
}
//流式输出 ChatModel(和大模型直接对接)
@GetMapping(value = "/stream2",produces = "text/html;charset=utf-8")
public Flux<String> stream2(@RequestParam("question") String question){
return ollamaChatModel.stream(question);//把对象封装起来
}
//普通输出 ChatModel
@GetMapping(value = "/call2",produces = "text/html;charset=utf-8")
public String call2(@RequestParam("question") String question){
return ollamaChatModel.call(question);
}
//流式输出 ChatModel(和大模型直接对接)
@GetMapping(value = "/stream3",produces = "event/stream;charset=utf-8")
public Flux<ChatResponse> stream3(@RequestParam("question") String question){
Flux<ChatResponse> responseFlux = ollamaChatClient.prompt().user(question).stream().chatResponse();
log.info("result:{}",responseFlux);
return responseFlux;
}
//普通输出 ChatModel
@GetMapping(value = "/call3",produces = "text/html;charset=utf-8")
public ChatResponse call3(@RequestParam("question") String question){
ChatResponse chatResponse = ollamaChatClient.prompt().user(question).call().chatResponse();
log.info("chartResponse:{}",chatResponse);
return chatResponse;
}
}
3.5编写启动类
java
package com.jiazhong.mingxing.ai.ollama.deepseek;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AiOllamaDeepseekApplication {
public static void main(String[] args) {
SpringApplication.run(AiOllamaDeepseekApplication.class,args);
}
}
3.6运行结果
1.普通返回效果

- 流式返回效果

4.两个常用类
在 Spring AI 框架中, ChatModel 和 ChatClient 都可以实现⼤模型的⽂本⽣成功能,例如聊天 机器⼈,但⼆者是两种不同层级的 API 封装,分别针对不同的开发场景和需求设计。
4.1功能定位
ChatModel 类
直接与具体的⼤语⾔模型进⾏交互,提供基础的 call() 和 stream() ⽅法,⽤于同步或流 式调⽤模型,具体使⽤如下。
java
String result1 = chatModel.call(message);
Flux<String> result2 = chatModel.stream(message);
它的特点是:使⽤简单、灵活性⾼。但需要开发者⼿动处理提示词组装、响应解析、参数配置 等细节,适合处理简单的⼤模型交互场景。
ChatClient 类
基于 ChatModel 构建,功能强⼤、开发效率⾼,通过流式 API 隐藏底层复杂性,提供链式调⽤的便捷接⼝,具体使⽤如下。
java
String result1 = chatClient.prompt().user(message).call().content();
Flux<String> result2 =
chatClient.prompt().user(message).stream().content();
核心功能对比
|--------|--------------------|-----------------------------------------|
| 维度 | ChatModel | ChatClient |
| 交互⽅式 | 直接调⽤模型,需⼿动处理 请求/响应 | 链式调⽤,⾃动封装提示词和解析响应 |
| 功能扩 展 | 弱 | 强,内置 Advisor 机制(如对话历史管理、 RAG) |
| 结构化 输出 | 需⼿动解析响应⽂本 | ⽀持⾃动映射为 Java 对象(如 entity(Recipe.class)) |
| 适⽤场 景 | 实现简单功能和场景 | 快速开发复杂功能的场景,如企业级智能客服、 连接外部⼯具等 |
两者并⾮互斥,实际项⽬中可混合使⽤,例如⽤ ChatModel 处理常规请求,⽽通过注⼊ ChatClient 实现复杂场景。
4.2ChatClient 详解
Spring AI 1.0 的核⼼是 ChatClient 接⼝,这是⼀个可移植且易于使⽤的 API ,是与 AI 模型 交互的主要接⼝。它⽀持调⽤ 20 多种 AI 模型,从 Anthropic 到 ZhiPu AI ,并⽀持多模态输⼊ 和输出(当底层模型⽀持时)以及结构化响应(通常以 JSON 格式,便于应⽤程序处理输出)。
- ⾃动装配⽅式
java
@Configuration
public class AiClientConfig {
@Bean
public ChatClient chatClient(ChatClient.Builder chatClientBuilder) {
return chatClientBuilder.build();
}
}
- 编程式⽅式
java
@Configuration
public class AiClientConfig {
@Bean(name = "ollamaChatClient")
public ChatClient ollamaClient(OllamaChatModel ollamaChatModel) {
return ChatClient.builder(ollamaChatModel).build();
}
}
4.3ChatClient 的响应
1.返回 ChatResponse
来⾃ AI 模型的响应是⼀个由 ChatResponse 类型定义的丰富结构。它包括有关响应如何⽣ 成的元数据,并且还可以包含多个响应,每个响应都有⾃⼰的元数据。元数据包括⽤于创建响 应的令牌数量(每个令牌约等于 3/4 个单词)。此信息很重要,因为托管的 AI 模型根据每 个请求使⽤的令牌数量收费。 下⾯通过调⽤ call() ⽅法后的 chatResponse() ⽅法展示了⼀个返回包含元数据的 ChatResponse 对象的示例。
java
ChatResponse chatResponse = ollamaChatClient.prompt()
.user("介绍⼀下宝鸡⽂理学院")
.call()
.chatResponse();

2.返回⽂本
直接返回响应的⽂本信息,其实就是返回 ChatResponse 的 textContent 属性
java
String content = ollamaChatClient.prompt()
.user("介绍⼀下宝鸡⽂理学院")
.call()
.content();
3.流式响应
返回流式的响应信息,可以是⽂本信息,也可以是 ChatResponse 对象。
java
Flux<String> result1 = ollamaChatClient.prompt()
.user("介绍⼀下宝鸡⽂理学院")
.stream()
.content();
Flux<ChatResponse> result2 = ollamaChatClient.prompt()
.user("介绍⼀下宝鸡⽂理学院")
.stream()
.chatResponse();
4.4背景设定
可以发现,当我们询问 AI 你是谁的时候,它回答⾃⼰是 DeepSeek-R1 ,这是⼤模型底层的设定。 如果我们希望 AI 按照新的设定⼯作,就需要给它设置 System 背景信息。 在 SpringAI 中,设置 System 信息⾮常⽅便,不需要在每次发送时封装到 Message ,⽽是创建 ChatClient 时指定即可。
java
@Bean(name = "ollamaChatClient")
public ChatClient chatClient() {
return ChatClient.builder(ollamaChatModel)
.defaultSystem("你是张三,来⾃于宝鸡⽂理学院。请以⼤学⽣的幽默欢快的语⽓说
话")
.build();
}
