首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Spring AI 实战:Tools能力详解—— 让大模型拥有动手能力

Spring AI 实战:Tools能力详解—— 让大模型拥有动手能力

作者头像
章为忠学架构
发布2026-04-21 10:40:58
发布2026-04-21 10:40:58
1540
举报
文章被收录于专栏:AI大模型AI大模型

在之前的文章中,我们已经掌握了 Agent 的记忆能力,实现了能够记住用户偏好的智能行程规划 Agent。然而,你可能会发现一个问题:当用户问 “北京明天天气怎么样?” 时,Agent 只能回复 “抱歉,我无法获取实时天气信息”。当用户问 “帮我推荐一些北京的热门景点” 时,Agent 只能依赖训练数据中的旧信息,无法提供最新、最准确的推荐。

这是因为 Agent 虽然具备强大的推理和记忆能力,但缺乏 “手脚”——无法主动获取外部信息或执行实际操作。本文将带你深入了解 Agent 的工具调用能力,通过 Spring AI 的 Tool 机制,让 Agent 从 “信息提供者” 升级为 “任务执行者”。

本系列文章源码:https://gitee.com/weizhong1988/weiz-spring-ai

一、为什么 Agent 需要工具调用能力?

1.1 大模型的局限性

大语言模型(LLM)虽然具备强大的认知能力,但存在天然局限:

  • 知识截止:模型训练数据有时间截止点,无法获取最新信息(如今日天气、最新新闻)
  • 无法访问外部系统:无法主动查询数据库、调用 API、执行代码
  • 缺乏执行能力:只能生成文本,无法完成实际操作(如发送邮件、预订酒店)

这就像一个 “身怀绝技但被困在密室的天才”——有满腹经纶,却无法触及外界。

1.2 工具调用的价值

工具调用(Tool Calling)为 Agent 提供了 “手脚”,使其能够:

  • 获取实时信息:查询天气、股票行情、航班动态
  • 执行实际操作:发送邮件、预订酒店、操作数据库
  • 访问企业内部系统:查询 CRM、ERP、知识库

有了工具,Agent 从 “只能对话的 AI” 进化为 “能完成任务的智能助手”。

1.3 典型应用场景

场景

调用工具类型

实现效果

智能客服

订单查询、退款处理、转人工

自动处理售后请求,无需人工介入

智能行程规划

天气查询、景点推荐、酒店预订

结合实时数据生成个性化行程方案

智能投研

股票行情、财报检索、新闻聚合

实时市场数据辅助投资分析与决策

智能办公

邮件发送、日程查询、报表生成

自动化日常办公任务,提升效率

二、核心概念解析

2.1 什么是 Tool?

Tool(工具) 是 Agent 可以调用的外部函数或 API,用于扩展 Agent 的能力边界。每个 Tool 通常包含:

  • 名称:工具的唯一标识(如 getWeather)
  • 描述:工具的功能说明(如 “获取指定城市的实时天气信息”)
  • 参数:调用工具所需的输入参数(如 city: String)
  • 返回值:工具执行后的输出结果(如天气数据 JSON)

核心流程如下:

2.2 工具调用的实现原理

工具调用的核心原理可以概括为 “三轮对话” 模式:

第一轮:用户提问 → 模型判断是否需要工具

代码语言:javascript
复制
用户:北京明天天气怎么样?
模型:我需要调用 getWeather 工具
返回:{ "tool_calls": [{ "name": "getWeather", "arguments": { "city": "北京" } }] }

第二轮:应用层执行工具 → 返回结果给模型

代码语言:javascript
复制
应用层:调用天气 API → { "city": "北京", "weather": "晴", "temp": "18-25°C" }
返回:{ "tool_call_id": "xxx", "content": "{ \"city\": \"北京\", \"weather\": \"晴\", \"temp\": \"18-25°C\" }" }

第三轮:模型基于工具结果生成最终回复

代码语言:javascript
复制
模型:北京明天晴,气温 18-25°C,适合出行。建议携带防晒用品。

这个 “判断 → 执行 → 回复” 的闭环,正是工具调用的核心流程。

三、Spring AI 实现 Tools 的原理

3.1 核心组件

代码语言:javascript
复制
定义工具的入口,标注在 Spring Bean 方法上,Spring AI 自动识别并注册为可调用工具

3.2 工作机制

Spring AI 已经把工具调用流程封装得非常简单,整体流程只有 5 步:

  1. 工具定义:通过@Tool注解定义一个工具,
  2. Schema 生成:自动提取方法签名生成JSON Schema,告诉模型 “我有这些工具可用”;
  3. 模型决策:用户提问 → 模型判断是否需要调用工具;模型判断是否需要调用工具,
  4. 自动执行:Spring AI 自动解析参数,自动执行工具方法;
  5. 结果回传:将结果回传给模型,工具返回真实数据 → 模型整理成自然语言回答。
  6. 生成回复:模型基于结果生成最终答案,返回给用户;

3.3 工具描述的 Schema 生成机制

Spring AI 通过自动化的 Schema 生成机制,将 Java 方法签名转换为模型可理解的 JSON Schema:

代码语言:javascript
复制
@Tool(description = "获取指定城市的实时天气信息,返回天气状况、温度范围、空气质量及出行建议")
public String getWeather(
    @ToolParam(description = "城市名称,支持中文") String city
) { ... }

// 自动生成的 JSON Schema:
{
  "type": "function",
  "function": {
    "name": "getWeather",
    "description": "获取指定城市的实时天气信息,返回天气状况...",
    "parameters": {
      "type": "object",
      "properties": {
        "city": { "type": "string", "description": "城市名称,支持中文" }
      },
      "required": ["city"]
    }
  }
}

3.4 工具定义方式

Spring AI 对工具的定义方式设计得十分简洁易用,开发者在使用过程中无需复杂配置,仅需通过@Tools注解即可快速完成工具的声明与注册,极大简化了工具接入与集成的流程。

代码语言:javascript
复制
@Component
public class WeatherTool {

    @Tool(description = "获取指定城市的实时天气信息")
    public String getWeather(
        @ToolParam(description = "城市名称") String city
    ) {
        return "{\"city\": \"北京\", \"weather\": \"晴\"}";
    }
}

四、【实战案例】:带工具调用能力的智能行程规划 Agent

4.1 案例目标

延续前面的智能行程规划 Agent 案例。Agent 已具备记忆能力,本次目标是为其集成两个实用工具:

  • 天气查询工具(getWeather):获取目的地实时天气,为出行提供针对性建议。
  • 景点推荐工具(recommendAttractions):根据城市和偏好返回热门景点信息,包括评分、游览时长、简介

实现效果:用户说"帮我规划北京周末游,看看天气,再推荐几个人文景点",Agent 自动判断需要调用天气和景点两个工具,获取实时数据后整合生成个性化行程。

4.2 技术选型

技术模块

选型方案

开发框架

Spring Boot 3.5.3 + Spring AI 1.0.0

大模型

智谱 AI(Chat:GLM-4-Flash)

核心依赖

Spring Web、Spring AI 智普 AI Starter、Lombok

工具实现

模拟天气 API + 模拟景点数据(可替换为真实 API)

4.3 项目初始化与配置

1. 创建 Spring Boot 项目

  • 项目名称:Weiz-SpringAI-Agent-Tool
  • JDK 版本:17
  • Spring Boot 版本:3.5.3
  • 核心依赖:Spring Web、Spring AI 智普 AI Starter、Lombok

2. 配置 pom.xml 依赖

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>Weiz-SpringAI-Agent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>Weiz-SpringAI-Agent-Tools</artifactId>
    <name>Weiz-SpringAI-Agent-Tools</name>
    <description>Weiz-SpringAI-Agent-Tools</description>

    <properties>
        <java.version>17</java.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-zhipuai</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-client-chat</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3. 配置 application.properties

代码语言:javascript
复制
spring.application.name=Weiz-SpringAI-Agent-Tools

server.port=8080

spring.ai.zhipuai.api-key=你的智谱api key
spring.ai.zhipuai.base-url=https://open.bigmodel.cn/api/paas
spring.ai.zhipuai.chat.options.model=GLM-4-Flash

logging.level.org.springframework.ai=INFO
logging.level.com.example=DEBUG

4.4 核心开发:定义天气查询工具

创建 com.example.weizspringai.tool.WeatherTool类,使用 @Tool 注解定义天气查询工具:

代码语言:javascript
复制
package com.example.weizspringai.tools;

import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;

/**
 * 天气查询工具
 * 实际项目中可替换为真实天气 API(如和风天气、彩云天气)
 */
@Component
public class WeatherTool {

    @Tool(description = "获取指定城市的实时天气信息,返回天气状况、温度范围、空气质量、出行建议")
    public String getWeather(
            @ToolParam(description = "城市名称,支持中文,如:北京、上海、广州、成都、西安、杭州") String city
    ) {
        // 模拟天气 API 调用(实际项目替换为真实 API)
        return simulateWeatherApi(city);
    }

    /**
     * 模拟天气 API(演示用)
     * 实际项目可接入:和风天气 API、彩云天气 API 等
     */
    private String simulateWeatherApi(String city) {
        String weatherData;
        if (city.contains("北京")) {
            weatherData = "晴,气温 18-25°C,空气质量优,紫外线较强,建议防晒";
        } else if (city.contains("上海")) {
            weatherData = "多云,气温 20-28°C,空气质量良,有轻微雾霾,建议佩戴口罩";
        } else if (city.contains("广州")) {
            weatherData = "小雨,气温 22-26°C,湿度 85%,建议携带雨具";
        } else if (city.contains("成都")) {
            weatherData = "阴天,气温 16-22°C,空气质量良,适合室内外活动";
        } else if (city.contains("西安")) {
            weatherData = "晴朗,气温 15-23°C,空气质量良,适合户外观光";
        } else if (city.contains("杭州")) {
            weatherData = "多云转晴,气温 19-27°C,空气质量优,西湖游览佳日";
        } else {
            weatherData = "晴,气温 20-25°C,空气质量良,适合出行";
        }

        return String.format(
                "{\"city\": \"%s\", \"weather\": \"%s\", \"source\": \"实时天气数据\"}",
                city, weatherData
        );
    }
}

4.5 核心开发:定义景点推荐工具

创建com.example.weizspringai.tool.AttractionTool 类,使用@Tool 注解定义景点推荐工具:

代码语言:javascript
复制
package com.example.weizspringai.tools;

import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 景点推荐工具
 * 实际项目中可对接旅游平台 API 或自建景点数据库
 */
@Component
public class AttractionTool {

    // 模拟景点数据库
    private static final Map<String, List<AttractionInfo>> ATTRACTIONS_DB = Map.of(
            "北京", List.of(
                    new AttractionInfo("故宫", "人文", "5.0", "3-4小时", "世界文化遗产,明清皇家宫殿"),
                    new AttractionInfo("长城(八达岭)", "人文", "5.0", "半天", "世界七大奇迹之一"),
                    new AttractionInfo("颐和园", "人文", "4.8", "2-3小时", "皇家园林博物馆"),
                    new AttractionInfo("天坛", "人文", "4.7", "2小时", "明清祭天场所"),
                    new AttractionInfo("北京环球影城", "娱乐", "4.9", "全天", "顶级主题乐园")
            ),
            "上海", List.of(
                    new AttractionInfo("外滩", "人文", "4.9", "1-2小时", "万国建筑博览群"),
                    new AttractionInfo("上海迪士尼", "娱乐", "4.8", "全天", "亚洲顶级迪士尼乐园"),
                    new AttractionInfo("豫园", "人文", "4.6", "2小时", "江南古典园林"),
                    new AttractionInfo("东方明珠", "人文", "4.7", "2小时", "上海地标建筑")
            ),
            "成都", List.of(
                    new AttractionInfo("大熊猫繁育研究基地", "自然", "4.9", "半天", "近距离观赏大熊猫"),
                    new AttractionInfo("宽窄巷子", "人文", "4.7", "2-3小时", "成都历史文化街区"),
                    new AttractionInfo("都江堰", "人文", "4.8", "半天", "世界文化遗产水利工程"),
                    new AttractionInfo("青城山", "自然", "4.7", "全天", "道教名山,天然氧吧")
            ),
            "西安", List.of(
                    new AttractionInfo("兵马俑", "人文", "5.0", "半天", "世界第八大奇迹"),
                    new AttractionInfo("大雁塔", "人文", "4.8", "2小时", "唐代佛教建筑"),
                    new AttractionInfo("古城墙", "人文", "4.7", "2-3小时", "中国现存最完整古城墙"),
                    new AttractionInfo("大唐不夜城", "人文", "4.8", "晚上", "沉浸式唐文化体验")
            ),
            "杭州", List.of(
                    new AttractionInfo("西湖", "自然", "5.0", "半天", "世界文化遗产,人间天堂"),
                    new AttractionInfo("灵隐寺", "人文", "4.7", "2小时", "千年古刹"),
                    new AttractionInfo("宋城", "娱乐", "4.6", "全天", "大型演艺主题公园"),
                    new AttractionInfo("西溪湿地", "自然", "4.5", "半天", "城市湿地公园")
            ),
            "广州", List.of(
                    new AttractionInfo("广州塔", "人文/娱乐", "4.9", "2-3小时", "广州地标,小蛮腰,高空观光与游乐项目"),
                    new AttractionInfo("广州长隆野生动物世界", "自然/娱乐", "4.9", "全天", "国家级野生动物园,亲子游玩首选"),
                    new AttractionInfo("广州杜莎夫人蜡像馆", "娱乐/室内", "4.7", "2小时", "室内明星蜡像打卡,全空调舒适游览"),
                    new AttractionInfo("广东省博物馆", "人文/室内", "4.8", "2-3小时", "岭南历史文化全室内展厅,免费需预约"),
                    new AttractionInfo("广东省博物馆", "人文", "4.8", "2-3小时", "了解岭南历史文化,免费参观需预约"),
                    new AttractionInfo("永庆坊", "人文", "4.7", "2小时", "老广州骑楼街区,粤剧艺术网红打卡地"),
                    new AttractionInfo("白云山", "自然", "4.8", "半天", "广州城市绿肺,登高俯瞰全城美景")
            )
    );

    @Tool(description = "根据城市和景点类型偏好推荐热门景点,返回景点名称、类型、评分、建议游览时长、景点简介")
    public String recommendAttractions(
            @ToolParam(description = "城市名称,如:北京、上海、成都、西安、杭州") String city,
            @ToolParam(description = "景点类型偏好:人文、自然、娱乐;不填则推荐全部类型", required = false) String preference
    ) {
        List<AttractionInfo> attractions = ATTRACTIONS_DB.getOrDefault(city, List.of());

        if (attractions.isEmpty()) {
            return String.format("{\"error\": \"暂无 %s 的景点数据,请尝试其他城市\"}", city);
        }

        // 根据偏好筛选
        if (preference != null && !preference.isEmpty()) {
            attractions = attractions.stream()
                    .filter(a -> a.type.contains(preference) || preference.contains(a.type))
                    .collect(Collectors.toList());
        }

        // 构建 JSON 返回结果
        StringBuilder result = new StringBuilder();
        result.append("{\"city\": \"").append(city).append("\", ");
        if (preference != null && !preference.isEmpty()) {
            result.append("\"preference\": \"").append(preference).append("\", ");
        }
        result.append("\"attractions\": [");

        for (int i = 0; i < attractions.size(); i++) {
            AttractionInfo a = attractions.get(i);
            result.append(String.format(
                    "{\"name\": \"%s\", \"type\": \"%s\", \"rating\": \"%s\", \"duration\": \"%s\", \"intro\": \"%s\"}",
                    a.name, a.type, a.rating, a.duration, a.intro
            ));
            if (i < attractions.size() - 1) {
                result.append(", ");
            }
        }

        result.append("], \"count\": ").append(attractions.size()).append("}");
        return result.toString();
    }

    // 景点信息内部类
    private static class AttractionInfo {
        String name;
        String type;
        String rating;
        String duration;
        String intro;

        AttractionInfo(String name, String type, String rating, String duration, String intro) {
            this.name = name;
            this.type = type;
            this.rating = rating;
            this.duration = duration;
            this.intro = intro;
        }
    }
}

4.6 核心开发:Agent 服务集成工具

创建com.example.weizspringai.service.ToolTripAgentService 类,封装带工具调用能力的行程规划逻辑:

代码语言:javascript
复制
package com.example.weizspringai.service;


import com.example.weizspringai.tools.AttractionTool;
import com.example.weizspringai.tools.WeatherTool;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.stereotype.Service;

/**
 * 带工具调用能力的智能行程规划 Agent
 * 核心能力:自动判断并调用天气、景点工具,生成个性化行程
 */
@Service
@RequiredArgsConstructor
public class ToolTripAgentService {

    private final ChatModel chatModel;
    private final WeatherTool weatherTool;
    private final AttractionTool attractionTool;

    /**
     * 带工具调用的行程规划
     * @param demand 用户出行需求(可包含天气查询、景点推荐、行程规划)
     * @return 结合实时数据的个性化行程规划
     */
    public String planTripWithTools(String demand) {
        // 定义 Agent 行为规则:引导模型合理使用工具
        String systemPrompt = """
            你是一个具备工具调用能力的智能行程规划 Agent,核心规则如下:

            1. 当用户询问天气时,必须调用 getWeather 工具获取实时天气数据;
            2. 当用户需要景点推荐时,必须调用 recommendAttractions 工具获取景点信息;
            3. 结合天气数据和景点信息,生成完整的行程规划建议;
            4. 行程安排要考虑天气因素(如雨天推荐室内景点,晴天推荐户外景点);
            5. 输出结构清晰,包含天气概况、推荐景点、行程安排、实用提示;
            6. 所有实时信息必须通过工具获取,严禁编造天气或景点数据。

            回复风格:简洁专业,突出实用信息,适合移动端阅读。
            """;

        // 克隆一个全新Builder,避免共享污染
        ChatClient chatClient = ChatClient.builder(chatModel)
                .defaultSystem(systemPrompt)
                .defaultTools(weatherTool, attractionTool)
                .build();

        // 调用大模型(自动判断是否需要工具调用)
        return chatClient.prompt()
                .user(demand)
                .call()
                .content();
    }
}

4.7 创建 Controller 接口

创建 com.example.weizspringai.controller.AgentToolController 类,提供带工具调用的行程规划 HTTP 接口:

代码语言:javascript
复制
package com.example.weizspringai.controller;

import com.example.weizspringai.service.ToolTripAgentService;
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;

import java.util.Map;

/**
 * 带工具调用的 Agent 接口
 */
@RestController
@RequestMapping("/agent/tool")
@RequiredArgsConstructor
public class AgentToolController {

    private final ToolTripAgentService toolTripAgentService;

    /**
     * 带工具调用的行程规划接口
     * @param demand 用户出行需求
     * @return 智能行程规划结果(自动调用天气、景点工具)
     */
    @GetMapping("/plan")
    public Map<String, String> planTrip(@RequestParam("demand") String demand) {
        String tripPlan = toolTripAgentService.planTripWithTools(demand);
        return Map.of(
                "userDemand", demand,
                "tripPlan", tripPlan,
                "agentType", "带工具调用能力的智能行程规划 Agent"
        );
    }
}

五、系统测试与验证

5.1 测试 1:查询天气(验证天气工具单工具调用)

访问接口 http://localhost:8080/agent/tool/plan?demand=北京明天天气怎么样?适合出行吗?

Agent 识别到用户询问天气问题,自动调用 getWeather 工具获取北京实时天气数据,返回结果:

代码语言:javascript
复制
{
  "userDemand": "北京明天天气怎么样?适合出行吗?",
  "tripPlan": "根据实时天气数据,北京明天的天气是晴,气温在18-25°C之间,空气质量优,紫外线较强,建议出行时注意防晒。",
  "agentType": "带工具调用能力的智能行程规划 Agent"
}

Agent 基于工具返回数据,生成包含天气概况和出行建议的回答。测试通过,验证了单工具调用的正确性。

5.2 测试 2:推荐景点(验证景点工具单工具调用)

访问接口http://localhost:8080/agent/tool/plan?demand=推荐几个北京的人文景点,最好评分高的

Agent 识别到用户需要景点推荐,自动调用 recommendAttractions 工具获取北京热门人文景点,返回结果:

代码语言:javascript
复制
{
  "agentType": "带工具调用能力的智能行程规划 Agent",
  "userDemand": "推荐几个北京的人文景点,最好评分高的",
  "tripPlan": "根据您的需求,我为您推荐了北京的人文景点。经过API调用,我找到了以下四个评分较高的景点:故宫、长城(八达岭)、颐和园和天坛。故宫是世界文化遗产,明清皇家宫殿,建议游览时长为3-4小时;长城(八达岭)是世界七大奇迹之一,建议游览半天;颐和园是皇家园林博物馆,建议游览时长为2-3小时;天坛是明清祭天场所,建议游览时长为2小时。希望这些信息能对您的旅行有所帮助。"
}

Agent 基于工具返回数据,整理为结构化的景点推荐列表。测试通过,验证了景点工具的参数传递和结果解析正确性。

5.3 测试 3:综合场景(天气 + 景点 + 行程规划,多工具组合调用)

访问接口http://localhost:8080/agent/tool/plan?demand=帮我规划北京周末两天游,先看看天气,再推荐几个人文景点,生成完整行程

Agent 识别到这是一个综合请求,自动先后调用两个工具。首先调用 getWeather 工具获取北京天气数据,然后调用 recommendAttractions 工具获取北京人文景点列表,最后综合两部分数据生成完整行程规划。

代码语言:javascript
复制
{
  "agentType": "带工具调用能力的智能行程规划 Agent",
  "userDemand": "帮我规划北京周末两天游,先看看天气,再推荐几个人文景点,生成完整行程",
  "tripPlan": "您好,根据实时天气数据,北京本周末天气晴好,气温18-25°C,空气质量优,紫外线较强,建议外出时注意防晒。根据您的需求,我为您推荐了以下四个人文景点:故宫、长城(八达岭)、颐和园、天坛。故宫是世界文化遗产,明清皇家宫殿,建议游览3-4小时;长城(八达岭)是世界七大奇迹之一,建议游览半天;颐和园是皇家园林博物馆,建议游览2-3小时;天坛是明清祭天场所,建议游览2小时。以下是您的行程安排:第一天:上午游览故宫,下午游览长城(八达岭);第二天:上午游览颐和园,下午游览天坛。希望对您有所帮助。"
}

测试通过,验证了多工具组合调用的正确性,以及 Agent 综合多源数据生成完整回答的能力。

5.4 测试 4:天气影响行程决策(雨天场景)

访问接口http://localhost:8080/agent/tool/plan?demand=广州天气怎么样?如果下雨的话推荐室内景点

Agent 自动调用天气工具获取广州天气数据,返回 "小雨,气温 22-26°C,湿度 85%"。结合天气结果,Agent 智能调整推荐策略,优先展示室内景点:

代码语言:javascript
复制
{
  "agentType": "带工具调用能力的智能行程规划 Agent",
  "tripPlan": "当前广州的天气情况为:小雨,气温 22-26°C,湿度 85%,建议携带雨具。根据您的要求,我为您推荐以下室内景点:广州杜莎夫人蜡像馆和广东省博物馆。广州杜莎夫人蜡像馆是一处娱乐/室内景点,评分高达4.7分,建议游览时长为2小时,您可以在这里室内打卡,感受明星的魅力。广东省博物馆则是一处人文/室内景点,评分高达4.8分,建议游览时长为2-3小时,这里可以了解岭南历史文化。希望这些信息能够帮助您制定行程计划。",
  "userDemand": "广州天气怎么样?如果下雨的话推荐室内景点"
}

通过上述功能测试验证可确认,Agent 调用工具的相关功能已实现并验证通过。

总结

本文通过 Spring AI 的工具调用能力,为智能行程规划 Agent 新增了实时信息获取能力,解决了 "依赖训练数据" 和 "无法执行操作" 两大核心问题。Spring AI 封装了 @Tool 注解、ChatClient 自动编排、JSON Schema 自动生成等复杂机制,开发者只需专注于定义工具的业务逻辑,极大降低了工具调用的开发门槛。

回顾 Agent 能力演进路径:基础 Agent(System Prompt 定义行为)→ 记忆型 Agent(ChatMemory 存储偏好)→ 工具型 Agent(Tool 调用获取实时数据)→ (未来)MCP 型 Agent(标准化协议实现跨系统交互)。

后续文章将继续深入 Agent 的高级特性,讲解如何结合记忆能力与工具调用能力(如记住用户偏好的景点类型后自动筛选推荐),以及 Agent + MCP(模型上下文协议) 的标准化交互模式,构建真正可投入生产环境的智能 Agent 系统。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 架构师精进 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、为什么 Agent 需要工具调用能力?
    • 1.1 大模型的局限性
    • 1.2 工具调用的价值
    • 1.3 典型应用场景
  • 二、核心概念解析
    • 2.1 什么是 Tool?
    • 2.2 工具调用的实现原理
  • 三、Spring AI 实现 Tools 的原理
    • 3.1 核心组件
    • 3.2 工作机制
    • 3.3 工具描述的 Schema 生成机制
    • Spring AI 通过自动化的 Schema 生成机制,将 Java 方法签名转换为模型可理解的 JSON Schema:
    • 3.4 工具定义方式
  • 四、【实战案例】:带工具调用能力的智能行程规划 Agent
    • 4.2 技术选型
    • 4.4 核心开发:定义天气查询工具
    • 4.5 核心开发:定义景点推荐工具
    • 4.6 核心开发:Agent 服务集成工具
    • 4.7 创建 Controller 接口
  • 五、系统测试与验证
    • 5.1 测试 1:查询天气(验证天气工具单工具调用)
    • 5.2 测试 2:推荐景点(验证景点工具单工具调用)
    • 5.3 测试 3:综合场景(天气 + 景点 + 行程规划,多工具组合调用)
    • 5.4 测试 4:天气影响行程决策(雨天场景)
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档