Langchain4j-4-Function Call

基本概念

大模型本身不调用工具,而是决策使用哪个工具。
工具调用一般会有两轮对话,以调用工具计算两数之和为例:

  1. 定义工具: 我们将手动创建一个 ToolSpecification 来描述一个名为 calculator 的工具,它有一个 add 方法。
  2. 首次请求: 用户提问 "What is the sum of 5 and 7?"。我们将此问题连同工具规范一起发送给 LLM。
  3. 处理模型响应: LLM 不会直接回答,而是返回一个 ToolExecutionRequest,要求我们执行 add 方法,并提供参数 {"a": 5, "b": 7}
  4. 执行工具: 我们的 Java 代码将解析这个请求,调用本地的 add 方法,得到结果 12
  5. 二次请求: 我们将工具的执行结果 12 封装成 ToolExecutionResultMessage,连同之前的对话历史一起再次发送给 LLM。
  6. 最终答案: LLM 收到工具的计算结果后,会用自然语言生成最终的答案,例如 "The sum of 5 and 7 is 12."。

调用工具的两种方式

调用工具需要告知大模型三个参数:

  1. 工具名称
  2. 工具描述
  3. 工具参数
    本地需要有模型的执行代码。

低阶 API:ChatModel

  • ToolSpecification :描述工具,包含名称,描述,参数
  • ToolExecutor :工具的业务逻辑
  • AiServices.tools() 挂载工具
// LLMConfig.java
@Bean  
public FunctionAssistant functionAssistant(ChatModel chatModel)  
{  
    // 工具说明 ToolSpecification    
    ToolSpecification toolSpecification = ToolSpecification.builder()  
                .name("开具发票助手")  //工具名称
                .description("根据用户提交的开票信息,开具发票")  //工具描述
                .parameters(JsonObjectSchema.builder()  	 //工具参数
                            .addStringProperty("companyName", "公司名称")  
                            .addStringProperty("dutyNumber", "税号序列")  
                            .addStringProperty("amount", "开票金额,保留两位有效数字")  
                        .build())  
            .build();  
  
  
    // 业务逻辑 ToolExecutor    
    ToolExecutor toolExecutor = (toolExecutionRequest, memoryId) -> {  
        System.out.println(toolExecutionRequest.id());  
        System.out.println(toolExecutionRequest.name());  
        String arguments1 = toolExecutionRequest.arguments();  
        System.out.println("arguments1****》 " + arguments1);  
        return "开具成功";  
    };  
  
    return AiServices.builder(FunctionAssistant.class)  
            .chatModel(chatModel)  
			// Tools (Function Calling)  
            .tools(Map.of(toolSpecification, toolExecutor)) 
            .build();  
}

高阶 API:AIService

  • @Tool@P 注解:描述工具
  • 具体的类方法:工具的业务逻辑
  • AiServices.tools() 挂载工具
// InvoiceHandler.java
@Slf4j  
public class InvoiceHandler  
{  
  
	@Tool(name = "开票助手", value = "根据用户提交的开票信息进行开票")
    public String handle(@P("公司名称") String companyName,  
                         @P("税号") String dutyNumber,  
                         @P("金额保留两位有效数字") String amount) throws Exception  
    {  
        log.info("companyName =>>>> {} dutyNumber =>>>> {} amount =>>>> {}", companyName, dutyNumber, amount);  
        
        return "开票成功";  
    }  
}
// LLMConfig.java
@Bean  
public FunctionAssistant functionAssistant(ChatModel chatModel)  
{  
    return AiServices.builder(FunctionAssistant.class)  
                .chatModel(chatModel)  
                .tools(new InvoiceHandler())  
            .build();  
}
posted @ 2025-08-17 18:04  Miaops  阅读(84)  评论(0)    收藏  举报