一、引言:当AI走进生活

在2026年的今天,人工智能早已不再是科幻电影中的遥远概念。从ChatGPT到DeepSeek,从Gemini到Qwen,大语言模型正以前所未有的速度改变着我们与计算机交互的方式。然而,对于大多数开发者而言,如何将这些强大的AI能力真正落地到实际应用中,仍然是一道需要跨越的门槛。

本文将通过一个完整的项目实战——AI智能伴侣,带你一步步掌握从大模型调用、会话管理到Web应用构建的全流程。无论你是Python初学者还是有一定经验的开发者,这篇文章都将为你打开AI应用开发的大门。


二、项目概述:什么是AI智能伴侣?

2.1 项目定位

AI智能伴侣是一个基于DeepSeek大模型和Streamlit框架构建的交互式聊天应用。它不仅仅是简单的问答机器人,而是一个能够记住对话历史、拥有个性化性格、支持会话管理的"虚拟伴侣"。

2.2 核心功能

  • 自然对话能力:基于DeepSeek大模型,能够理解并回应用户的各类问题

  • 性格定制:用户可以自由设定伴侣的昵称和性格特征

  • 会话记忆:通过"滚雪球"机制实现多轮对话的上下文理解

  • 会话管理:支持新建、保存、加载和删除历史会话

  • 流式输出:AI回复实时显示,提升交互体验

2.3 技术栈

技术组件 用途
Python 3.8+ 主要编程语言
Streamlit Web界面快速构建
OpenAI SDK DeepSeek API调用
JSON 会话数据持久化
OS/datetime 文件操作与时间管理

三、环境搭建与准备工作

3.1 安装依赖

首先,我们需要安装项目所需的核心库:

bash

# 安装Streamlit
pip install streamlit

# 安装OpenAI SDK(用于调用DeepSeek API)
pip install openai

3.2 获取DeepSeek API Key

要调用DeepSeek大模型,你需要:

  1. 访问DeepSeek官网注册账号

  2. 进入控制台,充值少量余额(最低1元即可)

  3. 创建API Key并妥善保存

bash

# 设置环境变量(推荐在终端中执行)
export DEEPSEEK_API_KEY="你的API密钥"

四、核心技术原理解析

4.1 大模型调用机制

在项目中,我们通过OpenAI SDK来调用DeepSeek的API。核心代码如下:

python

from openai import OpenAI
import os

client = OpenAI(
    api_key=os.environ.get('DEEPSEEK_API_KEY'),
    base_url="https://api.deepseek.com"
)

response = client.chat.completions.create(
    model="deepseek-chat",
    messages=[
        {"role": "system", "content": "你是一个智能助手"},
        {"role": "user", "content": "你好,请介绍一下自己"}
    ],
    stream=True  # 启用流式输出
)

这里的关键在于messages数组的结构:

  • system:设定AI的角色和行为准则

  • user:用户的实际问题

  • assistant:AI的历史回复(用于会话记忆)

4.2 会话记忆的"滚雪球"方案

大模型本质上是无状态的——每次请求都是独立的。为了实现多轮对话的记忆功能,我们采用了"历史消息累积"的策略:

python

# 每次对话时,将完整的消息历史发送给大模型
messages = [
    {"role": "system", "content": system_prompt},
    *st.session_state.messages  # 展开所有历史消息
]

这种方案就像滚雪球一样,每轮对话都会把之前的所有消息重新发送一遍。虽然会消耗更多token,但对于轻量级应用来说是最简单可靠的方案。

4.3 流式输出实现

流式输出能让用户实时看到AI的回复过程,体验更接近真人聊天:

python

response_message = st.empty()  # 创建占位组件
full_response = ""

for chunk in response:
    if chunk.choices[0].delta.content is not None:
        content = chunk.choices[0].delta.content
        full_response += content
        response_message.chat_message("assistant").write(full_response)

五、完整代码实现

5.1 项目结构

text

ai-companion/
├── app.py                 # 主程序文件
├── resources/
│   └── logo.png          # 应用Logo
├── sessions/              # 会话存储目录(自动创建)
│   ├── 2026-07-05_14-30-15.json
│   └── ...
└── requirements.txt       # 依赖清单

5.2 完整代码

以下是app.py的完整实现,我将逐段解释其核心逻辑:

python

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

# ==================== 页面配置 ====================
st.set_page_config(
    page_title="AI智能伴侣",
    page_icon="🤖",
    layout="wide",
    initial_sidebar_state="expanded"
)

# ==================== 工具函数 ====================
def generate_session_name():
    """生成基于时间戳的会话名称"""
    return datetime.now().strftime("%Y-%m-%d_%H-%M-%S")

def save_session():
    """保存当前会话到JSON文件"""
    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
        }
        
        if not os.path.exists("sessions"):
            os.mkdir("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=2)

def load_sessions():
    """加载所有历史会话列表"""
    session_list = []
    if os.path.exists("sessions"):
        for filename in os.listdir("sessions"):
            if filename.endswith(".json"):
                session_list.append(filename[:-5])
    session_list.sort(reverse=True)
    return session_list

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

def delete_session(session_name):
    """删除指定的会话文件"""
    try:
        os.remove(f"sessions/{session_name}.json")
        if session_name == st.session_state.current_session:
            st.session_state.messages = []
            st.session_state.current_session = generate_session_name()
    except Exception:
        st.error("删除会话失败!")

# ==================== 系统提示词模板 ====================
system_prompt = """
    你叫 %s,现在是用户的真实伴侣,请完全代入伴侣角色。
    规则:
        1. 每次只回1条消息
        2. 禁止任何场景或状态描述性文字
        3. 匹配用户的语言
        4. 回复简短,像微信聊天一样
        5. 有需要的话可以用❤️🌸等emoji表情
        6. 用符合伴侣性格的方式对话
        7. 回复的内容要充分体现伴侣的性格特征
    伴侣性格:%s
    你必须严格遵守上述规则来回复用户。
"""

# ==================== 初始化状态 ====================
if "messages" not in st.session_state:
    st.session_state.messages = []
if "nick_name" not in st.session_state:
    st.session_state.nick_name = "小甜甜"
if "nature" not in st.session_state:
    st.session_state.nature = "活泼开朗的东北姑娘"
if "current_session" not in st.session_state:
    st.session_state.current_session = generate_session_name()

# ==================== 界面标题与Logo ====================
st.title("💕 AI智能伴侣")
st.logo("resources/logo.png")

# ==================== 显示聊天历史 ====================
st.text(f"📝 会话: {st.session_state.current_session}")
for message in st.session_state.messages:
    st.chat_message(message["role"]).write(message["content"])

# ==================== 初始化AI客户端 ====================
client = OpenAI(
    api_key=os.environ.get('DEEPSEEK_API_KEY'),
    base_url="https://api.deepseek.com"
)

# ==================== 侧边栏 - 控制面板 ====================
with st.sidebar:
    st.subheader("🎛️ AI控制面板")
    
    # 新建会话按钮
    if st.button("✏️ 新建会话", width="stretch"):
        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])
        with col1:
            if st.button(session, width="stretch", 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", key=f"delete_{session}"):
                delete_session(session)
                st.rerun()
    
    st.divider()
    
    # 伴侣信息定制
    st.subheader("👤 伴侣信息")
    nick_name = st.text_input("昵称", value=st.session_state.nick_name)
    if nick_name:
        st.session_state.nick_name = nick_name
    
    nature = st.text_area("性格", value=st.session_state.nature)
    if nature:
        st.session_state.nature = nature

# ==================== 消息输入与AI响应 ====================
prompt = st.chat_input("💬 输入你的消息...")
if prompt:
    # 显示用户消息
    st.chat_message("user").write(prompt)
    st.session_state.messages.append({"role": "user", "content": prompt})
    
    # 构建完整的消息列表(包含系统提示词和历史)
    messages = [
        {"role": "system", "content": system_prompt % (st.session_state.nick_name, st.session_state.nature)},
        *st.session_state.messages
    ]
    
    # 调用AI并流式输出
    response = client.chat.completions.create(
        model="deepseek-chat",
        messages=messages,
        stream=True
    )
    
    response_placeholder = st.empty()
    full_response = ""
    for chunk in response:
        if chunk.choices[0].delta.content is not None:
            full_response += chunk.choices[0].delta.content
            response_placeholder.chat_message("assistant").write(full_response)
    
    # 保存AI回复到历史
    st.session_state.messages.append({"role": "assistant", "content": full_response})
    
    # 自动保存会话
    save_session()

六、运行与测试

6.1 启动应用

在项目目录下执行:

bash

streamlit run app.py

应用将在浏览器中自动打开,默认地址为 http://localhost:8501

6.2 功能测试流程

  1. 基础对话:在输入框中发送消息,观察AI的实时回复

  2. 性格定制:在侧边栏修改昵称和性格,AI的回复风格会随之变化

  3. 会话管理:创建多个会话,切换加载,验证数据持久化

  4. 流式体验:注意AI回复是逐字显示的,而非一次性弹出


七、知识扩展与进阶思考

7.1 JSON文件操作的最佳实践

在项目中,我们使用JSON格式存储会话数据。Python的json模块提供了简洁的API:

python

# 序列化写入
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

# 反序列化读取
with open("data.json", "r", encoding="utf-8") as f:
    data = json.load(f)

关键点

  • ensure_ascii=False:保证中文正常显示

  • indent=2:格式化输出,便于阅读

  • 使用with语句自动管理文件资源

7.2 Streamlit的核心API

API 用途
st.title() 页面大标题
st.chat_message() 聊天气泡
st.chat_input() 输入框
st.sidebar 侧边栏
st.button() 按钮
st.text_input() 文本输入
st.text_area() 多行文本
st.columns() 列布局
st.rerun() 页面刷新

7.3 优化方向建议

  1. 会话压缩:当对话历史过长时,可以使用摘要技术压缩上下文

  2. 多模型支持:扩展支持Gemini、Qwen等不同大模型

  3. 语音交互:集成语音识别与合成,实现全语音对话

  4. 情感分析:增加情感识别模块,让回复更具共情力

  5. 云端部署:使用Streamlit Cloud或Docker将应用部署到公网


八、总结

通过本文的项目实战,我们完整地走完了AI应用开发的整个流程:

阶段 核心内容
理论准备 理解大模型、HTTP协议、API调用
环境搭建 Python环境、依赖安装、API密钥配置
核心开发 大模型调用、会话记忆、流式输出
界面构建 Streamlit布局、交互组件
数据持久化 JSON文件读写、会话管理
测试优化 功能验证、用户体验提升

收获与启示

开发AI应用并不需要从零训练大模型,我们只需要学会如何"用好"现有的模型服务。通过合理的提示词工程、巧妙的状态管理和友好的界面设计,就能打造出富有价值的产品。

AI智能伴侣这个项目虽然简单,但它所包含的技术框架——前端交互层、业务逻辑层、数据持久层和AI服务层——正是所有AI应用开发的基础范式。掌握了这套方法论,你就具备了开发各类AI应用的能力。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐