七、SpringBoot配置Function Calling
Function Calling 函数调用也叫Tools工具
-
主要功能:
- 通过Function Calling计算一些特有的数学公式,最后与大模型交互
1、案例
- 例如,大语言模型本身并不擅长数学运算。如果应用场景中偶尔会涉及到数学计算,我们可以为他提供一个 “数学工具”。当我们提出问题时,大语言模型会判断是否使用某个工具。
2、实操过程
2.1、创建工具类
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.agent.tool.ToolMemoryId;
import org.springframework.stereotype.Component;
/**
* @description 计算器工具
*/
@Component
public class CalculatorTools {
/**
* 加法运算
*/
@Tool(name = "加法运算", value = "将两个参数a和b相加并返回运算结果")
public double sum(
@ToolMemoryId int memoryId,
@P(value = "a", required = true) double a,
@P(value = "a", required = true) double b) {
System.out.println("调用加法运算");
return a + b;
}
/**
* 求一个数的平方根运算
*/
@Tool(name = "求一个数的平方根运算", value = "将一个参数a求平方根并返回运算结果")
public double squareRoot(@ToolMemoryId int memoryId,
double a) {
System.out.println("调用平方根运算");
return Math.sqrt(a);
}
}
2.2、详解
-
用 @Tool 注解的方法
- 既可以是静态的,也可以是非静态的
- 可以具有任何可见性(公有,私有等)
2.3、配置工具类
import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
import dev.langchain4j.service.spring.AiService;
import static dev.langchain4j.service.spring.AiServiceWiringMode.EXPLICIT;
/**
* @description 隔离聊天记忆功能的 AIService 智能体
*/
@AiService(
// wiringMode: 标明使用哪个大模型聊天
wiringMode = EXPLICIT,
// chatModel: 具体的聊天大模型
chatModel = "qwenChatModel",
// chatMemoryProvider: 隔离聊天记忆功能的提供者
chatMemoryProvider = "chatMemoryProvider",
// tools: 工具类, 配置工具(Function Calling)
tools = "calculatorTools"
)
public interface SeparateChatAssistant {
/**
* 隔离聊天记忆功能
*
* @param memoryId 聊天ID
* @param message 用户信息
*/
// @SystemMessage("你是我的好朋友,请用东北话回答问题。今天是{{current_date}}") // 系统消息提示词 prompt
@SystemMessage(fromResource = "my-prompt-template.txt")
// 系统消息提示词 prompt 模版配置
String chat(@MemoryId int memoryId, @UserMessage String message);
@UserMessage("你是我的好朋友,请用上海话回答问题。今天是{{message}}")
String chat2(@MemoryId int memoryId, @V("message") String message);
@SystemMessage(fromResource = "my-prompt-template3.txt")
String chat3(
@MemoryId int memoryId,
@UserMessage String userMessage,
@V("userName") String userName,
@V("age") int age
);
}
其中
// tools: 工具类, 配置工具(Function Calling)
tools = "calculatorTools"
则为刚创建的工具配置类
2.4、测试代码
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.xg.assistant.SeparateChatAssistant;
/**
* @description Tools工具测试,也叫 Function Calling 函数调用
*/
@SpringBootTest
public class ToolsTest {
@Autowired
private SeparateChatAssistant separateChatAssistant;
@Test
void testCalculatorTools() {
String answer = separateChatAssistant.chat(1, "1+2等于几,475695037565的平方根是多少?");
System.out.println(answer);
}
}
3、@Tool 注解的可选字段
-
@Tool 注解有两个可选字段
- name(工具名称):工具的名称。如果没有提供该字段,方法名会作为工具的名称。
- value(工具描述):工具的描述信息。
-
根据工具的不同,即使没有任何描述,大语言模型可能也能很好地理解它(例如,add(a, b) 就很直观),但通常最好提供清晰且有意义的名称和描述。这样,大语言模型就能获得更多信息,以决定是否调用给定的工具以及如何调用。
4、@P 注解
-
方法参数可以选择使用 @P 注解进行标注:
-
@P 注解有两个字段:
- value:参数的描述信息,这是必填字段
- required:表示参数是否为必填项,默认值为 true,此为可选字段。
5、@ToolMemoryId
- 如果你的AIService方法中有一个参数使用 @MemoryId 注解,那么你也可以使用 @ToolMemoryId 注解 @Tool 方法中的一个参数。提供给AIService方法的值将自动传递给 @Tool 方法。如果你有多个用户,或每个用户有多个聊天记忆,并且希望在 @Tool 方法中对它们进行区分,那么这个功能会很有用。
- 综合以上解释的最终代码如下:
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.agent.tool.ToolMemoryId;
import org.springframework.stereotype.Component;
/**
* @description 计算器工具
*/
@Component
public class CalculatorTools {
/**
* 加法运算
*/
@Tool(name = "加法运算", value = "将两个参数a和b相加并返回运算结果")
public double sum(
@ToolMemoryId int memoryId,
@P(value = "a", required = true) double a,
@P(value = "a", required = true) double b) {
System.out.println("调用加法运算");
return a + b;
}
/**
* 求一个数的平方根运算
*/
@Tool(name = "求一个数的平方根运算", value = "将一个参数a求平方根并返回运算结果")
public double squareRoot(@ToolMemoryId int memoryId,
double a) {
System.out.println("调用平方根运算");
return Math.sqrt(a);
}
}
福利: