多function-calling 调用

2024-05-28 14:20
文章标签 调用 function calling

本文主要是介绍多function-calling 调用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

多function-calling 调用

接上一篇function-calling调用,本篇实现了一个多function-calling的调用。OpenAI会根据function的描述自己来判断应该调用哪个function。最终调用function的动作是由我们来决定的,当然你也可以不调对应的函数。

两个函数分别是:

  1. 根据POI名称查询经纬度坐标
  2. 搜索给定坐标附近的POI

下面上代码,代码中如有方法未找到,请翻看之前的文章:

import requests
## 这里的ampKey可以通过高德开发者平台免费注册一个,个人开发者可免费的少量调用
amap_key = "XXXX"def get_location_coordinate(location, city):url = f"https://restapi.amap.com/v5/place/text?key={amap_key}&keywords={location}&region={city}"print(url)r = requests.get(url)result = r.json()if "pois" in result and result["pois"]:return result["pois"][0]return Nonedef search_nearby_pois(longitude, latitude, keyword):url = f"https://restapi.amap.com/v5/place/around?key={amap_key}&keywords={keyword}&location={longitude},{latitude}"print(url)r = requests.get(url)result = r.json()ans = ""if "pois" in result and result["pois"]:for i in range(min(3, len(result["pois"]))):name = result["pois"][i]["name"]address = result["pois"][i]["address"]distance = result["pois"][i]["distance"]ans += f"{name}\n{address}\n距离:{distance}米\n\n"return ans# 定义tools和要调用的函数
def get_completion(messages, model="gpt-3.5-turbo"):response = client.chat.completions.create(model=model,messages=messages,temperature=0,  # 模型输出的随机性,0 表示随机性最小seed=1024,      # 随机种子保持不变,temperature 和 prompt 不变的情况下,输出就会不变tool_choice="auto",  # 默认值,由 GPT 自主决定返回 function call 还是返回文字回复。也可以强制要求必须调用指定的函数,详见官方文档tools=[{"type": "function","function": {"name": "get_location_coordinate","description": "根据POI名称,获得POI的经纬度坐标","parameters": {"type": "object","properties": {"location": {"type": "string","description": "POI名称,必须是中文",},"city": {"type": "string","description": "POI所在的城市名,必须是中文",}},"required": ["location", "city"],}}},{"type": "function","function": {"name": "search_nearby_pois","description": "搜索给定坐标附近的poi","parameters": {"type": "object","properties": {"longitude": {"type": "string","description": "中心点的经度",},"latitude": {"type": "string","description": "中心点的纬度",},"keyword": {"type": "string","description": "目标poi的关键字",}},"required": ["longitude", "latitude", "keyword"],}}}],)return response.choices[0].messageprompt = "我想在北京三里屯附近喝咖啡,给我推荐几个"
# prompt = "我到北京出差,给我推荐北京三里屯附近的酒店,和北京三里屯附近的咖啡"messages = [{"role": "system", "content": "你是一个地图通,你可以找到任何地址。"},{"role": "user", "content": prompt}
]
response = get_completion(messages)
messages.append(response)  # 把大模型的回复加入到对话中
print("=====GPT回复=====")
print_json(response)while (response.tool_calls is not None):# 新版模型支持一次返回多个函数调用请求,所以要考虑到这种情况for tool_call in response.tool_calls:args = json.loads(tool_call.function.arguments)print("函数参数展开:")print_json(args)if (tool_call.function.name == "get_location_coordinate"):print("Call: get_location_coordinate")result = get_location_coordinate(**args)elif (tool_call.function.name == "search_nearby_pois"):print("Call: search_nearby_pois")result = search_nearby_pois(**args)print("=====函数返回=====")print_json(result)messages.append({"tool_call_id": tool_call.id,  # 用于标识函数调用的 ID"role": "tool","name": tool_call.function.name,"content": str(result)  # 数值result 必须转成字符串})response = get_completion(messages)print(response)messages.append(response)  # 把大模型的回复加入到对话中print("=====最终回复=====")
print(response.content)
print("=====对话历史=====")
print(messages)

运行结果:

=====GPT回复=====
{"content": null,"role": "assistant","function_call": null,"tool_calls": [{"id": "call_C4xbz7ABvNOde510rStBhK8K","function": {"arguments": "{\"location\":\"三里屯\",\"city\":\"北京\"}","name": "get_location_coordinate"},"type": "function"}]
}
函数参数展开:
{"location": "三里屯","city": "北京"
}
Call: get_location_coordinate
https://restapi.amap.com/v5/place/text?key=59b58777beb50f8f180ac36ebe2159d9&keywords=三里屯&region=北京
=====函数返回=====
{"parent": "","address": "朝阳区","distance": "","pcode": "110000","adcode": "110105","pname": "北京市","cityname": "北京市","type": "地名地址信息;热点地名;热点地名","typecode": "190700","adname": "朝阳区","citycode": "010","name": "三里屯","location": "116.455294,39.937492","id": "B0FFF5BER7"
}
ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_TZc2RkF2uKmRag6PI1s67RKw', function=Function(arguments='{"longitude":"116.455294","latitude":"39.937492","keyword":"咖啡"}', name='search_nearby_pois'), type='function')])
函数参数展开:
{"longitude": "116.455294","latitude": "39.937492","keyword": "咖啡"
}
Call: search_nearby_pois
https://restapi.amap.com/v5/place/around?key=59b58777beb50f8f180ac36ebe2159d9&keywords=咖啡&location=116.455294,39.937492
=====函数返回=====
星巴克(北京三里屯三点三大厦店)
三里屯路33号3.3大厦1层1010号
距离:52米内山咖啡店(3·3大厦店)
三里屯路33号3·3大厦B1层
距离:82米春丽咖啡(3·3大厦店)
三里屯路33号3.3大厦东门1层1099
距离:93米ChatCompletionMessage(content='以下是在北京三里屯附近的几家咖啡店推荐:\n\n1. 星巴克(北京三里屯三点三大厦店)\n   地址:三里屯路33号3.3大厦1层1010号\n   距离:52米\n\n2. 内山咖啡店(3·3大厦店)\n   地址:三里屯路33号3·3大厦B1层\n   距离:82米\n\n3. 春丽咖啡(3·3大厦店)\n   地址:三里屯路33号3.3大厦东门1层1099\n   距离:93米\n\n您可以选择其中一家前往享受咖啡时光。祝您喝咖啡愉快!', role='assistant', function_call=None, tool_calls=None)
=====最终回复=====
以下是在北京三里屯附近的几家咖啡店推荐:1. 星巴克(北京三里屯三点三大厦店)地址:三里屯路33号3.3大厦1层1010号距离:52米2. 内山咖啡店(3·3大厦店)地址:三里屯路33号3·3大厦B1层距离:82米3. 春丽咖啡(3·3大厦店)地址:三里屯路33号3.3大厦东门1层1099距离:93米您可以选择其中一家前往享受咖啡时光。祝您喝咖啡愉快!
=====对话历史=====
[{'role': 'system', 'content': '你是一个地图通,你可以找到任何地址。'}, {'role': 'user', 'content': '我想在北京三里屯附近喝咖啡,给我推荐几个'}, ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_C4xbz7ABvNOde510rStBhK8K', function=Function(arguments='{"location":"三里屯","city":"北京"}', name='get_location_coordinate'), type='function')]), {'tool_call_id': 'call_C4xbz7ABvNOde510rStBhK8K', 'role': 'tool', 'name': 'get_location_coordinate', 'content': "{'parent': '', 'address': '朝阳区', 'distance': '', 'pcode': '110000', 'adcode': '110105', 'pname': '北京市', 'cityname': '北京市', 'type': '地名地址信息;热点地名;热点地名', 'typecode': '190700', 'adname': '朝阳区', 'citycode': '010', 'name': '三里屯', 'location': '116.455294,39.937492', 'id': 'B0FFF5BER7'}"}, ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_TZc2RkF2uKmRag6PI1s67RKw', function=Function(arguments='{"longitude":"116.455294","latitude":"39.937492","keyword":"咖啡"}', name='search_nearby_pois'), type='function')]), {'tool_call_id': 'call_TZc2RkF2uKmRag6PI1s67RKw', 'role': 'tool', 'name': 'search_nearby_pois', 'content': '星巴克(北京三里屯三点三大厦店)\n三里屯路33号3.3大厦1层1010号\n距离:52米\n\n内山咖啡店(3·3大厦店)\n三里屯路33号3·3大厦B1层\n距离:82米\n\n春丽咖啡(3·3大厦店)\n三里屯路33号3.3大厦东门1层1099\n距离:93米\n\n'}, ChatCompletionMessage(content='以下是在北京三里屯附近的几家咖啡店推荐:\n\n1. 星巴克(北京三里屯三点三大厦店)\n   地址:三里屯路33号3.3大厦1层1010号\n   距离:52米\n\n2. 内山咖啡店(3·3大厦店)\n   地址:三里屯路33号3·3大厦B1层\n   距离:82米\n\n3. 春丽咖啡(3·3大厦店)\n   地址:三里屯路33号3.3大厦东门1层1099\n   距离:93米\n\n您可以选择其中一家前往享受咖啡时光。祝您喝咖啡愉快!', role='assistant', function_call=None, tool_calls=None)]

这篇关于多function-calling 调用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1010816

相关文章

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

【LabVIEW学习篇 - 21】:DLL与API的调用

文章目录 DLL与API调用DLLAPIDLL的调用 DLL与API调用 LabVIEW虽然已经足够强大,但不同的语言在不同领域都有着自己的优势,为了强强联合,LabVIEW提供了强大的外部程序接口能力,包括DLL、CIN(C语言接口)、ActiveX、.NET、MATLAB等等。通过DLL可以使用户很方便地调用C、C++、C#、VB等编程语言写的程序以及windows自带的大

AutoGen Function Call 函数调用解析(一)

目录 一、AutoGen Function Call 1.1 register_for_llm 注册调用 1.2 register_for_execution 注册执行 1.3 三种注册方法 1.3.1 函数定义和注册分开 1.3.2 定义函数时注册 1.3.3  register_function 函数注册 二、实例 本文主要对 AutoGen Function Call

string字符会调用new分配堆内存吗

gcc的string默认大小是32个字节,字符串小于等于15直接保存在栈上,超过之后才会使用new分配。

京东物流查询|开发者调用API接口实现

快递聚合查询的优势 1、高效整合多种快递信息。2、实时动态更新。3、自动化管理流程。 聚合国内外1500家快递公司的物流信息查询服务,使用API接口查询京东物流的便捷步骤,首先选择专业的数据平台的快递API接口:物流快递查询API接口-单号查询API - 探数数据 以下示例是参考的示例代码: import requestsurl = "http://api.tanshuapi.com/a

vue 父组件调用子组件的方法报错,“TypeError: Cannot read property ‘subDialogRef‘ of undefined“

vue 父组件调用子组件的方法报错,“TypeError: Cannot read property ‘subDialogRef’ of undefined” 最近用vue做的一个界面,引入了一个子组件,在父组件中调用子组件的方法时,报错提示: [Vue warn]: Error in v-on handler: “TypeError: Cannot read property ‘methods

(function() {})();只执行一次

测试例子: var xx = (function() {     (function() { alert(9) })(); alert(10)     return "yyyy";  })(); 调用: alert(xx); 在调用的时候,你会发现只弹出"yyyy"信息,并不见弹出"10"的信息!这也就是说,这个匿名函数只在立即调用的时候执行一次,这时它已经赋予了给xx变量,也就是只是

js私有作用域(function(){})(); 模仿块级作用域

摘自:http://outofmemory.cn/wr/?u=http%3A%2F%2Fwww.phpvar.com%2Farchives%2F3033.html js没有块级作用域,简单的例子: for(var i=0;i<10;i++){alert(i);}alert(i); for循环后的i,在其它语言像c、java中,会在for结束后被销毁,但js在后续的操作中仍然能访

【微服务】Ribbon(负载均衡,服务调用)+ OpenFeign(服务发现,远程调用)【详解】

文章目录 1.Ribbon(负载均衡,服务调用)1.1问题引出1.2 Ribbon负载均衡1.3 RestTemplate整合Ribbon1.4 指定Ribbon负载均衡策略1.4.1 配置文件1.4.2 配置类1.4.3 定义Ribbon客户端配置1.4.4 自定义负载均衡策略 2.OpenFeign面向接口的服务调用(服务发现,远程调用)2.1 OpenFeign的使用2.1 .1创建

类和对象的定义和调用演示(C++)

我习惯把类的定义放在头文件中 Student.h #define _CRT_SECURE_NO_WARNINGS#include <string>using namespace std;class student{public:char m_name[25];int m_age;int m_score;char* get_name(){return m_name;}int set_name