Spring AI:工具调用核心特性与实战
摘要:本文以 Spring AI 框架为例,学习工具调用,大幅增强 AI 的能力,并实战主流工具的开发。


具体内容包括:工具调用介绍,Spring AI 工具开发,主流工具开发,工具调用进阶知识
一 需求分析
之前我们通过 RAG 技术让 AI 应用具备了根据苍穹外卖知识库获取信息并回答的能力,但是直到目前为止,AI 应用还只是个 "项目知识问答助手"。本节我们可以利用工具调用特性,实现更多实战开发需求。
1)异常智能分析:比如定位项目启动报错、接口异常、Bug 根源,示例用户提问:
- 帮我看下这个空指针异常是哪里引起的?
- 为什么 Redis 连接失败,该怎么解决?
2)代码逻辑解释:比如讲解苍穹外卖业务代码、接口作用、流程逻辑,示例用户提问:
- 帮我解释下订单提交接口的这段代码是干嘛的?
- 这段 WebSocket 推送代码的业务流程是什么?
而且这些需求还可以进行组合,比如用户先让 AI 解释一段代码、再分析运行时报错、最后给出完整可运行的修复方案,形成一站式开发辅助。
如果 AI 能够完成上述需求,就不再只是一个有项目知识的 "大脑",而是有手有脚,会利用工具排查问题、分析代码的 "智能开发助手" 了。
下面我们就来学习下实现上述需求的关键 —— 工具调用 技术。
二 工具调用介绍
什么是工具调用?
工具调用(Tool Calling)可以理解为让 AI 大模型 借用外部工具 来完成它自己做不到的事情。
跟人类一样,如果只凭手脚完成不了工作,那么就可以利用工具箱来完成。
工具可以是任何东西,如网页搜索、对外部 API 的调用、访问外部数据、或执行特定的代码等。
比如用户提问 “帮我查询上海最新的天气”,AI 本身并没有这些知识,它就可以调用 “查询天气工具”,来完成任务。
目前工具调用技术发展的已经比较成熟了,几乎所有主流的、新出的 AI 大模型和 AI 应用开发平台都支持工具调用。
工具调用的工作原理
其实,工具调用的工作原理非常简单,并不是 AI 服务器自己调用这些工具、也不是把工具的代码发送给 AI 服务器让它执行,它只能提出要求,表示 “我需要执行 XX 工具完成任务”。而真正执行工具的是我们自己的应用程序,执行后再把结果告诉 AI,让它继续工作。
举个例子,假如用户提问 "编程导航网站有哪些热门文章?",就需要经历下列流程:
- 用户提出问题:"编程导航网站有哪些热门文章?"
- 程序将问题传递给大模型
- 大模型分析问题,判断需要使用工具(网页抓取工具)来获取信息
- 大模型输出工具名称和参数(网页抓取工具,URL参数为 codefather.cn)
- 程序接收工具调用请求,执行网页抓取操作
- 工具执行抓取并返回文章数据
- 程序将抓取结果传回给大模型
- 大模型分析网页内容,生成关于编程导航热门文章的回答
- 程序将大模型的回答返回给用户

虽然看起来是 AI 在调用工具,但实际上整个过程是 由我们的应用程序控制的。AI 只负责决定什么时候需要用工具,以及需要传递什么参数,真正执行工具的是我们的程序。
你可能会好奇,为啥要这么设计呢?这样不是要让程序请求 AI 多次么?为啥不让 AI 服务器直接调用工具程序?
有这个想法很正常,但如果让你自己设计一个 AI 大模型服务,你就能理解了。很关键的一点是 安全性,AI 模型永远无法直接接触你的 API 或系统资源,所有操作都必须通过你的程序来执行,这样你可以完全控制 AI 能做什么、不能做什么。
举个例子,你有一个爆破工具,用户像 AI 提了需求 ”我要拆这栋房子“,虽然 AI 表示可以用爆破工具,但是需要经过你的同意,才能执行爆破。反之,如果把爆破工具植入给 AI,AI 觉得自己能炸了,就炸了,不需要再问你的意见。而且这样也给 AI 服务器本身增加了压力。
工具调用和功能调用
大家可能看到过 Function Calling(功能调用)这个概念,别担心,其实它和 Tool Calling(工具调用)完全是同一概念!只是不同平台或每个人习惯的叫法不同而已。
Spring AI 工具调用文档 的开头就说明了这一点:

个人更喜欢 "工具调用" 这个说法,因为 Function 这个词更像是计算机行业的术语,不如工具更形象易懂、更具普适性。
工具调用的技术选型
我们先来梳理一下工具调用的流程:
- 工具定义:程序告诉 AI "你可以使用这些工具",并描述每个工具的功能和所需参数
- 工具选择:AI 在对话中判断需要使用某个工具,并准备好相应的参数
- 返回意图:AI 返回 “我想用 XX 工具,参数是 XXX” 的信息
- 工具执行:我们的程序接收请求,执行相应的工具操作
- 结果返回:程序将工具执行的结果发回给 AI
- 继续对话:AI 根据工具返回的结果,生成最终回答给用户
通过上述流程,我们会发现,程序需要和 AI 多次进行交互、还要能够执行对应的工具,怎么实现这些呢?我们当然可以自主开发,不过还是更推荐使用 Spring AI、LangChain 等开发框架。此外,有些 AI 大模型服务商也提供了对应的 SDK,都能够简化代码编写。
本教程后续部分将以 Spring AI 为例,带大家实战工具调用开发。
💡 需要注意的是,不是所有大模型都支持工具调用。有些基础模型或早期版本可能不支持这个能力。可以在 Spring AI 官方文档 中查看各模型支持情况。

三 Spring AI 工具开发
首先我们通过 Spring AI 官方 提供的图片来理解 Spring AI 在实现工具调用时都帮我们做了哪些事情?

- 工具定义与注册:Spring AI 可以通过简洁的注解自动生成工具定义和 JSON Schema,让 Java 方法轻松转变为 AI 可调用的工具。
- 工具调用请求:Spring AI 自动处理与 AI 模型的通信并解析工具调用请求,并且支持多个工具链式调用。
- 工具执行:Spring AI 提供统一的工具管理接口,自动根据 AI 返回的工具调用请求找到对应的工具并解析参数进行调用,让开发者专注于业务逻辑实现。
- 处理工具结果:Spring AI 内置结果转换和异常处理机制,支持各种复杂 Java 对象作为返回值并优雅处理错误情况。
- 返回结果给模型:Spring AI 封装响应结果并管理上下文,确保工具执行结果正确传递给模型或直接返回给用户。
- 生成最终响应:Spring AI 自动整合工具调用结果到对话上下文,支持多轮复杂交互,确保 AI 回复的连贯性和准确性。
下面是一个较早版本的流程图,也能帮助我们理解这个过程:

定义工具
工具定义模式
在 Spring AI 中,定义工具主要有两种模式:基于 Methods 方法或者 Functions 函数式编程。
1)Methods 模式:通过 @Tool 注解定义工具,通过 tools 方法绑定工具
class WeatherTools {
@Tool(description = "Get current weather for a location")
public String getWeather(@ToolParam(description = "The city name") String city) {
return "Current weather in " + city + ": Sunny, 25°C";
}
}
// 使用方式
ChatClient.create(chatModel)
.prompt("What's the weather in Beijing?")
.tools(new WeatherTools())
.call();
2)Functions 模式:通过 @Bean 注解定义工具,通过 functions 方法绑定工具
@Configuration
public class ToolConfig {
@Bean
@Description("Get current weather for a location")
public Function<WeatherRequest, WeatherResponse> weatherFunction() {
return request -> new WeatherResponse("Weather in " + request.getCity() + ": Sunny, 25°C");
}
}
// 使用方式
ChatClient.create(chatModel)
.prompt("What's the weather in Beijing?")
.functions("weatherFunction")
.call();
显然 Methods 模式的开发量更少,更推荐这种方式,所以下面重点讲解这种方式。
定义工具
Spring AI 提供了两种定义工具的方法 —— 注解式 和 编程式。
1)注解式:只需使用 @Tool 注解标记普通 Java 方法,就可以定义工具了,简单直观。
每个工具最好都添加详细清晰的描述,帮助 AI 理解何时应该调用这个工具。对于工具方法的参数,可以使用 @ToolParam 注解提供额外的描述信息和是否必填。
class WeatherTools {
@Tool(description = "获取指定城市的当前天气情况")
String getWeather(@ToolParam(description = "城市名称") String city) {
// 获取天气的实现逻辑
return "北京今天晴朗,气温25°C";
}
}
2)编程式:如果想在运行时动态创建工具,可以选择编程式来定义工具,更灵活。
先定义工具类:
class WeatherTools {
String getWeather(String city) {
// 获取天气的实现逻辑
return "北京今天晴朗,气温25°C";
}
}
然后将工具类转换为 ToolCallback 工具定义类,之后就可以把这个类绑定给 ChatClient,从而让 AI 使用工具了。
Method method = ReflectionUtils.findMethod(WeatherTools.class, "getWeather", String.class);
ToolCallback toolCallback = MethodToolCallback.builder()
.toolDefinition(ToolDefinition.builder(method)
.description("获取指定城市的当前天气情况")
.build())
.toolMethod(method)
.toolObject(new WeatherTools())
.build();
String result = chatClient.prompt()
.user("北京今天天气怎么样?") // 用户问题
.tools(toolCallback) // 绑定工具
.call()
.content();
其实你会发现,编程式就是把注解式的那些参数,改成通过调用方法来设置了而已。
在定义工具时,需要注意方法参数和返回值类型的选择。Spring AI 支持大多数常见的 Java 类型作为参数和返回值,包括基本类型、复杂对象、集合等。而且返回值需要是可序列化的,因为它将被发送给 AI 大模型。
以下类型目前不支持作为工具方法的参数或返回类型:
- Optional
- 异步类型(如 CompletableFuture, Future)
- 响应式类型(如 Flow, Mono, Flux)
- 函数式类型(如 Function, Supplier, Consumer)
使用工具
定义好工具后,Spring AI 提供了多种灵活的方式将工具提供给 ChatClient,让 AI 能够在需要时调用这些工具。
1)按需使用:这是最简单的方式,直接在构建 ChatClient 请求时通过 tools() 方法附加工具。这种方式适合只在特定对话中使用某些工具的场景。
String response = ChatClient.create(chatModel)
.prompt("北京今天天气怎么样?")
.tools(new WeatherTools()) // 在这次对话中提供天气工具
.call()
.content();
2)全局使用:如果某些工具需要在所有对话中都可用,可以在构建 ChatClient 时注册默认工具。这样,这些工具将对从同一个 ChatClient 发起的所有对话可用。
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultTools(new WeatherTools(), new TimeTools()) // 注册默认工具
.build();
3)更底层的使用方式:除给 ChatClient 绑定工具外,也可以给更底层的 ChatModel 绑定工具。
ToolCallback[] weatherTools = ToolCallbacks.from(new WeatherTools());
// 绑定工具到对话
ChatOptions chatOptions = ToolCallingChatOptions.builder()
.toolCallbacks(weatherTools)
.build();
// 构造 Prompt 时指定对话选项
Prompt prompt = new Prompt("北京今天天气怎么样?", chatOptions);
chatModel.call(prompt);
总结一下,在使用工具时,Spring AI 会自动处理工具调用的全过程:从 AI 模型决定调用工具 => 到执行工具方法 => 再到将结果返回给模型 => 最后模型基于工具结果生成最终回答。这整个过程对开发者来说是透明的,我们只需专注于实现工具的业务逻辑即可。
那么,怎么实现工具呢?
工具生态
首先,工具的本质就是一种插件。能不自己写的插件,就尽量不要自己写。我们可以直接在网上找一些优秀的工具实现,比如 Spring AI Alibaba 官方文档 中提到了社区插件。

四 主流工具开发
如果社区中没找到合适的工具,我们就要自主开发。需要注意的是,AI 自身能够实现的功能通常没必要定义为额外的工具,因为这会增加一次额外的交互,我们应该将工具用于 AI 无法直接完成的任务。
下面我们依次来实现需求分析中提到的 6 大工具,开发过程中我们要 格外注意工具描述的定义,因为它会影响 AI 决定是否使用工具。
先在项目根包下新建 tools 包,将所有工具类放在该包下;并且工具的返回值尽量使用 String 类型,让结果的含义更加明确。
文件操作
文件操作工具主要提供 2 大功能:保存文件、读取文件。
由于会影响系统资源,所以我们需要将文件统一存放到一个隔离的目录进行存储,在 constant 包下新建文件常量类,约定文件保存目录为项目根目录下的 /tmp 目录中。
public interface FileConstant {
/**
* 文件保存目录
*/
String FILE_SAVE_DIR = System.getProperty("user.dir") + "/tmp";
}
建议同时将这个目录添加到 .gitignore 文件中,避免提交隐私信息。
编写文件操作工具类,通过注解式定义工具,代码如下:
public class FileOperationTool {
private final String FILE_DIR = FileConstant.FILE_SAVE_DIR + "/file";
@Tool(description = "Read content from a file")
public String readFile(@ToolParam(description = "Name of the file to read") String fileName) {
String filePath = FILE_DIR + "/" + fileName;
try {
return FileUtil.readUtf8String(filePath);
} catch (Exception e) {
return "Error reading file: " + e.getMessage();
}
}
@Tool(description = "Write content to a file")
public String writeFile(
@ToolParam(description = "Name of the file to write") String fileName,
@ToolParam(description = "Content to write to the file") String content) {
String filePath = FILE_DIR + "/" + fileName;
try {
// 创建目录
FileUtil.mkdir(FILE_DIR);
FileUtil.writeUtf8String(content, filePath);
return "File written successfully to: " + filePath;
} catch (Exception e) {
return "Error writing to file: " + e.getMessage();
}
}
}
网页抓取
网页抓取工具的作用是根据网址解析到网页的内容,可使用 jsoup 库实现网页内容抓取和解析
1)首先给项目添加依赖:
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.19.1</version>
</dependency>
2)编写网页抓取工具类:
public class WebScrapingTool {
@Tool(description = "Scrape the content of a web page")
public String scrapeWebPage(@ToolParam(description = "URL of the web page to scrape") String url) {
try {
Document doc = Jsoup.connect(url).get();
return doc.html();
} catch (IOException e) {
return "Error scraping web page: " + e.getMessage();
}
}
}
资源下载
资源下载工具的作用是通过链接下载文件到本地,使用 Hutool 的 HttpUtil.downloadFile 实现。
资源下载工具类的代码如下:
public class ResourceDownloadTool {
@Tool(description = "Download a resource from a given URL")
public String downloadResource(@ToolParam(description = "URL of the resource to download") String url, @ToolParam(description = "Name of the file to save the downloaded resource") String fileName) {
String fileDir = FileConstant.FILE_SAVE_DIR + "/download";
String filePath = fileDir + "/" + fileName;
try {
// 创建目录
FileUtil.mkdir(fileDir);
// 使用 Hutool 的 downloadFile 方法下载资源
HttpUtil.downloadFile(url, new File(filePath));
return "Resource downloaded successfully to: " + filePath;
} catch (Exception e) {
return "Error downloading resource: " + e.getMessage();
}
}
}
集中注册
开发好了这么多工具类后,结合我们自己的需求,可以给 AI 一次性提供所有工具,让它自己决定何时调用。所以我们可以创建 工具注册类,方便统一管理和绑定所有工具。
代码如下:
@Configuration
public class ToolRegistration {
@Bean
public ToolCallback[] allTools() {
FileOperationTool fileOperationTool = new FileOperationTool();
WebScrapingTool webScrapingTool = new WebScrapingTool();
ResourceDownloadTool resourceDownloadTool = new ResourceDownloadTool();
return ToolCallbacks.from(
fileOperationTool,
webScrapingTool,
resourceDownloadTool
);
}
}
有了这个注册类,如果需要添加或移除工具,只需修改这一个类即可,更利于维护。
使用工具
在 LoveApp 类中添加工具调用的代码,通过 tools 方法绑定所有已注册的工具:
@Resource
private ToolCallback[] allTools;
public String doChatWithTools(String message, String chatId) {
ChatResponse response = chatClient
.prompt()
.user(message)
.advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
// 开启日志,便于观察效果
.advisors(new MyLoggerAdvisor())
.tools(allTools)
.call()
.chatResponse();
String content = response.getResult().getOutput().getText();
log.info("content: {}", content);
return content;
}
五 指定工具开发
异常分析
异常分析工具的作用是智能解析苍穹外卖项目的报错日志、异常堆栈,自动定位 Bug 原因并给出修复方案,通过大模型实现专业异常诊断。
异常分析工具类的代码如下:
@Component
public class ExceptionDiagnoseTool {
private final ChatClient chatClient;
public ExceptionDiagnoseTool(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
@Tool(description = "智能分析苍穹外卖项目的报错日志、异常堆栈、Bug 定位与修复方案")
public String analyzeException(@ToolParam(description = "完整的异常堆栈或报错信息") String errorLog) {
String prompt = """
你是苍穹外卖项目专属技术专家。
请分析以下报错日志:
1. 明确异常原因
2. 指出在项目中可能出现的模块和位置
3. 提供可直接落地的解决方案
报错内容:
%s
""".formatted(errorLog);
return chatClient.prompt().user(prompt).call().content();
}
}
代码解释
代码解释工具的作用是智能解析苍穹外卖项目中的代码片段,讲解代码功能、业务作用、核心逻辑,帮助快速理解项目代码。
代码解释工具类的代码如下:
@Component
public class CodeExplainTool {
private final ChatClient chatClient;
public CodeExplainTool(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
@Tool(description = "解释苍穹外卖项目中的代码逻辑、功能作用、业务流程")
public String explainCode(@ToolParam(description = "需要解释的代码片段") String code) {
String prompt = """
你是苍穹外卖项目专家,请详细解释这段代码:
1. 代码功能
2. 业务作用
3. 关键逻辑说明
代码内容:
%s
""".formatted(code);
return chatClient.prompt().user(prompt).call().content();
}
}
集中注册
开发好了两个工具类后,结合我们自己的需求,可以给 AI 一次性提供所有工具,让它自己决定何时调用。所以我们可以创建工具注册类,方便统一管理和绑定所有工具。
代码如下:
@Configuration
public class ToolRegistration {
@Bean
public ToolCallback[] allTools(
ExceptionDiagnoseTool exceptionDiagnoseTool,
CodeExplainTool codeExplainTool
) {
return ToolCallbacks.from(
exceptionDiagnoseTool,
codeExplainTool
);
}
}
使用工具
在业务类中添加工具调用的代码,通过 tools 方法绑定所有已注册的工具:
@Resource
private ToolCallback[] allTools;
public String doChatWithTools(String message, String chatId) {
ChatResponse response = chatClient
.prompt()
.user(message)
.advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
.tools(allTools)
.call()
.chatResponse();
String content = response.getResult().getOutput().getText();
return content;
}
六 工具调用进阶
工具上下文
在实际应用中,工具执行可能需要额外的上下文信息,比如登录用户信息、会话 ID 或者其他环境参数。Spring AI 通过 ToolContext 提供了这一能力。如图:

我们可以在调用 AI 大模型时,传递上下文参数。比如传递用户名为 purse_wind:
// 从已登录用户中获取用户名称
String loginUserName = getLoginUserName();
String response = chatClient
.prompt("帮我查询用户信息")
.tools(new CustomerTools())
.toolContext(Map.of("userName", "purse_wind"))
.call()
.content();
System.out.println(response);
在工具中使用上下文参数。比如从数据库中查询 purse_wind 的信息:
class CustomerTools {
@Tool(description = "Retrieve customer information")
Customer getCustomerInfo(Long id, ToolContext toolContext) {
return customerRepository.findById(id, toolContext.getContext().get("userName"));
}
}
看源码我们会发现,ToolContext 本质上就是一个 Map:

它可以携带任何与当前请求相关的信息,但这些信息 不会传递给 AI 模型,只在应用程序内部使用。这样做既增强了工具的安全性,也很灵活。适用于下面的场景:
-
用户认证信息:可以在上下文中传递用户 token,而不暴露给模型
-
请求追踪:在上下文中添加请求 ID,便于日志追踪和调试
-
自定义配置:根据不同场景传递特定配置参数
举个应用例子,假如做了一个用户自助退款功能,如果已登录用户跟 AI 说:"我要退款",AI 就不需要再问用户 "你是谁?",让用户自己输入退款信息了;而是直接从系统中读取到 userId,在工具调用时根据 userId 操作退款即可。
立即返回
有时候,工具执行的结果不需要再经过 AI 模型处理,而是希望直接返回给用户(比如生成 PDF 文档)。Spring AI 通过 returnDirect 属性支持这一功能,流程如图:

立即返回模式改变了工具调用的基本流程:
-
定义工具时,将
returnDirect属性设为true -
当模型请求调用这个工具时,应用程序执行工具并获取结果
-
结果直接返回给调用者,不再 发送回模型进行进一步处理
这种模式很适合需要返回二进制数据(比如图片 / 文件)的工具、返回大量数据而不需要 AI 解释的工具,以及产生明确结果的操作(如数据库操作)。
启用立即返回的方法非常简单,使用注解方式时指定 returnDirect 参数:
class CustomerTools {
@Tool(description = "Retrieve customer information", returnDirect = true)
Customer getCustomerInfo(Long id) {
return customerRepository.findById(id);
}
}
使用编程方式时,手动构造 ToolMetadata 对象:
// 设置元数据包含 returnDirect 属性
ToolMetadata toolMetadata = ToolMetadata.builder()
.returnDirect(true)
.build();
Method method = ReflectionUtils.findMethod(CustomerTools.class, "getCustomerInfo", Long.class);
ToolCallback toolCallback = MethodToolCallback.builder()
.toolDefinition(ToolDefinition.builder(method)
.description("Retrieve customer information")
.build())
.toolMethod(method)
.toolObject(new CustomerTools())
.toolMetadata(toolMetadata)
.build();
工具底层执行原理
Spring AI 提供了两种工具执行模式:框架控制的工具执行和用户控制的工具执行。这两种模式都离不开一个核心组件 ToolCallingManager 。
ToolCallingManager
ToolCallingManager 接口可以说是 Spring AI 工具调用中最值得学习的类了。它是 管理 AI 工具调用全过程 的核心组件,负责根据 AI 模型的响应执行对应的工具并返回执行结果给大模型。此外,它还支持异常处理,可以统一处理工具执行过程中的错误情况。
接口定义如图:

其中的 2 个核心方法:
-
resolveToolDefinitions:发起对话请求前,筛选并组装出 AI 模型能够识别的 "可用工具列表"
-
executeToolCalls:执行模型请求对应的工具调用
ToolCallingManager 并不会主动判断是否要调用工具,而是完全由 AI 模型的返回结果决定:
1. 从 响应中提取工具调用:遍历 ChatResponse 里的 Generation,检查是否存在非空toolCalls列表:
Optional<Generation> toolCallGeneration = chatResponse
.getResults().stream()
.filter(g -> !CollectionUtils.isEmpty(g.getOutput().getToolCalls()))
.findFirst();
如果没有找到任何 toolCalls,就直接抛出异常:No tool call requested by the chat model,表示模型没有要求调用工具。
2. 执行工具并构造对话历史:若存在工具调用,则从 Generation 中取出 AssistantMessage,构建 ToolContext,调用 executeToolCall 执行具体工具逻辑,最后把工具执行结果包装成新的消息,追加到对话历史中,作为后续 AI 回答的上下文。
框架控制的工具执行
这是默认且最简单的模式,由 Spring AI 框架自动管理整个工具调用流程。所以我们刚刚开发时,基本没写几行非业务逻辑的代码,大多数活儿都交给框架负重前行了。
在这种模式下:
-
框架自动检测模型是否请求调用工具
-
自动执行工具调用并获取结果
-
自动将结果发送回模型
-
管理整个对话流程直到得到最终答案
如图:

上图中,我们会发现 ToolCallingManager 起到了关键作用,由框架使用默认初始化的 DefaultToolCallingManager 来自动管理整个工具调用流程,适合大多数简单场景。
用户控制的工具执行
对于需要更精细控制的复杂场景,Spring AI 提供了用户控制模式,可以通过设置 ToolCallingChatOptions 的 internalToolExecutionEnabled 属性为 false 来禁用内部工具执行。
// 配置不自动执行工具
ChatOptions chatOptions = ToolCallingChatOptions.builder()
.toolCallbacks(ToolCallbacks.from(new WeatherTools()))
.internalToolExecutionEnabled(false) // 禁用内部工具执行
.build();
然后我们就可以自己从 AI 的响应结果中提取工具调用列表,再依次执行了:
ChatModel chatModel = ...
ToolCallingManager toolCallingManager = ToolCallingManager.builder().build();
ChatOptions chatOptions = ToolCallingChatOptions.builder()
.toolCallbacks(new CustomerTools())
.internalToolExecutionEnabled(false)
.build();
Prompt prompt = new Prompt("Tell me more about the customer with ID 42", chatOptions);
ChatResponse chatResponse = chatModel.call(prompt);
while (chatResponse.hasToolCalls()) {
ToolExecutionResult toolExecutionResult = toolCallingManager.executeToolCalls(prompt, chatResponse);
prompt = new Prompt(toolExecutionResult.conversationHistory(), chatOptions);
chatResponse = chatModel.call(prompt);
}
System.out.println(chatResponse.getResult().getOutput().getText());
恭喜你学习完毕!✿
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)