Spring AI 2.x 全面指南:架构升级、工具调用、多模型生态与实战示例
让 AI 应用开发回归本质:统一接口,自由切换,一次编码,驱动全球大模型。
目录
2. 🗄️ Redis “史诗级”增强:从缓存到智能记忆引擎
实战示例:Spring AI 2.x + DeepSeek + Tool + Advisor
Spring AI 对 Function Calling 的支持演进
🌐 Spring AI 2.x:构建多模型智能应用的终极框架
Spring AI 最新版本概览
截至 2026 年 2 月,Spring AI 的最新里程碑版本为:
2.0.0-M2(发布于 2026 年 1 月)
⚙️ 技术栈要求
- Java 21(强制要求,不再支持 Java 17)
- Spring Boot 4.0.1
- Spring Framework 7.0
💡 重要提示:由于底层架构重构,Spring AI 2.x 与 Spring Boot 3.x 不兼容,不可混合使用。
✨ 主要更新亮点
- API 空安全:引入 JSpecify 规范,提升 API 健壮性。
- 存储扩展:新增对 Amazon S3、Infinispan 等向量存储的支持。
- 缓存增强:支持基于 Redis 的语义缓存,显著降低重复查询成本。
- 模型能力升级:
- Mistral AI 与 Ollama 支持 结构化输出(JSON Schema)
- 工具调用(Tool Calling)机制全面增强
🛑 生产建议:当前仍推荐使用 1.1.0 GA 版本,待 2.0 正式版(GA)发布后再迁移。
Spring AI 2.x 有哪些重大升级?
Spring AI 2.x 不是渐进式迭代,而是一次面向 AI 原生时代的架构重构,旨在解决企业级 AI 应用的性能、成本与复杂度问题。
1. 🚀 底层架构全面升级:拥抱 Java 21
| 项目 | 说明 |
|---|---|
| 最低 JDK | Java 21(虚拟线程、Pattern Matching 等特性可用) |
| 生态基座 | Spring Boot 4.0 + Spring Framework 7.0 |
| 性能红利 | 利用 虚拟线程(Virtual Threads) 提升高并发 LLM 调用效率;支持 AOT 编译 加速启动 |
2. 🗄️ Redis “史诗级”增强:从缓存到智能记忆引擎
- Redis Chat Memory:跨会话上下文持久化,支持全文检索。
- Redis Vector Store:
- 新增 文本搜索 + 范围查询
- 暴露 HNSW 索引参数(如
M,efConstruction),可精细调优召回率 vs 延迟
- 语义缓存顾问:自动识别语义相似请求,复用结果,节省 API 调用成本
✅ Redis 在 Spring AI 2.x 中已可部分替代专用向量数据库。
3. 🤖 模型能力与工具调用全面进化
| 厂商 | 升级亮点 |
|---|---|
| OpenAI | 集成官方 Java SDK;默认模型升级为 gpt-5-mini |
| Anthropic Claude | 支持 4.5 版本: • Citations API(回答可溯源) • Files API(生成可下载文件) |
| Google Gemini | 新增 ThinkingConfig,动态调节“思考深度” |
| Mistral / Ollama | 原生支持 结构化 JSON 输出,确保类型安全 |
工具调用增强:
- 支持 运行时动态修改工具 Schema
- 新增
conversationHistoryEnabled选项,精细控制上下文逻辑
4. 🛡️ API 设计规范与空安全
- 全面采用 JSpecify 空安全规范
- 编译期即可检测空指针风险
- Kotlin 开发者受益:获得真正的可空/非空类型支持
5. ⚠️ 破坏性变更(迁移注意)
| 变更项 | 说明 |
|---|---|
temperature 配置 |
移除默认值,必须显式配置,否则报错 |
| 默认模型 | OpenAI 从 gpt-4 → gpt-5-mini,行为可能变化 |
| 注解体系 | @Function → @Tool(见下文) |
实战示例:Spring AI 2.x + DeepSeek + Tool + Advisor
1. Maven 依赖配置 (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
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>4.0.0</version>
<relativePath/>
</parent>
<groupId>com.wx.ai.learn</groupId>
<artifactId>ai-learn</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ai-learn</name>
<properties>
<java.version>21</java.version>
<spring-ai.version>2.0.0-M2</spring-ai.version>
</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-openai</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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
</project>
2. 工具调用示例(@Tool 替代 @Function)
定义工具类
/*
* Copyright (c) 2026 the original author or authors. All rights reserved.
*
* @author wangxu
* @since 2026
*/
package com.wx.ai.learn.tool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Component;
import java.util.Random;
/**
* @author wangxu
* @version 1.0
* @date 2026/2/12
* @description 天气工具类
*/
@Component
public class WeatherTool {
private static final Logger LOGGER = LoggerFactory.getLogger(WeatherTool.class);
final int[] temperatures = {-125, 15, -255};
private final Random random = new Random();
/**
* 获取天气信息
*
* @param location 位置
* @return 答案
*/
@Tool(description = "Get the current weather for a given location")
public String weather(String location) {
LOGGER.info("WeatherTool called with location: {}", location);
int temperature = temperatures[random.nextInt(temperatures.length)];
System.out.println(">>> Tool Call responseTemp: " + temperature);
return "The current weather in " + location + " is sunny with a temperature of " + temperature + "°C.";
}
}
Tool注册
/*
* Copyright (c) 2026 the original author or authors. All rights reserved.
*
* @author wangxu
* @since 2026
*/
package com.wx.ai.learn.config;
import com.wx.ai.learn.advisor.MyLoggingAdvisor;
import com.wx.ai.learn.advisor.SelfRefineEvaluationAdvisor;
import com.wx.ai.learn.tool.WeatherTool;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
public class AiConfig {
@Bean
@Primary // 设置为默认,不加 Qualifier 时优先选这个
public ChatClient chatClient(ChatClient.Builder builder) {
return builder.defaultSystem("You are a helpful assistant.").defaultAdvisors().build();
}
@Bean
public ChatClient weatherChatClient(ChatClient.Builder builder, // 注入 Spring Boot 自动配置的 Builder 基础实例
ChatModel chatModel) {
// 在此处集中配置通用的工具、顾问和模型
return builder.defaultSystem("你是一个专业的气象助手。").defaultTools(new WeatherTool()) // 注册工具类
.defaultAdvisors(
// 1. 自我修正评估顾问(使用本地 Ollama 模型进行评估)
SelfRefineEvaluationAdvisor.builder().chatClientBuilder(ChatClient.builder(chatModel)).maxRepeatAttempts(15).successRating(4).order(0).build(),
// 2. 自定义日志顾问
new MyLoggingAdvisor(2)).build();
}
}
Service 调用模型
/*
* Copyright (c) 2026 the original author or authors. All rights reserved.
*
* @author wangxu
* @since 2026
*/
package com.wx.ai.learn.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class WeatherService {
private static final Logger LOGGER = LoggerFactory.getLogger(WeatherService.class);
private final ChatClient genericClient;
private final ChatClient weatherClient;
// 通过 @Qualifier 指定 Bean 的名称
public WeatherService(
@Qualifier("chatClient") ChatClient genericClient,
@Qualifier("weatherChatClient") ChatClient weatherClient) {
this.genericClient = genericClient;
this.weatherClient = weatherClient;
}
public String doWork(String city) {
//没有使用工具
String common = genericClient.prompt("你好").call().content();
//使用工具
String weather = this.weatherClient
.prompt("请查询 " + city + " 的天气,并友好地回复用户。")
.call()
.content();
LOGGER.info("common response: {}", common);
LOGGER.info("weather response: {}", weather);
return common + weather;
}
}
Controller 使用
/*
* Copyright (c) 2026 the original author or authors. All rights reserved.
*
* @author wangxu
* @since 2026
*/
package com.wx.ai.learn.cotroller;
import com.wx.ai.learn.service.AiService;
import com.wx.ai.learn.service.WeatherService;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
@RestController
@RequestMapping("/ai")
public class AiController {
private static final Logger LOGGER = LoggerFactory.getLogger(AiController.class);
@Resource
private AiService aiService;
@Resource
private WeatherService weatherService;
private final OpenAiChatModel chatModel;
@Autowired
public AiController(OpenAiChatModel chatModel) {
this.chatModel = chatModel;
}
@GetMapping("/weather")
public String weather(@RequestParam(value = "city", defaultValue = "Paris") String city) {
return weatherService.doWork(city);
}
@GetMapping(value = "/generateStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ChatResponse> generateStream(
@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return chatModel.stream(new Prompt(new UserMessage(message)));
}
}
3. Advisor 机制详解
Advisor(顾问) 是 Spring AI 的核心增强能力,借鉴 AOP 思想,专为 LLM 交互设计。
✅ 核心价值
- 无侵入性:业务代码无需感知
- 横切关注点解耦:日志、记忆、RAG、安全等
- 责任链模式:可插拔、可排序
内置 Advisor 类型
表格
| 类型 | 说明 |
|---|---|
MessageChatMemoryAdvisor |
保留完整消息结构,适合多轮对话 |
VectorStoreChatMemoryAdvisor |
超长历史对话支持(突破 token 限制) |
QuestionAnswerAdvisor |
自动 RAG 检索增强 |
SimpleLoggerAdvisor |
请求/响应日志记录 |
SelfRefineEvaluationAdvisor |
LLM-as-a-Judge 闭环评估 |
自定义 Advisor 示例
/*
* Copyright (c) 2026 the original author or authors. All rights reserved.
*
* @author wangxu
* @since 2026
*/
package com.wx.ai.learn.advisor;
import org.springframework.ai.chat.client.ChatClientRequest;
import org.springframework.ai.chat.client.ChatClientResponse;
import org.springframework.ai.chat.client.advisor.api.AdvisorChain;
import org.springframework.ai.chat.client.advisor.api.BaseAdvisor;
import org.springframework.ai.model.ModelOptionsUtils;
public class MyLoggingAdvisor implements BaseAdvisor {
private final int order;
public MyLoggingAdvisor(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
@Override
public ChatClientRequest before(ChatClientRequest chatClientRequest, AdvisorChain advisorChain) {
print("REQUEST", chatClientRequest.prompt().getInstructions());
return chatClientRequest;
}
@Override
public ChatClientResponse after(ChatClientResponse chatClientResponse, AdvisorChain advisorChain) {
print("RESPONSE", chatClientResponse.chatResponse().getResults());
return chatClientResponse;
}
private void print(String label, Object object) {
System.out.println(label + ":" + ModelOptionsUtils.toJsonString(object) + "\n");
}
}
💡 使用建议
- 合理设置
order:安全校验优先,日志最后 - 避免过度堆叠(≤5 个)
- 流式响应中慎用阻塞操作
- 生产环境使用 Redis/DB 替代 InMemoryChatMemory
4. 配置文件 (application.yml)
spring:
application:
name: ai-learn
ai:
openai:
api-key: ${OPENAI_API_KEY}
base-url: https://api.deepseek.com # 👈 关键!代理地址
chat:
options:
model: deepseek-chat
temperature: 0.7
5. 迁移注意事项
| 旧版 (1.x) | 新版 (2.x) |
|---|---|
@Function |
→ @Tool |
FunctionCallback |
→ 废弃,直接使用注解方法 |
| 配置前缀 | 统一至 spring.ai.* |
Spring AI 2.x 中工具方法的识别机制
Spring AI 2.x 采用 “声明 + 自动发现” 模式,实现零注册、开箱即用的工具集成。
🔍 识别流程四步走
-
声明身份
使用@Tool(description = "...")标记方法,定义其名称、参数、用途。 -
纳入容器
工具类需标注@Component/@Service,成为 Spring Bean。 -
自动注册
ChatClient初始化时,扫描所有 Bean,提取@Tool方法并转换为 JSON Schema。 -
运行时调用
LLM 返回工具调用指令 → Spring AI 解析 → 反射调用对应 Java 方法。
🧩 示例:JSON Schema 生成
{
"name": "getWeather",
"description": "获取指定城市的天气预报",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string", "description": "城市名称" }
},
"required": ["location"]
}
}
✅ 核心思想:开发者只需关注业务逻辑,框架自动完成“Java ↔ LLM”桥接。
Spring AI 对 Function Calling 的支持演进
| 版本阶段 | 支持方式 | 状态 |
|---|---|---|
| 旧版 (≤ 1.0.0-M5) |
原生 FunctionCallback、defaultFunctions() |
✅ 稳定,但已过时 |
| 过渡版 (1.0.0-M6 ~ 1.1.x) |
Function Calling 标记为 @Deprecated |
⚠️ 兼容但不推荐 |
| 新版 (≥ 2.0.0-M1) |
全面采用 Tool Calling(@Tool) |
✅ 官方推荐 |
📌 版本组合建议
| 场景 | 推荐组合 |
|---|---|
| 旧项目维护 | Spring Boot 3.2.x + Spring AI 0.8.1 |
| 新项目开发 | Spring Boot 4.0.x + Spring AI 2.0.0-M2 |
🌐 Spring AI 2.x:构建多模型智能应用的终极框架
统一接口,自由切换 —— 一套代码,驱动全球大模型。
🧠 一、国际主流商业大模型
| 厂商 | 模型示例 | 核心增强 |
|---|---|---|
| OpenAI | gpt-5-mini, gpt-4-turbo |
官方 SDK + 流式 + 工具调用 |
| Anthropic | Claude 4.5 Opus/Haiku | Citations API + Files API |
| Gemini 1.5 Pro/Flash | ThinkingConfig + 多模态 | |
| Mistral | Mixtral, Mistral Large | 结构化 JSON 输出 |
| Azure | Azure OpenAI | 企业合规 + 私有网络支持 |
🇨🇳 二、国产大模型(重点支持)
| 厂商 | 模型 | 接入方式 |
|---|---|---|
| 阿里云 | Qwen-Max/Plus/VL | 灵积平台 API |
| 智谱 AI | GLM-4, GLM-3-Turbo | 原生 API |
| 百度 | ERNIE-Bot 4.0 | 千帆平台 |
| 月之暗面 | Moonshot | 超长上下文(128K+) |
| DeepSeek | DeepSeek-V2/Coder | OpenAI 兼容代理 |
🖥️ 三、开源与本地部署模型
- Ollama:本地运行 Llama 3、Qwen、Mistral,通过 OpenAI 兼容 API 对接
- Hugging Face:调用 HF Inference Endpoints
- 高性能平台:Groq(低延迟)、NVIDIA NIM(GPU 加速)
🎨 四、多模态与专用能力
| 能力 | 支持服务 | 接口 |
|---|---|---|
| 文生图 | DALL·E 3, Stable Diffusion | ImageModel |
| 语音合成(TTS) | ElevenLabs | AudioModel |
| 语音识别(ASR) | Google Gemini | 音频输入支持 |
| 向量存储(RAG) | Redis, Milvus, Pinecone | VectorStore + EmbeddingModel |
💡 选型建议
| 场景 | 推荐方案 |
|---|---|
| 快速原型 | OpenAI (gpt-5-mini) 或 Ollama (Llama 3) |
| 中文生产 | Qwen-Max / GLM-4 |
| 长文本处理 | Claude 4.5 / Moonshot |
| 低成本 + 隐私 | Ollama + Qwen-7B(本地部署) |
⚙️ 开发体验:一行配置,无缝切换
spring:
ai:
openai:
api-key: ${API_KEY}
chat:
options:
model: qwen-max # ← 仅改此处,即可切换模型!
✅ 无需修改业务代码,真正实现“模型即插即用”。
✅ 总结
Spring AI 2.x 是面向未来的 AI 应用基础设施,它通过:
- 统一抽象接口(
ChatClient,EmbeddingModel...) - 深度模型集成(国内外 + 开源 + 多模态)
- 企业级能力增强(Redis 记忆、语义缓存、结构化输出)
帮助开发者:
- 专注业务逻辑,而非模型细节
- 自由选择模型,避免厂商锁定
- 平滑演进架构,从原型到生产无缝过渡
更多推荐



所有评论(0)