前言

你是否想过拥有一个24小时在线、性格可定制的AI伴侣?它可以是温柔贴心的倾听者,也可以是理性毒舌的吐槽对象。本文将带你从零开始,基于Streamlit和DeepSeek大模型,手把手构建一个功能完整的AI智能伴侣应用。项目涵盖会话管理、历史记录持久化、实时流式对话等核心功能,即使是AI初学者也能轻松上手。通过这个实战项目,你不仅能掌握大模型API的调用技巧,还能深入理解如何构建具有良好用户体验的AI应用。让我们开始这段有趣的编程之旅吧!


AI应用-基础

大模型部署

在这里插入图片描述
Ollama是一个在本地运行、管理大语言模型的工具。官网:https://ollama.com/

ollama run deepseek-r1:1.5b

在这里插入图片描述
主流的大模型(如:DeepSeek、Kimi等)官方都提供了开放API,无需部署,就可以直接调用访问

大模型调用

在这里插入图片描述

网络基础知识

网络,也就是我们通常所说的互联网(Internet),就是由无数个计算机网络设备连接起来形成的全球性的网络基础设施。
在这里插入图片描述
IP地址可以理解为就是设备在互联网中的地址(唯一身份证),每一个连入网络的设备都有一个自己的IP地址,用来定位设备在互联网中的位置。
在这里插入图片描述
IP地址可以理解为就是设备在互联网中的地址(唯一身份证),每一个连入网络的设备都有一个自己的IP地址,用来定位设备在互联网中的位置。
IPv4地址:32位二进制
IPv6地址:128位二进制
在这里插入图片描述

注意:127.0.0.1 是一个非常特殊的IP地址,表示的是本机地址(也称为本地回环地址)

IP地址可以理解为就是设备在互联网中的地址(唯一身份证),每一个连入网络的设备都有一个自己的IP地址,用来定位设备在互联网中的位置。
在这里插入图片描述
域名(Domain Name),是由一串用点分隔的英文字母组成的。IP地址不便于记忆,因此设计出了域名,并通过DNS(域名解析服务器)来将域名和IP地址相互映射,便于记忆和访问。
在这里插入图片描述
端口号(Port)是整数,取值范围在0-65535,它是用来标识计算机设备中的运行中的程序。
在这里插入图片描述

注意:HTTP协议默认端口号为 80,HTTPS协议默认端口为 443 。

网络模型
互联网(Internet)连接了数以亿计的设备,网络四通八达就如同时城市的复杂的道路。网络中传输的数据就像是城市道路中的车流,如果不加以管理那必然会出现混乱。在国际ISO组织就统一了程序在网络中通信的模型和标准。包括:
OSI网络模型:全球网络互连标准模型
TCP/IP网络模型:可以认为是OSI的简化版
在这里插入图片描述
HTTP协议
概念:Hyper Text Transfer Protocol,超文本传输协议,规定了客户端和服务器之间数据传输的规则。(只有在请求及响应中都遵循了统一的规则,服务端才能读懂客户端发送来的请求,客户端才能解析服务端响应的结果)
在这里插入图片描述
在这里插入图片描述

请求方式:

  • GET: 请求参数在请求行中,没有请求体。如:/api/courses?name=Python&status=1 。GET请求请求参数大小在浏览器中是有限制的。
  • POST: 请求参数在请求体中,POST请求大小是没有限制的。

在这里插入图片描述

Apifox测试

Apifox是一款API设计、开发、测试的一体化协作平台,是项目开发中进行API接口测试的神器。
在这里插入图片描述
Deepseek开放平台
在这里插入图片描述
Json格式
JSON(JavaScript Object Notation)是前端的一种对象表示方法。表示形式类似于Python中的字典,都是key:value这种形式,不过所有的key都必须使用双引号引起来 ,值可以是任何类型:

  • 对象:用{}表示,{}之间是键值对形式,键是字符串,值可以是任意其它类型
  • 数字:整数和小数都是数字,例如:12、3.14
  • 字符串:用""引起来,例如:“jack”
  • 布尔:有两种值:true或false
  • 列表:用[]表示,[]中是列表的元素,多个元素以,分割。

在这里插入图片描述

会话记忆方案

会话记忆-现状
在这里插入图片描述
与AI大模型的交互本质是无状态的,每一次请求响应都是相互独立的。
(AI大模型本身没有真正的会话记忆能力)
会话记忆-处理方案(会话历史滚雪球)
在这里插入图片描述

代码调用测试

在这里插入图片描述

import os
from openai import OpenAI

client = OpenAI(
    api_key='sk-e3ce9aae630141f5adbfeb45840526ac',
    base_url="https://api.deepseek.com")

response = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=[
        {"role": "system", "content": "You are a helpful assistant"},
        {"role": "user", "content": "你是那个大模型?"},
    ],
    stream=False,
    reasoning_effort="high",
    extra_body={"thinking": {"type": "enabled"}}
)

print(response.choices[0].message.content)

在这里插入图片描述

pip3 install openai

在这里插入图片描述

pip:pip是Python官方提供的Python包的管理工具,提供了对Python包的查找、下载、安装、卸载等功能 。

装第三方的软件包

  • 安装软件包(最新版本):pip install openai
  • 安装软件包(指定版本):pip install openai=2.13.0
  • 卸载软件包:pip uninstall openai
  • 列出已安装的包:pip list
  • 查看包详情:pip show openai

提示词工程

提示词(Prompt):是引导大模型(LLM)进行内容生成的命令(一句话、一个问题等)
在这里插入图片描述
引导AI思考,约束其输出范围,并明确你期望的结果
提示词工程(Prompt Engineering):通过有技巧的编写提示词,使大模型生成出尽可能符合预期的内容,这一持续性的过程就称为提示词工程。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

AI应用-实战 AI智能伴侣

Streamlit

Streamlit是一个开源的Python库,专为数据工程师及机器学习工程师设计,用来快速基于Python代码构建交互式的web网站(无需掌握前端技术)。
官方网站: https://streamlit.io
在这里插入图片描述
安装streamlit:

pip install streamlit

运行streamlit:

streamlit run xxx.py

在这里插入图片描述

安装插件Qoder CN
在这里插入图片描述
登录
在这里插入图片描述

#消息输入框
prompt = st.chat_input("请输入您的问题")

if prompt :
    st.chat_message("user").write(prompt)

在这里插入图片描述

#消息输入框
prompt = st.chat_input("请输入您的问题")

client = OpenAI(api_key='sk-24f18fd14177475082cf67c8807a1d69',base_url='https://api.deepseek.com')

# 系统提示词
system_prompt='你是一个活泼可爱的AI智能助手'

if prompt :
    st.chat_message("user").write(prompt)

    #调用ai大模型
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[
            {'role': 'system', 'content': system_prompt},
            {"role": "user", "content": prompt}
        ],
        stream=False
    )
    st.chat_message("assistant").write(response.choices[0].message.content)

在这里插入图片描述

# 初始化聊天信息
if 'messages' not in st.session_state.keys():
    st.session_state.messages = []

# 展示聊天信息
for message in st.session_state.messages:
    if message['role'] == 'user':
        st.chat_message("user").write(message['content'])
    else:
        st.chat_message("assistant").write(message['content'])

if prompt :
    st.chat_message("user").write(prompt)
    # 保存用户的提示词
    st.session_state.messages.append({"role": "user", "content": prompt})

    #调用ai大模型
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[
            {'role': 'system', 'content': system_prompt},
            {"role": "user", "content": prompt}
        ],
        stream=False
    )
    st.chat_message("assistant").write(response.choices[0].message.content)
    #保存大模型返回的结果
    st.session_state.messages.append({"role": "assistant", "content": response.choices[0].message.content})

叫用户的提示词和ai的回答存储并展示到界面中

在这里插入图片描述

会话记忆

会话历史滚雪球
在这里插入图片描述

if prompt :
    st.chat_message("user").write(prompt)
    # 保存用户的提示词
    st.session_state.messages.append({"role": "user", "content": prompt})

    #调用ai大模型
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[
            {'role': 'system', 'content': system_prompt},
            *st.session_state.messages
        ],
        stream=False
    )
    st.chat_message("assistant").write(response.choices[0].message.content)
    #保存大模型返回的结果
    st.session_state.messages.append({"role": "assistant", "content": response.choices[0].message.content})

st.session_state.messages 存储了之前所有的对话消息
每一次模型调用都会把当前 st.session_state.messages(即到目前为止的全部对话历史)当作「上下文」喂给模型。模型根据这段上下文生成回复,然后我们把新产生的用户消息和助手回复再写回历史,为下一轮对话做准备。这就实现了所谓的「会话记忆」。
在这里插入图片描述

流式输出

if prompt :
    st.chat_message("user").write(prompt)
    # 保存用户的提示词
    st.session_state.messages.append({"role": "user", "content": prompt})

    #调用ai大模型
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[
            {'role': 'system', 'content': system_prompt},
            *st.session_state.messages
        ],
        stream=True
    )
    # 非流式 st.chat_message("assistant").write(response.choices[0].message.content)

    # 流式
    response_message = st.empty() #创建一个空的组件,用于展示大模型返回的结果
    result = ''
    for chunk in response:
        if chunk.choices[0].delta.content is not None:
            content = chunk.choices[0].delta.content
            result += content
            response_message.chat_message("assistant").write(result)


    #保存大模型返回的结果
    st.session_state.messages.append({"role": "assistant", "content": result})

流式输出的核心是把模型返回的增量文本实时累积并刷新到同一个聊天气泡里。
通过 st.empty() 占位符 + 持续 .write() 实现“打字”效果。
每个 chunk 都只携带一小段新文本;判断 content is not None 防止处理结束标记。
最终把完整的 result 再存入会话历史,为后续对话提供完整上下文

侧边栏

# 系统提示词
system_prompt="""你是的 AI名字为%s(或自定)。你的性格核心是:%s。
"""

# 初始化聊天信息
if 'messages' not in st.session_state.keys():
    st.session_state.messages = []

#昵称
if 'nick_name' not in st.session_state.keys():
    st.session_state.nick_name = '洛月观'

# 性格
if 'nature' not in st.session_state.keys():
    st.session_state.nature = '外冷内热、理性至上、从不讨好、偶尔毒舌,但内心藏着不易察觉的温柔与责任感'

# 展示聊天信息
for message in st.session_state.messages:
    st.chat_message(message['role']).write(message['content'])

#左侧侧边栏
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
    # 性格输入框
    nature = st.text_area('性格',placeholder="请输入性格",value=st.session_state.nature)
    if nature:
        st.session_state.nature = nature





if prompt :
    st.chat_message("user").write(prompt)
    # 保存用户的提示词
    st.session_state.messages.append({"role": "user", "content": prompt})

    #调用ai大模型
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[
            {'role': 'system', 'content': system_prompt % (st.session_state.nick_name,st.session_state.nature)},
            *st.session_state.messages
        ],
        stream=True
    )

设置侧边栏,并将ai的昵称和性格设置默认值,存储到session_state中,并可随时修改
在这里插入图片描述

会话管理

JSON是软件开发中最常用的数据交换格式,而为了简化JSON数据的处理,在Python标准库中就提供了处理JSON数据的核心模块 json。
在这里插入图片描述
JSON是软件开发中最常用的数据交换格式,而为了简化JSON数据的处理,在Python标准库中就提供了处理JSON数据的核心模块 json。

# ==================== 序列化(写入JSON) ====================
import json

my_profile = {
    "full_name": "李小明",
    "age": 25,
    "gender": "女",
    "job": "软件工程师",
    "interests": ["coding", "photography", "hiking"]
}

# 将数据写入 JSON 文件(确保 data 目录已存在)
with open("data/user_info.json", "w", encoding="utf-8") as file:
    json.dump(my_profile, file, ensure_ascii=False, indent=4)

# ==================== 反序列化(读取JSON) ====================
import json

with open("data/user_info.json", "r", encoding="utf-8") as file:
    loaded_data = json.load(file)
    print("读取成功,内容如下:")
    print(json.dumps(loaded_data, ensure_ascii=False, indent=4))  # 美观打印

在这里插入图片描述

保存会话信息

# 保存会话信息的函数
def save_session():
    # 保存当前会话信息
    if st.session_state.current_session:
        # 构建新的会话对象
        session_data = {
            "nick_name": st.session_state.nick_name,
            "nature": st.session_state.nature,
            "current_session": st.session_state.current_session,
            "messages": st.session_state.messages
        }
        # 如果session目录不存在就创建

        if not os.path.exists('sessions'):
            os.makedirs('sessions')

        # 保存会话数据
        with open(f"sessions/{st.session_state.current_session}.json", "w", encoding="utf-8") as f:
            json.dump(session_data, f, ensure_ascii=False, indent=4)

将当前 Streamlit 应用中的聊天记录、用户昵称和人格设定保存到本地 sessions/ 文件夹下的一个 JSON 文件中,以便下次启动程序时可以“回忆”起之前的对话
在这里插入图片描述

新建会话

  # 新建会话
    if st.button('新建会话',width='stretch',icon='🦴'):

        # 保存当前会话
        save_session()
        # 创建新的会话
        if st.session_state.messages:
            st.session_state.messages = []
            st.session_state.current_session = generate_session_name()
            save_session()
            st.rerun()

当用户点击“新建会话”按钮时,首先调用 save_session() 保存当前会话(防止未保存的聊天记录丢失)。

然后判断当前是否存在聊天记录(st.session_state.messages 是否非空):

如果存在记录,则清空消息列表(messages = []),生成一个新的会话名称(调用 generate_session_name()),并立即保存这个新空会话(再次调用 save_session()),最后刷新页面(st.rerun())使界面更新为新会话状态。

如果当前没有聊天记录(空会话),则不会执行清空和新建操作(即点击按钮不会产生任何变化)

展示会话列表

# 加载所有的会话列表信息
def load_sessions():
    session_list = []
    # 加载session下的目录列表文件
    if os.path.exists('sessions'):
        for filename in os.listdir('sessions'):
            if filename.endswith('.json'):
                session_list.append(filename)
    return session_list

扫描本地 sessions 文件夹,筛选出所有以 .json 结尾的文件,将其文件名存入列表并返回;若文件夹不存在,则返回空列表

加载会话

import streamlit as st
from openai import OpenAI
from datetime import datetime
import os
import json

# 设置页面配置
st.set_page_config(
    page_title='AI智能伴侣',
    page_icon='🤩',
    # 布局
    layout='wide',
    #侧边栏状态
    initial_sidebar_state='expanded',
    menu_items={}
)

# 保存会话信息的函数
def save_session():
    # 保存当前会话信息
    if st.session_state.current_session:
        # 构建新的会话对象
        session_data = {
            "nick_name": st.session_state.nick_name,
            "nature": st.session_state.nature,
            "current_session": st.session_state.current_session,
            "messages": st.session_state.messages
        }
        # 如果session目录不存在就创建

        if not os.path.exists('sessions'):
            os.makedirs('sessions')

        # 保存会话数据
        with open(f"sessions/{st.session_state.current_session}.json", "w", encoding="utf-8") as f:
            json.dump(session_data, f, ensure_ascii=False, indent=4)

# 生成会话标识的函数
def generate_session_name():
    return datetime.now().strftime("%Y-%m-%d %H-%M-%S")


# 加载所有的会话列表信息
def load_sessions():
    session_list = []
    # 加载session下的目录列表文件
    if os.path.exists('sessions'):
        for filename in os.listdir('sessions'):
            if filename.endswith('.json'):
                session_list.append(filename)
    return session_list

# 加载指定的会话数据
def load_session(session_name):
    try:
        if os.path.exists(f"sessions/{session_name}"):
            with open(f"sessions/{session_name}", "r", encoding="utf-8") as f:
                session_data = json.load(f)
                st.session_state.nick_name = session_data["nick_name"]
                st.session_state.nature = session_data["nature"]
                st.session_state.current_session = session_data["current_session"]
                st.session_state.messages = session_data["messages"]
    except Exception as e:
        st.error(f"加载会话失败:{e}")


#大标题
st.title('AI智能伴侣')

#log
st.logo('../image/log.jpg')

#消息输入框
prompt = st.chat_input("请输入您的问题")

client = OpenAI(api_key='sk-24f18fd14177475082cf67c8807a1d69',base_url='https://api.deepseek.com')

# 系统提示词
system_prompt="""你是的 AI名字为%s(或自定)。你的性格核心是:%s。
"""

# 初始化聊天信息
if 'messages' not in st.session_state.keys():
    st.session_state.messages = []

#昵称
if 'nick_name' not in st.session_state.keys():
    st.session_state.nick_name = '洛月观'

# 性格
if 'nature' not in st.session_state.keys():
    st.session_state.nature = '外冷内热、理性至上、从不讨好、偶尔毒舌,但内心藏着不易察觉的温柔与责任感'

#会话标识
if 'current_session' not in st.session_state.keys():
    st.session_state.current_session = generate_session_name()


# 展示聊天信息
st.text(f"会话名称:{st.session_state.current_session}")
for message in st.session_state.messages:
    st.chat_message(message['role']).write(message['content'])

#左侧侧边栏
with st.sidebar:

    # 会话信息
    st.subheader('AI控制面板')

    # 新建会话
    if st.button('新建会话',width='stretch',icon='🦴'):

        # 保存当前会话
        save_session()
        # 创建新的会话
        if st.session_state.messages:
            st.session_state.messages = []
            st.session_state.current_session = generate_session_name()
            save_session()
            st.rerun()

    # 会话历史
    st.text('会话历史')
    session_list = load_sessions()
    for session in session_list:
        col1,col2 =  st.columns([4,1]) # 4:1比例
        with col1:
            # 加载会话信息
            if st.button(session,width='stretch', icon='🦴',key=f"load_{session}",type= "primary" if session.replace('.json','') == st.session_state.current_session 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
    # 性格输入框
    nature = st.text_area('性格',placeholder="请输入性格",value=st.session_state.nature)
    if nature:
        st.session_state.nature = nature





if prompt :
    st.chat_message("user").write(prompt)
    # 保存用户的提示词
    st.session_state.messages.append({"role": "user", "content": prompt})

    #调用ai大模型
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[
            {'role': 'system', 'content': system_prompt % (st.session_state.nick_name,st.session_state.nature)},
            *st.session_state.messages
        ],
        stream=True
    )
    # 非流式 st.chat_message("assistant").write(response.choices[0].message.content)

    # 流式
    response_message = st.empty() #创建一个空的组件,用于展示大模型返回的结果
    result = ''
    for chunk in response:
        if chunk.choices[0].delta.content is not None:
            content = chunk.choices[0].delta.content
            result += content
            response_message.chat_message("assistant").write(result)


    #保存大模型返回的结果
    st.session_state.messages.append({"role": "assistant", "content": result})

    # 保存会话信息
    save_session()

在这里插入图片描述

删除会话

# 删除会话信息
def delete_session(session_name):
    try:
        if os.path.exists(f"sessions/{session_name}"):
            os.remove(f"sessions/{session_name}")
            # 如果删除的是当前会话,则需要更新消息列表
            if session_name == f"{st.session_state.current_session}.json":
                st.session_state.messages = []
                st.session_state.current_session = generate_session_name()

    except Exception as e:
        st.error(f"删除会话失败:{e}")

删除指定名称的会话文件;若删除的是当前正在使用的会话,则清空消息列表并生成一个新的会话名称。若操作异常,则显示错误提示。

完整代码

import streamlit as st
from openai import OpenAI
from datetime import datetime
import os
import json

# 设置页面配置
st.set_page_config(
    page_title='AI智能伴侣',
    page_icon='🤩',
    # 布局
    layout='wide',
    #侧边栏状态
    initial_sidebar_state='expanded',
    menu_items={}
)

# 保存会话信息的函数
def save_session():
    # 保存当前会话信息
    if st.session_state.current_session:
        # 构建新的会话对象
        session_data = {
            "nick_name": st.session_state.nick_name,
            "nature": st.session_state.nature,
            "current_session": st.session_state.current_session,
            "messages": st.session_state.messages
        }
        # 如果session目录不存在就创建

        if not os.path.exists('sessions'):
            os.makedirs('sessions')

        # 保存会话数据
        with open(f"sessions/{st.session_state.current_session}.json", "w", encoding="utf-8") as f:
            json.dump(session_data, f, ensure_ascii=False, indent=4)

# 生成会话标识的函数
def generate_session_name():
    return datetime.now().strftime("%Y-%m-%d %H-%M-%S")


# 加载所有的会话列表信息
def load_sessions():
    session_list = []
    # 加载session下的目录列表文件
    if os.path.exists('sessions'):
        for filename in os.listdir('sessions'):
            if filename.endswith('.json'):
                session_list.append(filename)
    session_list.sort(reverse=True)
    return session_list


# 加载指定的会话数据
def load_session(session_name):
    try:
        if os.path.exists(f"sessions/{session_name}"):
            with open(f"sessions/{session_name}", "r", encoding="utf-8") as f:
                session_data = json.load(f)
                st.session_state.nick_name = session_data["nick_name"]
                st.session_state.nature = session_data["nature"]
                st.session_state.current_session = session_data["current_session"]
                st.session_state.messages = session_data["messages"]
    except Exception as e:
        st.error(f"加载会话失败:{e}")

# 删除会话信息
def delete_session(session_name):
    try:
        if os.path.exists(f"sessions/{session_name}"):
            os.remove(f"sessions/{session_name}")
            # 如果删除的是当前会话,则需要更新消息列表
            if session_name == f"{st.session_state.current_session}.json":
                st.session_state.messages = []
                st.session_state.current_session = generate_session_name()

    except Exception as e:
        st.error(f"删除会话失败:{e}")


#大标题
st.title('AI智能伴侣')

#log
st.logo('../image/log.jpg')

#消息输入框
prompt = st.chat_input("请输入您的问题")

client = OpenAI(api_key='sk-24f18fd14177475082cf67c8807a1d69',base_url='https://api.deepseek.com')

# 系统提示词
system_prompt="""你是的 AI名字为%s(或自定)。你的性格核心是:%s。
"""

# 初始化聊天信息
if 'messages' not in st.session_state.keys():
    st.session_state.messages = []

#昵称
if 'nick_name' not in st.session_state.keys():
    st.session_state.nick_name = '洛月观'

# 性格
if 'nature' not in st.session_state.keys():
    st.session_state.nature = '外冷内热、理性至上、从不讨好、偶尔毒舌,但内心藏着不易察觉的温柔与责任感'

#会话标识
if 'current_session' not in st.session_state.keys():
    st.session_state.current_session = generate_session_name()


# 展示聊天信息
st.text(f"会话名称:{st.session_state.current_session}")
for message in st.session_state.messages:
    st.chat_message(message['role']).write(message['content'])

#左侧侧边栏
with st.sidebar:

    # 会话信息
    st.subheader('AI控制面板')

    # 新建会话
    if st.button('新建会话',width='stretch',icon='🦴'):

        # 保存当前会话
        save_session()
        # 创建新的会话
        if st.session_state.messages:
            st.session_state.messages = []
            st.session_state.current_session = generate_session_name()
            save_session()
            st.rerun()

    # 会话历史
    st.text('会话历史')
    session_list = load_sessions()
    for session in session_list:
        col1,col2 =  st.columns([4,1]) # 4:1比例
        with col1:
            # 加载会话信息
            if st.button(session,width='stretch', icon='🦴',key=f"load_{session}",type= "primary" if session.replace('.json','') == 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.divider()

    st.subheader('伴侣信息')
    # 昵称输入框
    nick_name = st.text_input('昵称',placeholder="请输入昵称",value=st.session_state.nick_name)
    if nick_name:
        st.session_state.nick_name = nick_name
    # 性格输入框
    nature = st.text_area('性格',placeholder="请输入性格",value=st.session_state.nature)
    if nature:
        st.session_state.nature = nature





if prompt :
    st.chat_message("user").write(prompt)
    # 保存用户的提示词
    st.session_state.messages.append({"role": "user", "content": prompt})

    #调用ai大模型
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=[
            {'role': 'system', 'content': system_prompt % (st.session_state.nick_name,st.session_state.nature)},
            *st.session_state.messages
        ],
        stream=True
    )
    # 非流式 st.chat_message("assistant").write(response.choices[0].message.content)

    # 流式
    response_message = st.empty() #创建一个空的组件,用于展示大模型返回的结果
    result = ''
    for chunk in response:
        if chunk.choices[0].delta.content is not None:
            content = chunk.choices[0].delta.content
            result += content
            response_message.chat_message("assistant").write(result)


    #保存大模型返回的结果
    st.session_state.messages.append({"role": "assistant", "content": result})

    # 保存会话信息
    save_session()

核心功能流程:

初始化:页面加载时检查session_state中的消息列表、昵称、性格和会话标识,若不存在则设置默认值

消息发送:用户在输入框发送消息后,将用户消息存入session_state.messages,调用DeepSeek API(流式响应)获取AI回复,实时显示并保存到消息列表

会话管理:

每次发送消息后自动保存当前会话到本地sessions目录(JSON格式)

侧边栏显示所有历史会话列表,支持加载和删除

"新建会话"按钮清空当前消息并生成新会话标识

数据持久化:所有会话以JSON文件存储,包含昵称、性格、会话标识和完整消息历史

UI交互:左侧侧边栏提供控制面板(新建会话、会话历史列表、伴侣信息编辑),主区域显示对话内容

状态同步:修改昵称或性格时实时更新session_state,并在下次调用API时生效

在这里插入图片描述


总结

通过本文的实战演练,我们成功搭建了一个完整的AI智能伴侣应用,实现了以下关键功能:

  • 基于DeepSeek大模型的智能对话系统,支持流式响应
  • 灵活的伴侣性格与昵称自定义机制
  • 完整的会话管理:新建、保存、加载和删除历史会话
  • 本地JSON持久化存储,确保对话记录不丢失

这个项目框架具有良好的扩展性,你可以在此基础上增加更多功能,如情绪识别、多模态交互、记忆增强等。核心技术栈Streamlit + OpenAI SDK的组合轻量高效,适合快速原型开发。希望这个实战案例能激发你的创作灵感,打造出更富有个性的AI应用。AI时代,动手实践才是最好的学习方式!

更多推荐