SpringBoot集成大模型应用开发企业级项目--【篇七:SpringBoot中Function Calling使用】

764 阅读4分钟

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

福利:

项目地址:gitee.com/xuegang001/…