1. 项目概述:当Java遇上AI智能体
作为Java开发者,你可能已经注意到AI技术正在重塑编程范式。Spring AI的出现,让我们能够用熟悉的Spring Boot方式快速构建AI应用。今天要介绍的"5分钟搭建Java AI智能体"方案,正是基于Spring AI Alibaba这套面向Java开发者的AI智能体框架。
这个项目本质上是一个预配置的Spring Boot Starter,它封装了与阿里云通义系列大模型交互的复杂细节。通过简单的依赖引入和配置,开发者就能获得一个具备基础对话能力的AI智能体。不同于Python生态中常见的AI开发方式,Spring AI保持了Java开发者熟悉的工程化风格,同时提供了符合Java习惯的API设计。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与项目创建
2.1 基础环境要求
在开始之前,请确保你的开发环境满足以下要求:
- JDK 17或更高版本(推荐使用Amazon Corretto或OpenJDK)
- Maven 3.6+或Gradle 7.x
- IDE推荐IntelliJ IDEA(社区版即可)
- 有效的阿里云账号(用于获取API密钥)
注意:虽然Spring AI理论上支持JDK 11,但某些AI功能需要更高版本的JDK特性。如果遇到Lombok兼容性问题,建议升级到最新稳定版。
2.2 初始化Spring Boot项目
使用Spring Initializr快速创建项目:
- 访问start.spring.io
- 选择:
- Project: Maven
- Language: Java
- Spring Boot: 3.2.x
- 添加依赖:
- Spring Web
- Lombok
- 点击Generate下载项目压缩包
或者使用命令行快速创建:
bash复制curl https://start.spring.io/starter.tgz \
-d dependencies=web,lombok \
-d javaVersion=17 \
-d type=maven-project \
-d bootVersion=3.2.5 \
-d baseDir=spring-ai-demo \
| tar -xzvf -
3. 集成Spring AI Alibaba
3.1 添加依赖配置
在pom.xml中添加Spring AI Alibaba的starter依赖:
xml复制<dependency>
<groupId>com.alibaba.spring</groupId>
<artifactId>spring-ai-alibaba-spring-boot-starter</artifactId>
<version>0.8.1</version>
</dependency>
同时需要配置阿里云通义千问的访问密钥。在application.yml中添加:
yaml复制spring:
ai:
alibaba:
access-key: your-access-key
secret-key: your-secret-key
chat:
model: qwen-turbo
安全提示:实际项目中请使用Spring Cloud Config或Vault管理敏感信息,不要将密钥直接写在配置文件中。
3.2 创建第一个AI智能体
现在我们创建一个简单的对话服务。新建ChatController.java:
java复制@RestController
@RequiredArgsConstructor
public class ChatController {
private final AlibabaChatClient chatClient;
@PostMapping("/chat")
public String chat(@RequestBody String prompt) {
return chatClient.call(prompt);
}
}
这个简单的REST端点已经具备AI对话能力。启动应用后,你可以用curl测试:
bash复制curl -X POST http://localhost:8080/chat \
-H "Content-Type: text/plain" \
-d "用Java写一个快速排序算法"
4. 智能体功能扩展
4.1 添加记忆能力
基础对话缺乏上下文记忆。让我们升级为有记忆的智能体:
java复制@RestController
@RequiredArgsConstructor
public class ChatController {
private final AlibabaChatClient chatClient;
private final Map<String, List<Message>> conversations = new ConcurrentHashMap<>();
@PostMapping("/chat/{sessionId}")
public String chat(@PathVariable String sessionId,
@RequestBody String prompt) {
List<Message> history = conversations
.computeIfAbsent(sessionId, k -> new ArrayList<>());
history.add(new Message("user", prompt));
String response = chatClient.call(history);
history.add(new Message("assistant", response));
return response;
}
}
现在对话会记住上下文:
bash复制# 第一次提问
curl -X POST http://localhost:8080/chat/session1 \
-d "Java中的Stream有哪些优点?"
# 后续可以引用之前对话
curl -X POST http://localhost:8080/chat/session1 \
-d "请用代码示例说明最后一个观点"
4.2 集成工具能力
让智能体能够执行代码验证等操作。首先定义工具接口:
java复制public interface CodeTools {
@Tool(name = "codeValidator")
String validateCode(String code);
}
@Component
public class JavaCodeValidator implements CodeTools {
@Override
public String validateCode(String code) {
// 实现代码静态检查逻辑
return "代码验证通过";
}
}
然后配置工具增强的智能体:
java复制@Bean
public FunctionCallbackContext functionCallbackContext() {
return new FunctionCallbackContext();
}
@Bean
public PromptTemplate promptTemplate() {
return new PromptTemplate("""
你是一个Java专家,可以使用工具验证代码。
问题:{question}
""");
}
5. 生产环境注意事项
5.1 性能优化建议
- 连接池配置:
yaml复制spring:
ai:
alibaba:
client:
max-connections: 50
connection-timeout: 5000
read-timeout: 10000
- 启用响应缓存:
java复制@Bean
public CacheManager cacheManager() {
return new CaffeineCacheManager("aiResponses");
}
@Cacheable("aiResponses")
public String getCachedResponse(String prompt) {
return chatClient.call(prompt);
}
5.2 监控与可观测性
添加Actuator端点监控:
xml复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置Prometheus监控指标:
yaml复制management:
endpoints:
web:
exposure:
include: health,metrics,prometheus
metrics:
tags:
application: ${spring.application.name}
6. 常见问题排查
6.1 认证失败问题
错误现象:
code复制AlibabaAIException: InvalidAccessKeyId
解决方案:
- 检查AK/SK是否正确
- 确认RAM权限已添加"DashScopeFullAccess"
- 检查账号是否欠费
6.2 长响应超时问题
错误现象:
code复制SocketTimeoutException: Read timed out
优化方案:
yaml复制spring:
ai:
alibaba:
client:
read-timeout: 30000 # 适当延长超时
对于流式响应,建议使用SSE:
java复制@GetMapping("/stream-chat")
public SseEmitter streamChat(@RequestParam String prompt) {
SseEmitter emitter = new SseEmitter();
chatClient.streamCall(prompt)
.subscribe(
chunk -> emitter.send(chunk),
emitter::completeWithError,
emitter::complete
);
return emitter;
}
7. 项目进阶方向
7.1 多智能体协作
利用Spring AI Alibaba的Graph功能构建智能体工作流:
java复制@Bean
public GraphExecutionChain graphExecutionChain() {
return GraphExecutionChain.builder()
.addNode("codeGenerator", prompt -> generateCode(prompt))
.addNode("codeReviewer", code -> reviewCode(code))
.addEdge("codeGenerator", "codeReviewer")
.build();
}
7.2 领域知识增强
通过RAG(检索增强生成)接入私有知识库:
- 准备知识库文档
- 创建Embedding索引:
java复制@Bean
public VectorStore vectorStore(EmbeddingClient embeddingClient) {
return new SimpleVectorStore(embeddingClient);
}
public void indexDocument(String text) {
vectorStore.add(List.of(new Document(text)));
}
- 构建RAG智能体:
java复制public String ragChat(String question) {
List<Document> docs = vectorStore.similaritySearch(question);
String context = docs.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n\n"));
return chatClient.call("基于以下上下文回答:\n" +
context + "\n\n问题:" + question);
}
8. 开发心得与技巧
在实际项目中,我发现几个提升开发效率的关键点:
- 提示工程优化:为Java开发者定制系统提示词
java复制String systemPrompt = """
你是一个资深的Java开发助手,遵循以下原则:
1. 代码示例使用Java 17语法
2. 优先展示Spring Boot 3的最佳实践
3. 解释要结合JVM原理
""";
- 智能体个性设置:
yaml复制spring:
ai:
alibaba:
chat:
options:
temperature: 0.7
topP: 0.9
resultFormat: "text"
-
本地缓存策略:对常见技术问题(如Spring Bean生命周期)的答案进行本地缓存,减少API调用
-
异常处理增强:对网络波动等临时错误实现自动重试
java复制@Retryable(value = AlibabaAIException.class,
maxAttempts = 3,
backoff = @Backoff(delay = 1000))
public String reliableChat(String prompt) {
return chatClient.call(prompt);
}
- 限流保护:使用Resilience4j防止突发流量
java复制@Bulkhead(name = "chatApi", type = Type.SEMAPHORE)
public String bulkheadedChat(String prompt) {
return chatClient.call(prompt);
}
