结合openai协议谈谈tools调用是怎么实现的
·
一、背景
一直迷惑agent怎么实现tools的调用,可能我的prompt不对,问千问、豆包,回复都很抽象,感觉自己知道了,好像又不知道。下面以程序员的角度,以实例分析一下tools的调用过程
二、实现逻辑
- 开发者(Agent)请求中向 LLM 声明有哪些工具可用。
- LLM 在响应中通过特定的结构化格式 表达它想要调用哪个工具。
- 开发者(Agent)调用相应的工具,并将工具反思的结果拼到LLM请求的上下文中,再次请求LLM
三、实例说明
- 请求LLM,并在参数告之agent有哪些工具,注意下面的tools参数
{
"model": "qwen-plus",
"stream": true,
"messages": [
{
"role": "user",
"content": "今天的天气怎么样?我想出去露营,需要准备什么"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称"
}
},
"required": [
"location"
]
}
}
}
]
}
2. LLM返回,"finish_reason": "tool_calls"。告之agent,当前交互需要调用工具。如下所示,截取LLM返回的2个chunk。一个chunk提取了调用工具要输入的参数;另一个chunk,告之当前LLM请求结束,结束原因是需要调用工具
{
"id": "chatcmpl-7ed551c3-8360-9710-b4c6-5191d3c4db2a",
"object": "chat.completion.chunk",
"created": 1785218854,
"model": "qwen-plus",
"choices": [
{
"delta": {
"tool_calls": [
{
"function": {
"arguments": " \"北京\"}"
},
"index": 0,
"id": "",
"type": "function"
}
],
"content": null
},
"index": 0,
"finish_reason": null,
"logprobs": null
}
],
"usage": null
}
{
"id": "chatcmpl-7ed551c3-8360-9710-b4c6-5191d3c4db2a",
"object": "chat.completion.chunk",
"created": 1785218854,
"model": "qwen-plus",
"choices": [
{
"index": 0,
"delta": {},
"finish_reason": "tool_calls",
"logprobs": null
}
],
"usage": null
}
3. agent调用工具,并将工具返回的结果拼接到LLM的请求参数中,如下所示(role:tool):
{
"model": "qwen-plus",
"stream": true,
"messages": [
{
"role": "user",
"content": "今天的天气怎么样?我想出去露营,需要准备什么"
},
{
"role": "tool",
"tool_call_id": "call_xyz789",
"content": "{\"temp\": 32, \"humidity\": 75, \"condition\": \"雷阵雨\"}"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称"
}
},
"required": [
"location"
]
}
}
}
]
}
4. agent拼接上下文后(role:tool),再次请求LLM,LLM会返回请求的结果。这时结束标志是"finish_reason": "stop",而不是"finish_reason": "tool_calls"
{
"id": "chatcmpl-99f1e847-e42e-91d2-acd9-a43ce3a014e3",
"object": "chat.completion.chunk",
"created": 1785223492,
"model": "qwen-plus",
"choices": [
{
"index": 0,
"delta": {
"content": null
},
"finish_reason": "stop",
"logprobs": null
}
],
"usage": null
}
5. 注意,tools可能不是调一次,这就引入了ReAct。例如,你定义了一个递归的函数作为tool,然后让大模型调用函数,递归算结果。
四、推广


更多推荐

所有评论(0)