Python调用openai API实现多轮对话
如何实现多轮对话?
gpt-3.5-turbo 模型调用方法 openai.ChatCompletion.create 里传入的 message 是一个列表,列表里每个元素是字典,包含了角色和内容,我们只需将每轮对话都存储起来,然后每次提问都带上之前的问题和回答即可。
最终效果
实现代码
import openai
import json
import osos.environ["HTTP_PROXY"] = "http://127.0.0.1:20171"
os.environ["HTTPS_PROXY"] = "http://127.0.0.1:20171"# 获取 api
def get_api_key():# 可以自己根据自己实际情况实现# 以我为例子,我是存在一个 openai_key 文件里,json 格式'''{"api": "你的 api keys"}'''openai_key_file = './envs/openai_key'with open(openai_key_file, 'r', encoding='utf-8') as f:openai_key = json.loads(f.read())return openai_key['api']
openai.api_key = get_api_key() class ChatGPT:def __init__(self, user):self.user = userself.messages = [{"role": "system", "content": "一个有10年Python开发经验的资深算法工程师"}]self.filename="./user_messages.json"def ask_gpt(self):# q = "用python实现:提示手动输入3个不同的3位数区间,输入结束后计算这3个区间的交集,并输出结果区间"rsp = openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=self.messages)return rsp.get("choices")[0]["message"]["content"]def writeTojson(self):try:# 判断文件是否存在if not os.path.exists(self.filename):with open(self.filename, "w") as f:# 创建文件pass# 读取with open(self.filename, 'r', encoding='utf-8') as f:content = f.read()msgs = json.loads(content) if len(content) > 0 else {}# 追加msgs.update({self.user : self.messages})# 写入with open(self.filename, 'w', encoding='utf-8') as f:json.dump(msgs, f)except Exception as e:print(f"错误代码:{e}") def main():user = input("请输入用户名称: ")chat = ChatGPT(user)# 循环while 1:# 限制对话次数if len(chat.messages) >= 11:print("******************************")print("*********强制重置对话**********")print("******************************")# 写入之前信息chat.writeTojson()user = input("请输入用户名称: ")chat = ChatGPT(user)# 提问q = input(f"【{chat.user}】")# 逻辑判断if q == "0":print("*********退出程序**********")# 写入之前信息chat.writeTojson()breakelif q == "1":print("**************************")print("*********重置对话**********")print("**************************")# 写入之前信息chat.writeTojson()user = input("请输入用户名称: ")chat = ChatGPT(user)continue# 提问-回答-记录chat.messages.append({"role": "user", "content": q})answer = chat.ask_gpt()print(f"【ChatGPT】{answer}")chat.messages.append({"role": "assistant", "content": answer})if __name__ == '__main__':main()
代码解析:
ChatGPT
类,包含三个函数:
-
__init__
初始化函数,初始化了三个个实例变量,user、messages、filename(当前用户、消息列表、存储记录的文件路径)。 -
ask_gpt
函数,将当前用户所有历史消息+最新提问发送给 gpt-3.5-turbo ,并返回响应结果。 -
writeTojson
函数,结束/重置用户时记录当前用户之前的访问数据。 -
main
函数,程序入口函数,用户输入用户名后进入与 ChatGPT 的循环对话中,输入 0 退出程序,输入 1 重置用户,退出和重置都会将当前用户之前访问数据记录搭配 json 文件中。 -
由于 gpt-3.5-turbo 单次请求最大 token 数为:4096,所以代码里限制了下对话次数。
更多拓展
- 你可以写个函数,从 json 文件读取历史用户访问记录,然后每次访问可以选用户。
- 你可以写个 web 服务,使用 session 或者数据库支持多用户同时登录,同时访问。
- 你可以基于之前分享的钉钉机器人项目,将 gpt-3.5-turbo 接入钉钉机器人。