首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Langchain4j-05

Langchain4j-05

原创
作者头像
叶佳骏
发布2025-10-16 09:05:00
发布2025-10-16 09:05:00
1220
举报

Tools (Function Calling)

注意:并不是所有的LLMs都支持工具调用或者function calling。使用时注意选择的大模型。

“工具”或“功能调用”允许 LLM 在必要时调用一个或多个可用的工具,通常由开发者定义。工具可以是任何东西:网络搜索、调用外部 API 或执行特定的代码等。LLMs 实际上不能自己调用工具;相反,它们会在响应中表达调用特定工具的意图(而不是以纯文本形式响应)。然后,作为开发者,我们应该使用提供的参数执行此工具,并报告工具执行的结果。

代码语言:txt
复制
注意:为了提高 LLM 调用正确工具并传递正确参数的机会,我们应该提供清晰且明确的:
- 工具名称
- 工具的功能描述以及何时应该使用它
- 每个工具参数的描述
一条好的经验法则:如果人类能够理解一个工具的用途以及如何使用它,那么 LLM 很可能也能。
langchain4j-tool-calling-flow.drawio.png|600
langchain4j-tool-calling-flow.drawio.png|600

Low Level Tool API  低级工具 API

在lowLevelApi中,可以使用 ChatModel 的 chat(ChatRequest) 方法。类似的方法也存在于 StreamingChatModel 中。

在创建 ChatRequest 时指定一个或多个 ToolSpecification

创建工具:

代码语言:java
复制
//方法1
ToolSpecification toolSpecification = ToolSpecification.builder()
    .name("getWeather")
    .description("Returns the weather forecast for a given city")
    .parameters(JsonObjectSchema.builder()
        .addStringProperty("city", "The city for which the weather forecast should be returned")
        .addEnumProperty("temperatureUnit", List.of("CELSIUS", "FAHRENHEIT"))
        .required("city") // the required properties should be specified explicitly
        .build())
    .build();

//方法2
class WeatherTools { 
  
    @Tool("Returns the weather forecast for a given city")
    String getWeather(
            @P("The city for which the weather forecast should be returned") String city,
            TemperatureUnit temperatureUnit
    ) {
        ...
    }
}

List<ToolSpecification> toolSpecifications = ToolSpecifications.toolSpecificationsFrom(WeatherTools.class);

在ChatModel中使用工具:

代码语言:java
复制
ChatRequest request = ChatRequest.builder()
    .messages(UserMessage.from("What will the weather be like in London tomorrow?"))
    .toolSpecifications(toolSpecifications)
    .build();
ChatResponse response = model.chat(request);
AiMessage aiMessage = response.aiMessage();

如果 LLM 决定调用工具,返回的 AiMessage 将包含 toolExecutionRequests 字段中的数据。在这种情况下, AiMessage.hasToolExecutionRequests() 将返回 true 。根据 LLM 的不同,它可以包含一个或多个 ToolExecutionRequest 对象(一些 LLM 支持并行调用多个工具)。

每个 ToolExecutionRequest 包含:工具调用id,工具名字,调用参数。

拿到ToolExecutionRequest之后,就可以根据参数进行工具调用。然后将工具调用结果,添加到ToolExecutionResultMessage中,并与之前的消息,一块发送给大模型:

代码语言:java
复制
String result = "It is expected to rain in London tomorrow.";
ToolExecutionResultMessage toolExecutionResultMessage = ToolExecutionResultMessage.from(toolExecutionRequest, result);
ChatRequest request2 = ChatRequest.builder()
        .messages(List.of(userMessage, aiMessage, toolExecutionResultMessage))
        .toolSpecifications(toolSpecifications)
        .build();
ChatResponse response2 = model.chat(request2);

High Level Tool API  高级工具 API

在高级抽象层面,可以为任何 Java 方法添加 @Tool 注解,并在创建 AI 服务时指定它们。AIService将自动将这些方法转换为 ToolSpecification 并包含在每个与 LLM 交互的请求中。当 LLM 决定调用工具时,AIService将自动执行相应的方法,并将方法的返回值(如果有)发送回 LLM。可以在 DefaultToolExecutor 中找到实现细节。

使用示例:

代码语言:java
复制
  
import dev.langchain4j.agent.tool.Tool;  
import dev.langchain4j.memory.chat.MessageWindowChatMemory;  
import dev.langchain4j.model.chat.ChatModel;  
import dev.langchain4j.service.AiServices;  
import dev.langchain4j.service.spring.AiService;  
import jakarta.annotation.Resource;  
import lombok.extern.slf4j.Slf4j;  
import org.springframework.stereotype.Service;  
  
@Service  
@Slf4j  
public class ServiceWithToolsExample {  
  
    @Resource  
    private ChatModel qwenChatModel;  
    
    static class Calculator {  
        @Tool("Calculates the length of a string")  
        int stringLength(String s) {  
            System.out.println("Called stringLength with s='" + s + "'");  
            return s.length();  
        }  
        @Tool("Calculates the sum of two numbers")  
        int add(int a, int b) {  
            System.out.println("Called add with a=" + a + ", b=" + b);  
            return a + b;  
        }  
        @Tool("Calculates the square root of a number")  
        double sqrt(int x) {  
            System.out.println("Called sqrt with x=" + x);  
            return Math.sqrt(x);  
        }  
    }  
  
    @AiService  
    interface Assistant {  
        String chat(String userMessage);  
    }  
  
    public  void test() {  
        Assistant assistant = AiServices.builder(Assistant.class)  
                .chatModel(qwenChatModel)  
                .tools(new Calculator())  
                .chatMemory(MessageWindowChatMemory.withMaxMessages(10))  
                .build();  
        String question = "What is the square root of the sum of the numbers of letters in the words \"hello\" and \"world\"?";  
        String answer = assistant.chat(question);  
        System.out.println(answer);  
      
    }  
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Tools (Function Calling)
    • Low Level Tool API  低级工具 API
    • High Level Tool API  高级工具 API
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档