|
“ChatGPT API”于 2023 年 3 月 1 日发布后,围绕该 API 层出不穷地出现了不少应用,为本就相当火爆的ChatGPT话题又添了一把柴。借助新发布的GPT-3.5模型的自然语言处理能力,用户终于有机会自己创建真正的聊天机器人应用,用于各种目的,如回答问题、写小说、编程,甚至提供治疗建议。
之前关于使用OpenAI API做一个AI对话网站,我写过一个教程:
当时使用的OpenAI发布的GPT 3.0版本的Text Completion API,能完成很多AI文字任务,最大的缺点是不能像ChatGPT那样对对话的上下文进行记忆,因此只能完成单独的一问一答工作,另外,Davinci-003模型的使用费用也不便宜,需要0.02美元/1千Token。
如今,ChatGPT API(又可称为gpt-3.5-turbo模型API,或者Chat Completion API)的发布,无论是完整的上下文对话功能,还是十分廉价的0002美金/1千Token的价格,让我觉得有必要在写一个小教程,把API的使用和Streamlit网站的开发再串联一遍,让你尽快开发一个有面子有里子的网站,无论是给自己专用,还是分享给朋友,亦或是扩展到一些小型的商务用途,都挺有价值的。
通过这个网站,你将告别体验ChatGPT经常的限流和断线,比起支付20美元包月的pro用户,按需使用API产生的费用要低得多(如果你不是超重度用户),除了前期注册OpenAI,使用API你也不需要再科学上网,经过我的实验,API响应的速度目前也是相当杠杠的。此外,自制的网站还可以根据需要进行功能扩展和开发研究。花个十分钟,开发个Web应用,拥有这些好处,何乐而不为。
如果你没看过我之前的那篇文章,或者没有很多Python基础,都没关系,这篇文章会从头给你讲解。
老规矩,OpenAI网址:openai.com. 注册登录需要有谷歌访问能力,和海外手机号验证(教程很多,可以在平台里直接搜索到)。
创建API Key
如果你已经在帐户中申请了 OpenAI API Key,则可以继续使用该Key,而无需生成新Key。如果这是你第一次使用 OpenAI API,请注册一个新的 OpenAI 帐户并从帐户菜单中找到以下页面中的生成API Key的按钮:

请注意,整个 API Key在生成后只会显示一次,因此必须在第一时间将其复制到安全的地方以供进一步使用。 (我直接将我的Key代码复制到代码中了,仅用于演示目的,不建议你将其用于实际业务的应用程序)
Chat Completion API
新发布的“ChatGPT”API 归属为 Chat completion类别,文档可在此处找到。
即使你之前没有使用过其他 OpenAI API 的经验,对于使用这个API,也是一目了然的。 要想得到 GPT-3.5模型的对话回复,从它的官方介绍来看,你需要做的就是:
安装包
!pip install openai导入模块
import openai创建对话指令 Prompt
complete = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Who won the world series in 2020?"},
{"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
{"role": "user", "content": "Where was it played?"}
]
)
获取回复
message=complete.choices[0].message.content与其他旧版 GPT 模型相比,Message正文有了一种新的用法。 Message List里包含几个执行“聊天”功能的必要消息对象。
System、User、Assistant是消息对象中新定义的三个角色。System消息定义为通过用Content中的描述来定义Chat模型的行为。不过,如介绍中所述,目前此功能尚未在 gpt-3.5-turbo-0301 中实现完整。User消息就是用户的输入,而Assistant消息是指来自 GPT-3.5 API 的回复内容。 User和Assistant可以作为历史对话内容交替添加到Message list中,为Chat模型提供每一次对话的上下文,以便稍后生成相关性更强的AI回复。Message list中最后一条User消息则是指当前对话请求的用户输入内容。
Streamlit 和 Streamlit_chat
Streamlit 是一个开源Web框架,它使数据科学家和开发人员能够快速构建用于机器学习和数据科学项目的可交互 Web 应用。 它还提供了一堆很方便的小部件,只需要一行 python 代码即可创建,如 st.table(...)可以马上创建表格等等。针对我们是为了创建一个供私人使用的简单 Chatbot 网站这样的目标,Streamlit 确实是一个非常合适的工具。再加上基于它的第三方 Streamlit_chat 库,为生成“聊天式”Web 应用提供了进一步的便利,使我们不必处理HTML 元素和 CSS 的这些我们可能不太熟悉也不太想花太多时间琢磨的东西。

用Streamlit开发一个Web并使其上线,只要执行以下这几步:
安装包
!pip install streamlit创建一个demo.py文件,添加如下代码:
import streamlit as st
st.write("""
# My First App
Hello *world!*
""")在该文件目录下上执行:
!python -m streamlit run demo.py这时你就会看到类似如下的内容被打印了出来,如果你的运行设备具有外网地址,用户就可以直接在互联网上从External URL的地址访问到你的Web了。
You can now view your Streamlit app in your browser.
Network URL: http://xxx.xxx.xxx.xxx:8501
External URL: http://xxx.xxx.xxx.xxx:8501开发完整的ChatGPT Web应用
Web操作的运行数据都是由Streamlit的对象session_state管理的。我们定义了“prompt“列表来存储对话消息,这些消息从System消息开始,然后把之前产生的User和Assistant附加到生成的每个聊天中。
对于User角色定义,我在内容中尝试添加了“with a little humor expression”(带有一点幽默表情)的额外说明,看起来竟然是有效,因为当我问如何成为亿万富翁时,AI跟我开玩笑说抢银行......这样的设置让我想起了电影《星际穿越》中的机器人“TARS”。
另外两个 session_state 用于存储所有 API 响应(generated)和所有用户提示(past),并使用 Streamlit_chat 的 message() 函数以聊天方式成对显示。
还用Streamlit 小部件创建了两个按钮,“Send“按钮以激活 ChatCompletion 请求和”New Chat“按钮以清除之前的对话。这些功能在回调函数 chat_click() 和 end_click() 中分别定义。
为了更好复刻 ChatGPT 的用户体验,我们还需要考虑代码片段、表格等这些需要结构化显示的文本, 也就是如何把从API 响应中的Markdown格式文本完美的显示出来。不过有点遗憾的是,streamlit_chat 的聊天气泡不能很好地显示 markdown 内容,所以我使用Streamlit的Tab小部件来分隔,用“Normal”页放置气泡中的纯文本,用“Rich”页显示完整的Markdown格式。
效果参考下图:

Normal页的对话内容

Rich页的对话内容
完整程序代码如下:
import openai
import streamlit as st
from streamlit_chat import message
openai.api_key = '{Your API key}'
if 'prompts' not in st.session_state:
st.session_state['prompts'] = [{"role": "system", "content": "You are a helpful assistant. Answer as concisely as possible with a little humor expression."}]
if 'generated' not in st.session_state:
st.session_state['generated'] = []
if 'past' not in st.session_state:
st.session_state['past'] = []
def generate_response(prompt):
st.session_state['prompts'].append({"role": "user", "content":prompt})
completion=openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages = st.session_state['prompts']
)
message=completion.choices[0].message.content
return message
def end_click():
st.session_state['prompts'] = [{"role": "system", "content": "You are a helpful assistant. Answer as concisely as possible with a little humor expression."}]
st.session_state['past'] = []
st.session_state['generated'] = []
st.session_state['user'] = ""
def chat_click():
if st.session_state['user']!= '':
chat_input = st.session_state['user']
output=generate_response(chat_input)
#store the output
st.session_state['past'].append(chat_input)
st.session_state['generated'].append(output)
st.session_state['prompts'].append({"role": "assistant", "content": output})
st.session_state['user'] = ""
st.image("{Your logo}", width=80)
st.title("My ChatBot")
user_input=st.text_input("You:", key="user")
chat_button=st.button("Send", on_click=chat_click)
end_button=st.button("New Chat", on_click=end_click)
if st.session_state['generated']:
for i in range(len(st.session_state['generated'])-1, -1, -1):
tab1, tab2 = st.tabs(["normal", "rich"])
with tab1:
message(st.session_state['generated'], key=str(i))
with tab2:
st.markdown(st.session_state['generated'])
message(st.session_state['past'], is_user=True, key=str(i) + '_user')最后在该代码文件目录下执行:
!python -m streamlit run demo.py如果你的机器上有外网IP,你就可以通过http://{Your IP}:8501 访问你的私人ChatGPT网站了。
额外的两步操作
让你的用户通过类似于 http://111.22.333.44:8501 这样的地址去访问你的网站,肯定不是一个舒适的体验。为了让你的网站拥有一个www.openai.com这样域名的网站地址,你还需要做以下两步。
- 购买一个域名 - 仅仅用来个人使用的话,可以在namesilo等平台买一些冷门后缀的域名,如.life,.ai这种,即便宜又有个性,而且一般很难与你希望的名称重名。然后在平台后端管理界面里把域名对接你的网站IP地址上。
- 把应用部署在80端口上 - Streamlit无法把应用指定到80端口,所以你必须在网址后面指定其端口,如默认的:8501,这时你需要使用Docker,把Streamlit的Web应用部署到Docker里,再有Docker映射其8501到服务器的80端口。这样,以后的用户访问就无需再网址后面添加指定端口了。具体的Docker部署Streamlit的教程参考:Deploy Streamlit using Docker - Streamlit Docs。
以上就是建造一个ChatGPT个人网站的全部内容,希望你也可以有一个属于自己的ChatGPT。 |
|