OpenAI、Anthropic 与 Spring AI 2.0 被放在同一期 Spring Office Hours 节目中讨论,反映出 Java AI 应用正在面对一个现实问题:模型能力快速变化,但业务代码不能跟着每次供应商更新反复重写。对 Spring 开发者而言,关键不只是接通某个模型,而是把模型选择、提示词、超时、观测和故障处理放进可维护的应用结构。
由于来源摘要没有提供具体版本号、API 变更清单或发布日期,下面不推断 Spring AI 2.0 的具体新增接口,而是围绕标题所指向的多模型接入场景,给出一套可以改造的工程实践。实际使用时,应以所选 Spring AI 2.0 版本的发布说明为准。
模型供应商不应该渗透到业务代码
最容易启动的实现,是在控制器里直接调用某家供应商的 SDK。问题也会很快出现:请求对象、流式响应、工具调用和异常类型都会进入业务层。一旦需要比较 OpenAI 与 Anthropic,迁移成本就不再只是修改一个 URL。
更稳妥的边界是让业务代码依赖统一的聊天客户端或领域接口:
- 配置层决定当前使用哪个模型供应商。
- 应用层只表达用户输入、系统提示词和期望输出。
- 供应商特有参数集中放在适配层。
- 监控系统统一记录耗时、失败类型、模型名和 token 用量。
Spring AI 的价值正在于这层抽象。不过,抽象并不意味着所有模型完全等价。上下文窗口、结构化输出、工具调用格式和安全策略仍可能不同,切换模型前必须运行真实评测。
可以这样实践:用配置切换 OpenAI 与 Anthropic
下面是一个最小 Spring Boot 接入示例。假设所使用的 Spring AI 2.0 版本仍提供 ChatClient.Builder,并支持通过 spring.ai.model.chat 选择已安装的模型实现。不同里程碑或正式版本的属性名可能调整,运行前需要对照对应版本文档确认。
在项目中加入 OpenAI 与 Anthropic 的 Spring AI starter,并由 Spring AI BOM 管理版本。然后创建 application.yml:
spring:
application:
name: multi-model-demo
ai:
model:
chat: ${AI_PROVIDER:openai}
openai:
api-key: ${OPENAI_API_KEY:}
chat:
options:
model: ${OPENAI_MODEL:gpt-4o-mini}
temperature: 0.2
anthropic:
api-key: ${ANTHROPIC_API_KEY:}
chat:
options:
model: ${ANTHROPIC_MODEL:claude-3-5-sonnet-latest}
temperature: 0.2
server:
port: 8080
模型名称只是示例,应替换为账户当前可用的模型。接着创建一个不依赖供应商 SDK 的控制器:
package com.example.multimodel;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/chat")
public class ChatController {
private final ChatClient chatClient;
public ChatController(ChatClient.Builder builder) {
this.chatClient = builder
.defaultSystem("You are a concise assistant for Java developers.")
.build();
}
@PostMapping
public ChatResponse chat(@RequestBody ChatRequest request) {
String answer = chatClient.prompt()
.user(request.message())
.call()
.content();
return new ChatResponse(answer);
}
public record ChatRequest(String message) {}
public record ChatResponse(String answer) {}
}
设置密钥后可以这样启动和验证:
export AI_PROVIDER=openai
export OPENAI_API_KEY='replace-with-your-key'
./mvnw spring-boot:run
curl --fail-with-body \
-H 'Content-Type: application/json' \
-d '{"message":"Explain Java virtual threads in three sentences."}' \
http://localhost:8080/api/chat
切换 Anthropic 时,停止应用并更换环境变量:
export AI_PROVIDER=anthropic
export ANTHROPIC_API_KEY='replace-with-your-key'
./mvnw spring-boot:run
不要把两个生产密钥写进仓库。部署到 Kubernetes、Cloud Foundry 或其他平台时,应通过 Secret 管理系统注入环境变量,并限制日志系统采集请求正文。
真正的可移植性要靠评测,而不是接口一致
统一的 Java API 只能解决编译层面的切换。生产系统还需要一个固定评测集,例如准备 30 到 100 条脱敏请求,同时检查:
- 回答是否满足业务规则,而不只是语言是否流畅。
- JSON 或其他结构化结果能否稳定解析。
- 工具调用是否选择了正确函数和参数。
- P50、P95 延迟以及超时率是否可接受。
- 单次请求成本和每日预算是否符合预期。
- 内容过滤、数据保留和区域合规要求是否满足。
可以让 CI 对多个模型运行同一批测试,但不建议只用字符串完全相等来断言自然语言输出。更实用的方式是检查 JSON Schema、必要字段、禁用词、工具调用参数和确定性的业务规则。
升级 Spring AI 2.0 前的检查清单
升级不应从修改版本号开始,而应先梳理应用实际使用的能力。确认聊天、流式输出、结构化响应、工具调用、向量存储和观测接口是否受到影响,并在测试环境回放真实流量样本。
落地时可以按以下顺序推进:
- 锁定 Spring AI、Spring Boot 与 JDK 的兼容版本组合。
- 将供应商模型名、密钥、超时和重试策略移出业务代码。
- 为核心提示词建立版本记录和回归评测集。
- 对 OpenAI 与 Anthropic 分别测量质量、延迟和成本。
- 设置限流、超时、熔断和预算告警,避免自动重试放大费用。
- 确认敏感数据处理、日志脱敏和供应商数据保留策略。
Spring AI 2.0 值得关注的核心,不应只是新接口数量,而是它能否让 Java 团队在模型快速变化时保持清晰的应用边界。统一客户端可以降低接入成本,配置化切换可以减少迁移工作,但最终是否能够替换模型,仍要由评测数据和合规要求决定。