【Spring AI -01】Spring AI 2.0 架构重构深度解析:从单体核心到模块化领域的演进

Spring AI 2.0 架构重构深度解析:从单体核心到模块化领域的演进

一、架构重构的背景与必要性

Spring AI 2.0并非简单的版本号迭代,而是一次架构哲学的根本转变。在1.x时代,Spring AI采用相对集中的单体架构设计,随着AI模型生态的爆发式增长(从大语言模型到嵌入模型、从图像生成到向量存储),原有的spring-ai-core包已膨胀至难以维护的地步。

Spring AI 2.0.0-M1版本彻底摒弃了单体模式,转而采用领域驱动模块化(Domain-Driven Modularization)策略,将AI能力按技术边界拆分为五个核心领域模块。这一重构不仅契合Spring Boot 4.0自身的模块化趋势,更为企业级AI应用提供了更精细的依赖治理能力。

二、模块化架构的核心依赖链

Spring AI 2.0的模块设计遵循严格的分层依赖原则,底层模块禁止向上依赖,形成清晰的无环有向图(DAG)。以下是核心模块的依赖拓扑结构:

md 复制代码
┌─────────────────────────────────────────────────────────────┐
│                     应用层 (Application)                      │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │   RAG应用     │  │   ChatClient │  │  Function    │       │
│  │   模块        │  │   应用层      │  │  Call应用    │       │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘       │
└─────────┼─────────────────┼─────────────────┼───────────────┘
          │                 │                 │
          ▼                 ▼                 ▼
┌─────────────────────────────────────────────────────────────┐
│                客户端抽象层 (Client Abstraction)               │
│              spring-ai-client-chat (对话客户端)                │
│                   依赖: spring-ai-model                       │
└──────────────────────────┬──────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│                模型抽象层 (Model Abstraction)                  │
│                spring-ai-model (核心模型接口)                  │
│                  依赖: spring-ai-commons                      │
└──────────────────────────┬──────────────────────────────────┘
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│                基础设施层 (Infrastructure)                     │
│              spring-ai-commons (基础工具与接口)                 │
│                    零外部依赖 (Zero Dependencies)               │
└─────────────────────────────────────────────────────────────┘
                           ▲
                           │
┌──────────────────────────┴──────────────────────────────────┐
│                存储抽象层 (Storage Abstraction)                │
│           spring-ai-vector-store (向量存储抽象)                │
│              依赖: spring-ai-commons                          │
└─────────────────────────────────────────────────────────────┘

关键设计约束:

  • spring-ai-commons作为唯一的基础层,禁止依赖任何上层模块
  • spring-ai-model仅依赖commons,定义ChatModel/EmbeddingModel等核心接口
  • spring-ai-client-chat依赖model层,提供ChatClient的Fluent API实现
  • Vector Store模块独立存在,通过Advisor机制与Client层桥接

三、领域模块的职责边界与定位

模块名称 Maven坐标 职责边界 是否必须
spring-ai-commons org.springframework.ai:spring-ai-commons 定义AI领域的通用领域模型(Message、Prompt、Media等),提供跨模型的可复用数据结构 是(所有模块依赖)
spring-ai-model org.springframework.ai:spring-ai-model 定义模型调用抽象接口(ChatModelEmbeddingModelImageModel),实现可移植的Options模式 是(核心依赖)
spring-ai-client-chat org.springframework.ai:spring-ai-client-chat 提供ChatClient及Advisor机制,支持函数调用、多模态、RAG等高级功能 否(仅高级应用需要)
spring-ai-vector-store org.springframework.ai:spring-ai-vector-store 统一向量数据库的CRUD抽象,支持PgVector、Redis、Milvus等实现 否(RAG场景需要)
spring-ai-advisors-vector-store org.springframework.ai:spring-ai-advisors-vector-store 桥接ChatClient与Vector Store,实现QuestionAnswerAdvisor等RAG组件 否(显式RAG需要)

架构师视角解读:

这种拆分使得仅使用基础模型调用能力的应用无需引入client-chat层的复杂性。例如,一个仅需调用OpenAI API进行简单问答的微服务,只需依赖spring-ai-model和具体模型实现(如spring-ai-openai),而不必引入整个Client生态。

四、Jakarta EE 11 基线迁移与兼容性

Spring AI 2.0将技术基线全面迁移至Jakarta EE 11 + Spring Boot 4.0 GA + Spring Framework 7.0,这对企业现有系统产生深远影响:

4.1 强制性环境要求

md 复制代码
┌──────────────────────────────────────────────────────┐
│                  基线版本对比                         │
├──────────────────┬──────────────────┬────────────────┤
│     组件         │   Spring AI 1.x  │  Spring AI 2.0 │
├──────────────────┼──────────────────┼────────────────┤
│   Java版本       │      17+         │   21(强制)    │
│   Spring Boot    │     3.x          │   4.0 GA       │
│   Spring Framework│     6.x         │   7.0          │
│   Jakarta EE     │     9/10         │   11           │
│   Servlet        │     6.0          │   6.1          │
│   JPA            │     3.1          │   3.2          │
└──────────────────┴──────────────────┴────────────────┘

迁移红利:

  • 虚拟线程(Virtual Threads):默认启用,单个线程可承载数万AI对话会话
  • AOT编译优化:Native Image支持AI模型的提前编译,启动速度提升3-5倍
  • GraalVM 25:统一可达性元数据格式,减少反射配置复杂度

4.2 破坏性变更清单

包命名空间迁移(关键变更):

java 复制代码
// 1.x 旧包路径(已废弃)
import org.springframework.ai.transformer.KeywordMetadataEnricher;
import org.springframework.ai.model.Content;

// 2.x 新包路径
import org.springframework.ai.chat.transformer.KeywordMetadataEnricher;
import org.springframework.ai.content.Content;

Starter命名规范变更:

xml 复制代码
<!-- 1.x 旧坐标 -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>

<!-- 2.x 新坐标(遵循Spring Boot 4模块化规范) -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

配置属性重命名:

properties 复制代码
# 1.x
spring.ai.openai.include-prompt=true
spring.ai.chat.memory.redis.ttl=3600

# 2.x
spring.ai.openai.log-prompt=true
spring.ai.chat.memory.repository.redis.ttl=3600

五、依赖注入范式:ChatModel vs 旧版ModelClient

Spring AI 2.0最核心的API重构在于调用范式的分层。旧版ModelClient被彻底重命名为ChatModel,而新的ChatClient则成为基于ChatModel的高级封装层。

5.1 架构分层模型

md 复制代码
┌─────────────────────────────────────────────────────────────┐
│                     ChatClient (高级API)                     │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  职责:Fluent API、Advisor链、函数调用、多模态支持       │  │
│  │  定位:应用层开发首选,类似RestClient/WebClient         │  │
│  └───────────────────────────────────────────────────────┘  │
└───────────────────────────┬─────────────────────────────────┘
                            │ 组合
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                     ChatModel (基础API)                      │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  职责:模型调用的可移植抽象,call(Prompt)/stream(Prompt)│  │
│  │  定位:基础设施层,类似JDBC的DataSource                 │  │
│  └───────────────────────────────────────────────────────┘  │
└───────────────────────────┬─────────────────────────────────┘
                            │ 实现
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                  OpenAiChatModel / OllamaChatModel           │
│                       (具体模型实现)                          │
└─────────────────────────────────────────────────────────────┘

5.2 编程范式对比

ChatModel模式(基础层):

适合需要精细控制或轻量级集成的场景,如简单的HTTP接口代理。

java 复制代码
@RestController
public class SimpleChatController {
    
    @Autowired
    private ChatModel chatModel;  // 直接注入基础接口
    
    @GetMapping("/simple-chat")
    public String chat(@RequestParam String message) {
        // 函数式调用,一行代码完成
        return chatModel.call(message);
    }
    
    @GetMapping(value = "/stream-chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> stream(@RequestParam String message) {
        // 流式响应直接返回
        return chatModel.stream(message);
    }
}

ChatClient模式(应用层):

适合复杂对话管理、RAG、函数调用等企业级场景。

java 复制代码
@Service
public class AdvancedChatService {
    
    private final ChatClient chatClient;
    
    // 通过构造器注入并配置默认选项
    public AdvancedChatService(ChatModel chatModel) {
        this.chatClient = ChatClient.builder(chatModel)
            .defaultOptions(ChatOptions.builder()
                .model("gpt-4")
                .temperature(0.7)
                .maxTokens(2000)
                .build())
            .build();
    }
    
    public String chatWithMemory(String sessionId, String message) {
        return chatClient.prompt()
            .system("你是资深Java架构师助手")  // 系统提示
            .user(message)                         // 用户输入
            .advisors(new MessageChatMemoryAdvisor( // 记忆Advisor
                new InMemoryChatMemory(), 
                sessionId, 
                10
            ))
            .functions("queryOrderStatus")         // 函数调用
            .call()
            .content();
    }
}

5.3 选型决策树

md 复制代码
是否需要函数调用/工具使用?
├── 是 → 必须使用 ChatClient
│         └── 是否需要多轮对话记忆?
│               ├── 是 → ChatClient + MessageChatMemoryAdvisor
│               └── 否 → ChatClient + 默认配置
└── 否 → 是否需要RAG/向量检索?
          ├── 是 → ChatClient + QuestionAnswerAdvisor
          └── 否 → 性能敏感?
                    ├── 是 → ChatModel (减少一层代理开销)
                    └── 否 → ChatClient (更好的可维护性)

六、多模块Maven配置与依赖排除策略

在Spring AI 2.0的多模块架构下,合理的依赖管理是避免传递依赖地狱的关键。

6.1 典型项目依赖配置

xml 复制代码
<properties>
    <java.version>21</java.version>
    <spring-boot.version>4.0.0</spring-boot.version>
    <spring-ai.version>2.0.0-M1</spring-ai.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring-boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <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>

<dependencies>
    <!-- 基础模型能力(必须) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-model</artifactId>
    </dependency>
    
    <!-- OpenAI模型实现(按需) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-openai</artifactId>
    </dependency>
    
    <!-- 高级客户端API(可选,但推荐) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-client-chat</artifactId>
    </dependency>
    
    <!-- 向量存储(RAG场景) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-vector-store-redis</artifactId>
    </dependency>
</dependencies>

6.2 依赖排除实战场景

场景一:排除特定模型实现,避免starter传递依赖

当使用自定义的ChatModel实现(如内部私有大模型)时,需要排除默认的OpenAI依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-client-chat</artifactId>
    <exclusions>
        <!-- 排除默认的OpenAI自动配置 -->
        <exclusion>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-openai-spring-boot-autoconfigure</artifactId>
        </exclusion>
    </exclusions>
</dependency>

场景二:解决vector-store与client-chat的循环依赖风险

虽然官方已消除包之间的循环依赖,但在复杂项目中仍需注意:

java 复制代码
@Configuration
@ConditionalOnClass({VectorStore.class, ChatClient.class})
public class RAGConfiguration {
    
    // 显式通过方法参数注入,而非字段注入,避免初始化顺序问题
    @Bean
    public QuestionAnswerAdvisor questionAnswerAdvisor(VectorStore vectorStore) {
        return new QuestionAnswerAdvisor(vectorStore);
    }
}

场景三:模块化测试配置

在单元测试中仅加载必要的模块,避免完整的Spring Boot上下文:

java 复制代码
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {
    // 仅加载commons和model层,不加载client层
    CommonsConfiguration.class,
    OpenAiModelConfiguration.class
})
public class ModelLayerUnitTest {
    // 测试ChatModel接口实现...
}

七、迁移策略与兼容性建议

对于正在使用Spring AI 1.x的企业级应用,建议采用分阶段迁移策略:

  • 阶段一:基线升级(1-2周)
    将JDK升级至Java 21(Spring AI 2.0强制要求)
    升级Spring Boot至4.0.x,解决Jakarta EE 11命名空间冲突
    更新所有javax.导入为jakarta.
  • 阶段二:API迁移(2-3周)
    优先迁移:将旧版ModelClient调用点改为ChatModel
    渐进增强:在复杂业务场景中引入ChatClient替代原生Prompt构造
    配置更新:按照新命名规范更新application.yml
  • 阶段三:模块化重构(1周)
    梳理项目中实际使用的AI能力(仅对话?需要RAG?)
    移除未使用的starter依赖(如未使用向量存储则移除spring-ai-starter-vector-store-redis)
    利用新的模块化边界,拆分过大的AI服务模块
    高风险变更点 checklist:
  • MessageAggregator类已迁移至spring-ai-model模块,但aggregateChatClientResponse方法已移至ChatClientMessageAggregator
  • ChatMemory接口常量变更:CHAT_MEMORY_CONVERSATION_ID_KEY → CONVERSATION_ID,CHAT_MEMORY_RETRIEVE_SIZE_KEY → TOP_K
  • 工具调用API变更:tools()方法已重命名为toolSpecifications()
  • 移除的模型:Watson、Moonshot、QianFan已移至社区仓库

八、总结

Spring AI 2.0的模块化重构并非简单的代码重组,而是对AI工程化复杂度的战略回应。通过commons → model → client-chat的清晰分层,开发者得以在轻量级集成与企业级能力之间做出精确权衡。

对于架构师而言,这一变化要求重新评估AI能力在系统中的依赖边界。建议新 projects 直接采用ChatClient + 按需模块依赖的模式,而遗留系统则应制定分阶段迁移路线,优先解决Java 21与Jakarta EE 11的兼容性基线问题。

本文章基于SpringAI官方文档学习撰写。仅供学习参考,请勿用于商业用途。

相关推荐
未来之窗软件服务2 小时前
vosk-ASR asterisk-ari调用[AI人工智能(五十四)]—东方仙盟
人工智能·仙盟创梦ide·东方仙盟
芯片-嵌入式2 小时前
具身智能(4):最重要的感知sensor:相机
人工智能·深度学习·dnn
热点速递2 小时前
AI智能面试系统深度解析:重构面试效率与评估质量的关键路径!
人工智能·面试·重构·业界资讯
AAAAA92402 小时前
智变边缘:AI大模型如何重塑物联网蜂窝模组产业
人工智能·物联网
代码探秘者2 小时前
【Spring框架】彻底理解 Spring 单例线程安全
java·安全·spring
whyfail2 小时前
前端开发效率革命:(MCP+Skills)构建你的 AI 狙击手系统
人工智能
zhangshuang-peta2 小时前
弥合 n8n 中的 AI 上下文鸿沟:为何采用 MCP Gateway 构建更智能的工作流
网络·人工智能·gateway·ai agent·mcp·peta
前端双越老师2 小时前
AI 智能体 Memory 记忆模块
人工智能·node.js·agent
机器学习之心2 小时前
一区级光伏功率预测创新模型!CEEMDAN-KPCA-PINN多变量时序预测!完全自适应噪声集合经验模态分解+核主成份降维+物理信息神经网络
人工智能·深度学习·神经网络·ceemdan·光伏功率预测·多变量时序预测·pinn