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);}
}