目录
[1.1 Tool作用](#1.1 Tool作用)
[1.2 controller层请求用不到tool时,全程只有一个调用](#1.2 controller层请求用不到tool时,全程只有一个调用)
[1.3 当需要用到tool时,总共会有两个调用](#1.3 当需要用到tool时,总共会有两个调用)
一、LangChain4j中的Tool
1.1 Tool作用
Tool是使用LangChain4J开发Agent应用的重头戏,也是Function calling调用后,实际的业务逻辑代码所在。 工具可以是任何东西:网页搜索、外部API调用、或执行一段特定代码等。
例子,
public class CalculatorTool {
@Tool("计算整数的平方根")
double sqrt(@P("数值")int x) {
return Math.sqrt(x);
}
}
//定义工具类(类似函数调用) @Tool用于对函数进行功能描述描述的越清楚,大模型越容易考虑是否需要使用函数工具
-
@Tool接受一段话,这与一般LLM对话中的提示词(Prompt)作用相当,不同的是@Tool里的文字是引导LLM能根据用户发来的上下文信息、以及Tool的文字标注,推论是否该调用Tool。根据我们的测试,这一段文字描述对Tool是否被成功调用,有决定性的关系。试想一下,我们一直在调整提示词以引导LLM产生更好的生成内容,道理相同。
-
@P是一句较短的叙述,用以描述对应的参数。
-
Tool的function名称与parameter名称随意,只要符合Java或Kotlin规范即可,LangChain4J会自动把function与parameter的名称与类型取出来,在对LLM发送请求信息时一并送出。
调用:
LangChain4j帮我们分析了LLM回传的Body,自动识别要调用的Tool,完成调用。如果用Proxyman分析HTTP协议,可以发现只要涉及到Tool调用,则会出现两次HTTP POST,第一次是用户发送信息,LLM返回并提示要调用Tool;第二次是LangChain4J调用Tool并将数据发送给LLM,LLM根据Tool数据生成最终答案。对外部应用乃至对开发者,都只看到第二次协议交互的最终结果,LangChain4J帮我们做掉了复杂的部分。
注: 以上参考https://qianfan.cloud.baidu.com/qianfandev/topic/268753
当controller层调用接口时,后台实际上调用了URL接口:

来看一下【body】中传入的参数(附带了7个tool工具):

{
"model": "gpt-4o-mini",
"messages": [
{
"role": "system",
"content": "将用户每条消息以5个要点的形式总结。仅提供要点。"
},
{
"role": "user",
"content": "在处理自然语言处理(NLP)和生成式人工智能任务时,langchain4j 可能不是一个广泛认知的库或工具。通常,当我们谈论与自然语言相关的库或框架时,langchain 是一个更为常见的名称。langchain 是一个由 Hugging Face 开发的 Python 库,主要用于构建复杂的语言处理模型和应用。\nYou must put every item on a separate line."
}
],
"stream": false,
"tools": [
{
"type": "function",
"function": {
"name": "addUser",
"description": "新增用户服务",
"parameters": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "用户名称"
},
"age": {
"type": "string",
"description": "用户年龄"
},
"sex": {
"type": "string",
"description": "用户性别"
}
},
"required": [
"name",
"age",
"sex"
]
}
}
},
{
"type": "function",
"function": {
"name": "findUser",
"description": "根据用户名查询用户完整信息",
"parameters": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "用户名称"
}
},
"required": [
"name"
]
}
}
},
{
"type": "function",
"function": {
"name": "getUserAsync",
"description": "异步查询",
"parameters": {
"type": "object",
"properties": {
"userId": {
"type": "string"
}
},
"required": [
"userId"
]
}
}
},
{
"type": "function",
"function": {
"name": "calculate",
"description": "用于计算两个数字的加法、减法、乘法和除法",
"parameters": {
"type": "object",
"properties": {
"a": {
"type": "number"
},
"b": {
"type": "number"
},
"operator": {
"type": "string"
}
},
"required": [
"a",
"b",
"operator"
]
}
}
},
{
"type": "function",
"function": {
"name": "getCurrentDateTime",
"description": "获取当前时间,返回格式为 yyyy-MM-dd HH:mm:ss",
"parameters": {
"type": "object",
"properties": {},
"required": []
}
}
},
{
"type": "function",
"function": {
"name": "searchWeb",
"description": "在互联网上搜索实时信息,可以调用公开平台的api查询信息,例如当前新闻、天气等",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string"
}
},
"required": [
"query"
]
}
}
},
{
"type": "function",
"function": {
"name": "cancelBooking",
"parameters": {
"type": "object",
"properties": {
"bookingNumber": {
"type": "string"
},
"customerName": {
"type": "string"
},
"customerSurname": {
"type": "string"
}
},
"required": [
"bookingNumber",
"customerName",
"customerSurname"
]
}
}
}
]
}
1.2 controller层请求用不到tool时,全程只有一个调用

1.3 当需要用到tool时,总共会有两个调用
第一次调用:

第一次调用返回tool部分:


第二次调用:

第二次调用返回:
