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 改成了 MessageWindowChatMemory
  • ChatClient.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>


总结:踩坑规律

写完回头看,这些坑有规律:

  1. 环境类:JDK 版本、仓库配置、网络连通性——这类问题只要你第一次搭好环境,后面基本不会再踩
  2. 配置类:API Key、模型名、编码——这类问题有标准解法,踩一次记住就好
  3. 理解类:ChatMemory 实例作用域、多 Starter 冲突、版本兼容性——这类需要真正理解 Spring AI 的设计思想,踩了印象最深

前两类靠细心,第三类靠多读文档多看源码。Spring AI 的文档虽然有些不完整,但源码注释写得挺清楚的,IDE 里 Ctrl+点击 进去看,比百度有效率得多。

有问题欢迎评论区见,说说你踩过哪个最离谱的坑。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐