Spring AI Alibaba 接入 OpenAI 兼容协议第三方大模型实战

Spring AI Alibaba 接入 OpenAI 兼容协议第三方大模型实战

本文记录在 Spring AI Alibaba 项目中,以 OpenAI 兼容协议接入第三方大模型(以京东云 AI 为例)的完整过程,包含踩坑记录和解决方案。


背景

Spring AI Alibaba 是阿里云基于 Spring AI 构建的 Java AI 应用开发框架,原生集成 DashScope(通义千问等)。但在实际业务中,我们有时需要接入其他厂商提供的大模型服务。

好消息是:越来越多的大模型 API 提供商(京东云、DeepSeek、Moonshot、vLLM 等)都兼容 OpenAI 的接口协议,只需切换 base-urlapi-key,就能通过 spring-ai-starter-model-openai 无缝接入,无需修改业务代码。


技术栈

组件 版本
Java 17
Spring Boot 3.4.5
Spring AI BOM 1.1.2
模型服务 京东云 AI(OpenAI 兼容协议)

⚠️ 重要spring-ai 1.1.2 基于 Spring Framework 6.x 编译,不兼容 Spring Boot 4.x(Spring Framework 7.x)。若你的项目使用 Spring Boot 4.x,需降级至 Spring Boot 3.4.x。


一、pom.xml 配置

1.1 指定 Spring Boot 版本

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

1.2 引入 Spring AI BOM

<dependencyManagement> 中通过 BOM 统一管理 Spring AI 版本,无需在每个依赖上单独写版本号:

xml 复制代码
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.1.2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

1.3 添加 OpenAI Starter 依赖

xml 复制代码
<dependencies>
    <!-- OpenAI 兼容协议 Starter,版本由 BOM 管理 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-openai</artifactId>
    </dependency>

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

⚠️ 命名变更 :Spring AI 1.0.0-M7 之后,旧名 spring-ai-openai-spring-boot-starter 已废弃 ,1.1.2 中正确的 artifactId 为 spring-ai-starter-model-openai。使用旧名会导致 Maven 依赖解析失败。


二、application.properties 配置

properties 复制代码
spring.application.name=my-ai-app

# ===== 接入京东云 AI(OpenAI 兼容协议)=====
spring.ai.openai.api-key=your-api-key-here
spring.ai.openai.base-url=http://baseurl
spring.ai.openai.chat.options.model=GPT-5.4
spring.ai.openai.chat.options.temperature=0.7

# 若该端点不提供 Embedding 服务,需显式禁用,否则启动报错
spring.ai.model.embedding=none

配置项说明

配置项 说明
spring.ai.openai.base-url 第三方 API 的根地址,替换默认的 https://api.openai.com
spring.ai.openai.api-key 第三方服务的鉴权 Key
spring.ai.openai.chat.options.model 模型名称,使用目标服务支持的模型标识
spring.ai.openai.chat.options.temperature 采样温度,0~2,越高输出越随机
spring.ai.model.embedding=none 禁用 Embedding 自动装配(Spring AI 1.0+ 写法,旧版 spring.ai.openai.embedding.enabled=false 已废弃)

关于 spring.ai.model.embedding=none :旧版的 spring.ai.openai.embedding.enabled=false 在 Spring AI 1.0.0-M7 后已被移除,务必使用新写法。


三、业务代码

Spring AI 提供了高层抽象 ChatClient,配置完成后直接注入即可,无需关心底层是哪家厂商。

java 复制代码
package com.example.ai.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/ai")
public class ChatController {

    private final ChatClient chatClient;

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

    @GetMapping("/chat")
    public String chat(@RequestParam(defaultValue = "你好,请介绍一下你自己") String message) {
        return chatClient.prompt()
                .user(message)
                .call()
                .content();
    }
}

ChatClient.Builder 由 Spring AI 自动装配,内部已绑定好 spring.ai.openai.* 的配置,业务代码与具体模型提供商解耦。


四、验证

启动应用:

bash 复制代码
./mvnw spring-boot:run

调用接口:

bash 复制代码
# 默认问候
curl http://localhost:8080/ai/chat

# 自定义问题
curl "http://localhost:8080/ai/chat?message=1%2B1%E7%AD%89%E4%BA%8E%E5%87%A0"

正常响应示例:

bash 复制代码
Hello! How can I help you today?

五、踩坑记录

坑1:Spring Boot 4.x 与 Spring AI 1.1.2 不兼容

现象:

makefile 复制代码
java.lang.ClassNotFoundException: 
org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration

或:

vbnet 复制代码
NoSuchMethodError: 'void org.springframework.http.HttpHeaders.addAll(MultiValueMap)'

原因: Spring AI 1.1.2 编译时依赖 Spring Framework 6.x(对应 Spring Boot 3.x),RestClientAutoConfigurationHttpHeaders 的 API 在 Spring Framework 7.x(Spring Boot 4.x)中已变更或移除。

解决: 将 Spring Boot 降级至 3.4.x。

xml 复制代码
<!-- 改为 3.4.5 -->
<version>3.4.5</version>

坑2:spring-ai-alibaba 与 Spring Boot 4.x 不兼容

现象:

arduino 复制代码
Failed to process import candidates for configuration class 
[com.alibaba.cloud.ai.autoconfigure.dashscope.DashScopeAgentAutoConfiguration]

原因: spring-ai-alibaba-starter-dashscopespring-ai-alibaba-agent-framework 同样基于 Spring Boot 3.x 构建,无法在 Spring Boot 4.x 上运行。

解决: 若不需要 DashScope,直接移除这两个依赖,仅保留 spring-ai-starter-model-openai


坑3:Embedding 自动装配失败

现象:

启动时报 Bean 创建失败,与 Embedding 相关。

原因: OpenAI Starter 默认会同时装配 Chat 和 Embedding 客户端,但很多第三方 API 不提供 Embedding 端点。

解决:

properties 复制代码
# 正确写法(Spring AI 1.0+ )
spring.ai.model.embedding=none

# 错误写法(已废弃,无效)
spring.ai.openai.embedding.enabled=false

坑4:artifactId 命名变更

Spring AI 1.0.0-M7 对 starter 进行了重命名:

旧名(已废弃) 新名(1.1.2 使用)
spring-ai-openai-spring-boot-starter spring-ai-starter-model-openai

使用旧名会导致 Maven 无法解析依赖,报 Could not find artifact 错误。


六、兼容其他 OpenAI 协议服务商

同样的配置方式可接入任何 OpenAI 兼容协议的服务:

properties 复制代码
# DeepSeek
spring.ai.openai.base-url=https://api.deepseek.com
spring.ai.openai.chat.options.model=deepseek-chat

# Moonshot(Kimi)
spring.ai.openai.base-url=https://api.moonshot.cn
spring.ai.openai.chat.options.model=moonshot-v1-8k

# 本地 Ollama(OpenAI 兼容模式)
spring.ai.openai.base-url=http://localhost:11434
spring.ai.openai.chat.options.model=llama3

只需修改 base-urlapi-keymodel 三个配置,业务代码零改动。


总结

步骤 关键点
依赖 使用 spring-ai-starter-model-openai,版本由 spring-ai-bom 管理
Spring Boot 版本 必须使用 3.4.x,spring-ai 1.1.2 不兼容 Spring Boot 4.x
配置 覆盖 base-url + api-key + model 即可切换任意兼容服务商
Embedding 不需要时用 spring.ai.model.embedding=none 禁用
业务代码 注入 ChatClient 即可,与模型提供商完全解耦

Spring AI 的 OpenAI 兼容协议支持极大降低了厂商锁定风险,在不修改业务代码的前提下可以灵活切换或对比不同模型服务,是生产环境多模型策略的理想方案。

相关推荐
夕除2 小时前
spring boot 6
java·spring boot·后端
zhangxingchao2 小时前
AI应用开发二:Embedding与向量数据库
前端·人工智能·后端
倒流时光三十年2 小时前
Java String.split() 方法陷阱:为什么你应该始终使用 split(regex, -1)
后端
Full Stack Developme2 小时前
Spring 模块介绍
java·后端·spring
Mahir082 小时前
Redis 核心机制:数据过期策略与淘汰策略深度解析
数据库·redis·后端·缓存·面试
多敲代码防脱发2 小时前
Spring进阶(BeanFactory与ApplicationContext)
java·数据库·spring boot·后端·spring
zhangxingchao2 小时前
AI应用开发一: AI 编程、大模型调用和 Agent
前端·人工智能·后端
会编程的土豆2 小时前
Gin 核心概念速记
数据库·后端·gin·goland
Achou.Wang3 小时前
Concurrency patterns - Go 并发模式
开发语言·后端·golang