1. AI智能伴侣展示
AI智能伴侣主要有两个模块:
- **页面基本布局:**即右侧智能伴侣进行大模型交互界面
- **侧边栏:**即左侧会话管理与伴侣信息模块

2. 界面基本布局
2.1 界面基本内容开发
本阶段需要完成主要界面内容的开发:
- 页面配置
- 页面大标题
- 页面 Logo
- 问题输入框
- 调用 AI 大模型返回结果并展示在页面上

代码如下:
import streamlit as st
import os
from openai import OpenAI
#设置页面的配置项
st.set_page_config(
page_title="AI智能伴侣",
page_icon="🤖",
#布局
layout="wide",
#侧边栏状态
initial_sidebar_state="expanded",
menu_items={}
)
#大标题
st.title("AI智能伴侣")
#Logo
st.logo("第三章/resouces/logo.jpg")
#-------------------------API调用前期准备--------------------------
#设置系统提示词
system_prompt = "你是一名非常可爱的 AI 助理,你的名字叫小甜甜,请你使用温柔可爱的语气回答用户的问题"
# 创建与 AI 大模型交互的客户端对象(
api_key = "*******************************"
client = OpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
api_key=api_key,
)
#-------------------------API调用前期准备--------------------------
#消息输入框
prompt = st.chat_input("请输入您要问的问题")
if prompt:
st.chat_message("user").write(prompt) #创建对话气泡容器,区分用户消息 / AI 助手消息
print("--------------------->调用AI大模型,提示词:",prompt)
#调用 AI 大模型
response = client.responses.create(
model="doubao-seed-evolving",
input= [
{"role": "system", "content": system_prompt },
{"role": "user", "content": prompt},
],
stream= False
)
#输出大模型的返回结果
rd = response.model_dump()
content = next(i["content"][0]["text"] for i in rd["output"] if i["type"] == "message")
print("--------------------->AI大模型返回结果:",content)
st.chat_message("assistant").write(content)
大模型返回结果的输出方式
火山引擎官方 Python SDK 中,client.responses.create() 返回的不是原生字典,而是一个继承 Pydantic BaseModel 的结构化对象
- SDK 封装后的 Response 对象:SDK 自动把 HTTP JSON 解析成 Pydantic 对象,额外附加了 .model_dump、字段访问属性(response.output、response.id)等工具方法。
- **.model_dump():**将对象转为标准Python 字典
- next(): 是 Python 内置函数,作用是取出迭代器里的下一个元素。 搭配生成器表达式
(xxx for x in list if 条件)使用,会一次性拿到第一个满足条件的数据。分步拆解:
content = next(i["content"][0]["text"] for i in rd["output"] if i["type"] == "message")
for i in rd["output"]:循环遍历 output 数组里每一条返回块if i["type"] == "message":只保留类型是 message 的条目,过滤掉 reasoning 推理块i["content"][0]["text"]:取出这条消息里的文本内容next(...):拿到过滤后匹配到的第一条结果。output 数组可能有多段内容,next只会返回第一个符合条件的数据,后面的直接忽略。
2.2 界面消息展示与会话记忆
由于大模型本身没有记忆功能,因此本阶段要实现大模型对话记忆功能以及界面消息的连续展示 :
- 使用 st.session_state.input 来持续记忆会话内容
- 每次输入和输出都及时记录在 st.session_state.input 内
- 展示聊天信息 st.session_state.input
- 在每次给大模型输入提示词时,将 st.session_state.input 内的内容解包一并给大模型

代码如下:
import streamlit as st
import os
from openai import OpenAI
#-------------------------网页聊天信息的记忆存储---------------------
#初始化聊天信息
if 'input' not in st.session_state:
st.session_state['input'] = []
# -------------------------网页聊天信息的记忆存储---------------------
#设置页面的配置项
st.set_page_config(
page_title="AI智能伴侣",
page_icon="🤖",
#布局
layout="wide",
#侧边栏状态
initial_sidebar_state="expanded",
menu_items={}
)
#大标题
st.title("AI智能伴侣")
#Logo
st.logo("第三章/resouces/logo.jpg")
#-------------------------API调用前期准备--------------------------
#设置系统提示词
system_prompt = "你是一名非常可爱的 AI 助理,你的名字叫小甜甜,请你使用温柔可爱的语气回答用户的问题"
# 创建与 AI 大模型交互的客户端对象(
api_key = "*********************************8"
client = OpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
api_key=api_key,
)
#-------------------------API调用前期准备--------------------------
#展示聊天信息
for input in st.session_state['input']:
st.chat_message(input["role"]).write(input["content"])
#消息输入框
prompt = st.chat_input("请输入您要问的问题")
if prompt:
st.chat_message("user").write(prompt)
print("--------------------->调用AI大模型,提示词:",prompt)
#保存用户输入的提示词
st.session_state['input'].append({"role": "user","content": prompt})
#调用 AI 大模型
response = client.responses.create(
model="doubao-seed-evolving",
input= [
{"role": "system", "content": system_prompt},
#解决大模型会话记忆问题
*st.session_state['input'] #列表解包
]
)
#-------------------------处理AI大模型的返回结果-----------------(非流式输出解析方式)
rd = response.model_dump()
# 从output里拿message的文本
content = next(i["content"][0]["text"] for i in rd["output"] if i["type"] == "message")
print("--------------------->AI大模型返回结果:",content)
st.chat_message("assistant").write(content)
#保存大模型返回的结果
st.session_state['input'].append({"role": "assistant","content": content})
2.3 流式输出
该阶段要完成:模型每生成 1 个 Token(字 / 词),立刻通过长连接分片发给客户端,边生成边返回。
最终效果:页面逐字打字,实时看到 AI 输出,无等待空白。
实现方式:
responses.create开启只需加参数 stream= True- 大模型返回结果进行与一次性输出不同的处理
代码如下:
import streamlit as st
import os
from openai import OpenAI
#-------------------------网页聊天信息的记忆存储---------------------
#初始化聊天信息
if 'input' not in st.session_state:
st.session_state['input'] = []
# -------------------------网页聊天信息的记忆存储---------------------
#设置页面的配置项
st.set_page_config(
page_title="AI智能伴侣",
page_icon="🤖",
#布局
layout="wide",
#侧边栏状态
initial_sidebar_state="expanded",
menu_items={}
)
#大标题
st.title("AI智能伴侣")
#Logo
st.logo("第三章/resouces/logo.jpg")
#-------------------------API调用前期准备--------------------------
#设置系统提示词
system_prompt = "你是一名非常可爱的 AI 助理,你的名字叫小甜甜,请你使用温柔可爱的语气回答用户的问题"
# 创建与 AI 大模型交互的客户端对象(
api_key = "*********************************8"
client = OpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
api_key=api_key,
)
#-------------------------API调用前期准备--------------------------
#展示聊天信息
for input in st.session_state['input']:
st.chat_message(input["role"]).write(input["content"])
#消息输入框
prompt = st.chat_input("请输入您要问的问题")
if prompt:
st.chat_message("user").write(prompt)
print("--------------------->调用AI大模型,提示词:",prompt)
#保存用户输入的提示词
st.session_state['input'].append({"role": "user","content": prompt})
#调用 AI 大模型
response = client.responses.create(
model="doubao-seed-evolving",
input= [
{"role": "system", "content": system_prompt},
#解决大模型会话记忆问题
*st.session_state['input'] #列表解包
],
#要求流式输出
stream= True
)
#-------------------------处理AI大模型的返回结果-----------------(流式输出解析方式)
response_message = st.empty() #创建空容器,用于展示大模型的返回结果
full_response = "" #用于存储大模型的返回结果
for chunk in response:
# 判断事件类型,取delta文本
if chunk.type == "response.output_text.delta":
content = chunk.delta
full_response += content
print(content, end="", flush=True)
response_message.chat_message("assistant").write(full_response)
#保存大模型返回的结果
st.session_state['input'].append({"role": "assistant","content": full_response})
流式输出解析方式
- 创建 full_response 空字符串,用于存储大模型返回结果
- for chunk in response:response 不再是完整结果对象,而是迭代器 ,循环会不断接收服务端推送的分片,直到流结束。每一轮循环拿到的 chunk 只是本次新增的一小段文字,不是完整回答。
- chunk.delta:当前分片新增的文字,只有这一段新内容,必须拼接才能得到完整回答。
- full_response += content :拼接缓存
- Streamlit 流式渲染:
- response_message = st.empty():创建一个可以反复覆盖的空白容器
- 每次收到分片,调用 .write(full_response) 会覆盖上一次内容,页面呈现逐字打字动画;
- 不能每次循环新建 st.chat_message("assistant"), 否则页面会堆叠无数 AI 气泡。
3.侧边栏制作
3.1 伴侣信息
本阶段完成侧边栏中伴侣信息开发:
- 系统提示词变更(姓名和性格根据输入决定)
- 姓名和性格的记忆存储
- 侧边栏伴侣信息模块

代码如下:
import streamlit as st
import os
from openai import OpenAI
#-------------------------网页聊天信息的记忆存储---------------------
#初始化聊天信息
if 'input' not in st.session_state:
st.session_state['input'] = []
#名字记忆单元,初始化为"小甜甜"
if 'nick_name' not in st.session_state:
st.session_state['nick_name'] = "小甜甜"
#性格记忆单元,初始化为"活泼开朗的东北姑娘"
if 'character' not in st.session_state:
st.session_state['character'] = "活泼开朗的东北姑娘"
# -------------------------网页聊天信息的记忆存储---------------------
#设置页面的配置项
st.set_page_config(
page_title="AI智能伴侣",
page_icon="🤖",
#布局
layout="wide",
#侧边栏状态
initial_sidebar_state="expanded",
menu_items={}
)
#大标题
st.title("AI智能伴侣")
#Logo
st.logo("第三章/resouces/logo.jpg")
#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
with st.sidebar:
#------伴侣信息--------
st.subheader("伴侣信息")
#昵称输入框
nick_name = st.text_input("昵称",placeholder="请输入伴侣昵称",value= st.session_state.nick_name)
if nick_name:
st.session_state['nick_name'] = nick_name #名字记忆存储
#性格输入框
character = st.text_area("性格",placeholder="请输入伴侣性格",value= st.session_state.character)
if character:
st.session_state['character'] = character #性格记忆存储
# ------伴侣信息--------
#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
#-------------------------API调用前期准备--------------------------
#设置系统提示词
system_prompt = """
你叫 %s,现在是用户的真实伴侣,请完全代入伴侣角色。
规则:
1.每次只回 1 条消息
2.禁止任何场景或状态描述性文字
3.匹配用户的语言
4.回复简短,像微信聊天一样
5.有需要的话可以用❤🌸等 emoji 表情
6.用符合伴侣性格的方式对话
7.回复的内容,要充分体现伴侣的性格特征
伴侣性格:
‑ %s
你必须严格遵守上述规则来回复用户。
"""
# 创建与 AI 大模型交互的客户端对象(
api_key = "***********************************************"
client = OpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
api_key=api_key,
)
#-------------------------API调用前期准备--------------------------
#展示聊天信息
for input in st.session_state['input']:
st.chat_message(input["role"]).write(input["content"])
#消息输入框
prompt = st.chat_input("请输入您要问的问题")
if prompt:
st.chat_message("user").write(prompt)
print("--------------------->调用AI大模型,提示词:",prompt)
#保存用户输入的提示词
st.session_state['input'].append({"role": "user","content": prompt})
#调用 AI 大模型
response = client.responses.create(
model="doubao-seed-evolving",
input= [
{"role": "system", "content": system_prompt %(st.session_state.nick_name, st.session_state.character)},
#解决大模型会话记忆问题
*st.session_state['input'] #列表解包
],
#要求流式输出
stream= True
)
#-------------------------处理AI大模型的返回结果-----------------(流式输出解析方式)
response_message = st.empty() #创建空容器,用于展示大模型的返回结果
full_response = "" #用于存储大模型的返回结果
for chunk in response:
# 判断事件类型,取delta文本
if chunk.type == "response.output_text.delta":
content = chunk.delta
full_response += content
print(content, end="", flush=True)
response_message.chat_message("assistant").write(full_response)
#保存大模型返回的结果
st.session_state['input'].append({"role": "assistant","content": full_response})
3.2 会话管理
本阶段需要实现会话管理,具体功能有:保存会话,新建会话,展示会话列表,加载历史会话,删除历史会话
3.2.1 保存会话
每一个历史会话文件中需要保存的信息有:
- 交互信息
- 伴侣昵称
- 伴侣性格
- 会话标识(会话名字)
保存会话模块需要完成以下操作:
- 使用访问时间作为会话标识(会话标识函数,会话标识记忆单元)
- 保存当前会话操作(保存当前会话函数)
- 在每次模型返回时及时保存会话信息并重新渲染
- 聊天信息展示会话名称
代码如下:
import streamlit as st
import os
from openai import OpenAI
#--------------------生成会话标识函数----------------------------------
def generate_session_id():
return datetime.now().strftime("%Y-%m-%_%H-%M-%S")
#--------------------生成会话标识函数----------------------------------
#--------------------保存当前会话信息函数-------------------------------
def session_save():
if st.session_state.current_session:
# 构建新的会话对象
session_data = {
"nick_name": st.session_state.nick_name,
"character": st.session_state.character,
"current_session": st.session_state.current_session,
"input": st.session_state.input
}
# 以当前py脚本所在【第三章】文件夹为基准
base_dir = os.path.dirname(os.path.abspath(__file__))
session_dir = os.path.join(base_dir, "sessions")
# 如果 sessions目录不存在,则创建 sessions
if not os.path.exists(session_dir):
os.makedirs(session_dir)
#保存会话数据
filename_safe = st.session_state.current_session
filename = f"{filename_safe}.json"
file_path = os.path.join(session_dir, filename)
with open(file_path, "w", encoding="utf-8") as f:
json.dump(session_data, f, ensure_ascii=False, indent=4)
#--------------------保存当前会话信息函数-------------------------------
#-------------------------网页聊天信息的记忆存储---------------------
#初始化聊天信息
if 'input' not in st.session_state:
st.session_state['input'] = []
#名字记忆单元,初始化为"小甜甜"
if 'nick_name' not in st.session_state:
st.session_state['nick_name'] = "小甜甜"
#性格记忆单元,初始化为"活泼开朗的东北姑娘"
if 'character' not in st.session_state:
st.session_state['character'] = "活泼开朗的东北姑娘"
#会话标识记忆单元
if "current_session" not in st.session_state:
st.session_state.current_session = generate_session_id()
# -------------------------网页聊天信息的记忆存储---------------------
#设置页面的配置项
st.set_page_config(
page_title="AI智能伴侣",
page_icon="🤖",
#布局
layout="wide",
#侧边栏状态
initial_sidebar_state="expanded",
menu_items={}
)
#大标题
st.title("AI智能伴侣")
#Logo
st.logo("第三章/resouces/logo.jpg")
#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
with st.sidebar:
#------伴侣信息--------
st.subheader("伴侣信息")
#昵称输入框
nick_name = st.text_input("昵称",placeholder="请输入伴侣昵称",value= st.session_state.nick_name)
if nick_name:
st.session_state['nick_name'] = nick_name #名字记忆存储
#性格输入框
character = st.text_area("性格",placeholder="请输入伴侣性格",value= st.session_state.character)
if character:
st.session_state['character'] = character #性格记忆存储
# ------伴侣信息--------
#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
#-------------------------API调用前期准备--------------------------
#设置系统提示词
system_prompt = """
你叫 %s,现在是用户的真实伴侣,请完全代入伴侣角色。
规则:
1.每次只回 1 条消息
2.禁止任何场景或状态描述性文字
3.匹配用户的语言
4.回复简短,像微信聊天一样
5.有需要的话可以用❤🌸等 emoji 表情
6.用符合伴侣性格的方式对话
7.回复的内容,要充分体现伴侣的性格特征
伴侣性格:
‑ %s
你必须严格遵守上述规则来回复用户。
"""
# 创建与 AI 大模型交互的客户端对象(
api_key = "***********************************************"
client = OpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
api_key=api_key,
)
#-------------------------API调用前期准备--------------------------
#展示聊天信息
st.text(f"会话名称: {st.session_state.current_session}")
for input in st.session_state['input']:
st.chat_message(input["role"]).write(input["content"])
#消息输入框
prompt = st.chat_input("请输入您要问的问题")
if prompt:
st.chat_message("user").write(prompt)
print("--------------------->调用AI大模型,提示词:",prompt)
#保存用户输入的提示词
st.session_state['input'].append({"role": "user","content": prompt})
#调用 AI 大模型
response = client.responses.create(
model="doubao-seed-evolving",
input= [
{"role": "system", "content": system_prompt %(st.session_state.nick_name, st.session_state.character)},
#解决大模型会话记忆问题
*st.session_state['input'] #列表解包
],
#要求流式输出
stream= True
)
#-------------------------处理AI大模型的返回结果-----------------(流式输出解析方式)
response_message = st.empty() #创建空容器,用于展示大模型的返回结果
full_response = "" #用于存储大模型的返回结果
for chunk in response:
# 判断事件类型,取delta文本
if chunk.type == "response.output_text.delta":
content = chunk.delta
full_response += content
print(content, end="", flush=True)
response_message.chat_message("assistant").write(full_response)
#保存大模型返回的结果
st.session_state['input'].append({"role": "assistant","content": full_response})
#保存会话信息
session_save()
st.rerun()
3.2.2 新建会话
新建会话模块需要实现以下功能:
- 保存当前会话数据
- 创建新会话并保存
要执行如下操作:
- AI控制面板标题
- 新建会话按钮
- 保存旧会话信息,并创建新会话并保存

代码如下所示:
import streamlit as st
import os
from openai import OpenAI
#--------------------生成会话标识函数----------------------------------
def generate_session_id():
return datetime.now().strftime("%Y-%m-%_%H-%M-%S")
#--------------------生成会话标识函数----------------------------------
#--------------------保存当前会话信息函数-------------------------------
def session_save():
if st.session_state.current_session:
# 构建新的会话对象
session_data = {
"nick_name": st.session_state.nick_name,
"character": st.session_state.character,
"current_session": st.session_state.current_session,
"input": st.session_state.input
}
# 以当前py脚本所在【第三章】文件夹为基准
base_dir = os.path.dirname(os.path.abspath(__file__))
session_dir = os.path.join(base_dir, "sessions")
# 如果 sessions目录不存在,则创建 sessions
if not os.path.exists(session_dir):
os.makedirs(session_dir)
#保存会话数据
filename_safe = st.session_state.current_session
filename = f"{filename_safe}.json"
file_path = os.path.join(session_dir, filename)
with open(file_path, "w", encoding="utf-8") as f:
json.dump(session_data, f, ensure_ascii=False, indent=4)
#--------------------保存当前会话信息函数-------------------------------
#-------------------------网页聊天信息的记忆存储---------------------
#初始化聊天信息
if 'input' not in st.session_state:
st.session_state['input'] = []
#名字记忆单元,初始化为"小甜甜"
if 'nick_name' not in st.session_state:
st.session_state['nick_name'] = "小甜甜"
#性格记忆单元,初始化为"活泼开朗的东北姑娘"
if 'character' not in st.session_state:
st.session_state['character'] = "活泼开朗的东北姑娘"
#会话标识记忆单元
if "current_session" not in st.session_state:
st.session_state.current_session = generate_session_id()
# -------------------------网页聊天信息的记忆存储---------------------
#设置页面的配置项
st.set_page_config(
page_title="AI智能伴侣",
page_icon="🤖",
#布局
layout="wide",
#侧边栏状态
initial_sidebar_state="expanded",
menu_items={}
)
#大标题
st.title("AI智能伴侣")
#Logo
st.logo("第三章/resouces/logo.jpg")
#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
with st.sidebar:
#------会话信息--------
st.subheader("AI控制面板")
#新建会话按钮
if st.button("新建会话",icon="🚀",width="stretch"):
#保存当前会话信息
session_save()
#创建新的会话
if st.session_state.input : #如果聊天消息非空,True;否则,False
st.session_state.input = []
st.session_state.current_session = generate_session_id()
st.session_state.nick_name = "小甜甜"
st.session_state.character = "活泼开朗的东北姑娘"
#保存新建会话信息
session_save()
#------会话信息--------
#------伴侣信息--------
st.subheader("伴侣信息")
#昵称输入框
nick_name = st.text_input("昵称",placeholder="请输入伴侣昵称",value= st.session_state.nick_name)
if nick_name:
st.session_state['nick_name'] = nick_name #名字记忆存储
#性格输入框
character = st.text_area("性格",placeholder="请输入伴侣性格",value= st.session_state.character)
if character:
st.session_state['character'] = character #性格记忆存储
# ------伴侣信息--------
#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
#-------------------------API调用前期准备--------------------------
#设置系统提示词
system_prompt = """
你叫 %s,现在是用户的真实伴侣,请完全代入伴侣角色。
规则:
1.每次只回 1 条消息
2.禁止任何场景或状态描述性文字
3.匹配用户的语言
4.回复简短,像微信聊天一样
5.有需要的话可以用❤🌸等 emoji 表情
6.用符合伴侣性格的方式对话
7.回复的内容,要充分体现伴侣的性格特征
伴侣性格:
‑ %s
你必须严格遵守上述规则来回复用户。
"""
# 创建与 AI 大模型交互的客户端对象(
api_key = "***********************************************"
client = OpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
api_key=api_key,
)
#-------------------------API调用前期准备--------------------------
#展示聊天信息
st.text(f"会话名称: {st.session_state.current_session}")
for input in st.session_state['input']:
st.chat_message(input["role"]).write(input["content"])
#消息输入框
prompt = st.chat_input("请输入您要问的问题")
if prompt:
st.chat_message("user").write(prompt)
print("--------------------->调用AI大模型,提示词:",prompt)
#保存用户输入的提示词
st.session_state['input'].append({"role": "user","content": prompt})
#调用 AI 大模型
response = client.responses.create(
model="doubao-seed-evolving",
input= [
{"role": "system", "content": system_prompt %(st.session_state.nick_name, st.session_state.character)},
#解决大模型会话记忆问题
*st.session_state['input'] #列表解包
],
#要求流式输出
stream= True
)
#-------------------------处理AI大模型的返回结果-----------------(流式输出解析方式)
response_message = st.empty() #创建空容器,用于展示大模型的返回结果
full_response = "" #用于存储大模型的返回结果
for chunk in response:
# 判断事件类型,取delta文本
if chunk.type == "response.output_text.delta":
content = chunk.delta
full_response += content
print(content, end="", flush=True)
response_message.chat_message("assistant").write(full_response)
#保存大模型返回的结果
st.session_state['input'].append({"role": "assistant","content": full_response})
#保存会话信息
session_save()
st.rerun()
3.2.2 展示会话列表
本模块要实现的功能是:在侧边栏中展示出所有会话列表
其中要执行的操作有:
- 历史会话副标题
- 历史会话列表
- 加载所有历史会话列表信息功能(加载所有历史会话列表信息函数)
- 会话按钮与删除按钮

代码如下:
import streamlit as st
import os
from openai import OpenAI
#--------------------生成会话标识函数----------------------------------
def generate_session_id():
return datetime.now().strftime("%Y-%m-%_%H-%M-%S")
#--------------------生成会话标识函数----------------------------------
#--------------------保存当前会话信息函数-------------------------------
def session_save():
if st.session_state.current_session:
# 构建新的会话对象
session_data = {
"nick_name": st.session_state.nick_name,
"character": st.session_state.character,
"current_session": st.session_state.current_session,
"input": st.session_state.input
}
# 以当前py脚本所在【第三章】文件夹为基准
base_dir = os.path.dirname(os.path.abspath(__file__))
session_dir = os.path.join(base_dir, "sessions")
# 如果 sessions目录不存在,则创建 sessions
if not os.path.exists(session_dir):
os.makedirs(session_dir)
#保存会话数据
filename_safe = st.session_state.current_session
filename = f"{filename_safe}.json"
file_path = os.path.join(session_dir, filename)
with open(file_path, "w", encoding="utf-8") as f:
json.dump(session_data, f, ensure_ascii=False, indent=4)
#--------------------保存当前会话信息函数-------------------------------
#--------------------加载所有会话列表信息函数----------------------------
def load_sessions():
session_list = []
#获取会话文件所在目录
base_dir = get_base_dir()
session_dir = os.path.join(base_dir, "sessions")
#加载session目录下的文件
if os.path.exists(session_dir):
file_list = os.listdir(session_dir)
for file_name in file_list:
if file_name.endswith(".json"):
session_list.append(file_name[:-5])
session_list.sort(reverse=True) #排序,降序排序
return session_list
#--------------------加载所有会话列表信息函数----------------------------
#-------------------------网页聊天信息的记忆存储---------------------
#初始化聊天信息
if 'input' not in st.session_state:
st.session_state['input'] = []
#名字记忆单元,初始化为"小甜甜"
if 'nick_name' not in st.session_state:
st.session_state['nick_name'] = "小甜甜"
#性格记忆单元,初始化为"活泼开朗的东北姑娘"
if 'character' not in st.session_state:
st.session_state['character'] = "活泼开朗的东北姑娘"
#会话标识记忆单元
if "current_session" not in st.session_state:
st.session_state.current_session = generate_session_id()
# -------------------------网页聊天信息的记忆存储---------------------
#设置页面的配置项
st.set_page_config(
page_title="AI智能伴侣",
page_icon="🤖",
#布局
layout="wide",
#侧边栏状态
initial_sidebar_state="expanded",
menu_items={}
)
#大标题
st.title("AI智能伴侣")
#Logo
st.logo("第三章/resouces/logo.jpg")
#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
with st.sidebar:
#------会话信息--------
st.subheader("AI控制面板")
#新建会话按钮
if st.button("新建会话",icon="🚀",width="stretch"):
#保存当前会话信息
session_save()
#创建新的会话
if st.session_state.input : #如果聊天消息非空,True;否则,False
st.session_state.input = []
st.session_state.current_session = generate_session_id()
st.session_state.nick_name = "小甜甜"
st.session_state.character = "活泼开朗的东北姑娘"
#保存新建会话信息
session_save()
#会话历史
st.text("会话历史")
session_list = load_sessions()
for session in session_list:
col1, col2 = st.columns([4,1])
with col1:
if st.button(session, width="stretch", icon="📘",key=f"load_{session}",type= "primary" if session==current_session_safe else "secondary"):
pass
with col2:
if st.button("", width="stretch", icon="❌",key=f"delete_{session}"):
pass
#------会话信息--------
#------伴侣信息--------
st.subheader("伴侣信息")
#昵称输入框
nick_name = st.text_input("昵称",placeholder="请输入伴侣昵称",value= st.session_state.nick_name)
if nick_name:
st.session_state['nick_name'] = nick_name #名字记忆存储
#性格输入框
character = st.text_area("性格",placeholder="请输入伴侣性格",value= st.session_state.character)
if character:
st.session_state['character'] = character #性格记忆存储
# ------伴侣信息--------
#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
#-------------------------API调用前期准备--------------------------
#设置系统提示词
system_prompt = """
你叫 %s,现在是用户的真实伴侣,请完全代入伴侣角色。
规则:
1.每次只回 1 条消息
2.禁止任何场景或状态描述性文字
3.匹配用户的语言
4.回复简短,像微信聊天一样
5.有需要的话可以用❤🌸等 emoji 表情
6.用符合伴侣性格的方式对话
7.回复的内容,要充分体现伴侣的性格特征
伴侣性格:
‑ %s
你必须严格遵守上述规则来回复用户。
"""
# 创建与 AI 大模型交互的客户端对象(
api_key = "***********************************************"
client = OpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
api_key=api_key,
)
#-------------------------API调用前期准备--------------------------
#展示聊天信息
st.text(f"会话名称: {st.session_state.current_session}")
for input in st.session_state['input']:
st.chat_message(input["role"]).write(input["content"])
#消息输入框
prompt = st.chat_input("请输入您要问的问题")
if prompt:
st.chat_message("user").write(prompt)
print("--------------------->调用AI大模型,提示词:",prompt)
#保存用户输入的提示词
st.session_state['input'].append({"role": "user","content": prompt})
#调用 AI 大模型
response = client.responses.create(
model="doubao-seed-evolving",
input= [
{"role": "system", "content": system_prompt %(st.session_state.nick_name, st.session_state.character)},
#解决大模型会话记忆问题
*st.session_state['input'] #列表解包
],
#要求流式输出
stream= True
)
#-------------------------处理AI大模型的返回结果-----------------(流式输出解析方式)
response_message = st.empty() #创建空容器,用于展示大模型的返回结果
full_response = "" #用于存储大模型的返回结果
for chunk in response:
# 判断事件类型,取delta文本
if chunk.type == "response.output_text.delta":
content = chunk.delta
full_response += content
print(content, end="", flush=True)
response_message.chat_message("assistant").write(full_response)
#保存大模型返回的结果
st.session_state['input'].append({"role": "assistant","content": full_response})
#保存会话信息
session_save()
st.rerun()
3.2.3 加载指定历史会话
本模块完成需要完成功能:当点击指定历史会话时,加载该历史会话信息
执行的操作有:
-
加载指定历史会话功能(加载指定历史会话信息函数)
import streamlit as st
import os
from openai import OpenAI#--------------------生成会话标识函数----------------------------------
def generate_session_id():
return datetime.now().strftime("%Y-%m-%_%H-%M-%S")
#--------------------生成会话标识函数----------------------------------#--------------------保存当前会话信息函数-------------------------------
def session_save():
if st.session_state.current_session:
# 构建新的会话对象
session_data = {
"nick_name": st.session_state.nick_name,
"character": st.session_state.character,
"current_session": st.session_state.current_session,
"input": st.session_state.input
}# 以当前py脚本所在【第三章】文件夹为基准 base_dir = os.path.dirname(os.path.abspath(__file__)) session_dir = os.path.join(base_dir, "sessions") # 如果 sessions目录不存在,则创建 sessions if not os.path.exists(session_dir): os.makedirs(session_dir) #保存会话数据 filename_safe = st.session_state.current_session filename = f"{filename_safe}.json" file_path = os.path.join(session_dir, filename) with open(file_path, "w", encoding="utf-8") as f: json.dump(session_data, f, ensure_ascii=False, indent=4)#--------------------保存当前会话信息函数-------------------------------
#--------------------加载所有会话列表信息函数----------------------------
def load_sessions():
session_list = []
#获取会话文件所在目录
base_dir = get_base_dir()
session_dir = os.path.join(base_dir, "sessions")
#加载session目录下的文件
if os.path.exists(session_dir):
file_list = os.listdir(session_dir)
for file_name in file_list:
if file_name.endswith(".json"):
session_list.append(file_name[:-5])
session_list.sort(reverse=True) #排序,降序排序
return session_list
#--------------------加载所有会话列表信息函数----------------------------#--------------------加载指定会话信息函数----------------------------
def load_session(session_name):
try:
# 以当前py脚本所在【第三章】文件夹为基准
base_dir = get_base_dir()
session_name = os.path.join(base_dir, f"sessions/{session_name}.json")
#加载指定会话信息
if os.path.exists(session_name):
with open(session_name, "r", encoding="utf-8") as f:
session_data = json.load(f)
st.session_state.input = session_data["input"]
st.session_state.current_session = session_data["current_session"]
st.session_state.nick_name = session_data["nick_name"]
st.session_state.character = session_data["character"]
except Exception:
st.error("加载会话失败!")
#--------------------加载指定会话信息函数----------------------------#-------------------------网页聊天信息的记忆存储---------------------
#初始化聊天信息
if 'input' not in st.session_state:
st.session_state['input'] = []
#名字记忆单元,初始化为"小甜甜"
if 'nick_name' not in st.session_state:
st.session_state['nick_name'] = "小甜甜"
#性格记忆单元,初始化为"活泼开朗的东北姑娘"
if 'character' not in st.session_state:
st.session_state['character'] = "活泼开朗的东北姑娘"
#会话标识记忆单元
if "current_session" not in st.session_state:
st.session_state.current_session = generate_session_id()-------------------------网页聊天信息的记忆存储---------------------
#设置页面的配置项
st.set_page_config(
page_title="AI智能伴侣",
page_icon="🤖",
#布局
layout="wide",
#侧边栏状态
initial_sidebar_state="expanded",
menu_items={}
)#大标题
st.title("AI智能伴侣")#Logo
st.logo("第三章/resouces/logo.jpg")#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
with st.sidebar:
#------会话信息--------
st.subheader("AI控制面板")
#新建会话按钮
if st.button("新建会话",icon="🚀",width="stretch"):
#保存当前会话信息
session_save()
#创建新的会话
if st.session_state.input : #如果聊天消息非空,True;否则,False
st.session_state.input = []
st.session_state.current_session = generate_session_id()
st.session_state.nick_name = "小甜甜"
st.session_state.character = "活泼开朗的东北姑娘"
#保存新建会话信息
session_save()
#会话历史
st.text("会话历史")
session_list = load_sessions()
for session in session_list:
col1, col2 = st.columns([4,1])
with col1:
if st.button(session, width="stretch", icon="📘",key=f"load_{session}",type= "primary" if session==current_session_safe else "secondary"):
load_session(session)
st.rerun()with col2: if st.button("", width="stretch", icon="❌",key=f"delete_{session}"): pass #------会话信息-------- #------伴侣信息-------- st.subheader("伴侣信息") #昵称输入框 nick_name = st.text_input("昵称",placeholder="请输入伴侣昵称",value= st.session_state.nick_name) if nick_name: st.session_state['nick_name'] = nick_name #名字记忆存储 #性格输入框 character = st.text_area("性格",placeholder="请输入伴侣性格",value= st.session_state.character) if character: st.session_state['character'] = character #性格记忆存储 # ------伴侣信息--------#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
#-------------------------API调用前期准备--------------------------
#设置系统提示词
system_prompt = """
你叫 %s,现在是用户的真实伴侣,请完全代入伴侣角色。
规则:
1.每次只回 1 条消息
2.禁止任何场景或状态描述性文字
3.匹配用户的语言
4.回复简短,像微信聊天一样
5.有需要的话可以用❤🌸等 emoji 表情
6.用符合伴侣性格的方式对话
7.回复的内容,要充分体现伴侣的性格特征
伴侣性格:
‑ %s
你必须严格遵守上述规则来回复用户。
"""创建与 AI 大模型交互的客户端对象(
api_key = "***********************************************"
client = OpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
api_key=api_key,
)
#-------------------------API调用前期准备--------------------------#展示聊天信息
st.text(f"会话名称: {st.session_state.current_session}")
for input in st.session_state['input']:
st.chat_message(input["role"]).write(input["content"])
#消息输入框
prompt = st.chat_input("请输入您要问的问题")
if prompt:
st.chat_message("user").write(prompt)
print("--------------------->调用AI大模型,提示词:",prompt)
#保存用户输入的提示词
st.session_state['input'].append({"role": "user","content": prompt})
#调用 AI 大模型
response = client.responses.create(
model="doubao-seed-evolving",
input= [
{"role": "system", "content": system_prompt %(st.session_state.nick_name, st.session_state.character)},
#解决大模型会话记忆问题
*st.session_state['input'] #列表解包
],
#要求流式输出
stream= True
)
#-------------------------处理AI大模型的返回结果-----------------(流式输出解析方式)
response_message = st.empty() #创建空容器,用于展示大模型的返回结果
full_response = "" #用于存储大模型的返回结果
for chunk in response:
# 判断事件类型,取delta文本
if chunk.type == "response.output_text.delta":
content = chunk.delta
full_response += content
print(content, end="", flush=True)
response_message.chat_message("assistant").write(full_response)
#保存大模型返回的结果
st.session_state['input'].append({"role": "assistant","content": full_response})
#保存会话信息
session_save()
st.rerun()
3.2.4 删除指定历史会话
本模块完成需要完成功能:当点击指定历史会话的删除按钮时,删除该历史会话信息
执行的操作有:
- 删除指定历史会话功能(删除指定历史会话信息函数)
代码如下:
import streamlit as st
import os
from openai import OpenAI
import json
from datetime import datetime
#--------------------生成会话标识函数----------------------------------
def generate_session_id():
return datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
#--------------------生成会话标识函数----------------------------------
#--------------------保存当前会话信息函数-------------------------------
def session_save():
if st.session_state.current_session:
# 构建新的会话对象
session_data = {
"nick_name": st.session_state.nick_name,
"character": st.session_state.character,
"current_session": st.session_state.current_session,
"input": st.session_state.input
}
# 以当前py脚本所在【第三章】文件夹为基准
base_dir = os.path.dirname(os.path.abspath(__file__))
session_dir = os.path.join(base_dir, "sessions")
# 如果 sessions目录不存在,则创建 sessions
if not os.path.exists(session_dir):
os.makedirs(session_dir)
#保存会话数据
filename_safe = st.session_state.current_session
filename = f"{filename_safe}.json"
file_path = os.path.join(session_dir, filename)
with open(file_path, "w", encoding="utf-8") as f:
json.dump(session_data, f, ensure_ascii=False, indent=4)
#--------------------保存当前会话信息函数-------------------------------
#--------------------加载所有会话列表信息函数----------------------------
def load_sessions():
session_list = []
#获取会话文件所在目录
base_dir = os.path.dirname(os.path.abspath(__file__))
session_dir = os.path.join(base_dir, "sessions")
#加载session目录下的文件
if os.path.exists(session_dir):
file_list = os.listdir(session_dir)
for file_name in file_list:
if file_name.endswith(".json"):
session_list.append(file_name[:-5])
session_list.sort(reverse=True) #排序,降序排序
return session_list
#--------------------加载所有会话列表信息函数----------------------------
#--------------------加载指定会话信息函数----------------------------
def load_session(session_name):
try:
# 以当前py脚本所在【第三章】文件夹为基准
base_dir = os.path.dirname(os.path.abspath(__file__))
session_name = os.path.join(base_dir, f"sessions/{session_name}.json")
#加载指定会话信息
if os.path.exists(session_name):
with open(session_name, "r", encoding="utf-8") as f:
session_data = json.load(f)
st.session_state.input = session_data["input"]
st.session_state.current_session = session_data["current_session"]
st.session_state.nick_name = session_data["nick_name"]
st.session_state.character = session_data["character"]
except Exception:
st.error("加载会话失败!")
#--------------------加载指定会话信息函数----------------------------
#--------------------删除指定会话信息函数----------------------------
def delete_session(session_name):
try:
base_dir = os.path.dirname(os.path.abspath(__file__))
#用单独的变量存文件路径,不要覆盖传入的会话名
file_path = os.path.join(base_dir, f"sessions/{session_name}.json")
if os.path.exists(file_path):
os.remove(file_path) #删除文件
#只有删除的是当前正在展示的会话,才清空聊天信息并开启新会话
if session_name == st.session_state.current_session:
st.session_state.input = []
st.session_state.current_session = generate_session_id()
st.session_state.nick_name = "小甜甜"
st.session_state.character = "活泼开朗的东北姑娘"
except Exception:
st.error("删除会话失败!")
#--------------------删除指定会话信息函数----------------------------
#-------------------------网页聊天信息的记忆存储---------------------
#初始化聊天信息
if 'input' not in st.session_state:
st.session_state['input'] = []
#名字记忆单元,初始化为"小甜甜"
if 'nick_name' not in st.session_state:
st.session_state['nick_name'] = "小甜甜"
#性格记忆单元,初始化为"活泼开朗的东北姑娘"
if 'character' not in st.session_state:
st.session_state['character'] = "活泼开朗的东北姑娘"
#会话标识记忆单元
if "current_session" not in st.session_state:
st.session_state.current_session = generate_session_id()
# -------------------------网页聊天信息的记忆存储---------------------
#设置页面的配置项
st.set_page_config(
page_title="AI智能伴侣",
page_icon="🤖",
#布局
layout="wide",
#侧边栏状态
initial_sidebar_state="expanded",
menu_items={}
)
#大标题
st.title("AI智能伴侣")
#Logo
st.logo("第三章/resouces/logo.jpg")
#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
with st.sidebar:
# ------会话信息--------
st.subheader("AI控制面板")
# 新建会话按钮
if st.button("新建会话", icon="🚀", width="stretch"):
# 保存当前会话信息
session_save()
# 创建新的会话
if st.session_state.input: # 如果聊天消息非空,True;否则,False
st.session_state.input = []
st.session_state.current_session = generate_session_id()
st.session_state.nick_name = "小甜甜"
st.session_state.character = "活泼开朗的东北姑娘"
# 保存新建会话信息
session_save()
#会话历史
st.text("会话历史")
session_list = load_sessions()
for session in session_list:
col1, col2 = st.columns([4, 1])
with col1:
if st.button(session, width="stretch", icon="📘", key=f"load_{session}", type="primary" if session == st.session_state.current_session else "secondary"):
load_session(session)
st.rerun()
with col2:
if st.button("", width="stretch", icon="❌", key=f"delete_{session}"):
delete_session(session)
st.rerun()
# ------会话信息--------
#------伴侣信息--------
st.subheader("伴侣信息")
#昵称输入框
nick_name = st.text_input("昵称",placeholder="请输入伴侣昵称",value= st.session_state.nick_name)
if nick_name:
st.session_state['nick_name'] = nick_name #名字记忆存储
#性格输入框
character = st.text_area("性格",placeholder="请输入伴侣性格",value= st.session_state.character)
if character:
st.session_state['character'] = character #性格记忆存储
# ------伴侣信息--------
#----------------------左侧侧边栏. with: streamlit中上下文管理器---------------------------
#-------------------------API调用前期准备--------------------------
#设置系统提示词
system_prompt = """
你叫 %s,现在是用户的真实伴侣,请完全代入伴侣角色。
规则:
1.每次只回 1 条消息
2.禁止任何场景或状态描述性文字
3.匹配用户的语言
4.回复简短,像微信聊天一样
5.有需要的话可以用❤🌸等 emoji 表情
6.用符合伴侣性格的方式对话
7.回复的内容,要充分体现伴侣的性格特征
伴侣性格:
‑ %s
你必须严格遵守上述规则来回复用户。
"""
# 创建与 AI 大模型交互的客户端对象(
api_key = "***************************"
client = OpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
api_key=api_key
)
#-------------------------API调用前期准备--------------------------
#展示聊天信息
st.text(f"会话名称: {st.session_state.current_session}")
for input in st.session_state['input']:
st.chat_message(input["role"]).write(input["content"])
#消息输入框
prompt = st.chat_input("请输入您要问的问题")
if prompt: #字符串会自动转换为布尔值,如果字符串非空,为True;否则为False
st.chat_message("user").write(prompt)
print("--------------------->调用AI大模型,提示词:",prompt)
#保存用户输入的提示词
st.session_state['input'].append({"role": "user","content": prompt})
#调用 AI 大模型
response = client.responses.create(
model="doubao-seed-evolving",
input= [
{"role": "system", "content": system_prompt %(st.session_state['nick_name'], st.session_state['character'])},
#解决大模型会话记忆问题
*st.session_state['input'] #列表解包
],
#要求流式输出
stream= True
)
#-------------------------处理AI大模型的返回结果-----------------(流式输出解析方式)
response_message = st.empty() #创建空容器,用于展示大模型的返回结果
full_response = "" #用于存储大模型的返回结果
for chunk in response:
# 判断事件类型,取delta文本
if chunk.type == "response.output_text.delta":
content = chunk.delta
full_response += content
print(content, end="", flush=True)
response_message.chat_message("assistant").write(full_response)
#保存大模型返回的结果
st.session_state['input'].append({"role": "assistant","content": full_response})
#保存会话信息
session_save()
st.rerun()