问题现象
在Spring AI项目中注入:
public AiService(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
启动时却出现:
No qualifying bean of type
'org.springframework.ai.chat.client.ChatClient$Builder'
available
Spring AI官方说明,Spring Boot自动配置会为已配置的 ChatModel 创建一个原型作用域的 ChatClient.Builder。因此,找不到Bean通常不是ChatClient本身的问题,而是模型自动配置链路没有成立。
一、先确认依赖是否正确
以DeepSeek为例,Spring AI 2.0应使用:
org.springframework.ai
spring-ai-starter-model-deepseek
同时通过BOM统一版本:
org.springframework.ai
spring-ai-bom
2.0.0
pom
import
常见错误包括:
- 只引入
spring-ai-core; - 只引入ChatClient API,没有引入模型Starter;
- Starter版本与BOM版本混用;
- 使用Spring AI 1.x依赖名称配合2.0配置;
- Maven依赖没有刷新成功。
执行:
mvn dependency:tree | grep spring-ai
确认实际解析到的版本一致。
二、确认版本兼容
Spring AI 2.0.x支持Spring Boot 4.0.x和4.1.x。
推荐组合:
Spring Boot 4.1.0
Spring AI 2.0.0
JDK 21
如果Spring Boot 3.x项目强行引入Spring AI 2.0,自动配置可能无法正常生效。反过来,Spring Boot 4项目也不要继续复制Spring AI 1.x时期的旧配置。
三、确认模型自动配置没有被关闭
DeepSeek配置示例:
spring:
ai:
model:
chat: deepseek
deepseek:
api-key: ${DEEPSEEK_API_KEY}
chat:
model: deepseek-v4-flash
Spring AI 2.0使用:
spring.ai.model.chat: deepseek
不要再使用已经移除的:
spring.ai.deepseek.chat.enabled: true
如果配置成:
spring.ai.model.chat: none
或者指定了一个与当前Starter不匹配的模型名,ChatModel不会创建,ChatClient.Builder自然也不会出现。
四、检查API Key
确保环境变量存在:
echo $DEEPSEEK_API_KEY
IDEA启动进程不一定自动继承终端中新设置的环境变量,应在运行配置中增加:
DEEPSEEK_API_KEY=sk-xxxxxxxx
不要设置一个伪默认密钥来“让应用先启动”,否则会把配置错误推迟到首次调用阶段。
五、检查组件扫描范围
启动类建议位于业务包上层:
package com.zyentor.springai;
@SpringBootApplication
public class Application {
}
业务类位于:
com.zyentor.springai.service
com.zyentor.springai.controller
如果启动类放在过深的包中,自定义配置类和业务Bean可能没有被扫描。
六、多模型场景下的Bean冲突
当项目同时接入多个模型时,可能出现:
expected single matching bean but found 2
更推荐基于不同 ChatModel 手动创建ChatClient:
@Configuration
public class MultiModelConfig {
@Bean("deepSeekClient")
ChatClient deepSeekClient(DeepSeekChatModel model) {
return ChatClient.builder(model).build();
}
@Bean("openAiClient")
ChatClient openAiClient(OpenAiChatModel model) {
return ChatClient.builder(model).build();
}
}
注入时显式使用:
public AiService(
@Qualifier("deepSeekClient") ChatClient chatClient
) {
this.chatClient = chatClient;
}
多模型项目中不要依赖“默认模型到底是哪一个”。
七、检查是否排除了自动配置
排查启动类中是否存在:
@SpringBootApplication(exclude = {
// 某些AI自动配置类
})
测试类也要注意。@WebFluxTest默认只加载Web层,不会加载完整模型自动配置。
测试Controller时可以Mock业务服务:
@WebFluxTest(AiController.class)
class AiControllerTest {
@MockBean
AiService aiService;
}
测试真正的ChatClient集成时使用:
@SpringBootTest
并提供测试环境变量。
八、用Condition Evaluation Report定位
启动时增加:
java -jar app.jar --debug
或者:
debug: true
搜索:
DeepSeek
ChatClient
ChatModel
重点查看:
- 哪个自动配置已匹配;
- 哪个条件未满足;
- 是否缺少Class;
- 是否缺少属性;
- 是否因为已有Bean而退让;
- 是否被显式排除。
九、最小可运行示例
@RestController
public class AiController {
private final ChatClient chatClient;
public AiController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
@GetMapping("/ai")
public String chat(@RequestParam String message) {
return chatClient.prompt()
.user(message)
.call()
.content();
}
}
十、排查清单
1. Spring Boot是否为4.0/4.1
2. Spring AI是否为2.0.0
3. 是否引入具体模型Starter
4. BOM与Starter版本是否一致
5. spring.ai.model.chat是否正确
6. API Key是否存在
7. 是否错误使用旧版enabled配置
8. 是否排除自动配置
9. 是否处于Web切片测试
10. 是否存在多模型Bean冲突
11. 查看Condition Evaluation Report
总结
找不到 ChatClient.Builder 的根因通常是:
ChatModel没有成功自动配置。
不要只在业务类上反复增加 @Bean 或 @Component。先从依赖、版本、模型Starter、属性和自动配置条件逐层排查。