Java大模型开发入门 (11/15):让AI自主行动 - 初探LangChain4j中的智能体(Agents)

发布于:2025-06-15 ⋅ 阅读:(18) ⋅ 点赞:(0)
前言

在过去的十篇文章里,我们已经打造出了一个相当强大的AI应用。它有记忆,能进行多轮对话;它有知识,能通过RAG回答关于我们私有文档的问题。它就像一个博学的“学者”,你可以向它请教任何在其知识范围内的问题。

但是,这个“学者”有一个巨大的局限:它只能说,不能做

  • 如果你问它:“今天北京天气怎么样?” 它只能根据训练数据回答一个大概,无法获取实时信息。
  • 如果你问它:“345乘以678等于多少?” 像gpt-4o-mini这样的高级模型或许能算对,但它本质上是在“预测”答案,而非进行精确计算,对于复杂运算容易出错。
  • 如果你让它:“帮我预订一张明天去上海的火车票。” 它更是无能为力。

今天,我们将为我们的AI引入一个革命性的新能力:行动。我们将把它从一个“问答机器人”,升级为一个能使用工具的 “智能体(Agent)” ,让它能够响应我们的指令,去执行真正的任务。

第一部分:什么是AI Agent?从“聊天”到“行动”

AI Agent和我们之前构建的聊天机器人(Chatbot)最大的区别在于:

Chatbot 的工作是根据上下文生成文本
Agent 的工作是根据用户目标,选择并执行动作(使用工具),最终达成目标。

这个过程模仿了人类助理的工作模式。当你对助理说:“帮我算一下5加上7等于几?” 助理不会凭空猜测,而是会执行以下步骤:

  1. 思考(Reasoning): “老板想让我算个数,这是一个加法运算。”
  2. 选择工具(Tool Selection): “我应该使用‘计算器’这个工具。”
  3. 准备参数(Parameter Extraction): “计算器的‘加法’功能需要两个数字,它们是5和7。”
  4. 执行工具(Tool Execution): 在计算器上按下 5 + 7 =
  5. 观察结果(Observation): 计算器显示结果是 12
  6. 生成最终回复(Response Generation): “老板,5加上7等于12。”

这个“思考->行动”的循环,就是Agent的核心。这之所以能实现,得益于现代大语言模型(如gpt-4o-mini)内置的强大能力——工具调用(Tool Calling)。我们只需向模型描述我们有哪些可用的工具,模型就能在需要时,告诉我们应该调用哪个工具以及需要提供哪些参数。

第二部分:在LangChain4j中定义一个“工具”

在LangChain4j中,赋予AI一个工具非常简单:你只需要创建一个普通的Java方法,并给它加上@Tool注解。

这个注解的作用就是向大语言模型“注册”这个方法,并告诉模型:

  • 这个工具是干什么用的(通过注解的value属性或方法的 Javadoc)。
  • 这个工具需要哪些参数(通过方法的参数列表)。

实战:创建一个计算器工具

  1. 创建Tools
    service包下创建一个新文件CalculatorTools.java

    package com.example.aidemoapp.service;
    
    import dev.langchain4j.agent.tool.Tool;
    import org.springframework.stereotype.Component;
    
    @Component // 将这个类注册为一个Spring Bean
    public class CalculatorTools {
    
        @Tool("Calculates the sum of two integers")
        public int add(int a, int b) {
            System.out.println("Tool executed: add(" + a + ", " + b + ")");
            return a + b;
        }
    
        @Tool("Calculates the difference between two integers")
        public int subtract(int a, int b) {
            System.out.println("Tool executed: subtract(" + a + ", " + b + ")");
            return a - b;
        }
    }
    

    代码解析

    • @Component:让Spring能够发现并管理这个类的实例。
    • @Tool("..."):注解的描述至关重要!LLM会根据这个描述来判断用户的意图是否与该工具匹配。描述写得越清晰,Agent就越“聪明”。
第三部分:构建一个能使用工具的Agent

我们将使用AiServices来创建一个新的Agent。这次,在构建AiService时,我们会告诉它有哪些工具(Tools)是可用的。

  1. config/LangChain4jConfig.java中创建Agent Bean
    我们将创建一个新的AI服务,专门用于演示Agent功能。

    // LangChain4jConfig.java
    
    // ... 其他Bean的定义 ...
    import com.example.aidemoapp.service.AgentAssistant;
    import com.example.aidemoapp.service.CalculatorTools;
    
    // ...
    
    @Configuration
    public class LangChain4jConfig {
        
        // ... 其他已有的Bean ...
    
        // 步骤1: 定义一个新的Agent服务接口Bean
        @Bean
        public AgentAssistant agentAssistant(ChatModel chatLanguageModel, CalculatorTools calculatorTools) {
            return AiServices.builder(AgentAssistant.class)
                    .chatModel(chatLanguageModel)
                    .tools(calculatorTools) // <-- 关键步骤:将工具注册到AI服务中
                    .build();
        }
    }
    
  2. 定义AgentAssistant接口
    service包下创建AgentAssistant.java

    package com.example.aidemoapp.service;
    
    public interface AgentAssistant {
        String chat(String userMessage);
    }
    
  3. 创建AgentController
    controller包下创建AgentController.java

    package com.example.aidemoapp.controller;
    
    import com.example.aidemoapp.service.AgentAssistant;
    import lombok.RequiredArgsConstructor;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/api/agent")
    @RequiredArgsConstructor
    public class AgentController {
    
        private final AgentAssistant agentAssistant;
    
        @GetMapping("/chat")
        public String chat(@RequestParam("query") String query) {
            return agentAssistant.chat(query);
        }
    }
    
第四步:测试我们的新Agent!
  1. 启动Spring Boot应用。

  2. 进行一次普通聊天
    请求URL: http://localhost:8080/api/agent/chat?query=Who are you?
    你会得到一个正常的回答,比如“我是一个乐于助人的助手”。此时,查看后台日志,没有任何"Tool executed"的打印。

  3. 进行一次需要使用工具的聊天
    请求URL: http://localhost:8080/api/agent/chat?query=What is 5 plus 7?
    稍等片刻,你会得到回答:“5 plus 7 is 12.”
    现在,查看后台日志,你会看到:

    Tool executed: add(5, 7)
    

    这证明了Agent成功地理解了你的意图,并调用了正确的Java方法!

  4. 再试一次
    请求URL: http://localhost:8080/api/agent/chat?query=What is 100 minus 33?
    你会得到回答:“100 minus 33 is 67.”
    后台日志会显示:

    Tool executed: subtract(100, 33)
    
总结

今天,我们成功地为我们的AI应用解锁了一项颠覆性的能力——行动。通过LangChain4j的@Tool注解和AiServices,我们轻松地将一个普通的Java方法变成了AI可以调用的工具,构建了一个初级的AI智能体。

我们的AI不再只是一个“知道分子”,它变成了一个能干活的“行动派”。

目前我们的工具还很简单,只是一个本地的计算器。但在真实世界中,工具的能力是无限的:它可以是一个调用外部天气API的HTTP客户端,一个查询数据库的DAO,甚至是一个发送邮件的服务。如何构建一个能与真实世界API交互的、更强大的Agent呢?


源码获取

本文中所有实战代码均已同步更新至Gitee仓库。建议您git pull拉取最新代码,对照本文进行学习。


下一篇预告:
Java大模型开发入门 (12/15):Agent实战 - 打造能调用外部API的智能助手》—— 我们将把难度升级,封装一个能查询实时天气信息的API作为工具,打造一个能回答“明天上海天气怎么样?”这类问题的、更实用的智能助手。


网站公告

今日签到

点亮在社区的每一天
去签到