随着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个核心模块,用一张图就能看懂(文字拆解如下):

  1. 指令解析模块:接收用户自然语言指令,转化为AI可理解的结构化目标(比如把“统计近30天订单数据并生成报表”拆解为“查询订单表→筛选时间范围→计算核心指标→生成Excel报表”);

  2. 规划调度模块:核心中枢,负责规划任务执行步骤、判断依赖关系(比如必须先查数据才能生成报表)、处理异常情况(比如查询超时重试);

  3. 工具调用模块:连接各类外部工具/服务(如数据库查询、Excel生成、邮件发送、LLM接口调用),是Agent实现“落地能力”的关键;

  4. 记忆存储模块:存储任务执行过程中的中间结果、用户偏好、历史交互记录(比如用户上次要求报表按销售额排序,这次自动沿用),Java中常用Redis+MySQL组合实现;

  5. 结果输出模块:将执行结果转化为用户易理解的形式(如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("your-email@xxx.com");
            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("your-email@xxx.com");
            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,然后发送到test@xxx.com邮箱,邮件主题为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的实战案例和源码解析~

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐