Java开发者必看:从零搭建可落地的AI Agent,这篇实战指南够硬核
随着AI Agent概念的爆火,很多Java开发者都在问:“怎么用Java搭建属于自己的AI Agent?”“现有Java技术栈能适配AI Agent的核心需求吗?”“有没有可直接复用的实战方案?”
答案是:完全可以。Java的稳定性、丰富的生态库(如Spring、LangChain4j)以及成熟的企业级应用适配能力,其实是搭建生产级AI Agent的优质选择。本文就从核心原理、技术选型、实战搭建、优化技巧四个维度,带大家从零打造一个能自主完成“数据查询-结果分析-报告生成”的Java AI Agent,全程干货,可直接落地。
先理清核心逻辑:Java AI Agent的底层架构是什么?
不管是用哪种语言开发,AI Agent的核心都是“目标拆解-工具调用-步骤执行-结果反馈”的闭环。对应到Java技术栈,一个可落地的AI Agent架构主要包含5个核心模块,用一张图就能看懂(文字拆解如下):
- 指令解析模块:接收用户自然语言指令,转化为AI可理解的结构化目标(比如把“统计近30天订单数据并生成报表”拆解为“查询订单表→筛选时间范围→计算核心指标→生成Excel报表”);
- 规划调度模块:核心中枢,负责规划任务执行步骤、判断依赖关系(比如必须先查数据才能生成报表)、处理异常情况(比如查询超时重试);
- 工具调用模块:连接各类外部工具/服务(如数据库查询、Excel生成、邮件发送、LLM接口调用),是Agent实现“落地能力”的关键;
- 记忆存储模块:存储任务执行过程中的中间结果、用户偏好、历史交互记录(比如用户上次要求报表按销售额排序,这次自动沿用),Java中常用Redis+MySQL组合实现;
- 结果输出模块:将执行结果转化为用户易理解的形式(如Excel报表、自然语言总结),并支持多渠道输出(直接返回、发邮件、存云盘)。
这5个模块在Java项目中可通过“Spring Boot分层架构”实现解耦:控制层接收指令,服务层实现核心逻辑(解析、规划、调度),工具层封装外部服务调用,数据层负责记忆存储,视图层处理结果输出。
技术选型:Java生态下的最优组合(附选型理由)
搭建Java AI Agent,技术选型直接决定项目的稳定性和可扩展性。结合多个企业级项目经验,整理了一套“性价比拉满”的技术栈,每个组件都标注了选型逻辑,避免踩坑:
1. 核心开发框架:Spring Boot 3.x + Spring Cloud(可选)
选型理由:Spring Boot的自动配置、依赖注入能力能快速搭建项目骨架,减少重复代码;如果需要实现Agent的分布式部署(比如多Agent协同),可搭配Spring Cloud实现服务注册与发现。3.x版本支持Java 17+,兼容更多新特性。
2. LLM交互核心:LangChain4j
选型理由:LangChain4j是专为Java开发者设计的LLM应用开发框架,完美适配OpenAI、通义千问、文心一言等主流LLM接口,提供了“指令解析、任务规划、工具调用”的开箱即用组件,比直接调用LLM API减少80%的编码工作量。
3. 记忆存储:Redis + MySQL
选型理由:Redis用于存储短期记忆(如任务执行中的中间结果、用户当前会话信息),查询速度快,支持过期策略;MySQL用于存储长期记忆(如用户偏好、历史任务记录、工具配置信息),支持复杂查询和事务,保证数据持久性。
4. 工具调用封装:Spring Cloud OpenFeign + 自定义工具适配器
选型理由:OpenFeign用于调用外部HTTP服务(如邮件服务、云存储服务),声明式API简化调用逻辑;对于数据库查询、Excel生成等本地工具,通过自定义适配器封装,统一工具调用接口,方便规划模块统一调度。
5. 任务调度与异步:Spring Scheduler + CompletableFuture
选型理由:Spring Scheduler用于定时执行周期性任务(如定时生成日报、重试失败任务);CompletableFuture实现异步任务执行,避免单步骤阻塞导致整体效率下降,提升Agent的响应速度。
6. 结果导出:EasyExcel
选型理由:阿里开源的EasyExcel的内存占用低,支持大数据量报表生成,API简洁,能快速实现Excel导出功能,适配Agent的报表生成需求。
实战环节:从零搭建“订单数据统计AI Agent”
接下来用一个具体场景实战:搭建一个能接收用户自然语言指令(如“统计2025年5月1日至5月31日的订单数据,包含总销售额、订单数、Top3热销商品,生成Excel报表并发送到指定邮箱”),自主完成数据查询、分析、报表生成、邮件发送的AI Agent。
步骤1:搭建项目骨架,引入核心依赖
首先创建Spring Boot 3.x项目,在pom.xml中引入核心依赖(LangChain4j、Redis、EasyExcel、OpenFeign等):
<!-- 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-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-scheduling</artifactId> </dependency> <!-- LangChain4j核心依赖,适配OpenAI --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-openai</artifactId> <version>0.32.0</version> </dependency> <!-- EasyExcel --> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.3.2</version> </dependency> <!-- OpenFeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- MySQL驱动 --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency>步骤2:配置LLM与核心组件
在application.yml中配置OpenAI API密钥(也可替换为通义千问、文心一言的密钥和接口地址)、Redis、MySQL连接信息:
spring: datasource: url: jdbc:mysql://localhost:3306/order_db?useSSL=false&serverTimezone=UTC username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver redis: host: localhost port: 6379 password: database: 0 # LangChain4j配置 langchain4j: openai: api-key: sk-your-openai-api-key model-name: gpt-4o temperature: 0.3 # 控制生成内容的确定性,越低越稳定然后创建LangChain4j核心Bean,用于初始化LLM客户端和Agent规划器:
import dev.langchain4j.agent.Agent; import dev.langchain4j.agent.AgentExecutor; import dev.langchain4j.agent.tool.Tool; import dev.langchain4j.memory.chat.MessageWindowChatMemory; import dev.langchain4j.model.openai.OpenAiChatModel; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class LangChain4jConfig { // 初始化OpenAI聊天模型 @Bean public OpenAiChatModel openAiChatModel() { return OpenAiChatModel.builder() .apiKey("sk-your-openai-api-key") .modelName("gpt-4o") .temperature(0.3) .build(); } // 初始化Agent:注入模型、记忆、工具 @Bean public AgentExecutor agentExecutor(OpenAiChatModel openAiChatModel, OrderTool orderTool, ExcelTool excelTool, EmailTool emailTool) { return AgentExecutor.builder() .agent(Agent.builder() .chatModel(openAiChatModel) .chatMemory(MessageWindowChatMemory.withMaxMessages(10)) // 保存最近10条会话信息 .tools(orderTool, excelTool, emailTool) // 注册可用工具 .build()) .build(); } }步骤3:开发核心工具类(Agent的“手脚”)
工具是Agent实现落地能力的关键,我们需要封装3个核心工具:订单数据查询工具、Excel生成工具、邮件发送工具。每个工具都需要用LangChain4j的@Tool注解标记,让Agent能识别并调用。
3.1 订单数据查询工具(OrderTool)
import dev.langchain4j.agent.tool.Tool; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import java.util.Map; @Component public class OrderTool { @Autowired private JdbcTemplate jdbcTemplate; /** * 查询指定时间范围内的订单统计数据 * @param startDate 开始日期(格式:yyyy-MM-dd) * @param endDate 结束日期(格式:yyyy-MM-dd) * @return 统计数据:总销售额、订单数、Top3热销商品 */ @Tool("查询指定时间范围内的订单统计数据,参数为开始日期和结束日期(格式:yyyy-MM-dd)") public Map<String, Object> queryOrderStatistic(String startDate, String endDate) { // 1. 查询总销售额和订单数 String statSql = "SELECT SUM(amount) AS totalSales, COUNT(id) AS orderCount " + "FROM order_table WHERE create_time BETWEEN ? AND ?"; Map<String, Object> statMap = jdbcTemplate.queryForMap(statSql, startDate, endDate); // 2. 查询Top3热销商品 String top3Sql = "SELECT product_name, SUM(sales_num) AS salesNum " + "FROM order_item WHERE order_create_time BETWEEN ? AND ? " + "GROUP BY product_name ORDER BY salesNum DESC LIMIT 3"; statMap.put("top3Products", jdbcTemplate.queryForList(top3Sql, startDate, endDate)); return statMap; } }3.2 Excel生成工具(ExcelTool)
import com.alibaba.excel.EasyExcel; import dev.langchain4j.agent.tool.Tool; import org.springframework.stereotype.Component; import java.io.File; import java.util.List; import java.util.Map; @Component public class ExcelTool { /** * 生成订单统计Excel报表 * @param statData 统计数据(包含总销售额、订单数、Top3热销商品) * @param filePath 生成文件路径(如:D:/order_stat.xlsx) * @return 文件路径 */ @Tool("生成订单统计Excel报表,参数为统计数据和文件保存路径") public String generateOrderExcel(Map<String, Object> statData, String filePath) { // 构建Excel数据列表 List<Map<String, Object>> excelData = List.of( Map.of("统计项", "总销售额", "数值", statData.get("totalSales")), Map.of("统计项", "订单数", "数值", statData.get("orderCount")), Map.of("统计项", "Top3热销商品", "数值", statData.get("top3Products")) ); // 生成Excel EasyExcel.write(filePath) .sheet("订单统计") .doWrite(excelData); return "Excel报表生成成功,路径:" + filePath; } }3.3 邮件发送工具(EmailTool)
import dev.langchain4j.agent.tool.Tool; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Component; @Component public class EmailTool { @Autowired private JavaMailSender mailSender; /** * 发送邮件(带附件) * @param to 收件人邮箱 * @param subject 邮件主题 * @param text 邮件内容 * @param filePath 附件路径(如:D:/order_stat.xlsx) * @return 发送结果 */ @Tool("发送带附件的邮件,参数为收件人邮箱、主题、内容、附件路径") public String sendEmailWithAttachment(String to, String subject, String text, String filePath) { try { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom("[email protected]"); message.setTo(to); message.setSubject(subject); message.setText(text); // 此处简化,实际带附件需使用MimeMessage mailSender.send(message); return "邮件发送成功,收件人:" + to; } catch (Exception e) { return "邮件发送失败:" + e.getMessage(); } } }import dev.langchain4j.agent.tool.Tool; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Component; @Component public class EmailTool { @Autowired private JavaMailSender mailSender; /** * 发送邮件(带附件) * @param to 收件人邮箱 * @param subject 邮件主题 * @param text 邮件内容 * @param filePath 附件路径(如:D:/order_stat.xlsx) * @return 发送结果 */ @Tool("发送带附件的邮件,参数为收件人邮箱、主题、内容、附件路径") public String sendEmailWithAttachment(String to, String subject, String text, String filePath) { try { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom("[email protected]"); message.setTo(to); message.setSubject(subject); message.setText(text); // 此处简化,实际带附件需使用MimeMessage mailSender.send(message); return "邮件发送成功,收件人:" + to; } catch (Exception e) { return "邮件发送失败:" + e.getMessage(); } } }步骤4:开发控制层,接收用户指令并触发Agent
import dev.langchain4j.agent.AgentExecutor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/ai-agent") public class AgentController { @Autowired private AgentExecutor agentExecutor; /** * 接收用户自然语言指令,触发AI Agent执行任务 * @param request 包含用户指令的请求体 * @return Agent执行结果 */ @PostMapping("/execute") public String executeTask(@RequestBody AgentRequest request) { // 调用Agent执行任务,返回结果 return agentExecutor.execute(request.getInstruction()); } // 内部静态类:请求体封装 public static class AgentRequest { private String instruction; // getter、setter public String getInstruction() { return instruction; } public void setInstruction(String instruction) { this.instruction = instruction; } } }步骤5:测试验证
启动项目后,通过Postman发送POST请求到http://localhost:8080/ai-agent/execute,请求体为:
{ "instruction": "统计2025年5月1日至5月31日的订单数据,包含总销售额、订单数、Top3热销商品,生成Excel报表保存到D:/202505_order_stat.xlsx,然后发送到[email protected]邮箱,邮件主题为2025年5月订单统计" }正常情况下,Agent会自动执行以下步骤:1. 调用OrderTool查询指定时间范围的订单数据;2. 调用ExcelTool生成报表;3. 调用EmailTool发送带附件的邮件;4. 返回执行结果(包含报表路径、邮件发送状态)。
Java AI Agent的优化技巧(企业级落地关键)
上面的实战案例实现了基础功能,要落地到生产环境,还需要做好以下优化:
1. 指令解析优化:增加参数校验与格式标准化
用户输入的自然语言可能存在歧义(如日期格式不明确),可在工具调用前增加拦截器,对关键参数(如日期、邮箱、文件路径)进行校验,若参数缺失或格式错误,Agent主动询问用户补充,避免执行失败。
2. 异常处理优化:增加重试机制与降级策略
工具调用可能出现异常(如数据库连接超时、邮件服务不可用),可通过Spring Retry实现重试机制;对于非核心工具(如邮件发送),可设置降级策略(如失败后记录日志,后续手动补发),避免单个步骤失败导致整个任务终止。
3. 性能优化:异步执行与任务拆分
对于复杂任务(如多维度数据统计+多文件生成),可通过CompletableFuture实现异步执行,并行调用多个工具;同时将大任务拆分为小步骤,通过Redis记录每个步骤的执行状态,支持断点续跑(如某步骤失败,修复后可从该步骤继续执行,无需重新开始)。
4. 安全优化:工具权限控制与指令过滤
生产环境中,需对Agent的工具调用权限进行控制(如普通用户无法调用删除数据的工具);同时增加指令过滤机制,拒绝恶意指令(如“删除数据库所有数据”),避免安全风险。
总结与展望
用Java搭建AI Agent,核心是借助LangChain4j将LLM的“规划能力”与Java的“企业级落地能力”结合,通过工具封装实现各类业务场景的适配。从实战案例能看出,Java开发者无需学习全新技术栈,基于现有Spring生态就能快速上手。
未来,Java AI Agent的落地场景会更加丰富:如企业内部的智能运维Agent(自动排查系统故障)、电商领域的智能客服Agent(自主处理订单咨询与售后)、金融领域的风险控制Agent(实时监测交易风险)。
如果你在Java AI Agent开发中遇到了技术难题(如LangChain4j适配国产LLM、多Agent协同),欢迎在评论区留言讨论;关注我,后续会分享更多Java+AI的实战案例和源码解析~