Openai于北京事件2023年6月14日,北美事件13日发布了新版本模型、gpt-3.5-turbo-0613、gpt-3.5-turbo-16k、gpt-3.5-turbo-16k-0613、gpt-4-0613。其中版本号带0613的支持函数调用,我们可以利用这一功能实现GPT接入互联网。
2023.06.15 17:00 更新:
- 增加一个画图函数,让gpt能够调用画图函数
- 你可以自己修改成sd的画图接口
代码下载地址:https://kd.qccq.cc/#s/9GzTq9DA 代码运行教程: https://lucent.blog/?p=118 (其中关于newbing的配置可以忽略,这版本没加newbing)
实现过程及原理
首先我们先在之前代码的基础上加一个互联网搜索的函数 由于众所周知的原因,搜索引擎的地址同样使用了我的代理
# 搜索互联网
def search_internet(query):
res = requests.post(url="https://duck.lucent.blog/search", json=query).json()
return res
然后声明一个json,告诉GPT我们提供了什么函数供它调用,你如果有其他函数,可以接着往下写
my_functions = [
{
"name": "search_internet",
"description": "通过互联网搜索信息的方法",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词",
}
},
"required": ["query"],
},
}
]
在与GPT交互的方法上增加一些代码,使gpt能够访问我们的函数:
def chat_with_gpt(messages):
global current_key_index
max_length = len(config_data['openai']['api_key']) - 1
try:
if not config_data['openai']['api_key']:
return "请设置Api Key"
else:
if current_key_index > max_length:
current_key_index = 0
return "全部Key均已达到速率限制,请等待一分钟后再尝试"
openai.api_key = config_data['openai']['api_key'][current_key_index]
resp = openai.ChatCompletion.create(
model=config_data['chatgpt']['model'],
messages=messages,
functions=my_functions
)
# stop是正常返回的标识
if "stop" == resp['choices'][0]['finish_reason']:
resp = resp['choices'][0]['message']['content']
# function_call是GPT请求调用函数的标识
elif "function_call" == resp['choices'][0]['finish_reason']:
# GPT请求调用的函数名
fun_name = resp['choices'][0]['message']['function_call']['name']
# GPT想要传递给函数的参数
param = resp['choices'][0]['message']['function_call']['arguments']
# 如果你有自己的函数,可以接着写
if "search_internet" == fun_name:
query = json.loads(param)
print("GPT请求调用搜索函数,搜索参数:")
print(query)
search_res = search_internet(query)
print("互联网搜索结果:")
print(search_res)
# 函数返回结果交给gpt
messages.append({"role": "function", "name": fun_name, "content": search_res['data']})
# 重新与gpt交互
return chat_with_gpt(messages)
else:
resp = "未知函数"
else:
resp = "未知错误"
except openai.OpenAIError as e:
if str(e).__contains__("Rate limit reached for default-gpt-3.5-turbo") and current_key_index <= max_length:
# 切换key
current_key_index = current_key_index + 1
print("速率限制,尝试切换key")
return chat_with_gpt(messages)
elif str(e).__contains__(
"Your access was terminated due to violation of our policies") and current_key_index <= max_length:
print("请及时确认该Key: " + str(openai.api_key) + " 是否正常,若异常,请移除")
if current_key_index + 1 > max_length:
return str(e)
else:
print("访问被阻止,尝试切换Key")
# 切换key
current_key_index = current_key_index + 1
return chat_with_gpt(messages)
else:
print('openai 接口报错: ' + str(e))
resp = str(e)
return resp
相比之前的代码,我们只增加了如下内容:
# stop是正常返回的标识
if "stop" == resp['choices'][0]['finish_reason']:
resp = resp['choices'][0]['message']['content']
# function_call是GPT请求调用函数的标识
elif "function_call" == resp['choices'][0]['finish_reason']:
# GPT请求调用的函数名
fun_name = resp['choices'][0]['message']['function_call']['name']
# GPT想要传递给函数的参数
param = resp['choices'][0]['message']['function_call']['arguments']
# 如果你有自己的函数,可以接着写
if "search_internet" == fun_name:
query = json.loads(param)
print("GPT请求调用搜索函数,搜索参数:")
print(query)
search_res = search_internet(query)
print("互联网搜索结果:")
print(search_res)
# 函数返回结果交给gpt
messages.append({"role": "function", "name": fun_name, "content": search_res['data']})
# 重新与gpt交互
return chat_with_gpt(messages)
else:
resp = "未知函数"
这些代码就可以让GPT拥有联网搜索的能力,当然,如果你想要更多能力,比如调用AI绘图,可以自己写一个函数,把函数定义加到上面声明的json,GPT就可以调用了。