chatGPT官网经常会因为系统升级等情况而不能用, 有时候响应也特别慢, 于是API排上用场.
之前写了一个简易的命令窗式的问答, 能多轮对话, 还能保存对话, 但是输入很不方便.
回头一看额度才用了4毛钱, 于是在api免费期限还剩一个一个月的时候写了一个对话界面, 目前只是单轮对话,后期将加入更多功能, 尽最大努力用完剩下余额.
API接口
首先是chatGPT的接口, 这个网上例程很多, 主要是返回消息和所耗费的taken.
import os
import openai
import json
# from main_window import *
if os.getenv('chatgpt_key'):openai.api_key = os.getenv('chatgpt_key')
else:openai.api_key_path = "E:\chatgpt\key.txt"def connect(message):response = openai.ChatCompletion.create(model="gpt-3.5-turbo",messages=message)message = response["choices"][0]["message"]token = int(response["usage"]["total_tokens"])return token, message
主界面
主界面采用tkinter, 利用chatGPT先生成一个简单示例, 然后在此基础上不断优化界面, 在不拥专门学习这个库的情况下就能写出外观不错的界面, 可以很容易修改输入内容. 同时能够显示对话耗费了多少taken, 换算的多少刀.
代码如下, 没太注意格式风格, 只为快速迭代
import tkinter as tkimport time
import threading
import uChat_0.coreChat as coreclass DarkChatGUI():def __init__(self, title="Chat"):self.title = titleself.message_user = ''self.taken = 0self.total_taken = 0self.cost = 0self.info = ''font = 'Consolas'# 创建主窗口self.root = tk.Tk()self.root.title(self.title)self.root.configure(bg="black")self.root.geometry("700x580")# self.root.overrideredirect(True) # 使窗口没有边框和标题栏# 创建聊天显示框self.display_frame = tk.Frame(self.root, bg="#262626") # #262626 blackself.display_frame.pack(side="top", fill="both", expand=True)self.chat_display = tk.Text(self.display_frame, bg="#2f2f2f", fg="white", wrap="word", state="disabled",font=(font, 12))self.chat_display.pack(side="top", fill="both", expand=True, padx=8, pady=8)# 聊天显示样式设置self.chat_display.tag_configure('user_name', background="red", font=(font, 12, 'bold'))self.chat_display.tag_configure('ai_name', background="green", font=(font, 12, 'bold'))self.chat_display.tag_configure('user_text', spacing1=10, spacing2=8, foreground='#D6D6D6')self.chat_display.tag_configure('ai_text', spacing1=10, spacing2=8, foreground='#D6D6D6')self.chat_display.tag_configure('info', foreground='orange', font=(font, 11, 'bold'))# 创建信息输入框self.input_frame = tk.Frame(self.root, bg="#262626")self.input_frame.pack(side="bottom", fill="both", expand=False, padx=3, pady=3)self.message_entry = tk.Text(self.input_frame, height=10, spacing3=10, bg="#2f2f2f",fg="white", font=(font, 11), insertbackground='white')self.message_entry.pack(side="left", fill="both", expand=True)self.message_entry.tag_configure('text', spacing2=6, foreground='white')# 发送按键self.send_button = tk.Button(self.input_frame, text="Send", bg="#3860C0", fg="white",font=(font, 12, 'bold'), command=self.send_message)self.send_button.pack(side="left", fill="both")# 监听 Enter 键self.root.bind('<Control-Return>', self.send_message)def send_message(self, event=None):self.message_user = self.message_entry.get('0.0', "end").strip()if self.message_user:# cut_line = '\t '*7 + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())self.message_entry.delete('0.0', "end")self.chat_display.configure(state="normal")self.chat_display.insert("end", ' 我:\t', 'user_name')print(self.info)cut_line = '\n' + '--' * 40 + ''self.chat_display.insert("end", cut_line, 'info')self.chat_display.insert("end", '\n' + self.message_user + "\n\n", "user_text")# 弹出提示框self.chat_display.insert("end","\n\t\t\t---------- 等待AI回应 ---------\n", 'info')# self.chat_display.configure(state="disabled")self.chat_display.see(tk.END)t = threading.Thread(target=self.receive_message, args=())t.start()# self.receive_message()def receive_message(self):send_message = [{"role": "user", "content": self.message_user}]self.taken, message_r = core.connect(send_message)message = message_r['content']self.comp_taken()if message:# print(message)self.chat_display.delete("end-2l", tk.END)self.chat_display.configure(state="normal")self.chat_display.insert("end", ' ChatGPT:\t', 'ai_name')self.chat_display.insert("end", self.info, 'info')self.chat_display.insert("end", '\n' + message + "\n\n", "ai_text")self.chat_display.configure(state="disabled")self.chat_display.see(tk.END)def start(self):self.root.mainloop()def comp_taken(self):self.total_taken += self.takenself.cost = self.total_taken * 0.002/1000self.info = '\t\tpast: ' + str(self.taken) + \'\t\ttotal: ' + str(self.total_taken) + \'\t\tcost: $' + str(round(self.cost, 4))if __name__ == "__main__":gui = DarkChatGUI()gui.start()
后续有空了再加人更多功能, 例如对本地数据库文献库的管理, 还可以结合单机的本地模型. 实现高效学习和工作