Java转 AI高薪领域必备-从0到1打通生产级AI Agent开发(高清同步)

62 阅读4分钟

45b9a081ca106ca9c3009fd0962e33f2.jpeg

在 AI 技术飞速发展的今天,Java 程序员面临着新的机遇与挑战。传统的 CRUD 开发已不足以支撑未来的业务需求,企业急需能够将大语言模型(LLM)能力深度融入现有企业级系统的 AI 工程师。得益于 Spring AI 等框架的诞生,Java 开发者无需放弃熟悉的生态,即可构建生产级的智能体。本文将从架构设计到代码实现,带你从零构建一个具备“记忆”与“工具调用”能力的 Agent。

一、 架构选型:为何选择 Spring AI?

对于 Java 程序员来说,Python 虽然是 AI 的母语,但在企业级落地中,Java 的稳定性、类型安全和微服务生态无可替代。Spring AI 作为 Spring 生态的 AI 扩展,提供了类似于 OpenAI API 的抽象层,不仅支持多种大模型厂商,还完美集成了向量数据库和 Function Calling。

我们的目标是构建一个“企业知识问答 Agent”,它能够根据用户的提问,自主判断是查询本地数据库,还是调用 API 获取实时数据。

二、 环境搭建与核心配置

首先,我们需要在 Spring Boot 项目中引入 Spring AI 的依赖(以 OpenAI 接口为例):

在 application.yml 中配置 API Key 和基础参数:

yaml

复制

spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:
          model: gpt-4o
          temperature: 0.7

三、 核心:实现 Function Calling(工具调用)

生产级 Agent 的核心在于“手眼协调”。Function Calling 允许 LLM 在生成文本之外,输出一个结构化的 JSON 对象,指示 Java 程序执行特定的代码逻辑。

假设我们需要 Agent 具备查询用户订单状态的能力。首先定义一个 Java 记录类来描述函数的参数:

java

复制

package com.example.agent.service;

import com.fasterxml.jackson.annotation.JsonClassDescription;
import com.fasterxml.jackson.annotation.JsonInclude;

import java.util.function.Function;

// 1. 定义请求参数结构
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonClassDescription("查询用户订单的请求参数")
public record OrderRequest(
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonClassDescription("订单的唯一标识 ID")
        String orderId
) {}

接着,实现具体的业务逻辑,并利用 Spring AI 的注解将其注册为 Agent 的“技能”:

java

复制

import org.springframework.context.annotation.Description;
import org.springframework.stereotype.Service;
import java.util.UUID;

@Service
@Description("查询用户的订单状态和物流信息") // 关键:这个描述会被发给 LLM
public class OrderService implements Function<OrderService.OrderRequest, String> {

    // 模拟数据库查询逻辑
    @Override
    public String apply(OrderService.OrderRequest request) {
        if (request.orderId() == null) {
            return "错误:请提供订单 ID。";
        }
        
        // 这里模拟从数据库查询
        String status = "已发货";
        String location = "上海转运中心";
        
        return String.format("订单 %s 当前状态:%s,位置:%s。", 
                             request.orderId(), status, location);
    }

    // 内部 Record 引用
    public record OrderRequest(String orderId) {}
}

四、 编排 Agent:连接大脑与双手

有了“技能”后,我们需要在 Controller 层或专门的 Service 层进行编排。这是 Agent 的“大脑”工作的地方:它接收用户输入,决定是否调用 OrderService,并将返回结果组织成自然语言。

java

复制

package com.example.agent.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/agent")
public class AgentController {

    private final ChatClient chatClient;

    // 3. 注入 ChatClient 和我们定义的 Service Bean
    public AgentController(ChatClient.Builder builder, OrderService orderService) {
        this.chatClient = builder
                .defaultSystem("你是一个智能客服助手,可以查询订单信息。")
                // 启用 Function Calling,将 OrderService 注册进去
                .defaultFunctions(orderService) 
                // 启用记忆能力,让 Agent 记住之前的对话
                .defaultAdvisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
                .build();
    }

    @PostMapping("/chat")
    public String chat(@RequestBody String userMessage) {
        // 4. 一行代码完成 Agent 调用
        // Agent 会自动思考:用户问的是订单吗?是 -> 调用 orderService -> 把结果给 LLM -> 回复用户
        return chatClient.prompt()
                .user(userMessage)
                .call()
                .content();
    }
}

五、 进阶思考:从 Demo 到生产

上述代码虽然简洁,但已经包含了生产级 Agent 的核心要素。在进阶之路上,Java 程序员还需要关注以下几点:

  1. Prompt 管理工程化:不要将硬编码的 System Prompt 写在代码里。应结合 Spring 的配置管理或专门的 Prompt 模板引擎(如 StringTemplate)进行版本化管理。
  2. 向量数据库集成:对于企业私有知识,需要引入 Redis Vector 或 Milvus,利用 QuestionAnswerAdvisor 实现 RAG(检索增强生成)。
  3. 可观测性:Agent 的执行过程是不透明的。我们需要通过 Spring Boot Actuator 或自定义切面,记录 LLM 的 Token 消耗、Function Call 的调用链路以及响应时间,以便监控成本与性能。
  4. 异步流式响应:为了提升用户体验,应使用 Flux<String> 替代同步的 String 返回,实现打字机效果。

结语

Java 程序员转型 AI 并非从零开始,而是在坚实的软件工程地基之上,安装 AI 的“引擎”。通过 Spring AI,我们可以利用熟悉的依赖注入、AOP 等特性,将大模型的能力封装成标准的组件。掌握这种开发范式,将使你在构建企业级智能应用时如虎添翼。