从 OpenAI、Anthropic 到 Spring AI 2.0:如何设计可切换的模型接入层

2026-07-13 34 预计阅读时间: 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.

预计阅读时间:8 分钟

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 前的检查清单

升级不应从修改版本号开始,而应先梳理应用实际使用的能力。确认聊天、流式输出、结构化响应、工具调用、向量存储和观测接口是否受到影响,并在测试环境回放真实流量样本。

落地时可以按以下顺序推进:

  1. 锁定 Spring AI、Spring Boot 与 JDK 的兼容版本组合。
  2. 将供应商模型名、密钥、超时和重试策略移出业务代码。
  3. 为核心提示词建立版本记录和回归评测集。
  4. 对 OpenAI 与 Anthropic 分别测量质量、延迟和成本。
  5. 设置限流、超时、熔断和预算告警,避免自动重试放大费用。
  6. 确认敏感数据处理、日志脱敏和供应商数据保留策略。

Spring AI 2.0 值得关注的核心,不应只是新接口数量,而是它能否让 Java 团队在模型快速变化时保持清晰的应用边界。统一客户端可以降低接入成本,配置化切换可以减少迁移工作,但最终是否能够替换模型,仍要由评测数据和合规要求决定。


相关推荐