Python学习笔记07-基于Python+Streamlit的千问AI对话应用开发实战
·
本教程将手把手带你使用Python和Streamlit框架,结合阿里云千问大模型,开发一个具备流式输出、对话保存和历史记录管理功能的桌面级AI应用。你将学会如何申请API密钥、配置开发环境,并编写核心代码实现一个完整的AI助理。

1. 准备工作:申请千问API Key
在开始编码前,我们需要获取调用千问大模型的“钥匙”。
- 访问阿里云官网并登录/注册账号。
- 进入“百炼”(Model Studio)平台。
- 在“我的模型”或“API密钥”管理页面,创建一个新的API Key。
- 注意:代码中
api_key=''目前是空的,运行前必须填入你的 Key,否则会报错。
2. 环境搭建与依赖安装
本项目主要依赖以下库:
streamlit: 用于快速构建Web应用界面。dashscope: 阿里云通义千问的Python SDK。json&os: 用于文件操作和系统交互。
你可以使用pip命令安装所需依赖:
pip install streamlit dashscope
3. 项目结构
界面非常直观,主要分为 侧边栏(控制区) 和 主区域(对话区)
1. 侧边栏操作
- 新建对话 (
➕️):点击后会清空当前聊天记录,并生成一个新的会话(以当前时间命名)。 - 历史会话:程序会自动在本地创建
SessionData文件夹来保存聊天记录。- 点击会话名:切换不同的历史对话。
- 点击
X:删除对应的会话记录。
- AI 设置:
- 昵称:修改 AI 的名字(默认是“小卓子”)。
- 性格:修改 AI 的回复风格(默认是“可爱”)。
2. 主对话区
- 输入问题:在底部的输入框中输入你的问题。
- 流式输出:AI 的回复是逐字显示的(类似打字机效果),非常有交互感。
4. 核心代码实现详解
1. 初始化与配置 应用启动时,会检查session_state中是否存在必要的变量(如messages, nickName等),若不存在则初始化默认值。同时,配置了页面标题、布局等信息。
2. 侧边栏功能:历史对话与设置 侧边栏提供了“新建对话”、“历史会话列表”以及“AI设置”功能。
- 历史会话:通过
os.listdir读取SessionData目录下的所有.json文件,并动态生成按钮。点击按钮即可调用change_session函数加载对应的历史记录。 - AI设置:允许用户自定义AI的昵称和性格(System Prompt),并实时更新到
session_state中。
3. 流式对话与渲染 这是应用最核心的交互部分。当用户输入问题并提交后,代码会执行以下步骤:
- 展示用户输入:使用
st.chat_message('user').write(prompt)在界面上展示用户的提问。 - 构建消息列表:将系统设定(角色、性格)与历史对话记录合并,作为上下文传给模型。
- 调用API:使用
dashscope.Generation.call发起请求,并设置stream=True以启用流式输出。 - 实时渲染:通过
for循环遍历response的每一个chunk,将内容实时拼接并写入一个空的st.empty()占位符中,从而实现文字逐字出现的“打字机”效果。 - 保存记录:将完整的AI回复追加到
session_state.messages中,以便后续对话使用。
完整代码如下:
import json
import os
import streamlit as st
import dashscope
import Module.AI实例Module.SaveSession as sessionOp
import datetime
# 保存会话
def save_session():
if st.session_state["messages"] != []:
session_data={
"nickName":st.session_state["nickName"],
"nature":st.session_state["nature"],
"messages":st.session_state["messages"],
"sessionName":st.session_state["sessionName"]
}
sessionOp.SaveSessionToFile(session_data,f"{session_data['sessionName']}.json")
# 重置会话
def rest_session():
st.session_state.messages = []
st.session_state.nickName = "小卓子"
st.session_state.nature = "可爱"
st.session_state.sessionName = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
st.session_state.messages=[]
# 加载会话
def change_session(filepath):
save_session()
with open(f"SessionData/{filepath}","r",encoding="utf-8") as f:
session_data=json.load(f)
st.session_state.nickName = session_data["nickName"]
st.session_state.nature = session_data["nature"]
st.session_state.sessionName = session_data["sessionName"]
st.session_state.messages = session_data["messages"]
# 删除会话
def remove_session(filepath):
os.remove(f"SessionData/{filepath}")
# 设置页面配置
st.set_page_config("AI对话","👨🏽💻","wide","expanded")
# 创建一个标题
st.title("AI对话")
# 初始化聊天缓存
if "messages" not in st.session_state:
st.session_state.messages = []
if "nickName" not in st.session_state:
st.session_state.nickName = "小卓子"
if "nature" not in st.session_state:
st.session_state.nature="可爱"
if "sessionName" not in st.session_state:
st.session_state.sessionName=datetime.datetime.now().strftime("%Y%m%d%H%M%S")
# 侧边栏
st.sidebar.subheader("新建对话")
with st.sidebar:
if(st.button("新建对话",width="stretch",icon="➕️")):
save_session()
rest_session()
st.text("历史会话")
if os.path.exists("SessionData"):
for fileName in os.listdir("SessionData"):
col1, col2 = st.columns([0.8, 0.2], width="stretch")
if fileName.endswith(".json"):
session_key = fileName.replace(".json", "")
with col1:
if st.button(fileName.replace(".json",""),width="stretch",type="primary" if st.session_state.sessionName+".json"==fileName else "secondary"):
change_session(fileName)
with col2:
if st.button("X",key=f"delete_{session_key}"):
remove_session(fileName)
st.rerun()
st.sidebar.subheader("AI设置")
with st.sidebar:
nickName=st.text_input("昵称",placeholder="请输入昵称",value=st.session_state.nickName)
if nickName:
st.session_state.nickName=nickName
nature=st.text_area("性格",placeholder="请输入性格",value=st.session_state.nature)
if nature:
st.session_state.nature=nature
# 展示聊天记录
for message in st.session_state.messages:
st.chat_message(message["role"]).write(message["content"])
# 创建一个文本输入框
prompt=st.chat_input("请输入您的问题")
if prompt:
# 内容
st.chat_message('user').write(prompt)
# 保存用户的问题
st.session_state.messages.append({'role': 'user', 'content': prompt})
# 调用AI
response = dashscope.Generation.call(
api_key='',
model="qwen-plus",
messages=[
{'role': 'system','content': f'你是一名{st.session_state.nature}的AI助理,你的名字叫{st.session_state.nickName},请你使用温柔可爱的语气回答用户的问题'}
]+st.session_state.messages,
result_format='message',
stream=True
)
# 创建一个空组件 流式输出
response_messages=st.empty()
full_content=""
for chunk in response:
if chunk.output.choices[0].message.content is not None:
full_content=chunk.output.choices[0].message.content
response_messages.chat_message("ai").write(full_content)
# 非流式输出
# st.chat_message('ai').write(response.output.choices[0].message.content)
# 保存AI的回答
st.session_state.messages.append({'role': 'assistant', 'content': full_content})
5. 运行与测试
- 将上述代码保存为
app.py。 - 在终端执行
streamlit run app.py启动应用。 - 浏览器将自动打开,你就可以开始与你的专属AI助理聊天了。
- 尝试在侧边栏修改AI的性格和昵称,体验不同的对话风格。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐




所有评论(0)