Spring AI 学习笔记

一、是什么

1.1 核心定位

Spring AI 是 Spring 官方在 2024 年推出的 AI 开发框架,它将 Spring 的设计原则——可移植性、模块化设计和 POJO 编程模型——应用到了 AI 工程领域。它不是一个简单的“AI SDK”,而是一套完整的 AI 应用开发框架,让 Java 开发者可以用熟悉的 Spring Boot 风格来构建 AI 应用。

Spring AI 解决的核心问题是:将企业的“数据”和“API”与“AI 模型”连接起来。它把所有主流 AI 模型的 API 统一成了一致的高层抽象,你只需学会一套接口,就能调用 OpenAI、阿里云通义千问、Ollama 本地模型等各种模型,切换模型只需改配置文件。

1.2 设计理念

Spring AI 并非传统意义上的独立框架,而是基于 Spring 生态对 AI 开发场景的扩展。其核心设计理念完全传承自 Spring:依赖注入、POJO 编程、模块化架构与可配置性。它重构了 AI 应用的全开发流程,让开发者无需关注底层模型的适配细节,就能像调用数据库、Web API 一样轻松集成聊天、文本嵌入、图像生成、语音处理等 AI 能力。

Spring AI 从著名的 Python 项目(如 LangChain 和 LlamaIndex)中汲取灵感,但 Spring AI 并不是这些项目的直接移植。该项目的成立信念是,下一波生成式人工智能应用程序将不仅适用于 Python 开发人员,而是将在许多编程语言中无处不在。


二、能干嘛

2.1 核心特性一览

Spring AI 覆盖了 AI 应用开发的全流程,其核心特性可以总结为以下 7 点:

特性 说明
全栈多供应商模型适配 深度对接 OpenAI、Anthropic、通义千问、DeepSeek、Ollama 等主流服务商
标准化抽象 API 提供 ChatClient、EmbeddingModel、ImageModel 等标准化接口,统一调用体验
原生集成 Spring Boot 通过 Starter 依赖与自动装配实现 AI 组件一键集成,开箱即用
结构化输出与类型安全 支持将 AI 非结构化响应自动解析映射到 Java POJO
内置向量存储与 RAG 支持 集成 PostgreSQL/pgvector、Pinecone、Milvus、Redis 等主流向量数据库
函数调用(Tool Calling) 允许 AI 模型调用外部 API 和工具,增强模型能力
可观测性与生产就绪 支持虚拟线程、GraalVM 原生镜像以及通过 Micrometer 实现的可观察性

2.2 支持的能力矩阵

Spring AI 支持的能力类型覆盖广泛:

  • 聊天完成:对话、代码生成、内容创作(OpenAI、通义千问、DeepSeek、Claude 等)
  • 嵌入:文本向量化、语义搜索
  • 多模态:图像识别、视频理解、音频转录(GPT-4o、Qwen-VL 等)
  • 函数调用:外部 API 集成、工具调用
  • 向量数据库:PGVector、Milvus、Redis、Chroma 等
  • MCP:模型上下文协议、外部工具集成

2.3 适用场景

Spring AI 让你可以轻松实现以下常见用例:

  • 智能问答系统:基于文档的问答(“对文档进行问答”或“与文档聊天”)
  • RAG 知识库:检索增强生成,激活私有知识库
  • AI Agent:构建自主决策智能体
  • 内容生成:文本生成、图像生成、代码生成
  • 语义搜索:基于向量嵌入的相似性检索

三、怎么玩

3.1 环境准备

在开始之前,请确保你已准备好以下基础环境:

  • JDK 17 或更高版本
  • Spring Boot 3.2.x / 3.3.x / 3.4.x(与 Spring AI 版本对应)
  • Maven 或 Gradle(本文以 Maven 为例)
  • 一个 AI 模型的 API Key(如 DeepSeek、OpenAI)

3.2 添加依赖

首先,在 pom.xml 中添加 Spring Milestones 仓库(Spring AI 的 jar 包托管在此):

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
    </repository>
</repositories>

然后,添加 Spring AI BOM 和具体模型的 Starter 依赖:

<properties>
    <spring-ai.version>1.1.2</spring-ai.version>
</properties>

<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>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    </dependency>
</dependencies>

💡 提示:DeepSeek 采用了与 OpenAI 完全兼容的 API 规范,可以直接复用 OpenAI 的客户端实现。

3.3 配置 API Key

application.yml 中配置 AI 服务的 API Key:

spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:
          model: gpt-4o

如果使用 DeepSeek:

spring:
  ai:
    openai:
      api-key: ${DEEPSEEK_API_KEY}
      base-url: https://api.deepseek.com
      chat:
        options:
          model: deepseek-chat

3.4 ChatClient 基础调用

ChatClient 是 Spring AI 提供的高阶客户端,采用构建者模式(Builder Pattern)设计,支持链式调用。

方式一:配置类注入(推荐)

@Configuration
public class ChatClientConfig {

    @Bean
    ChatClient chatClient(ChatClient.Builder builder) {
        return builder
            .defaultSystem("你是专业的技术助手")
            .build();
    }
}

方式二:构造函数注入

@RestController
public class ChatController {

    private final ChatClient chatClient;

    public ChatController(ChatClient.Builder builder) {
        this.chatClient = builder.build();
    }
}

基础调用示例

@GetMapping("/ai/generate")
public String generate(@RequestParam String message) {
    return chatClient.prompt()
        .user(message)
        .call()
        .content();
}

设置系统消息

系统消息用于定义 AI 的角色和行为准则:

String response = chatClient.prompt()
    .system("你是一位资深Java工程师,回答需简洁准确")
    .user("说说Spring Boot源码?")
    .call()
    .content();

3.5 流式响应

Spring AI 支持流式调用,实现 AI 内容的“边生成边返回”,获得“打字机”效果。

@Component
public class ChatService {

    private final ChatClient chatClient;

    public ChatService(ChatModel chatModel) {
        this.chatClient = ChatClient.builder(chatModel).build();
    }

    public Flux<String> chatStream(String prompt) {
        return chatClient.prompt()
            .user(prompt)
            .stream()
            .content();
    }
}

在 Controller 中配合 SSE(Server-Sent Events)使用:

@GetMapping(value = "/ai/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(@RequestParam String message) {
    return chatService.chatStream(message);
}

3.6 结构化输出

Spring AI 支持将 AI 的非结构化响应自动解析映射到 Java POJO,保障类型安全。

首先定义一个 Java Record 作为输出结构:

public record ActorsFilms(String actor, List<String> films) {
}

然后使用 .entity() 方法直接映射:

ActorsFilms result = chatClient.prompt()
    .user("请生成一位随机演员的电影作品列表")
    .call()
    .entity(ActorsFilms.class);

3.7 函数调用(Tool Calling)

函数调用(也称为 Tool Calling)是 AI 应用中的常见模式,允许模型与一组 API 或工具交互,从而增强其能力。

使用 @Tool 注解定义工具:

@Component
public class WeatherService {

    @Tool(description = "获取指定城市的实时天气信息")
    public String getWeather(String city) {
        // 调用外部天气 API 获取实时天气
        return city + ":晴,25°C";
    }
}

然后在 ChatClient 中注册工具:

@RestController
public class WeatherController {

    private final ChatClient chatClient;

    public WeatherController(ChatClient.Builder builder, WeatherService weatherService) {
        this.chatClient = builder
            .defaultTools(weatherService)
            .build();
    }

    @GetMapping("/weather")
    public String askWeather(@RequestParam String question) {
        return chatClient.prompt()
            .user(question)
            .call()
            .content();
    }
}

当用户问“北京今天天气怎么样?”时,AI 模型会自动识别需要调用 getWeather 函数,并返回实时天气信息。

3.8 RAG(检索增强生成)

Spring AI 通过提供模块化架构支持 RAG,允许你构建自定义 RAG 流程,或使用 Advisor API 实现开箱即用的 RAG。

假设你已经将数据加载到 VectorStore 中,可以通过向 ChatClient 提供 QuestionAnswerAdvisor 来执行 RAG:

@RestController
public class RagController {

    private final ChatClient chatClient;
    private final VectorStore vectorStore;

    public RagController(ChatClient.Builder builder, VectorStore vectorStore) {
        this.vectorStore = vectorStore;
        this.chatClient = builder.build();
    }

    @GetMapping("/rag/ask")
    public String askWithRag(@RequestParam String question) {
        return chatClient.prompt()
            .user(question)
            .advisors(new QuestionAnswerAdvisor(vectorStore))
            .call()
            .content();
    }
}

3.9 Advisor(拦截器)

Advisors API 提供了一种灵活而强大的方式来拦截、修改和增强 AI 驱动的交互。内置顾问包括对话记忆、RAG、日志记录和护栏等。

// 使用 ChatMemoryAdvisor 实现多轮对话记忆
String response = chatClient.prompt()
    .user("你好,我叫张三")
    .advisors(chatMemoryAdvisor)
    .call()
    .content();

// 后续请求中 AI 会记住之前的对话上下文
String response2 = chatClient.prompt()
    .user("我叫什么名字?")
    .advisors(chatMemoryAdvisor)
    .call()
    .content();  // 输出:你叫张三

四、总结

Spring AI 为 Java 开发者提供了一条低门槛、高效率的 AI 应用开发路径。它继承了 Spring 生态“约定优于配置”、依赖注入、声明式编程等核心思想,与大模型交互、向量数据库集成、AI 工作流编排等能力深度融合。无论你是想给现有系统加上 AI 能力,还是从零开始搭建 RAG 知识库,Spring AI 都值得你认真了解。

快速上手三步走

  1. 添加依赖:引入 Spring AI BOM 和对应模型的 Starter
  2. 配置凭证:在 application.yml 中配置 API Key
  3. 编写代码:注入 ChatClient,开始调用 AI 能力

从 2025 年 Spring AI 1.0 GA 正式发布,到如今全面拥抱 Agent 工程,Spring AI 已成为 Java 开发者构建企业级 AI 应用的首选框架。