首先简单说一下:调用openAI的模型,需要申请API key,用于鉴权和计费嘛。你注册之后有18美元体验金,3个月有效期。
更多信息可以看我上一篇文章,或者官网文档。
API key不能暴露于网络,否则要重新申请(不影响什么),比如你把你的含有key的代码同步到github仓库,很快这个key就失效了。
使用API请求后,完整的回复是这样的json结构数据:我们只需要解析出 choices 的 text 即可。其中 usage 显示了本次请求使用的token数量信息。
当你发现回答内容或格式不正确时,就可以打印全部恢复,看看问题出在什么地方。
You: hello
GPT-3: {
"choices": [
{
"finish_reason": "stop",
"index": 0,
"logprobs": null,
"text": "\n\nHi there! How can I help you?"
}
],
"created": 1677321094,
"id": "cmpl-6nm7ywWcF6tQYhrKkPA6mOIvi9OEY",
"model": "text-davinci-003",
"object": "text_completion",
"usage": {
"completion_tokens": 11,
"prompt_tokens": 1,
"total_tokens": 12
}
}
此外,即使是GPT-3的API,使用的人也不少(毕竟chatGPT API没出来,不少人拿这个骗人),所以有时候并不会秒响应。
模型非常适合写文本以及算法类型的代码(毕竟用了github数十亿开源代码来训练),但回答内容的正确性需要用户判断(尽管大多数时间是可用、正确的)。
很简单,但不支持连续对话,你每一次都要把你的需求描述完整。
主要的请求如下:
response = openai.Completion.create(
# 模型名称
model= self.model,
# 用户提供的输入文本,用于指导GPT输出
prompt=prompt,
# 控制输出的多样性,0-1,其中0表示最保守的输出,1表示最多样化的输出。
temperature=0,
# 输出的最大长度(输入+输出的token不能大于模型的最大token),可以动态调整
max_tokens=1500,
# [控制字符的重复度] -2.0 ~ 2.0 之间的数字,正值会根据新 tokens 在文本中的现有频率对其进行惩罚,从而降低模型逐字重复同一行的可能性
frequency_penalty=0.2,
# [控制主题的重复度] -2.0 ~ 2.0 之间的数字,正值会根据到目前为止是否出现在文本中来惩罚新 tokens,从而增加模型谈论新主题的可能性
presence_penalty=0.15,
)
直接打印就是完整的返回数据,我们只打印对话内容即可:
print(self.bot, response["choices"][0]["text"].strip())
完整代码:
# -*- coding = utf-8 -*-
# @TIME : 2023-2-21 下午 9:47
# @Author : CQUPTLei
# @File : gpt_3.py
# @Software : PyCharm
# @Abstract : GPT-3的简单使用,不支持上下文连续对话,自己申请API key,很简单哈。
import openai
openai.api_key = "你的key"
class Chat_bot:
def __init__(self,model):
self.user = "\nYou: "
self.bot = "GPT-3: "
# 具体的GPT-3模型名称
self.model = model
def Generate(self):
while True:
prompt = input(self.user)
if prompt == 'exit':
break
else:
try:
response = openai.Completion.create(
# 模型名称
model= self.model,
# 用户提供的输入文本,用于指导GPT输出
prompt=prompt,
# 控制输出的多样性,0-1,其中0表示最保守的输出,1表示最多样化的输出。
temperature=0,
# 输出的最大长度(输入+输出的token不能大于模型的最大token),可以动态调整
max_tokens=1500,
# [控制字符的重复度] -2.0 ~ 2.0 之间的数字,正值会根据新 tokens 在文本中的现有频率对其进行惩罚,从而降低模型逐字重复同一行的可能性
frequency_penalty=0.2,
# [控制主题的重复度] -2.0 ~ 2.0 之间的数字,正值会根据到目前为止是否出现在文本中来惩罚新 tokens,从而增加模型谈论新主题的可能性
presence_penalty=0.15,
)
# print(self.bot,response)
print(self.bot, response["choices"][0]["text"].strip())
except Exception as exc:
print(exc)
if __name__ =='__main__':
bot = Chat_bot('text-davinci-003')
bot.Generate()
运行示例:
实现方式:将最新几次的对话保存下来,作为prompt输入即可。这里最新取了5次对话,太大的话会超过token数量限制。
另外用变量将问答保存下来,待对话结束保存下来即可。
完整示例:
# -*- coding = utf-8 -*-
# @TIME : 2023-2-25 下午 7:01
# @Author : CQUPTLei
# @File : gpt_3_continuous.py
# @Software : PyCharm
# @Abstract : 可连续对话,并在退出时将对话保存为文件
import openai
import time
from pathlib import Path
openai.api_key = "你的key"
class Chat_bot:
def __init__(self,model):
self.user = "\nYou: "
self.bot = "GPT-3: "
self.model = model
self.question_list = []
self.answer_list = []
self.text = ''
self.turns = []
self.last_result = ''
def dialogue_save(self):
timestamp = time.strftime("%Y%m%d-%H%M-%S", time.localtime()) # 时间戳
file_name = 'output/Chat_' + timestamp + '.md' # 文件名
f = Path(file_name)
f.parent.mkdir(parents=True, exist_ok=True)
with open(file_name, "w", encoding="utf-8") as f:
for q, a in zip(self.question_list, self.answer_list):
f.write(f"You: {q}\nGPT-3: {a}\n\n")
print("对话内容已保存到文件中: " + file_name)
def Generate(self):
print('\n请开始你们的对话,以exit结束。')
while True:
# 用户输入
question = input(self.user)
self.question_list.append(question) # 将问题添加到问题列表中
# 把输入换成这样,就可以联系上下文进行连续对话了(text里面保存了最新10次对话)
prompt = self.bot + self.text + self.user + question
# 退出命令
if question == 'exit':
break
else:
try:
response = openai.Completion.create(
# 模型名称
model= self.model,
# 用户提供的输入文本,用于指导GPT输出
prompt=prompt,
# 控制输出的多样性,0-1,其中0表示最保守的输出,1表示最多样化的输出。
temperature=0,
# 输出的最大长度(输入+输出的token不能大于模型的最大token),可以动态调整
max_tokens=1500,
# [控制字符的重复度] -2.0 ~ 2.0 之间的数字,正值会根据新 tokens 在文本中的现有频率对其进行惩罚,从而降低模型逐字重复同一行的可能性
frequency_penalty=0.2,
# [控制主题的重复度] -2.0 ~ 2.0 之间的数字,正值会根据到目前为止是否出现在文本中来惩罚新 tokens,从而增加模型谈论新主题的可能性
presence_penalty=0.15,
)
result = response["choices"][0]["text"].strip()
result = result[result.index('G'):]
self.answer_list.append(result) #将回答添加到回答列表中
self.last_result = result
# 只有这样迭代才能连续提问理解上下文
self.turns += [question] + [result]
# 为了防止超过字数(token)限制,总是取最新5轮对话
if len(self.turns) <= 10:
self.text = " ".join(self.turns)
else:
self.text = " ".join(self.turns[-10:])
print(result)
# 打印异常
except Exception as exc:
print(exc)
# 退出对话后保存
self.dialogue_save()
if __name__ =='__main__':
bot = Chat_bot('text-davinci-003')
bot.Generate()
# -*- coding = utf-8 -*-
# @TIME : 2023-2-21 下午 10:55
# @Author : CQUPTLei
# @File : GPT_3_GUI.py
# @Software : PyCharm
# @Abstract :
import openai
import tkinter as tk
openai.api_key = "你的key"
#设置窗口大小,位置
def window_set(root, width, height):
screenwidth = root.winfo_screenwidth() #获取显示器尺寸
screenheight = root.winfo_screenheight()
size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 5)
root.geometry(size)
root.update()
# 创建tkinter GUI应用程序
root = tk.Tk()
root.title("OpenAI Text-Davinci-003")
sw=root.winfo_screenwidth()
sh=root.winfo_screenheight()
window_set(root,800,500)
# root.iconphoto(False, tkinter.PhotoImage(file='D:\yt_dlp_python_GUI\logo_icon\lucid.png')) # logo
# root.iconbitmap(default=r'icon\r14.ico') # 更改窗口图标
root.resizable(False, False) # 设置窗口大小不可变
# 创建输入框
input_field = tk.Text(root,font=("SimSun", 12),wrap='word',bg='#A1CBD1')
input_field.place(x=0, y=0,width=700,height=50)
# 创建文本框,用于显示机器人的回复文本
response_field = tk.Text(root,font=("SimSun", 12),bg='black',fg='orange',wrap='word')
response_field.place(x=0, y=50,width=800,height=450)
# 创建按钮,用于发送输入文本到OpenAI API
def send_input():
# 获取输入文本
input_text = input_field.get("1.0",'end')
response_field.insert(tk.END, '\n\nYou:' + input_text)
# 调用OpenAI API,获取回复文本
response = openai.Completion.create(
# 模型名称
model='text-davinci-003',
# 用户提供的输入文本,用于指导GPT输出
prompt=input_text,
# 控制输出的多样性,0-1,其中0表示最保守的输出,1表示最多样化的输出。
temperature=0,
# 输出的最大长度(输入+输出的token不能大于模型的最大token),可以动态调整
max_tokens=1500,
# [控制字符的重复度] -2.0 ~ 2.0 之间的数字,正值会根据新 tokens 在文本中的现有频率对其进行惩罚,从而降低模型逐字重复同一行的可能性
frequency_penalty=0.2,
# [控制主题的重复度] -2.0 ~ 2.0 之间的数字,正值会根据到目前为止是否出现在文本中来惩罚新 tokens,从而增加模型谈论新主题的可能性
presence_penalty=0.15,
)
# 显示回复文本到GUI界面上的文本框中
result = response['choices'][0]['text'].strip()
response_field.insert(tk.END,'GPT-3:'+ result)
send_button = tk.Button(root, font=("SimSun", 12),text="发送", command=send_input,bg='#FCC09C')
send_button.place(x=700, y=0,width=100,height=50)
# 运行tkinter GUI应用程序
root.mainloop()