Tool Calling 工具调用

发布时间:2026/9/25 12:19:07

Tool Calling 工具调用 目录一、概述二、工具定义与使用工具定义工具使用三、Tool Calling 使用案例1) 创建SpringBoot项目命名为“SpringAIToolCalling”2) 配置项目pom.xml3) 配置resources/application.properties4) 创建tools包并创建MyTools.java类5) 创建controller包并创建ToolUseController.java文件6) 启动项目并测试一、概述Tool Calling工具调用也称为函数调用是让大语言模型LLM在对话中“调用”外部定义的工具或 API 的机制通过这个机制模型可以在生成回答前提出需要执行的操作如获取实时天气、设置数据库记录、触发业务流程等然后由应用端执行工具结果再反馈回模型最终给用户完整回复。Tool Calling主要应用场景如下信息检索从外部源如数据库、Web 服务、文件系统或 Web 搜索引擎检索信息增强模型的知识使其能够回答其他方式无法回答的问题。执行操作在软件系统中执行特定操作如发送电子邮件、在数据库中创建新记录、提交表单或触发工作流。目标是自动执行原本需要人工干预或显式编程的任务。Spring AI 提供了方便的 API 来定义工具、解析来自模型的工具调用请求以及执行工具调用。二、工具定义与使用Spring AI中工具调用流程示意图如下开发者定义工具并将其注册到 Spring 容器中。模型在生成响应时识别到需要调用工具会生成包含工具调用信息的响应。应用程序接收到模型的响应后解析其中的工具调用信息执行相应的工具。工具执行完成后将结果返回给应用程序。应用程序将工具执行结果作为上下文信息传递给模型。模型使用工具执行结果生成最终的响应。工具定义开发者可以通过在方法上添加Tool注解定义工具该注解允许提供工具的名称、描述和输入参数等信息模型在调用工具时会根据这些信息生成相应的调用请求。定义工具示例如下Component public class Tools { Tool(description 获取当前日期和时间) public String getCurrentDateTime() { return 当前日期...; } Tool(description 设置闹钟) public void setAlarm(ToolParam(description 闹钟时间) String alarmTime) { // 设置闹钟的逻辑 } }以上注意点a. Component 加到类中表示是一个组件关键是将工具类让Spring容器管理起来也可以使用Configuration、Service标记类只要Spring 能扫描到并将其实例管理起来就可以。b. 工具方法使用Tool标注工具名称默认就是方法本身也可以通过Tool(nametool name)方式来指定。c. Tool(description...)中这里的description是工具描述大模型根据该描述决定要不要调用该工具。d. 工具方法中需要传入参数的通过使用ToolParam标注大模型自动决定调用时机和自动根据语义传入参数调用完成后生成最终对话。e. 工具不支持如下类型作为参数或返回值:Optional、异步类型如 CompletableFuture、Future、响应式类型如 Flow、Mono、Flux、函数式类型如 Function、Supplier、Consumer。工具使用//注册多个工具 ChatClient chatClient ChatClient.builder(chatModel) .defaultSystem(你是一个非常有帮助的助手你可以使用工具来帮助回答问题) .defaultTools(new ATools(),new BTools,new CTools ...) .build(); //与模型进行对话 String result chatClient.prompt() .user(给我设置10分钟后的闹钟) .call() .content();三、Tool Calling 使用案例如下创建SpringBoot项目在该项目中定义多个工具演示Spring AI中工具使用按照如下步骤实现即可。1) 创建SpringBoot项目命名为“SpringAIToolCalling”2) 配置项目pom.xml?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.5.3/version relativePath/ !-- lookup parent from repository -- /parent groupIdcom.example/groupId artifactIdSpringAIToolCalling/artifactId version0.0.1-SNAPSHOT/version nameSpringAIToolCalling/name descriptionSpringAIToolCalling/description properties java.version17/java.version /properties !-- 导入 Spring AI BOM用于统一管理 Spring AI 依赖的版本 引用每个 Spring AI 模块时不用再写 version只要依赖什么模块 Mavens 自动使用 BOM 推荐的版本 -- dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version1.0.0-SNAPSHOT/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-deepseek/artifactId /dependency /dependencies !-- 声明仓库 用于获取 Spring AI 以及相关预发布版本-- repositories repository idspring-snapshots/id nameSpring Snapshots/name urlhttps://repo.spring.io/snapshot/url releases enabledfalse/enabled /releases /repository repository nameCentral Portal Snapshots/name idcentral-portal-snapshots/id urlhttps://central.sonatype.com/repository/maven-snapshots//url releases enabledfalse/enabled /releases snapshots enabledtrue/enabled /snapshots /repository /repositories /project以上pom.xml中引入了“spring-ai-starter-model-deepseek”依赖包。3) 配置resources/application.propertiesspring.application.nameSpringAIToolCalling server.port8080 #配置 Deepseek的基础URL、密钥和使用模型 spring.ai.deepseek.base-urlhttps://api.deepseek.com spring.ai.deepseek.api-keysk-...21 spring.ai.deepseek.chat.options.modeldeepseek-chat4) 创建tools包并创建MyTools.java类package com.example.springaitoolcalling.tools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.tool.annotation.ToolParam; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; Component public class MyTools { Logger log LoggerFactory.getLogger(MyTools.class); Tool(description 返回当前系统时间) public String getCurrentTime() { log.info(调用 getCurrentTime 工具当前时间java.time.LocalDateTime.now().toString()); return java.time.LocalDateTime.now().toString(); } Tool(description 对两个数字执行加、减、乘、除运算) public double calculate( ToolParam(description 第一个数字) double a, ToolParam(description 第二个数字) double b, ToolParam(description 运算类型) String operation) { log.info(调用 calculate 工具第一个数字a,第二个数字b,运算类型operation); double result 0; switch (operation) { case add: result a b; break; case subtract: result a - b; break; case multiply: result a * b; break; case divide: if (b ! 0) { result a / b; } } return result; } private RestTemplate restTemplate new RestTemplate(); private String baseUrl http://shanhe.kim/api/youjia/youjia.php; Tool(description 查询指定省份的油价直接返回完整 JSON 字符串) public String getOilPriceJson(ToolParam(description 省份名称) String province) { log.info(调用 getOilPriceJson 工具查询省份province); String url String.format(%s?province%s, baseUrl, province); return restTemplate.getForObject(url, String.class); } }在MyTools.java类中我们定义了三个工具每个方法中进行了log日志输出getCurrentTime返回当前系统时间。calculate:对两个数字执行加、减、乘、除运算。getOilPriceJson:查询指定省份的油价直接返回完整 JSON 字符串。5) 创建controller包并创建ToolUseController.java文件package com.example.springaitoolcalling.controller; import com.example.springaitoolcalling.tools.MyTools; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatModel; 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(/ai) public class ToolUseController { private final ChatClient chatClient; public ToolUseController(ChatModel chatModel, MyTools tools) { this.chatClient ChatClient.builder(chatModel) .defaultSystem(你是一个非常有帮助的助手你可以使用工具来帮助回答问题) .defaultTools(tools) .build(); } GetMapping(/chat) public String chat(RequestParam(message) String message) { return chatClient.prompt() .user(message) .call() .content(); } }6) 启动项目并测试启动项目后浏览器输入如下内容进行测试# http://localhost:8080/ai/chat?message今天是什么日期 今天是xxx年xx月xx日 # http://localhost:8080/ai/chat?message123乘以200是多少 123乘以200等于24600。 # http://localhost:8080/ai/chat?message北京油价是多少 北京的油价如下 - 92号汽油7.17 元/升 - 95号汽油7.64 元/升 - 98号汽油9.14 元/升 - 0号柴油6.86 元/升 数据更新时间xxx xxx # http://localhost:8080/ai/chat?message今天天气如何 我无法直接获取天气信息但您可以告诉我您所在的城市或地区我可以尝试为您提供相关的天气查询建议或链接。特别提示以上代码运行后与工具调用相关的提问可以看到后台打印的日志会调用到工具对应的方法。我们也可以在“ToolUseController.java”中设置不使用工具将“defaultToolsnew MyTools”注释掉再进行测试会发现以上访问不会调用工具都由大模型根据已有知识进行回复可能存在不精准情况。
延伸阅读

更多相关文章

2026/9/24 12:59:43

网络安全自学路线图:从零基础到实战渗透测试的90天学习路径

网络安全领域的技术迭代速度很快,但核心的知识体系、方法论和实践技能是相对稳定的。对于希望从零开始系统学习,并最终能够胜任渗透测试、漏洞挖掘等安全岗位的初学者而言,一个清晰、务实、可执行的学习路径远比追逐“最新”的标题更为重要。…

2026/9/23 21:56:41

VC++实战:从控制台到MFC的Windows计算器开发全解析

1. 项目概述与核心价值“VC编程实践:Windows计算器应用源代码详解”这个标题,对于任何一位从Windows桌面开发时代走过来的老程序员来说,都像是一把钥匙,瞬间打开了记忆的闸门。VC,或者说Visual C,不仅仅是微…

2026/9/20 11:29:03

PTA基础编程题目集 7-21求特殊方程的正整数解(C++语言实现)

摘要:本文是PTA编程题"求特殊方程的正整数解"的题解,涵盖题目描述、输入输出格式及C语言实现,展示双重枚举暴力搜索算法。题目描述 本题要求对任意给定的正整数N,求方程X Y N的全部正整数解。 输入格式: 输…

2026/9/25 12:18:05

用ESP32绕过射频直连DMR网络:纯网络终端设计与实现

前两天我把手头的ESP32 DevKitC接上家里的路由器,没装天线、没有PA、没有射频调制器,却在串口日志里看到DMR主站发来了语音帧,耳机里传出清晰的通话声。这个标题里说的“纯网络DMR终端”不是玄学,而是一种非常实际的玩法&#xff…

2026/9/25 12:18:05

Modbus TCP温湿度变送器选型避坑指南

1. 为什么动环监控里温湿度变送器选型总踩坑?先搞清Modbus TCP和以太网不是一回事机房动环监控设备怎么选?这个问题我干了八年,从最早用RS485手拉线、接终端电阻、调波特率调到凌晨三点,到现在坐在办公室看Web界面刷数据&#xff…

2026/9/25 12:18:05

Atlas 300V 24G是运算加速卡吗?昇腾AI推理卡部署YOLO完整实战

前两天刷到一条热搜:「atlas 300v 24g 是运算加速卡吗」。底下吵得挺热闹,有人说这是显卡,有人说这是矿卡,还有人直接说华为的卡跑不了深度学习。作为一个真金白银买过 Atlas 300V 24G、并在上面折腾了大半年 YOLO 部署的工程师&a…

2026/9/25 12:13:05

COZE 平台智能体开发实战:从工作流搭建到 API 集成与本地部署避坑

简介:这份《COZE从入门到精通实战指南》面向希望快速上手AI应用开发的开发者与业务人员,无论有无编程基础均可阅读,重点解决低代码环境下构建对话机器人、自动化工作流与数据分析助手的实际问题。资源包内含1个docx文档,大小约15K…

2026/9/24 20:24:47

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/25 0:02:35

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:02:35

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:02:35

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑