012.今天我们来实现一个“自己的 GPT”

该教程旨在带大家从 0 起步,掌握用 Python 开发大模型应用的技能。若当前内容让你感到晦涩,可回溯本合集的前期文章,降低学习难度。

1. 先看演示效果

实现功能:可自定义秘钥;有多轮记忆;可清除历史对话。

2. 具体实现

2.1. 先写工具类 get_chat_response

python 复制代码
# utils.py
import os
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
from langchain_deepseek import ChatDeepSeek

def get_chat_response(prompt, memory, api_key):
    model = ChatDeepSeek(model="deepseek-chat", api_key=api_key, temperature=0)
    chain = ConversationChain(llm=model, memory=memory)
    response = chain.invoke({"input": prompt})
    return response["response"]

2.2. 本地测试代码

python 复制代码
# test.py
from utils import get_chat_response
from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory(return_messages=True)
print(get_chat_response("牛顿提出哪些知名定律?", memory, os.getenv("DEEPSEEK_API_KEY")))
print(get_chat_response("我上一个问题是什么?", memory, os.getenv("DEEPSEEK_API_KEY")))

2.3. 创建 Streamlit 页面框架

python 复制代码
# app.py
import streamlit as st
from langchain.memory import ConversationBufferMemory
from utils import get_chat_response

st.title("克隆GPT")

2.4. 让用户输入密钥

python 复制代码
with st.sidebar:
    deepseek_api_key = st.text_input("请输入DeepSeek API密钥:", type="password")
    st.markdown("[获取DeepSeek API密钥](https://platform.deepseek.com/api_keys)")

2.5. 把 memory & message 放入 session

python 复制代码
if "memory" not in st.session_state:
    st.session_state["memory"] = ConversationBufferMemory(return_messages=True)
if "message" not in st.session_state:
    st.session_state["message"] = [{"role": "ai", "content": "你好,我是你的AI助手,有什么可以帮你的吗?"}]

2.6. 显示历史消息(AI 初始欢迎已在内)

python 复制代码
for message in st.session_state["message"]:
    st.chat_message(message["role"]).write(message["content"])

2.7. 获取用户输入

python 复制代码
prompt = st.chat_input()
if prompt:
    if not deepseek_api_key:
        st.info("请输入你的API key")
        st.stop()
    # 8. 立即展示用户消息
    st.session_state["message"].append({"role": "human", "content": prompt})
    st.chat_message("human").write(prompt)

2.8. 调用 AI 并回显

python 复制代码
    with st.spinner("AI正在思考中,请稍等..."):
        response = get_chat_response(prompt, st.session_state["memory"], deepseek_api_key)
    # 9. 把 AI 回答加入会话
    msg = {"role": "ai", "content": response}
    st.session_state["message"].append(msg)
    st.chat_message("ai").write(response)

2.9. 添加清除会话按钮

python 复制代码
    if st.button("清除历史对话"):
        st.session_state["memory"] = ConversationBufferMemory(return_messages=True)
        st.session_state["message"] = [{"role": "ai", "content": "你好,我是你的AI助手,有什么可以帮你的吗?"}]
        st.success("历史对话已清除")

3. 完整代码

3.1. 文件结构

3.2. 代码

python 复制代码
import os

from langchain.chains.conversation.base import ConversationChain
from langchain.memory import ConversationBufferMemory
from langchain_deepseek import ChatDeepSeek


def get_chat_response(prompt, memory, api_key):
    model = ChatDeepSeek(model="deepseek-chat", api_key=api_key, temperature=0)
    chain = ConversationChain(llm=model, memory=memory)

    response = chain.invoke({"input": prompt})
    print(response)
    return response["response"]

# memory = ConversationBufferMemory(return_messages=True)
# print(get_chat_response("牛顿提出哪些知名定律?", memory, os.getenv("DEEPSEEK_API_KEY")))
# print(get_chat_response("我上一个问题是什么?", memory, os.getenv("DEEPSEEK_API_KEY")))
python 复制代码
import streamlit as st
from langchain.memory import ConversationBufferMemory

from utils import get_chat_response

st.title("克隆GPT")

with st.sidebar:
    deepseek_api_key = st.text_input("请输入DeepSeek API密钥:", type="password")
    st.markdown("[获取DeepSeek API密钥](https://platform.deepseek.com/api_keys)")

    # 添加清除对话按钮
    if st.button("清除历史对话"):
        # 重置记忆对象
        st.session_state["memory"] = ConversationBufferMemory(return_messages=True)
        # 重置消息列表(保留初始欢迎消息)
        st.session_state["message"] = [{"role": "ai", "content": "你好,我是你的AI助手,有什么可以帮你的吗?"}]
        # 显示清除成功提示
        st.success("历史对话已清除")

# 初始化会话状态(如果不存在)
if "memory" not in st.session_state:
    st.session_state["memory"] = ConversationBufferMemory(return_messages=True)
if "message" not in st.session_state:
    st.session_state["message"] = [{"role": "ai", "content": "你好,我是你的AI助手,有什么可以帮你的吗?"}]

# 显示历史消息
for message in st.session_state["message"]:
    st.chat_message(message["role"]).write(message["content"])

# 处理用户输入
prompt = st.chat_input()
if prompt:
    if not deepseek_api_key:
        st.info("请输入你的API key")
        st.stop()

    # 添加用户消息到会话状态并显示
    st.session_state["message"].append({"role": "human", "content": prompt})
    st.chat_message("human").write(prompt)

    # 获取AI响应
    with st.spinner("AI正在思考中,请稍等..."):
        response = get_chat_response(prompt, st.session_state["memory"], deepseek_api_key)

    # 添加AI响应到会话状态并显示
    msg = {"role": "ai", "content": response}
    st.session_state["message"].append(msg)
    st.chat_message("ai").write(response)

4. 运行命令

shell 复制代码
streamlit run main.py
相关推荐
神奇小汤圆2 小时前
告别手写HTTP请求!Spring Feign 调用原理深度拆解:从源码到实战,一篇搞懂
后端
布列瑟农的星空2 小时前
前端都能看懂的Rust入门教程(三)——控制流语句
前端·后端·rust
汤姆yu2 小时前
基于springboot的尿毒症健康管理系统
java·spring boot·后端
暮色妖娆丶3 小时前
Spring 源码分析 单例 Bean 的创建过程
spring boot·后端·spring
野犬寒鸦3 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
Java编程爱好者3 小时前
Seata实现分布式事务:大白话全剖析(核心讲透AT模式)
后端
神奇小汤圆3 小时前
比MySQL快800倍的数据库:ClickHouse的性能秘密
后端
小小张说故事3 小时前
BeautifulSoup:Python网页解析的优雅利器
后端·爬虫·python
怒放吧德德3 小时前
后端 Mock 实战:Spring Boot 3 实现入站 & 出站接口模拟
java·后端·设计
biyezuopinvip4 小时前
基于Spring Boot的企业网盘的设计与实现(任务书)
java·spring boot·后端·vue·ssm·任务书·企业网盘的设计与实现