-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExample-3-2-functioncalling multi functions.py
More file actions
164 lines (144 loc) · 5.95 KB
/
Copy pathExample-3-2-functioncalling multi functions.py
File metadata and controls
164 lines (144 loc) · 5.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# Example of Multiple Function Calling
"""
Requirement: Query information about hotels, restaurants, scenic spots, and other points of interest (POIs) near a given location. In essence, this involves querying POIs in proximity to a specified POI.
"""
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
import os
import json
_ = load_dotenv(find_dotenv())
client = OpenAI()
def print_json(data):
"""
打印参数。如果参数是有结构的(如字典或列表),则以格式化的 JSON 形式打印;
否则,直接打印该值。
"""
if hasattr(data, 'model_dump_json'):
data = json.loads(data.model_dump_json())
if (isinstance(data, (list, dict))):
print(json.dumps(
data,
indent=4,
ensure_ascii=False
))
else:
print(data)
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].message
import requests
# amap_key = "6d672e6194caa3b639fccf2caf06c342"
amap_key = os.getenv('AMAP_POIKEY')
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 None
def 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
prompt = "我想在北京五道口附近喝咖啡,给我推荐几个"
# prompt = "我到北京出差,给我推荐三里屯的酒店,和五道口附近的咖啡"
messages = [
{"role": "system", "content": "你是一个地图通,你可以找到任何地址。"},
{"role": "user", "content": prompt}
]
response = get_completion(messages)
messages.append(response) # 把大模型的回复加入到对话中
ii = 0
print(f"=====第{ii}次GPT回复=====")
print_json(response)
while (response.tool_calls is not None):
# 1106 版新模型支持一次返回多个函数调用请求,所以要考虑到这种情况
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)
ii += 1
print(f"=====第{ii}次GPT回复=====")
print_json(response)
messages.append(response) # 把大模型的回复加入到对话中
print("=====最终messages=====")
print(messages)
print("=====最终回复=====")
print(response.content)