Java 25 发了但更让我兴奋的是这个:Spring AI 让 Java 调大模型终于不用手写 HTTP 了

昨天刷掘金满屏都是 Java 25,什么 Pattern Matching、Stable Values、Module Import... 说实话这些特性确实不错,但作为一个每天都在调 AI API 的后端仔,让我更兴奋的反而是另一件事------Spring AI 终于把 Java 调大模型这件事做对了

之前用 Java 调 GPT、Claude 这些模型,要么手写 OkHttp/RestTemplate 拼 JSON,要么用一堆非官方 SDK 担心跑路。现在 Spring AI 1.0 GA 了,配合 Java 25 的新语法糖,体验直接拉满。

先说结论

对比项 手写 HTTP Python openai 库 Spring AI 1.0
接入成本 高(拼 JSON、处理流式) 低(3 行代码) 低(3 行配置)
类型安全 有(编译期检查)
切换模型 改一堆代码 改 model 参数 改一行配置
切换厂商 重写 改 base_url 改一行配置
流式响应 手动处理 SSE 简单 Flux 原生支持
Spring 生态集成 自己搞 不存在 原生(DI、AOP、配置中心)

一句话:Java 调大模型的体验,终于追上 Python 了。某些方面甚至更好。

从 0 到跑通:10 分钟搞定

第一步:建项目

Java 25 + Spring Boot 3.5 + Spring AI 1.0,用 start.spring.io 勾一下就行。如果你习惯手动搞,pom.xml 加这些:

xml 复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.5.0</version>
</parent>

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

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

第二步:配置(重点来了)

application.yml 只需要 3 行:

yaml 复制代码
spring:
  ai:
    openai:
      api-key: ${AI_API_KEY}
      base-url: https://api.openai.com/v1
      chat:
        options:
          model: gpt-5-mini
          temperature: 0.7

这里的关键在于 base-url------Spring AI 用的是 OpenAI 兼容协议,意味着任何兼容 OpenAI 协议的服务都能直接用。后面会细说这个。

第三步:写代码

java 复制代码
@RestController
public class ChatController {

    private final ChatClient chatClient;

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

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

没了。不是简化版,这就是完整代码。跑起来访问 /chat?message=你好 就能拿到 AI 回复。

要是之前用 OkHttp 写,光拼请求体、解析响应就得 50 行起步,还得处理各种边界情况。

Java 25 新语法 + Spring AI 的化学反应

Java 25 的几个新特性和 Spring AI 配合起来特别舒服。

Pattern Matching 处理多模型响应

java 复制代码
// Java 25 的增强 Pattern Matching,处理不同类型的 AI 响应
public String handleResponse(Generation generation) {
    var result = generation.getResult();

    return switch (result) {
        case AssistantMessage msg when msg.hasToolCalls() ->
            processToolCalls(msg.getToolCalls());
        case AssistantMessage msg when msg.getContent().length() > 5000 ->
            summarize(msg.getContent());
        case AssistantMessage msg ->
            msg.getContent();
        default -> "未知响应类型";
    };
}

比起之前的 if-else 嵌套,这个可读性好太多了。

Record + Structured Output = 类型安全的 AI 输出

这是我觉得 Spring AI 最香的功能------结构化输出。配合 Java 的 Record 类型:

java 复制代码
// 定义你想要的输出结构
record CodeReview(
    String summary,
    List<Issue> issues,
    int score
) {
    record Issue(String file, int line, String severity, String description) {}
}

// AI 直接返回强类型对象,不用手动 parse JSON
@GetMapping("/review")
public CodeReview reviewCode(@RequestParam String code) {
    return chatClient.prompt()
        .user("Review this code and identify issues:\n" + code)
        .call()
        .entity(CodeReview.class);
}

返回值直接就是 CodeReview 对象,Spring AI 在底层帮你把 AI 的 JSON 输出反序列化成强类型。如果 AI 返回的格式不对,它会自动重试。

这在 Python 里得用 Pydantic + instructor 才能做到,Java 原生 Record 就够了。

实战:3 个真实场景

场景 1:智能客服(流式输出)

java 复制代码
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamChat(@RequestParam String message) {
    return chatClient.prompt()
        .system("你是一个专业的客服助手,回答要简洁准确")
        .user(message)
        .stream()
        .content();
}

前端用 EventSource 接收就行,打字机效果直接就有了。底层走的是 Reactor 的 Flux,和 Spring WebFlux 天然集成,不用自己搞 SSE。

场景 2:批量文档摘要(并发优化)

java 复制代码
@Service
public class DocumentSummarizer {

    private final ChatClient chatClient;

    public List<String> summarizeBatch(List<String> documents) {
        return documents.parallelStream()
            .map(doc -> chatClient.prompt()
                .user("用一句话总结这段文档:\n" + doc)
                .call()
                .content())
            .toList();
    }
}

Java 25 的虚拟线程加持下,parallelStream 跑 AI 调用不会阻塞平台线程。100 个文档并发摘要,线程池都不用配。

场景 3:Function Calling(让 AI 调你的 API)

java 复制代码
@Bean
@Description("查询指定城市的实时天气")
public Function<WeatherRequest, WeatherResponse> getWeather() {
    return request -> weatherService.query(request.city());
}

record WeatherRequest(String city) {}
record WeatherResponse(String city, double temp, String condition) {}

注册一个 Bean,加个 @Description 注解,Spring AI 就会自动把这个函数暴露给大模型。用户问"北京今天天气怎么样",AI 会自动调用 getWeather("北京"),拿到结果后再组织语言回复。

这个功能之前要手写一堆 JSON Schema 描述,现在 Spring AI 从 Record 的字段名自动推断,省了一大坨模板代码。

踩坑记录

坑 1:OpenAI 官方 API 在国内延迟感人

测试环境用 OpenAI 官方 API 没问题,但上了国内服务器后首 token 延迟 3-8 秒,流式输出断断续续。

解决办法:换一个兼容 OpenAI 协议的国内接口。Spring AI 的好处就在这------只改配置,代码一行不动:

yaml 复制代码
spring:
  ai:
    openai:
      api-key: ${OFOX_API_KEY}
      base-url: https://api.ofox.ai/v1
      chat:
        options:
          model: gpt-5-mini

改完 base-urlapi-key 就行了。我用 ofox.ai 的聚合接口测了一下,首 token 延迟从 5 秒降到了 300ms 左右,而且同一套配置可以切 GPT、Claude、Gemini 各种模型,不用换 SDK。

坑 2:Structured Output 偶尔解析失败

AI 返回的 JSON 有时候会多一些字段或者格式不对,导致反序列化失败。Spring AI 默认会重试一次,但如果你的 Record 定义比较复杂,建议加个 @JsonIgnoreProperties(ignoreUnknown = true)

java 复制代码
@JsonIgnoreProperties(ignoreUnknown = true)
record CodeReview(String summary, List<Issue> issues, int score) {
    // ...
}

坑 3:Spring AI 的 BOM 版本别搞混

Spring AI 1.0.x 和 Spring Boot 3.5.x 配套使用。如果你还在 Spring Boot 3.3,需要用 Spring AI 0.8.x。版本不匹配会报一堆 NoSuchMethodError,debug 到怀疑人生。

坑 4:流式输出的错误处理

stream() 返回的 Flux 如果中途 AI 报错,默认会直接断掉连接。建议加个 onErrorResume

java 复制代码
return chatClient.prompt()
    .user(message)
    .stream()
    .content()
    .onErrorResume(e -> Flux.just("[AI 响应异常,请重试]"));

和 Python 方案的对比

说实话,写这篇文章之前我一直觉得 Java 调 AI 不如 Python 方便。但实际用下来,Spring AI 在几个方面甚至超过了 Python:

  1. 类型安全:Record + Structured Output 比 Pydantic 更简洁
  2. 并发能力:虚拟线程 + Reactor 碾压 Python 的 asyncio
  3. 工程化:配置中心、健康检查、指标监控全是现成的
  4. 切换厂商:改一行 YAML 配置 vs Python 里可能要换 SDK

Python 赢在原型速度------写个脚本调一下 API,Python 确实更快。但一旦要上生产、要维护,Java + Spring AI 的工程化优势就出来了。

小结

Java 25 + Spring AI 1.0 这个组合确实让 Java 在 AI 开发领域翻身了。以前 Java 同学看 Python 同学三行代码调 GPT 只能流口水,现在 Java 也是三行配置的事。

而且 Spring AI 最聪明的设计是用 OpenAI 兼容协议做底层------你今天用 GPT,明天想换 Claude 或者国产模型,改一行配置就行,代码完全不动。这对企业项目来说太重要了。

如果你是 Java 开发者,强烈建议现在就试试 Spring AI。真不是让你放弃 Python,而是该用 Java 的场景终于不用为了调个 AI 硬切 Python 了。

相关推荐
好家伙VCC1 分钟前
Web Components主题热切换方案揭秘
java·前端
慕木沐9 分钟前
Google ADK Java 1.0版本 核心机制与实战 Demo
java·开发语言·python
Flying_Fish_roe24 分钟前
springcloud-Eureka的原理
spring·spring cloud·eureka
甲维斯33 分钟前
Kimi版超级玛丽效果“惊人”,配额不足5厘米!
前端·人工智能
console.log('npc')1 小时前
AI前端工程与生成式UI学习路线
前端·人工智能·ui
焦虑的说说1 小时前
秒杀系统设计方案
java
许彰午1 小时前
30_Java Stream流操作全解
java·windows·python
qq_2518364572 小时前
基于java Web网络订餐系统设计与实现 源码文档
java·开发语言·前端
秋92 小时前
3年经验Python后端转AI Engineer:3个月实战转型计划(2026版)
开发语言·人工智能·python
圣殿骑士-Khtangc2 小时前
GPT-5.5 技术深度解析与企业级生产落地实战:从幻觉率下降到百万Token工程化
人工智能·gpt