“ 一些LLM除了生成文本外,还可以触发操作。”
Tool
有一个概念被称为“工具”,或“函数调用”。它允许LLM在必要时调用通常由开发人员定义的一个或多个可用工具。工具可以是任何东西:网络搜索、对外部API的调用,或者执行特定的代码段,等等。LLM本身实际上不能调用工具;相反,它们在响应中表达了调用特定工具的意图(而不是以纯文本形式响应)。作为开发人员我们应该使用提供的参数执行这个工具,并报告工具执行的结果。
举个例子,我们知道LLM本身数学不是很好。如果您的用例涉及偶尔的数学计算,您可能希望为LLM提供一个“数学工具”。通过在对LLM的请求中声明一个或多个工具,它可以决定调用其中的一个工具(如果它认为合适的话)。给定一个数学问题以及一组数学工具,LLM可能会决定要正确地回答这个问题,它应该首先调用所提供的数学工具之一。
Request:
- messages:
- UserMessage:
- text: What is the square root of 475695037565?
Response:
- AiMessage:
- text: The square root of 475695037565 is approximately 689710.
我们使用以下工具再来一次
Request 1:
- messages:
- UserMessage:
- text: What is the square root of 475695037565?
- tools:
- sum(double a, double b): Sums 2 given numbers
- squareRoot(double x): Returns a square root of a given number
Response 1:
- AiMessage:
- toolExecutionRequests:
- squareRoot(475695037565)
here we are executing the squareRoot method with the "475695037565" argument and getting "689706.486532" as a result
Request 2:
- messages:
- UserMessage:
- text: What is the square root of 475695037565?
- AiMessage:
- toolExecutionRequests:
- squareRoot(475695037565)
- ToolExecutionResultMessage:
- text: 689706.486532
Response 2:
- AiMessage:
- text: The square root of 475695037565 is 689706.486532.
当然,以上只是官方给出来的示例,我用千帆大模型测试了一下下,好像tool并不太好用。@2024/5/27
两个抽象级别
LangChain4j 为使用tools提供了两个抽象级别
Low level tool Api
ToolSpecofication
- 一个包含工具所有信息的对象name,description,parameters
High level tool Api
ToolSpecofication
两种方法创建ToolSpecofication
ToolSpecification toolSpecification = ToolSpecification.builder() .name("getSquareRoot") .description("Returns the weather forecast for a given city") .addParameter("number", type("string"), description("The city for which the weather forecast should be returned")) .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);
High level tool Api
在更高的层次上,你可以用@Tool注释任何Java方法,并将其与AlServices一起使用。AlServices将自动将这些方法转换为ToolSpecifications,并将其包含在与LLM的每次交互的请求中。当LLM决定调用该工具时,AlService将自动执行适当的方法,方法的返回值(如果有的话)将被发送回LLM您可以在DefaultToolExecutor中找到实现细节。
用@Tool注释的方法可以接受各种类型的任意数量的参数。
它们还可以返回任何类型,包括void。如果方法返回类型为void,则如果方法成功返回,则将“success”字符串发送到LLM。如果方法具有字符串返回类型,则返回值将按原样发送到LLM,不进行任何转换。对于其他返回类型,返回值在发送到LLM之前被转换为JSON
以下是几个示例
@Tool("Searches Google for relevant URLs, given the query")
public List<String> searchGoogle(@P("search query") String query) {
return googleSearchService.search(query);
}
@Tool("Returns the content of a web page, given the URL")
public String getWebPageContent(@P("URL of the page") String url) {
Document jsoupDocument = Jsoup.connect(url).get();
return jsoupDocument.body().text();
}
工具我是玩了两天,愁了两天,这玩意儿他也没调用过工具类 愁.jpg。
annotation
@Tool
有2个可选字段:
名称:工具的名称。如果没有提供,则该方法的名称将用作工具的名称。
值:工具的描述。
根据不同的工具,LLM可能在没有任何描述的情况下也能很好地理解它(例如,add(a,b)是显而易见的,但通常最好提供清晰且有意义的名称和描述。这样,LLM就有更多的信息来决定是否调用给定的工具,以及如何调用。
@P
方法参数可以有选择地用@P注释,有一个强制字段(value)用于提供参数的说明。
@ToolMemoryId
如果你的Al Service方法有一个用@MemoryId注释的参数,你也可以用@ToolMemoryld注释一个@Tool方法的参数。提供给AlService方法的值将自动传递给非@Tool方法。如果您有多个用户和/或每个用户有多个聊天记录/记忆,并且希望在@Tool方法中区分它们,则此功能非常有用。
评论 (0)