本文主要是介绍多function-calling 调用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
多function-calling 调用
接上一篇function-calling调用,本篇实现了一个多function-calling的调用。OpenAI会根据function的描述自己来判断应该调用哪个function。最终调用function的动作是由我们来决定的,当然你也可以不调对应的函数。
两个函数分别是:
- 根据POI名称查询经纬度坐标
- 搜索给定坐标附近的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}®ion={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=三里屯®ion=北京
=====函数返回=====
{"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 调用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!