源起
在那个宁静的午后,我沉浸在实验的乐趣中,耳边轻柔的音乐伴随着我专注的探索。然而,每当实验中需要查阅资料时,我总是不得不依赖ChatGPT。众所周知,访问ChatGPT并非易事,而国内的使用又因登录步骤繁琐而让人望而却步。我渴望有一个便捷的窗口,只需将问题抛出,便能直接获得所需的信息。比如,最近我在研究Greenplum数据库,对于gpstop
命令的众多参数,我并不喜欢阅读那些冗长的英文帮助文档。如果能有人帮我简要总结一下各个参数的含义及其使用方法,那将是我莫大的福音。毕竟,这种信息在网上固然不少,但繁琐的查找过程实在让人心生厌烦。
思考
我心中萌生了一个构想:打造一个专属的个人工具。这个工具设计得极为简约,核心功能仅限于对话交流,无需繁琐的登录或注册流程。它的界面设计将充满个性,酷炫十足,完美契合我的审美风格。无论是手机端、平板还是电脑上,都能流畅使用。更重要的是,它不会存储对话历史,每次刷新界面后,历史信息都会被清空,从而确保每一次对话都是全新的开始。这样的设想,既实用又充满未来感。
架构
我只是一个小运维、不会后端java、也不想接触VUE、而且也不想那么困难,因此采用的架构是:
- 前端:Streamlit 框架
- 后端:Streamlit 框架
- 编程语言:Python 语言
- 部署方式:Docker 运行时
- 模型:GLM4-Flash 模型(FREE)
设计蓝图既定,我便满怀热情地着手实施。首要任务是开发一个API接口。鉴于预算有限,我决定寻找一个免费的API服务。在网络上广泛搜寻后,我发现了一个理想的平台——清华智谱SDK。仔细阅读了官方的SDK说明文档,我发现搭建过程似乎并不复杂,很快就能上手。于是,我跃跃欲试,开始了调试工作。然而,令人意外的是,系统竟然提示我欠费。这让我感到困惑,难道是我误解了什么?这究竟是怎么回事呢?
原来如此,我竟然早已拥有这个账户,只是没想到API服务已经过期了,连官方赠送的期限也早已届满。既然如此,那也没关系,重新申请一个新的API即可。既然模型选择了性能卓越的GLM4-Flash,那就开始编写一个简单的code.py
文件,来测试一下模型的调用功能。
代码
core.py
我将启动一个核心API的调用测试,亲自检验这个接口的实用性与性能。当然,为了更深入地了解,我将利用AI的辅助,看看这个接口是否能够满足我们的期待。
from zhipuai import ZhipuAI# 读取 API 密钥def read_api_key(file_path="GLM4-Flash.key"): with open(file_path, "r") as file: api_key = file.read().strip() # 读取并去掉多余的空白字符 return api_key# 使用读取到的 API 密钥初始化客户端api_key = read_api_key("GLM4-Flash.key") # 根据实际路径调整文件名client = ZhipuAI(api_key=api_key)# 用来存储对话历史messages = []def chat_with_model(): while True: # 获取用户输入 user_input = input("你:") if user_input.lower() == "exit": print("退出对话") break # 将用户输入添加到消息历史 messages.append({"role": "user", "content": user_input}) # 调用 API 获取模型的响应 response = client.chat.completions.create( model="glm-4-flash", # 使用的模型 messages=messages # 传递对话历史 ) # 提取并打印模型的响应 model_response = response.choices[0].message.content # 修正此行 print(f"模型:{model_response}") # 将模型的响应添加到消息历史 messages.append({"role": "assistant", "content": model_response})if __name__ == "__main__": print("欢迎与自然语言模型聊天!输入 'exit' 结束对话。") chat_with_model()
PS D:\zhipu> python core.py
欢迎与自然语言模型聊天!输入 ‘exit’ 结束对话。 你:你好!你是什么模型? 模型:你好!我是一个基于人工智能的语言模型,名为 ChatGLM。我是在清华大学 KEG 实验室和智谱 AI 公司于 2024 年共同训练的语言模型 GLM-4 的基础上开发的。我的任务是针对用户的问题和要求提供适当的答复和支持。 你:exit 退出对话 PS D:\zhipu>
经过一番测试,一切顺利,接口表现良好。接下来,我将着手解决界面设计的问题。我选择了一个之前使用过的框架——Streamlit。这个框架非常有趣,它允许我使用Markdown(MD)语法直接编写前端页面。最令人兴奋的是,如果我对代码进行了修改,甚至无需退出页面,只需刷新一下,就能实时看到修改后的效果。
ui.py
开干!
import streamlit as stfrom zhipuai import ZhipuAI# 读取 API 密钥...(略)# 页面标题st.set_page_config(page_title="# AI @heike07")st.title("# AI @heike07")# 历史对话with st.container(): st.markdown('<div>') # 显示消息 for msg in st.session_state.messages: if msg["role"] == "user": st.markdown(f'<div>{msg["content"]}</div>') else: st.markdown(f'<div>{msg["content"]}</div>') st.markdown('</div>')# 用户输入框user_input = st.text_input("请输入消息:", "")if st.button("提交") and user_input: st.session_state.messages.append({"role": "user", "content": user_input}) response = client.chat.completions.create( model="glm-4-flash", messages=st.session_state.messages ) model_response = response.choices[0].message.content st.session_state.messages.append({"role": "assistant", "content": model_response}) st.rerun()if not user_input: st.warning("请输入消息进行对话。")
通过浏览器访问localhost:8501测试了,一下没有什么问题,也可以实现基础的对话。
礼成,接下来就是界面的优化。
# 找到历史记录这部分带入class样式# 显示历史对话for msg in st.session_state.messages: if msg["role"] == "user": st.markdown(f'<div >{msg["content"]}</div>', unsafe_allow_html=True) else: st.markdown(f'<div >{msg["content"]}</div>', unsafe_allow_html=True)# 再写一点样式st.markdown(""" <style> .user-message { background: linear-gradient(135deg, #00c6ff, #0072ff); /* 蓝色渐变 */ padding: 15px; border-radius: 20px; margin: 12px 0; width: auto; word-wrap: break-word; text-align: left; display: inline-block; float: right; box-shadow: 0 8px 30px rgba(0, 114, 255, 0.3); /* 强化阴影 */ color: white; border: 2px solid rgba(0, 114, 255, 0.6); /* 边框 */ } .assistant-message { background: linear-gradient(135deg, #00b09b, #96c93d); /* 绿色渐变 */ padding: 15px; border-radius: 20px; margin: 12px 0; width: auto; word-wrap: break-word; text-align: left; display: inline-block; box-shadow: 0 8px 30px rgba(0, 255, 123, 0.3); /* 强化阴影 */ color: white; border: 2px solid rgba(0, 255, 123, 0.6); /* 边框 */ } </style>""", unsafe_allow_html=True)
OK,没问题了,非常酷炫!
看一下效果,没什么问题了。
部署
接下来就是部署了,我们采用docker方式来部署,蛮简单的写一个dockerfile文件来实现这个事情
# 使用官方的 Python 镜像作为基础镜像FROM python:3.10-slim# 设置工作目录WORKDIR /app# 复制当前目录下的所有文件到容器中的 /app 目录COPY . /app# 设置清华大学的 PyPI 镜像源RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple# 安装程序所需的 Python 库RUN pip install -r requirements.txt# 开放 8501 端口(Streamlit 默认端口)EXPOSE 8501# 设置容器启动时的命令,运行 Streamlit 应用CMD ["streamlit", "run", "ui.py"]
访问
上面只是简单解释一下从0-1的过程,该项目已经开源到github,具体可以去ai.heike07.cn查看并访问,当然如果你不想构建自己的也可以用我的,嘿嘿,不要搞破坏就行~
继续滚去做实验了,但是多了一个便携的小工具,多端都可以访问,嘿嘿!
作者:heike07 链接:https://juejin.cn/post/7449419385947602978