源起

在那个宁静的午后,我沉浸在实验的乐趣中,耳边轻柔的音乐伴随着我专注的探索。然而,每当实验中需要查阅资料时,我总是不得不依赖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,没问题了,非常酷炫!

看一下效果,没什么问题了。

image.png

部署

接下来就是部署了,我们采用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

免责声明:本文系转载,版权归原作者所有;旨在传递信息,不代表一休教程网的观点和立场。