Spring AI 与 Spring Framework 的近期方向:从播客话题落到可运行实践

2026-07-02 28 预计阅读时间: 1 分钟
来源: spring.io AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

这期 A Bootiful Podcast 把焦点放在 Sébastien Deleuze 对 Spring AI 和 Spring Framework 近况的讨论上。虽然播客本身是访谈形式,但它指向了一个很实际的变化:Spring 生态正在把 AI 应用开发拉回 Java 开发者熟悉的工程模型里,配置、Bean、自动装配、测试和部署仍然是主战场。

Spring AI 的价值不只是“调模型”

对后端工程师来说,AI 接入最容易被低估的部分不是 HTTP 请求本身,而是模型客户端、提示词、上下文、向量检索、重试、限流、观测性这些工程细节如何进入现有应用。

Spring AI 的意义在于,它尝试把这些能力包装成 Spring 风格的抽象:你可以把大模型调用当作服务依赖注入,把提示词模板当作应用资源,把模型配置放进 application.yml,再用熟悉的测试和配置隔离方式管理不同环境。

这并不意味着 AI 应用会自动变简单。它只是把问题放到了更容易被团队治理的位置:

  • 模型供应商可以通过配置切换,而不是散落在业务代码里。
  • Prompt 可以像模板一样版本化,而不是藏在字符串拼接中。
  • AI 调用可以进入已有的日志、指标、追踪和异常处理体系。
  • Java 团队不需要为了第一个 AI 功能立刻重写技术栈。

Spring Framework 仍然是底座

Spring AI 听起来是新东西,但它真正能落地,靠的还是 Spring Framework 的基本功:依赖注入、配置绑定、资源加载、Web 编程模型、测试支持,以及和 Spring Boot 的自动配置配合。

这也是为什么关注 Spring Framework 本身仍然重要。AI 功能通常不会独立存在,它会进入现有订单系统、知识库、客服后台、研发平台或内部工具。你需要的是一个能被纳入生产系统的 AI 能力,而不是一个孤立 demo。

可以把它理解为三层:

  • Spring Framework 提供应用结构和运行时基础。
  • Spring Boot 降低配置和集成成本。
  • Spring AI 把模型调用、Prompt 和相关 AI 能力接入这个结构。

可以这样实践:写一个最小 Spring AI 聊天接口

下面是一个可改造的最小示例,用 Spring Boot 暴露一个 /chat 接口,并通过 Spring AI 的 ChatClient 调用模型。你需要替换自己的模型供应商配置和 API Key。

pom.xml 示例:

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

    <groupId>com.example</groupId>
    <artifactId>spring-ai-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>21</java.version>
        <spring-ai.version>1.0.0-M3</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>
</project>

src/main/resources/application.yml

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

src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

@RestController
class ChatController {
    private final ChatClient chatClient;

    ChatController(ChatClient.Builder builder) {
        this.chatClient = builder
                .defaultSystem("You are a concise assistant for Java backend developers.")
                .build();
    }

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

运行方式:

export OPENAI_API_KEY="替换成你的 API Key"
mvn spring-boot:run

调用接口:

curl "http://localhost:8080/chat?message=Explain%20Spring%20AI%20in%203%20sentences"

需要注意:上面的依赖版本只是一个可实践起点。Spring AI 仍在快速演进,真实项目应以当前官方 BOM 和 starter 名称为准,并锁定版本,避免构建在升级时突然漂移。

不要把 Prompt 写成散装字符串

AI 功能进入业务系统后,最常见的维护问题是 Prompt 越写越散。一个接口里拼接系统指令,另一个 service 里拼接用户上下文,再加几段条件判断,几周后很难回答“线上模型到底收到了什么”。

可以这样实践:把 Prompt 模板放到资源文件里,用明确变量填充。即使暂时不用复杂模板引擎,也要先让 Prompt 可读、可审查、可版本化。

src/main/resources/prompts/review-system.txt

You are a senior Java reviewer.
Focus on correctness, maintainability, and production risk.
Return concise findings with severity and evidence.

控制器中加载资源的思路如下:

package com.example.demo;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

@RestController
class ReviewController {
    private final ChatClient.Builder builder;
    private final Resource systemPrompt;

    ReviewController(ChatClient.Builder builder,
                     @Value("classpath:prompts/review-system.txt") Resource systemPrompt) {
        this.builder = builder;
        this.systemPrompt = systemPrompt;
    }

    @PostMapping("/review")
    String review(@RequestBody String diff) throws IOException {
        String system = StreamUtils.copyToString(systemPrompt.getInputStream(), StandardCharsets.UTF_8);

        return builder.defaultSystem(system)
                .build()
                .prompt()
                .user("Review this diff:\n" + diff)
                .call()
                .content();
    }
}

这段代码的重点不是“代码审查机器人”,而是 Prompt 的工程化方式:系统提示词作为资源文件管理,业务输入作为用户消息传入,二者边界清楚,后续做审计和测试更容易。

落地时该保守的地方

Spring AI 很适合 Java/Spring 团队做增量试点,但生产接入要把边界先画清楚。

建议从低风险场景开始:内部知识问答、摘要、草稿生成、运营辅助、研发工具,而不是一上来接管核心交易流程。模型输出要默认不可信,尤其涉及权限、金额、合规、医疗、法律或安全动作时,必须有明确校验和人工确认。

上线前可以用这份简短清单检查:

  • API Key 是否只来自环境变量或密钥系统。
  • 模型请求和响应是否有必要的日志脱敏。
  • 超时、重试、限流和降级策略是否明确。
  • Prompt 是否版本化,而不是散落在业务字符串里。
  • 是否记录模型名称、参数和调用链,方便排查线上问题。
  • 是否为高成本调用设置预算或速率保护。

这期播客值得关注的地方,不在于某个单点 API,而在于 Spring 生态正在把 AI 应用开发纳入成熟的 Java 工程节奏。对团队来说,最好的切入点不是追逐每个新模型能力,而是选一个具体业务流程,把配置、Prompt、测试、观测和安全边界一起做扎实。


相关推荐