
一、概述
在 AI 應(yīng)用開發(fā)中,工具調(diào)用 Tool Calling 是增強(qiáng)大模型能力的核心技術(shù)。通過讓模型與外部 API 或工具交互,可實(shí)現(xiàn) 實(shí)時(shí)信息檢索(如天氣查詢、新聞獲取)、系統(tǒng)操作(如創(chuàng)建任務(wù)、發(fā)送郵件)等功能。
Spring AI 作為企業(yè)級(jí) AI 開發(fā)框架,在 1.0.0.M6 版本中進(jìn)行了重要升級(jí):廢棄 Function Calling 引入 Tool Calling 以更貼合行業(yè)術(shù)語(yǔ);本文結(jié)合 Spring AI 與大模型,演示如何通過 Tool Calling 實(shí)現(xiàn)系統(tǒng) API 調(diào)用,同時(shí)處理多輪對(duì)話中的會(huì)話記憶。
關(guān)于 Spring AI 與 DeepSeek 的集成,以及 API-KEY 的申請(qǐng)等內(nèi)容,可參考文章《Spring AI與DeepSeek實(shí)戰(zhàn)一:快速打造智能對(duì)話應(yīng)用》
?
二、函數(shù)調(diào)用原理
大模型僅負(fù)責(zé) 決定是否調(diào)用工具 和 提供參數(shù),實(shí)際執(zhí)行邏輯由客戶端(Spring 應(yīng)用)實(shí)現(xiàn),確保工具調(diào)用的可控性與安全性。

2.1. 工具元數(shù)據(jù)注入
在發(fā)起Chat Request時(shí),將工具描述(name/description)、參數(shù)結(jié)構(gòu)(input schema)等元數(shù)據(jù)封裝至請(qǐng)求體,建立大模型的工具調(diào)用能力基線。
2.2. 模型決策響應(yīng)
大模型根據(jù)上下文推理生成工具調(diào)用指令(tool_calls字段),返回包含選定工具名稱及結(jié)構(gòu)化參數(shù)的中間響應(yīng)。
2.3. 服務(wù)端路由執(zhí)行
Spring AI模塊解析工具調(diào)用指令,通過服務(wù)發(fā)現(xiàn)機(jī)制定位目標(biāo)工具實(shí)例,注入?yún)?shù)并觸發(fā)同步/異步執(zhí)行。
2.4. 執(zhí)行結(jié)果標(biāo)準(zhǔn)化
工具返回原始執(zhí)行結(jié)果后,系統(tǒng)進(jìn)行數(shù)據(jù)類型校驗(yàn)、異常捕獲和JSON序列化處理,生成模型可解析的標(biāo)準(zhǔn)化數(shù)據(jù)結(jié)構(gòu)。
2.5. 上下文增強(qiáng)推理
將標(biāo)準(zhǔn)化結(jié)果作為新增上下文(tool_outputs)回傳大模型,觸發(fā)基于增強(qiáng)上下文的二次推理流程。
2.6. 終端響應(yīng)生成
模型綜合初始請(qǐng)求與工具執(zhí)行結(jié)果,生成最終自然語(yǔ)言響應(yīng),完成工具增強(qiáng)的對(duì)話閉環(huán)。
?
三、核心代碼
3.1. 定義工具
創(chuàng)建類 TestTools 并用 @Tool 注解定義 tool 的描述
public static class TestTools {
@Tool(description = "獲取今天日期")
String getCurrentDateTime() {
System.out.println("======getCurrentDateTime");
return LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
}
@Tool(description = "獲取當(dāng)前溫度")
String getCurrentTemperature(MyToolReques toolReques) {
System.out.println("======getCurrentTemperature: " + toolReques.localName + "__" + toolReques.date);
return toolReques.date + toolReques.localName + "溫度為20攝氏度";
}
public record MyToolReques(String localName, String date) {}
}
這里定義了兩個(gè)方法,并通過注解的 description 參數(shù)告訴大模型方法的用途。
record 類型是 Java17 的新特性,可用于替代傳統(tǒng)的 POJO 類。
3.2. 創(chuàng)建對(duì)話接口
private ChatMemory chatMemory = new InMemoryChatMemory();
private MessageChatMemoryAdvisor messageChatMemoryAdvisor = new MessageChatMemoryAdvisor(chatMemory);
@GetMapping(value = "/chat")
public String chat(@RequestParam String input, String sessionId, HttpServletResponse response) {
response.setCharacterEncoding("UTF-8");
return chatClient.prompt().user(input)
.tools(new TestTools())
.advisors(messageChatMemoryAdvisor)
.advisors(spec -> spec
.param(MessageChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY, sessionId))
.call()
.content();
}
- tools 給大模型注冊(cè)可以調(diào)用的方法。
-
MessageChatMemoryAdvisor 實(shí)現(xiàn)聊天記憶,
InMemoryChatMemory為SpringAI自帶的實(shí)現(xiàn)(基于內(nèi)存)。 - 可以使用 CHAT_MEMORY_CONVERSATION_ID_KEY 參數(shù)指定對(duì)話ID,不同的會(huì)話ID用于隔離記憶。
3.3. 測(cè)試

通過后臺(tái)打印信息可以看到大模型會(huì)自動(dòng)識(shí)別,先調(diào)用 getCurrentDate 方法獲取今天日期,再調(diào)用 getCurrentTemperature 方法獲取天氣。
======getCurrentDate
======getCurrentTemperature: 廣州__2025年04月13日
?
加一個(gè)聊天框,測(cè)試多輪對(duì)話效果:

第二次會(huì)話直接輸入 廣州 大模型就知道我要問什么了,說明聊天記憶功能已生效。
?
四、總結(jié)
本文以問天氣為場(chǎng)景,通過 Tool Calling 實(shí)現(xiàn)系統(tǒng) API 調(diào)用,同時(shí)實(shí)現(xiàn)多輪對(duì)話中的會(huì)話記憶。需要注意的是 InMemoryChatMemory 只能作為測(cè)試使用,在企業(yè)應(yīng)用中需要使用其他實(shí)現(xiàn)方式,把聊天記錄存儲(chǔ)在 Redis 或者 數(shù)據(jù)庫(kù)中,并且需要考慮消息的保存時(shí)間、容量、如何清除等問題。
?
五、完整代碼
- Gitee地址:
https://gitee.com/zlt2000/zlt-spring-ai-app
- Github地址:
https://github.com/zlt2000/zlt-spring-ai-app
本文由mdnice多平臺(tái)發(fā)布