Function Calling 函數調用也叫
Tools 工具`
入門案例
例如,大語言模型本身并不擅長數學運算。如果應用場景中偶爾會涉及到數學計算,我們可以**為他提供一個 “數學工具”。**當我們提出問題時,大語言模型會判斷是否使用某個工具。
創建工具類
用 @Tool
注解的方法:
- 既可以是靜態的,也可以是非靜態的;
- 可以具有任何可見性(公有、私有等)。
package com.atguigu.java.ai.langchain4j.tools;@Component
public class CalculatorTools {@Tooldouble sum(double a, double b) { System.out.println("調用加法運算");return a + b;}@Tooldouble squareRoot(double x) {System.out.println("調用平方根運算");return Math.sqrt(x);}
}
配置工具類
在SeparateChatAssistant
中添加tools
屬性配置
@AiService(wiringMode = EXPLICIT,chatModel = "qwenChatModel",chatMemoryProvider = "chatMemoryProvider",tools = "calculatorTools" //配置tools
)
測試工具類
添加了tools屬性后,AI就能自動根據我們寫的函數進行相應計算
package com.atguigu.java.ai.langchain4j;@SpringBootTest
public class ToolsTest {@Autowiredprivate SeparateChatAssistant separateChatAssistant;@Testpublic void testCalculatorTools() {String answer = separateChatAssistant.chat(1, "1+2等于幾,475695037565的平方根是多少?");//答案:3,689706.4865System.out.println(answer);}
}
測試后可以查看持久化存儲中SYSTEM、USER、AI
以及Tools
的消息,分析tools
的調用流程:
Request:
\- messages:\- SystemMessage:\- text: 系統定義AI的角色\- UserMessage:\- text: 用戶提問\- AiMessage:\- toolExecutionRequests:\- ai獲取提問信息組織參數調用工具方法\- ToolExecutionResultMessage:\- text: 工具方法執行Response :
\- AiMessage:\- text: 根據工具方法的執行ai再次組織結果返回
@Tool 可選字段
@Tool
注解有兩個可選字段:
- name(工具名稱):工具的名稱。如果未提供該字段,方法名會作為工具的名稱。
- value(工具描述):工具的描述信息。
根據工具的不同,即使沒有任何描述,大語言模型可能也能很好地理解它(例如,add(a, b)
就很直觀),但通常最好提供清晰且有意義的名稱和描述。這樣,大語言模型就能獲得更多信息,以決定是否調用給定的工具以及如何調用。
@P 注解
方法參數可以選擇使用 @P
注解進行標注。
@P
注解有兩個字段:
- value:參數的描述信息,這是必填字段。
- required:表示該參數是否為必需項,默認值為
true
,此為可選字段。
@ToolMemoryId
如果你的AIService
方法中有一個參數使用 @MemoryId
注解,那么你也可以使用 @ToolMemoryId
注解 @Tool
標記的 方法中的一個參數。
提供給AIService
方法的值將自動傳遞給 @Tool
方法。如果你有多個用戶,或每個用戶有多個聊天記憶,并且希望在 @Tool
方法中對它們進行區分,那么這個功能會很有用。
package com.atguigu.java.ai.langchain4j.tools;public class CalculatorTools {@Tool(name = "加法", value = "返回兩個參數相加之和")double sum(@ToolMemoryId int memoryId, //AIservice方法的memory將傳遞到工具類里@P(value="加數1", required = true) double a,@P(value="加數2", required = true) double b) {System.out.println("調用加法運算 " + memoryId);return a + b;}@Tool(name = "平方根", value = "返回給定參數的平方根")double squareRoot(@ToolMemoryId int memoryId, double x) {System.out.println("調用平方根運算 " + memoryId);return Math.sqrt(x);}
}