在 Python 中创建 ChatGPT 克隆
我们将学习如何使用 Python 中的 Flet 开发具有多个节点的聊天应用程序以及使用 OpenAI 的 text-davinci-003 [ChatGPT API]模型引擎制作的应答机器人。
Flet是什么?
无需直接使用 Flutter,程序员就可以使用 Flet Python 库创建实时 Web
、移动和桌面应用程序。在使用Flutter创建应用程序时,开发人员必须了解Dart 编程语言,但通过使用 Flet 模块和简单的 Python
代码,我们可以创建功能与使用 Flutter 创建的应用程序类似的应用程序。
Flet的主要特点:
- 由
Flutter
提供支持:您的应用程序在任何平台上都会看起来很棒并且功能强大,因为Flet UI
是使用Flutter
制作的。Flet 通过使用命令式编程语言将较小的“小部件”合并到即用型“控件”中,从而简化了 Flutter 策略。 - 架构:使用 Flet,您只需使用
Python
编写一个整体式有状态应用程序,并获得一个多用户、实时单页应用程序。 - 能够将应用程序交付到任何设备:我们可以将 Flet 应用程序部署为 Web 应用程序并在浏览器中运行它。该软件包还可以安装在
Windows、macOS 和 Linux
上。也可以安装在手机上。
所需模块:
在本教程中,我们将使用 Python 的 Flet 模块和 openai
模块 [ChatGPT]。要使用 pip 安装它,请在终端中运行以下命令。
pip install flet
pip install openai
源代码 :
import flet as ft
class Message():
def __init__(self, user_name: str, text: str, message_type: str):
self.user_name = user_name
self.text = text
self.message_type = message_type
class ChatMessage(ft.Row):
def __init__(self, message: Message):
super().__init__()
self.vertical_alignment = "start"
self.controls = [
ft.CircleAvatar(
content=ft.Text(self.get_initials(message.user_name)),
color=ft.colors.WHITE,
bgcolor=self.get_avatar_color(message.user_name),
),
ft.Column(
[
ft.Text(message.user_name, weight="bold"),
ft.Text(message.text, selectable=True),
],
tight=True,
spacing=5,
),
]
def get_initials(self, user_name: str):
return user_name[:1].capitalize()
def get_avatar_color(self, user_name: str):
colors_lookup = [
ft.colors.AMBER,
ft.colors.BLUE,
ft.colors.BROWN,
ft.colors.CYAN,
ft.colors.GREEN,
ft.colors.INDIGO,
ft.colors.LIME,
ft.colors.ORANGE,
ft.colors.PINK,
ft.colors.PURPLE,
ft.colors.RED,
ft.colors.TEAL,
ft.colors.YELLOW,
]
return colors_lookup[hash(user_name) % len(colors_lookup)]
def main(page: ft.Page):
page.horizontal_alignment = "stretch"
page.title = "ChatGPT - Flet"
def join_chat_click(e):
if not join_user_name.value:
join_user_name.error_text = "Name cannot be blank!"
join_user_name.update()
else:
page.session.set("user_name", join_user_name.value)
page.dialog.open = False
new_message.prefix = ft.Text(f"{join_user_name.value}: ")
page.pubsub.send_all(Message(user_name=join_user_name.value,
text=
f"{join_user_name.value}+has joined the chat.", message_type="login_message"))
page.update()
def send_message_click(e):
if new_message.value != "":
page.pubsub.send_all(Message(page.session.get(
"user_name"), new_message.value, message_type="chat_message"))
temp = new_message.value
new_message.value = ""
new_message.focus()
res = chatgpt(temp)
if len(res) > 220: # adjust the maximum length as needed
res = '\n'.join([res[i:i+220]
for i in range(0, len(res), 220)])
page.pubsub.send_all(
Message("ChatGPT", res, message_type="chat_message"))
page.update()
def chatgpt(message):
import openai
# 设置 OpenAI API 客户端
openai.api_key = "YOUR API"
# Set up the model and prompt
model_engine = "text-davinci-003"
prompt = message
# Generate a response
completion = openai.Completion.create(
engine=model_engine,
prompt=prompt,
max_tokens=1024,
n=1,
stop=None,
temperature=0.5,
)
response = completion.choices[0].text.strip()
if response.startswith('\n'):
response = response[1:]
return response
def on_message(message: Message):
if message.message_type == "chat_message":
m = ChatMessage(message)
elif message.message_type == "login_message":
m = ft.Text(message.text, italic=True,
color=ft.colors.BLACK45, size=12)
chat.controls.append(m)
page.update()
page.pubsub.subscribe(on_message)
# 对话框要求输入用户显示名称
join_user_name = ft.TextField(
label="Enter your name to join the chat",
autofocus=True,
on_submit=join_chat_click,
)
page.dialog = ft.AlertDialog(
open=True,
modal=True,
title=ft.Text("Welcome!"),
content=ft.Column([join_user_name], width=300, height=70, tight=True),
actions=[ft.ElevatedButton(
text="Join chat", on_click=join_chat_click)],
actions_alignment="end",
)
# Chat messages
chat = ft.ListView(
expand=True,
spacing=10,
auto_scroll=True,
)
# A new message entry form
new_message = ft.TextField(
hint_text="Write a message...",
autofocus=True,
shift_enter=True,
min_lines=1,
max_lines=5,
filled=True,
expand=True,
on_submit=send_message_click,
)
# Add everything to the page
page.add(
ft.Container(
content=chat,
border=ft.border.all(1, ft.colors.OUTLINE),
border_radius=5,
padding=10,
expand=True,
),
ft.Row(
[
new_message,
ft.IconButton(
icon=ft.icons.SEND_ROUNDED,
tooltip="Send message",
on_click=send_message_click,
),
]
),
)
# 将 flet 应用程序作为网络应用程序在浏览器上运行
ft.app(target=main, port=9000, view=ft.WEB_BROWSER)
# 将 flet 应用程序作为桌面应用程序运行
ft.app(target=main)
代码说明:
Message 类定义消息的结构,ChatMessage 类创建可在聊天中显示的消息的图形表示。主函数定义了聊天应用程序的整体结构,包括聊天窗口、新的消息输入表单以及从 OpenAI 的 GPT-3 语言模型发送消息和接收响应的功能。
聊天应用程序使用 flet 库创建图形用户界面,包括文本字段、按钮和图标。ft.app 函数启动 Web 服务器并在 Web 浏览器中呈现聊天应用程序。
笔记:
在上面代码的第 88 行添加您自己的 OpenAI 密钥 (https://platform.openai.com/account/api-keys
)。
要在浏览器上运行 Flet 应用程序,请将这段代码添加到代码底部:
ft.app(port=any-port-number,target=main,view=ft.WEB_BROWSER)
要将 Flet 应用程序作为桌面应用程序运行,请将这段代码添加到代码底部:
ft.app(target=main)