告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)

摘要:在AI Agent开发中,"工具调用"(Tool Calling,也叫Function Calling)是一项核心能力。很多Java开发者已经会用Spring AI Alibaba搭建带记忆的AI聊天应用,但这类应用通常只能回答预设范围内的问题------问"今天北京天气怎么样",它多半会说"我无法获取实时信息";问"帮我查一下订单",它只能说"请提供订单号"。

AI真正的价值不只是回答问题,而是执行动作。比如用户说"退订我最近一笔订单",AI自己判断要调用退订API,而不是让用户自己去后台操作。今天就来聊聊Java后端如何实现这种能力。

一、为什么需要工具调用

大模型本质上是一个"文本生成器",它看过海量数据,可以聊起很多话题,但能力边界很明显:没有实时数据,无法获取当前天气、实时股价;没有执行能力,不能发送邮件、创建订单;也不具备精确计算能力,复杂数学题容易出错。

工具调用就是解决这些局限的方案。简单说,开发者先把一些Java方法(比如查天气、查订单)注册为"工具",并把每个工具的作用和参数告诉模型。当用户提问需要用到某个工具时,模型会返回一个调用请求,后端执行对应方法,再把结果交给模型,让它组织成自然语言回答。

整个过程模型并不真正执行任何操作,它只负责"决策"------判断该不该用工具、用哪个工具、用什么参数。真正的执行由后端的Java代码完成。

二、工具调用的完整流程

理解工具调用的最好方式,是看一次完整的交互。

假如用户问"帮我查一下订单10086的物流状态",系统里有一个queryLogistics工具可以查物流。整个过程分四步:

  1. 用户提问 :用户说"查一下订单10086物流"。后端把问题连同工具清单(queryLogistics工具的用途和参数要求)一起发给大模型。
  2. 模型决策 :大模型理解用户意图,返回一个调用请求------调用queryLogistics,参数orderId=10086
  3. 后端执行:后端收到请求,执行Java方法查物流,拿到"已发货,预计明天送达"这类结果。
  4. 模型生成回答:后端把结果返回给模型,模型整合信息,说"订单10086已发货,预计明天送达"。

如果模型判断不需要调用工具(比如问的是"什么是物流"),它会直接返回自然语言回答。

两步调用是工具调用的核心模式:第一次调用让模型决定调什么工具,第二次调用把工具执行结果带回来做最终回答。

三、用Spring AI Alibaba实现工具调用

下面通过Spring AI Alibaba + 通义千问,构建一个能查天气和查订单的智能助手。

3.1 添加依赖

xml 复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.10</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.spring</groupId>
        <artifactId>spring-ai-alibaba-starter</artifactId>
        <version>1.1.2.0</version>
    </dependency>
</dependencies>

3.2 配置API

yaml 复制代码
# application.yml
spring:
  ai:
    dashscope:
      api-key: sk-xxx-your-real-key

3.3 第一步:定义工具

@Tool注解把Java方法标记为可被AI调用的工具。description参数很重要,模型依据它判断什么时候该用这个工具。

java 复制代码
@Service
public class AssistantTools {
    
    @Tool(description = "查询指定城市的实时天气信息,返回温度、天气状况和湿度")
    public String getWeather(String city) {
        // 实际生产环境调用真实天气API
        return switch (city) {
            case "北京" -> "{"city":"北京", "temperature":"25°C", "weather":"晴", "humidity":"40%"}";
            case "上海" -> "{"city":"上海", "temperature":"22°C", "weather":"多云", "humidity":"60%"}";
            case "广州" -> "{"city":"广州", "temperature":"28°C", "weather":"小雨", "humidity":"80%"}";
            default -> "暂不支持该城市的天气查询";
        };
    }
    
    @Tool(description = "根据订单ID查询订单状态,返回订单详情和物流信息")
    public String getOrder(String orderId) {
        // 实际生产环境调用订单服务
        return "{"orderId":"" + orderId + "", "status":"已发货", "tracking":"预计明天送达"}";
    }
}

两个工具分别返回JSON格式的数据,方便模型理解。工具方法返回值会被序列化后发给模型,格式越规整,模型提取信息的准确率越高。

3.4 第二步:注册工具并创建ChatClient

java 复制代码
@Configuration
public class AiConfig {
    
    @Bean
    public ChatClient chatClient(DashScopeChatModel chatModel, AssistantTools assistantTools) {
        return ChatClient.builder(chatModel)
                .defaultSystem("你是一个智能助手,可以帮用户查询天气和订单信息。")
                .defaultTools(assistantTools)  // 注册工具,AI自动决定调用时机
                .build();
    }
}

3.5 第三步:实现聊天接口

java 复制代码
@RestController
@RequestMapping("/api/chat")
public class ChatController {
    
    @Autowired
    private ChatClient chatClient;
    
    @PostMapping("/send")
    public String chat(@RequestBody ChatRequest request) {
        return chatClient.prompt()
                .user(request.getMessage())
                .call()
                .content();
    }
}

只需三步:定义工具、注册工具、调用------框架会自动处理工具发现的请求、解析模型返回的调用指令、执行对应方法、回填结果。

3.6 效果测试

bash 复制代码
# 查询天气
curl -X POST http://localhost:8080/api/chat/send \
  -H "Content-Type: application/json" \
  -d '{"message": "北京今天天气怎么样"}'
# 返回: 北京今天天气晴,气温25°C,湿度40%,适合外出活动。

# 查询订单
curl -X POST http://localhost:8080/api/chat/send \
  -H "Content-Type: application/json" \
  -d '{"message": "帮我查一下订单10086的物流"}'
# 返回: 订单10086已发货,预计明天送达。

用户用自然语言提问,AI自动识别意图并调用相应工具------体验就像人在替你操作。

四、多工具协同:一个请求调多个工具

较复杂的场景可能需要AI连续调用多个工具。比如"帮我查北京天气,顺便查一下订单20086",AI判断要同时调用getWeathergetOrder。两个工具并行执行,框架收集结果后一并返回给模型,整合成完整回答。

注册多工具的方式与单个工具完全相同------Spring AI Alibaba的defaultTools()方法支持传入多个工具实例。框架会自动管理调用链,支持工具间的并行执行和结果聚合。

五、工程落地的注意事项

分享几个在真实项目中踩过的坑:

高危操作须加权限@Tool注解的工具方法建议增加身份校验或二次确认,防止AI在上下文混淆时误触发。比如"删除数据"这类工具,可以增加"请确认"的交互环节。

返回值用JSON格式 。工具返回的数据最好以结构化JSON形式呈现,而非纯文本。模型更容易从JSON中提取字段,回答质量明显更高。

Token消耗翻倍要留意 。每次调用工具都涉及多次模型请求(分析是否需要工具→执行工具→生成最终回答),Token开销比普通对话高,建议给工具设置合理的调用频率限制。

描述要写清楚 。每个工具和参数的description是模型判断调用时机的核心依据,写得不清晰,模型会在不该调用工具的时候胡乱调用。建议遵循"动词+对象+场景"的格式,比如"根据订单ID查询订单的当前状态和物流信息"。

六、接入大模型的选择

工具调用的实现高度依赖底层模型的能力。目前主流的AI大模型对Function Calling的支持程度存在差异------OpenAI的GPT系列是最早推出这一能力的厂商;Google的Gemini模型也提供了类似的工具调用接口;Anthropic的Claude通过tool_use机制实现。

Spring AI Alibaba对各大模型厂家的统一抽象是其核心优势 。开发者只需通过配置切换ChatModel实现,业务代码无需任何修改。这意味着同一个工具方法,可以无缝对接通义千问、百川、DeepSeek等多种国产大模型,方便对比不同模型在具体业务场景下的表现。选型时建议优先考虑中文理解能力强的国产模型,在工具调用的准确率和响应速度上往往更有优势。

七、写在最后

工具调用是大模型从"聊天玩具"走向"生产力工具"的核心能力。有了它,AI不再只是陪你闲聊的网友,而是真正可以帮你干活的助手。

给Java开发者的几点建议:

  • 先从小场景开始,做个支持天气查询的Demo,体验完整的工具注册和调用流程
  • 逐步扩展工具类型,从查询类(信息检索)到操作类(发送邮件、创建工单)
  • 生产环境务必加上权限校验、日志审计和成本控制
  • 多尝试不同大模型,找到最适合业务场景的底座

AI Agent的下一步,是让多个Agent协同工作:一个Agent负责拆解任务,一个负责调工具,还有一个负责汇总结果。下次有机会聊聊多Agent协作的设计思路。

如果你对AI Agent开发感兴趣,欢迎在评论区交流。

相关推荐
编程大师哥1 小时前
匿名函数 lambda + 高阶函数
java·python·算法
vb2008111 小时前
FastAPI APIRouter
开发语言·python
会编程的土豆1 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
東雪木1 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
Cosolar1 小时前
从零写一个 Attention Is All You Need
人工智能·面试·架构
adrninistrat0r1 小时前
Java调用链MCP分析工具
java·python·ai编程
ai_xiaogui1 小时前
PanelAI:新一代AI算力调度系统,支持本地大模型一键部署与商业运营
人工智能·panelai·panelai算力调度系统·本地大模型一键部署平台·ai应用市场管理面板·企业级部署·2026本地ai私有化解决方案
冬奇Lab1 小时前
Agent 系列(9):多 Agent 架构设计模式——Supervisor 与 Pipeline
人工智能·源码·agent
喵个咪1 小时前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm