Spring AI Alibaba 报错合集:我踩过的那些坑
说实话,Spring AI 入门文档写得挺顺的,但真正跑起来报错的时候,那个体验落差能让你怀疑人生。
这不是一篇教你"如何优雅使用 Spring AI"的文章。这是我的踩坑实录,每一个坑都是真实付出过时间代价的。有些错误重复踩过三四次才记住,写下来算是给自己提个醒,顺便帮后来者少走点弯路。
1. JDK 17 以下,报错 Unsupported class file major version XX
报错信息:
java.lang UnsupportedClassVersionError: class file version XX.0
does not match Java version requirement (class file version must be one of '65')
出现场景:
项目跑起来,直接崩,或者启动时看到 UnsupportedClassVersionError。
根因:
Spring AI 基于 Spring Boot 3.x 开发,而 Spring Boot 3.x 要求最低 JDK 17。JDK 8、11、14、16 全都不行。
解决:
去 Alibaba Dragonwell 或 Adoptium 下载安装 JDK 17 或 21,然后:
# 确认当前 Java 版本
java -version
# 如果用的是 IDEA,在 File > Project Structure > Project
# SDK 里手动改成本地装好的 JDK 17+
这条没什么技巧,就是装 JDK,没别的办法。踩过三次之后我终于把环境变量里的 JAVA_HOME 永久改成了 JDK 21。
2. pom.xml 里的依赖拉不下来,报 Could not resolve dependencies
报错信息:
Could not resolve dependencies for project xxx:chatbot:jar:0.0.1-SNAPSHOT:
Could not find artifact org.springframework.ai:spring-ai-starter-model-zhipuai:jar:1.1.2
出现场景:
pom.xml 写好了,一 mvn compile,报找不到依赖。
根因:
Spring AI 的包还没进 Maven 中央仓库,spring-ai-starter-model-zhipuai 这类 artifact 都在 Spring 的 Milestone 仓库里。
解决:
在 pom.xml 里补上仓库配置:
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>sonatype-snapshots</id>
<name>Sonatype Snapshot Repository</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
这条我第一次踩的时候,百度了半小时没解决,后来发现就是仓库没配。国内网络可能还访问不了国外仓库,要配一下阿里云镜像:
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>Aliyun Maven</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
不过注意:sonatype-snapshots 这个仓库如果也被镜像覆盖,snapshot 版本可能拉不到。那就改成:
<mirror>
<id>aliyunmaven</id>
<mirrorOf>spring-milestones,central</mirrorOf>
<name>Aliyun Maven</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
只镜像 central 和 spring-milestones,放过 sonatype。
3. API Key 报错 401 Unauthorized 或 Invalid API key
报错信息:
[ERROR] org.springframework.ai.zhipuai.ZhiPuAiApiException:
Invalid API key. Please check your API key.
出现场景:
项目启动没问题,接口也调了,但每次请求都返回 401。
根因:
就三个可能:Key 写错了、Key 没生效、环境变量没读到。
排查顺序:
第一步,先看 application.yml 里有没有写死 Key:
spring:
ai:
zhipuai:
api-key: ${ZHIPUAI_API_KEY:your-api-key-here} # 这里
如果冒号后面那个 your-api-key-here 就是你环境变量的默认值,而你环境变量没配,就会用这个假 Key 去请求。
第二步,确认环境变量名对不对:
# Windows PowerShell
echo $env:ZHIPUAI_API_KEY
# macOS / Linux
echo $ZHIPUAI_API_KEY
输出为空或者空的,就说明环境变量没设上。
第三步,确认 Key 本身没问题。登录 open.bigmodel.cn,进 API Key 管理页面,确认 Key 没被禁用、没过期、额度还有。
4. 模型名写错,报 model not found
报错信息:
[ERROR] ZhiPuAiApiException: model [glm-4.7-flash] not found or not available
出现场景:
配置写好了,Key 也没问题,但就是跑不通。
根因:
模型名大小写敏感,且智谱的模型名格式要求严格。
踩坑记录:
- 写成
GLM-4(全大写)→ 报错 - 写成
glm-4-flash(混了glm-4和4.7)→ 报错 - 写成
glm-4.7-flash(实际想用但当前账号没权限)→ 报错 - 写成
glm-4→ 成功
正确写法(对照表):
| 你想用的模型 | 正确写法 |
|---|---|
| GLM-4 最新版 | glm-4 |
| GLM-4 Flash | glm-4-flash |
| GLM-4.7 Flash | glm-4.7-flash |
| GLM-4V(多模态) | glm-4v |
建议先在 open.bigmodel.cn 的体验中心测试一下,确认模型能跑再写到配置里。
5. 同时引入多个 Starter,启动报 NoUniqueBeanDefinitionException
报错信息:
NoUniqueBeanDefinitionException: No qualifying bean of type
'org.springframework.ai.chat.client.ChatClient$Builder' available
出现场景:
同时引了 spring-ai-starter-model-zhipuai 和 spring-ai-starter-model-dashscope,或者同时引了 spring-ai-alibaba-starter,然后启动直接崩。
根因:
每个 Starter 都会自动装配自己的 ChatClient.Builder 实现,同时引入多个 Spring AI 扩展的 Starter,就会产生冲突——Spring 不知道该用哪个 Builder。
踩坑场景还原:
<!-- 这样写会报错 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-zhipuai</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter</artifactId>
</dependency>
解决:
按需只选一个。如果当前用智谱,只保留 zhipuai 的 starter;如果后续要换通义,到时候再改。
如果你确实需要同时支持多个模型,可以手动指定使用哪个 Builder:
// 在 @Configuration 类里显式注入需要的 Builder
@Configuration
public class ChatClientConfig {
@Bean
public ChatClient zhipuChatClient(ChatClient.Builder builder) {
return builder.defaultSystem("你是一个助手").build();
}
}
6. ChatMemory 不生效,连续对话记不住上下文
报错信息:
不报错,但连续问问题模型"失忆"了。上一轮说"我叫张三",下一轮问"我叫什么",模型回答"你没有告诉我你的名字"。
踩坑过程:
兴冲冲加了 MessageChatMemoryAdvisor,以为完事了:
// 这是错误的用法,实际每次请求都会创建新的 Memory 实例
.defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
这样写 ChatMemory 是局部变量,请求结束后就没了,每次对话都是全新的。
正确写法:
把 ChatMemory 提出来作为类成员变量:
private final ChatMemory chatMemory = MessageWindowChatMemory.builder()
.maxMessages(50)
.build();
public ChatController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder
.defaultSystem(DEFAULT_PROMPT)
.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())
.defaultAdvisors(new SimpleLoggerAdvisor())
.build();
}
另外,如果你的应用是多实例部署,每个实例的 ChatMemory 是独立的——A 实例记住的上下文,B 实例不知道。这是分布式场景下的额外坑,需要引入 Redis 等外部存储做 Memory 持久化。
7. 启动成功但接口没响应,一直转圈
报错信息:
无报错,但请求发出去之后一直 pending,30 秒后超时。
踩坑排查过程:
- 网络通不通?
curl http://localhost:8080/chat/simple?query=hi直接返回,说明本地没问题 - API Key 有没有额度?没额度不会马上报错,有些平台会静默超时
- 模型名有没有写错?写错有时候不是报 404,而是静默超时
最后发现:
公司网络限制了外网访问,Java 应用能连 GitHub 拉依赖,但连不上 open.bigmodel.cn,请求发不出去。
解决:
# 测试网络连通性
ping open.bigmodel.cn
curl -v https://open.bigmodel.cn/api/paas/v4
# 如果 ping 不通但能拉依赖,说明是 DNS 污染或者白名单问题
# 可以尝试在 application.yml 里指定 base-url(部分 starter 支持)
在国内用智谱模型,基本不存在这个问题。但如果你用的是通义千问或者 OpenAI,而且走的代理,一定注意不要在代码里设全局代理(http.proxyHost),否则可能导致请求头里的 API Key 被意外转发到不该去的地方。
8. @GetMapping 传中文参数变乱码
报错信息:
不报错,但 query 参数传中文,返回的结果像是随机抽的,完全不对。
踩坑过程:
// 以为是模型的问题,结果是编码问题
http://localhost:8080/chat/simple?query=你好
用 Postman 调没问题,用浏览器地址栏直接输就出问题。
根因:
Tomcat 默认 URL 参数编码是 ISO-8859-1,Spring Boot 3.x 虽然默认改成了 UTF-8,但某些版本或配置下仍然有问题。
解决:
在 application.yml 里显式指定:
server:
port: 8080
servlet:
encoding:
charset: UTF-8
enabled: true
force: true
或者不用 @GetMapping 的 query 参数,改用 @RequestBody 接收 JSON:
@PostMapping("/simple")
public String simpleChat(@RequestBody Map<String, String> request) {
String query = request.get("query");
return chatClient.prompt(query).call().content();
}
// 请求体:
// { "query": "你好" }
POST + JSON 彻底绕开 URL 编码问题,推荐这种方式。
9. spring-ai-alibaba 版本升级后 API 变了
报错信息:
升级了 spring-ai-alibaba.version,然后编译报错,很多类找不到或者方法签名变了。
踩坑场景:
从 1.0.0-M5.1 升级到 1.1.2.2,发现:
DashScopeChatOptions包名变了InMemoryChatMemory改成了MessageWindowChatMemoryChatClient.Builder的配置方法名也有调整
根因:
Spring AI 和 Spring AI Alibaba 都还在快速迭代,版本之间的 API 兼容性没有保证。里程碑版本尤其明显——1.0.0-M1 和 1.0.0-M6 之间 API 差距能让人崩溃。
建议:
- 锁定 BOM 版本,不要用
LATEST或者不写版本号 - 升级前先看 Changelog,确认 breaking changes
- 如果是生产项目,锁定 minor 版本,只做 patch 升级
<properties>
<spring-ai.version>1.1.2</spring-ai.version> <!-- 锁定到 1.1.x,不要写 1.x -->
<spring-ai-alibaba.version>1.1.2.2</spring-ai-alibaba.version>
</properties>
总结:踩坑规律
写完回头看,这些坑有规律:
- 环境类:JDK 版本、仓库配置、网络连通性——这类问题只要你第一次搭好环境,后面基本不会再踩
- 配置类:API Key、模型名、编码——这类问题有标准解法,踩一次记住就好
- 理解类:ChatMemory 实例作用域、多 Starter 冲突、版本兼容性——这类需要真正理解 Spring AI 的设计思想,踩了印象最深
前两类靠细心,第三类靠多读文档多看源码。Spring AI 的文档虽然有些不完整,但源码注释写得挺清楚的,IDE 里 Ctrl+点击 进去看,比百度有效率得多。
有问题欢迎评论区见,说说你踩过哪个最离谱的坑。
🎯 收藏+关注,持续更新
如果觉得有帮助,请:
- ⭐ 收藏本文 —— 方便后续查阅,随时回顾核心概念
- 📱 关注同名公众号 —— 点击菜单「获取源码」获取完整代码(Gitee 仓库)
- 🔗 分享给同事 —— 一起学习 Spring AI Alibaba,少走弯路
系列更新不迷路,下篇推荐:暂无!后续更新都会以一个实战项目为主