之前在某宝上购买的open ai的key一直是中转的。商家提供了一个对话界面,直接在设置中粘贴购买的key就可以实现对话。

但是今天下午购买了直连的key。中转的对话界面就不能使用了。只能通过代码获取回答,自己日常使用很不方便。
因此做了一个简单的streamlit界面用于对话。
主要内容是:调用api获取回答;构建对话界面;将回答传到界面上实现流式输出。
界面长这样。
使用到的包。
import sys
import streamlit as st
import os
from langchain.chat_models import ChatOpenAI
from get_response import ask_and_get_answer
from openai import OpenAI
构建对话界面:
st.subheader('GPT-4o 🤖')
# 定义侧边栏。在此部分内的所有控件都会被添加到侧边栏。
with st.sidebar:
api_key = st.text_input('OpenAI API Key:', type='password')
# 创建一个文本输入控件,用于输入OpenAI API密钥。输入的内容将被隐藏。
if api_key:
os.environ['OPENAI_API_KEY'] = api_key
# 如果输入了API密钥,则将其设置为环境变量,以供后续使用。
print("OpenAI API Key set successfully.")
llm=ChatOpenAI(model='gpt-4o', temperature=1)
print(f"Selected LLM: {llm}")
# 创建一个下拉选择框,让用户选择本地大语言模型(LLM)。
output_type = st.selectbox("选择输出方式", ('流式输出', '普通输出'))
# 创建一个下拉选择框,让用户选择输出方式(普通输出或流式输出)。
# 初始化history
if "messages" not in st.session_state:
st.session_state.messages = []
# 如果会话状态中没有消息记录,则初始化一个空列表。
# 展示对话
for msg in st.session_state.messages:
with st.chat_message(msg['role']):
st.markdown(msg["content"])
# 遍历会话状态中的所有消息,并在应用中显示它们。
# React to user input
if prompt := st.chat_input("Say something"):
# Display user message in chat message container
with st.chat_message("user"):
st.markdown(prompt)
# Add user message to chat history
st.session_state.messages.append({"role": "user", "content": prompt})
print(f"User prompt: {prompt}")
# 如果用户在聊天输入框中输入了消息,则显示用户消息并将其添加到消息记录中。
普通输出:
# 普通方式输出
if prompt is not None:
# st.warning(body='正在努力加载模型中,稍后再试', icon="⚠️")
if output_type == "普通输出" :
response = ""
response = ask_and_get_answer(prompt)
print("Using GPT model for response...")
print(f"Generated response: {response}")
with st.chat_message("assistant"):
st.markdown(response)
st.session_state.messages.append({"role": "assistant", "content": response})
流式输出:
else:
# 流式输出
# 初始化一个空的占位符,用于实现流式输出。
output_placeholder = st.empty()
# Add assistant response to chat history
client = OpenAI()
stream = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
stream=True,
)
collected_messages = ""
for chunk in stream:
if chunk.choices[0].delta.content is not None:
collected_messages += chunk.choices[0].delta.content
print(chunk.choices[0].delta.content, end="")
output_placeholder.text(collected_messages)
主要代码如上。这是拿之前一个RAG-LLM对话界面改的。所以里面有一些注释(数据库或者模型之类)是之前的界面内容。影响不大。
分割线:
更新一下,昨天新加了流式输出的markdown、保存聊天记录并且每次加载的功能。这样流式输出的效果会好很多,而且可以保留每次的聊天记录。
接下来打算新加上传图片/文件、多轮对话的选项。
markdown流式效果。

新增代码:
# 保存聊天记录的函数
def save_chat_history(history, filename):
with open(filename, 'w') as f:
json.dump(history, f)
# 加载聊天记录的函数
def load_chat_history(filename):
if os.path.exists(filename):
with open(filename, 'r') as f:
return json.load(f)
return []
以json格式保存聊天记录在指定文件路径下。
BASE_DIR = os.path.dirname(__file__)
BASE_DIR = BASE_DIR+"\chat_history"
#print(BASE_DIR)
os.environ['CHAT_HISTORY'] = BASE_DIR
这里我选择的路径是该py文件的目录。加上chat_history。
修改了原来初始化history部分的代码。
# 文件名从环境变量中读取
chat_history_file = os.getenv('CHAT_HISTORY')
print(chat_history_file)
# 初始化history
if "messages" not in st.session_state:
#st.session_state.messages = []
st.session_state.messages = load_chat_history(chat_history_file)
# 如果会话状态中没有消息记录,则初始化一个空列表。
# 展示对话
for msg in st.session_state.messages:
with st.chat_message(msg['role']):
st.markdown(msg["content"])
# 遍历会话状态中的所有消息,并在应用中显示它们。
在聊天结束之后要保存聊天记录。
save_chat_history(st.session_state.messages, chat_history_file)
print(f"聊天记录已保存至{chat_history_file}。")
80

被折叠的 条评论
为什么被折叠?



