本文主要阐述了如何通过LangChain框架基于大模型调用业务系统的接口,从而实现搜索增强,真正解决AI与业务系统集成的问题
主要介绍了LangChain4j中工具(Tools)的概念和使用方法。工具允许语言模型(LLM)在生成文本的同时,触发外部操作(如调用API、执行代码等)。
工具(函数调用)
一些语言模型(LLM)不仅可以生成文本,还可以触发操作。
注意: 支持工具的所有LLM可以在这里找到(查看“Tools”列)。
“工具”或“函数调用”的概念允许LLM在必要时调用一个或多个可用工具,这些工具通常由开发者定义。工具可以是任何东西:一个网络搜索、对外部API的调用,或者执行一段特定代码等。LLM本身无法直接调用工具;相反,它们会在响应中表达调用特定工具的意图(而不是以纯文本形式响应)。作为开发者,我们需要执行这个工具,并将工具执行的结果反馈给LLM。
例如,我们知道LLM本身不擅长数学计算。如果你的用例涉及偶尔的数学计算,你可能希望为LLM提供一个“数学工具”。通过在请求中声明一个或多个工具,LLM可以在认为合适的情况下决定调用其中一个工具。给定一个数学问题和一组数学工具,LLM可能会决定为了正确回答问题,它应该首先调用其中一个提供的数学工具。
让我们看看实际中的工作方式(有工具和没有工具的情况):
没有工具的消息交换示例:
请求:
- 消息:
- UserMessage:
- 文本:475695037565的平方根是多少?
响应:
- AiMessage:
- 文本:475695037565的平方根大约是689710。
接近,但不正确。
有工具的消息交换示例:
@Tool("计算两个给定数字的和")
double sum(double a, double b) {
return a + b;
}
@Tool("返回给定数字的平方根")
double squareRoot(double x) {
return Math.sqrt(x);
}
请求1:
- 消息:
- UserMessage:
- 文本:475695037565的平方根是多少?
- 工具:
- sum(double a, double b): 计算两个给定数字的和
- squareRoot(double x): 返回给定数字的平方根
响应1:
- AiMessage:
- toolExecutionRequests:
- squareRoot(475695037565)
... 在这里,我们执行带有“475695037565”参数的squareRoot方法,并得到“689706.486532”作为结果 ...
请求2:
- 消息:
- UserMessage:
- 文本:475695037565的平方根是多少?
- AiMessage:
- toolExecutionRequests:
- squareRoot(475695037565)
- ToolExecutionResultMessage:
- 文本:689706.486532
响应2:
- AiMessage:
- 文本:475695037565的平方根是689706.486532。
正如你所看到的,当LLM可以访问工具时,它可以在适当的时候决定调用其中一个工具。
这是一个非常强大的功能。在这个简单的例子中,我们为LLM提供了基本的数学工具,但想象一下,如果我们给它提供了googleSearch和sendEmail工具,以及一个查询“我的朋友想了解人工智能领域的最新消息。请将简要总结发送到xxx@email.com”,那么它可以使用googleSearch工具查找最新消息,然后总结并使用sendEmail工具发送总结。
注意: 为了增加LLM调用正确工具及其正确参数的机会,我们应该提供清晰且无歧义的:
- 工具的名称
- 工具的功能描述以及何时使用
- 每个工具参数的描述
一个好的经验法则是:如果一个人能够理解工具的用途以及如何使用它,那么LLM很可能也能做到。
LLM被特别微调以检测何时调用工具以及如何调用它们。某些模型甚至可以同时调用多个工具,例如OpenAI。
注意: 并非所有模型都支持工具。要查看哪些模型支持工具,请参考此页面的“Tools”列。
注意: 工具/函数调用与JSON模式不是同一件事。
两个抽象层次
LangChain4j提供了两个抽象层次来使用工具:
- 低级抽象:使用ChatLanguageModel和ToolSpecification API。
- 高级抽象:使用AI服务和@Tool注解的Java方法。
在低级抽象中,你可以使用ChatLanguageModel的generate(List, List)方法。StreamingChatLanguageModel中也有类似的方法。
- ToolSpecification是一个包含工具所有信息的对象,包括:
- 工具的名称(name)
- 工具的描述(description)
- 工具的参数及其描述
建议尽可能多地提供工具信息:清晰的名称、全面的描述,以及每个参数的描述等。
创建ToolSpecification有两种方式:
手动创建:
ToolSpecification toolSpecification = ToolSpecification.builder()
.name("getWeather")
.description("返回指定城市的天气预报")
.parameters(JsonObjectSchema.builder()
.addStringProperty("city", "返回天气预报的城市")
.addEnumProperty("temperatureUnit",