
注意:并不是所有的LLMs都支持工具调用或者function calling。使用时注意选择的大模型。
“工具”或“功能调用”允许 LLM 在必要时调用一个或多个可用的工具,通常由开发者定义。工具可以是任何东西:网络搜索、调用外部 API 或执行特定的代码等。LLMs 实际上不能自己调用工具;相反,它们会在响应中表达调用特定工具的意图(而不是以纯文本形式响应)。然后,作为开发者,我们应该使用提供的参数执行此工具,并报告工具执行的结果。
注意:为了提高 LLM 调用正确工具并传递正确参数的机会,我们应该提供清晰且明确的:
- 工具名称
- 工具的功能描述以及何时应该使用它
- 每个工具参数的描述
一条好的经验法则:如果人类能够理解一个工具的用途以及如何使用它,那么 LLM 很可能也能。
在lowLevelApi中,可以使用 ChatModel 的 chat(ChatRequest) 方法。类似的方法也存在于 StreamingChatModel 中。
在创建 ChatRequest 时指定一个或多个 ToolSpecification。
创建工具:
//方法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中使用工具:
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中,并与之前的消息,一块发送给大模型:
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);在高级抽象层面,可以为任何 Java 方法添加 @Tool 注解,并在创建 AI 服务时指定它们。AIService将自动将这些方法转换为 ToolSpecification 并包含在每个与 LLM 交互的请求中。当 LLM 决定调用工具时,AIService将自动执行相应的方法,并将方法的返回值(如果有)发送回 LLM。可以在 DefaultToolExecutor 中找到实现细节。
使用示例:
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 删除。