1. Spring Boot与AI Agent整合实战指南
在当今企业级应用开发中,将AI能力无缝集成到现有系统已成为提升业务效率的关键手段。最近我在一个电商后台系统中成功实现了Spring Boot与AI Agent的深度整合,通过自然语言指令就能自动完成订单统计、报表生成和邮件发送等系列操作。这种技术组合特别适合需要处理复杂业务流程但又希望降低使用门槛的场景。
2. 技术选型与项目配置
2.1 核心依赖说明
首先在pom.xml中配置以下关键依赖:
xml复制<!-- Spring Boot基础组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- LangChain4j核心库 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-openai</artifactId>
<version>0.32.0</version>
</dependency>
<!-- 报表生成工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>
选择LangChain4j的原因在于它提供了最贴近Java开发者习惯的API设计,与Spring生态的整合度也最高。相比直接调用OpenAI API,它能帮我们处理以下复杂问题:
- 工具方法的动态路由
- 对话上下文管理
- 复杂指令的分解执行
2.2 关键配置详解
application.yml中需要特别注意这些配置项:
yaml复制langchain4j:
openai:
api-key: ${OPENAI_API_KEY}
model-name: gpt-4o
temperature: 0.3
timeout: 60s
spring:
datasource:
url: jdbc:mysql://localhost:3306/order_db?useSSL=false
username: root
password: 123456
重要提示:temperature参数控制AI输出的确定性,值越低结果越稳定。对于业务流程类应用,建议设置在0.2-0.5之间以避免随机性导致的业务问题。
3. AI Agent核心实现
3.1 工具方法开发
每个业务能力都需要封装成独立的Tool组件。以下是订单统计工具的典型实现:
java复制@Component
public class OrderTool {
@Autowired
private JdbcTemplate jdbcTemplate;
@Tool("查询订单统计数据")
public Map<String, Object> queryOrderStatistic(
@P("开始日期") String startDate,
@P("结束日期") String endDate) {
// 防止SQL注入的日期格式校验
if(!isValidDate(startDate) || !isValidDate(endDate)){
throw new IllegalArgumentException("日期格式应为yyyy-MM-dd");
}
String sql = """
SELECT
SUM(amount) AS totalSales,
COUNT(id) AS orderCount,
JSON_ARRAYAGG(
JSON_OBJECT(
'productName', product_name,
'sales', sales_num
)
) AS topProducts
FROM orders
WHERE create_time BETWEEN ? AND ?
GROUP BY DATE(create_time)""";
return jdbcTemplate.queryForMap(sql, startDate, endDate);
}
}
工具方法设计时需要特别注意:
- 使用@P注解明确参数说明
- 必须进行输入校验
- 返回结构要尽可能规范
3.2 Agent装配逻辑
在配置类中完成Agent的组装:
java复制@Configuration
public class AgentConfig {
@Bean
public OpenAiChatModel chatModel() {
return OpenAiChatModel.builder()
.apiKey(apiKey)
.modelName("gpt-4o")
.maxTokens(1000)
.build();
}
@Bean
public AgentExecutor agentExecutor(
OpenAiChatModel model,
OrderTool orderTool,
ExcelTool excelTool) {
return AgentExecutor.builder()
.agent(Agent.builder()
.chatModel(model)
.chatMemory(MessageWindowChatMemory.withMaxMessages(20))
.tools(orderTool, excelTool)
.build())
.build();
}
}
4. 业务接口实现
4.1 REST API设计
java复制@RestController
@RequestMapping("/api/agent")
public class AgentController {
@Autowired
private AgentExecutor executor;
@PostMapping("/execute")
public ResponseEntity<String> execute(
@RequestBody AgentRequest request,
@RequestHeader("X-User-Id") String userId) {
try {
String result = executor.execute(
"用户ID: " + userId + "\n" +
"指令: " + request.getInstruction());
return ResponseEntity.ok(result);
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("执行失败: " + e.getMessage());
}
}
}
4.2 典型业务流程测试
使用Postman测试完整业务流程:
json复制POST /api/agent/execute
Headers:
X-User-Id: 10086
Body:
{
"instruction": "统计5月订单数据,生成报表保存到/var/reports/五月订单.xlsx,然后邮件发送到finance@company.com"
}
系统会依次执行:
- 查询数据库获取统计数据
- 调用EasyExcel生成报表
- 通过邮件服务发送带附件的邮件
5. 生产环境注意事项
5.1 性能优化方案
-
连接池配置:
yaml复制spring: datasource: hikari: maximum-pool-size: 20 connection-timeout: 30000 -
AI调用超时:
java复制OpenAiChatModel.builder() .timeout(Duration.ofSeconds(60)) -
缓存策略:
java复制@Cacheable("orderStats") public Map<String, Object> queryOrderStatistic(String start, String end) { //... }
5.2 常见问题排查
-
工具方法未被识别:
- 检查是否添加了@Component注解
- 确认方法参数命名清晰
- 验证@Tool注解的description是否明确
-
中文指令处理异常:
java复制OpenAiChatModel.builder() .responseFormat("text") // 确保返回纯文本 -
长流程执行超时:
java复制@Transactional(timeout = 120) public String executeComplexTask() { //... }
6. 进阶开发技巧
6.1 动态工具注册
通过实现ToolSupplier接口可以实现运行时工具注册:
java复制@Bean
public ToolSupplier dynamicTools() {
return () -> List.of(
new DynamicOrderTool(orderService),
new InventoryTool(warehouseService)
);
}
6.2 多租户支持
在工具方法中通过ThreadLocal获取租户上下文:
java复制@Tool
public String queryTenantData() {
String tenantId = TenantContext.getCurrentTenant();
//...
}
6.3 执行过程监控
通过EventListener监控Agent执行:
java复制@EventListener
public void handleAgentEvent(AgentExecutionEvent event) {
log.info("工具调用记录: {}", event.getToolName());
metrics.increment("agent.tool." + event.getToolName());
}
在实际项目中,这种技术组合已经帮我们减少了约40%的传统接口开发工作量。特别是在需要跨系统协作的场景,业务人员可以直接用自然语言描述需求,系统就能自动完成以往需要多个接口协作才能实现的功能。