如何实现一个多轮对话聊天,且将聊天记录存放到本地数据库中。

1.来源

点击memory即可观察到。

from langchain.memory.chat_memory import BaseChatMemory
from langchain.memory import ConversationBufferMemory
from langchain.callbacks.base import BaseCallbackHandler


1.1.首先对ConversationBufferMemory的使用进行介绍

该方法主要用于在多轮对话的时候被使用到。作为参数传入到ConversationChain当中。

from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory

# 1️⃣ 定义 Prompt 模板(带历史记录变量)
prompt = PromptTemplate(
    input_variables=["history", "input"],
    template="""
你是一个智能助手,以下是你和用户的对话历史:
{history}
用户: {input}
助手:"""
)
llm = ChatOpenAI()#在这里情实现自己的大模型。
# 2️⃣ 定义记忆(会自动记录历史对话)
memory = ConversationBufferMemory(memory_key="history", return_messages=False)

# 3️⃣ 实例化 LLM(可以换成 Qwen、ChatGLM 等)
# llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.7)

# 4️⃣ 创建对话链条
conversation = ConversationChain(
    llm=llm,
    prompt=prompt,
    memory=memory,
    verbose=True
)

# 5️⃣ 启动对话
print(conversation.predict(input="你好"))
print(conversation.predict(input="你还记得我刚刚说了什么吗?"))

1.2.数据库代码

这里是简单的数据库存放。所以只做了少个字段的描述信息。其中下面的代码是数据库的操作信息。

#!/usr/bin/env python
# coding=utf-8

"""
@author: zgw
@date: 2025/4/4 14:09
@source from: 
"""
# -- 创建 messages 表
# CREATE TABLE IF NOT EXISTS messages (
#     id TEXT PRIMARY KEY,
#     conversation_id TEXT NOT NULL,
#     query TEXT NOT NULL,
#     response TEXT,
#     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
# );
import sqlite3
from typing import List, Dict, Optional

DB_PATH = "chat_memory.db"  # SQLite 文件路径


def init_db():
    with sqlite3.connect(DB_PATH) as conn:
        cursor = conn.cursor()
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS messages (
                id TEXT PRIMARY KEY,
                conversation_id TEXT NOT NULL,
                query TEXT NOT NULL,
                response TEXT,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        conn.commit()


def insert_message(message_id: str, conversation_id: str, query: str, response: Optional[str] = None):
    with sqlite3.connect(DB_PATH) as conn:
        cursor = conn.cursor()
        cursor.execute('''
            INSERT INTO messages (id, conversation_id, query, response) 
            VALUES (?, ?, ?, ?)
        ''', (message_id, conversation_id, query, response))
        conn.commit()


def update_message(message_id: str, response: str):
    with sqlite3.connect(DB_PATH) as conn:
        cursor = conn.cursor()
        cursor.execute('''
            UPDATE messages SET response = ? WHERE id = ?
        ''', (response, message_id))
        conn.commit()


def filter_message(conversation_id: str, limit: int = 10) -> List[Dict]:
    with sqlite3.connect(DB_PATH) as conn:
        cursor = conn.cursor()
        cursor.execute('''
            SELECT query, response FROM messages 
            WHERE conversation_id = ? 
            ORDER BY created_at DESC 
            LIMIT ?
        ''', (conversation_id, limit))
        rows = cursor.fetchall()

    return [{"query": row[0], "response": row[1]} for row in rows]

#init_db()

1.3.实现chain调用callback、llm、memory的代码。

#!/usr/bin/env python
# coding=utf-8

"""

"""
from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory
from langchain.callbacks.base import BaseCallbackHandler
from langchain.schema import LLMResult
from sql import update_message
import uuid

# 自定义 CallbackHandler
class ConversationCallbackHandler(BaseCallbackHandler):
    def __init__(self, conversation_id: str, message_id: str, chat_type: str, query: str):
        self.conversation_id = conversation_id
        self.message_id = message_id
        self.chat_type = chat_type
        self.query = query

    def on_llm_end(self, response: LLMResult, **kwargs):
        answer = response.generations[0][0].text
        update_message(self.message_id, answer)  # 落库更新回答

# Prompt 模板
prompt = PromptTemplate(
    input_variables=["history", "input"],
    template="""
你是一个智能助手,以下是你和用户的对话历史:
{history}
用户: {input}
助手:"""
)

# Memory
memory = ConversationBufferMemory(memory_key="history", return_messages=False)

# 模型(qwen 可替换)
def get_llm(callbacks):
    return ChatOpenAI()

# 对话 ID 固定,消息 ID 每轮更新
conversation_id = "conv-123"

# 构建链
def build_chain(callbacks):
    return LLMChain(
        llm=get_llm(callbacks),
        prompt=prompt,
        memory=memory,
        verbose=True
    )

# 多轮对话
for user_input in ["介绍一下langchain", "介绍一下朱元璋", "你记得我说过什么吗?"]:
    message_id = str(uuid.uuid4())
    handler = ConversationCallbackHandler(
        conversation_id=conversation_id,
        message_id=message_id,
        chat_type="chat",
        query=user_input
    )
    chain = build_chain(callbacks=[handler])
    res = chain.invoke({"input": user_input})
    print("🤖", res["text"])

    # ✅ 每轮处理:
    # •    自动记录上下文对话
    # •    回答自动写入数据库
    # •    可自由扩展
    # message_id / conversation_id
    # 生成策略

# 数据库将会记录这些信息。
# > Entering new LLMChain chain...
# Prompt after formatting:
#
# 你是一个智能助手,以下是你和用户的对话历史:
# Human: 你好
# AI: 你好!今天过得怎么样?如果有什么问题或需要帮助的地方,请随时告诉我!
# Human: 你是谁
# AI: 我是通义千问,阿里巴巴集团旗下的超大规模语言模型。我能够回答问题、创作文字,比如写故事、写公文、写邮件、写剧本、逻辑推理、编程等等,还能表达观点,玩游戏等。如果你有任何问题或需要帮助,欢迎随时向我提问!
# 用户: 你记得我说过什么吗?
# 助手:
#
# > Finished chain.
# 🤖 我能够记住在本次会话中你所说过的内容,并基于此进行上下文连贯的对话。但在会话结束之后,我不会保存或记忆任何个人用户的对话内容,以确保用户的数据隐私和安全。所以,在当前会话中的交流内容我是可以记得的,但如果你之前与我有过其他会话,那些内容我就不记得了哦。如果你有任何关于数据隐私的问题或担忧,请随时告诉我!

1.4.简单的对callback进行描述

✅ 什么是回调函数?

回调函数就是你传给别人执行的函数,等某个事件发生时,系统会反过来调用它。

你可以理解为:
📦 “提前交给别人一段函数”,等到特定时机再执行。

🧠 类比举例(生活版):

你订了快递(大模型推理),
你留了个手机号(回调函数)📱

等快递送到(模型推理结束),
快递员就会打你电话通知你(触发回调)

🧪 编程中的例子:
🔹 普通函数:

def say_hello():
    print("Hello!")
say_hello()

🔹 回调函数的用法:

def run_something(callback):
    print("开始处理...")
    callback()  # ✅ 回调执行

def after_finish():
    print("我在任务结束后被调用了!")

run_something(after_finish)

🧠 在大模型中的用法(比如 LangChain):
比如你用 LLMChain 生成回答时,可以传入一个回调:

class MyCallback(BaseCallbackHandler):
    def on_llm_end(self, response, **kwargs):
        print("回答结束了,内容是:", response.generations[0][0].text)

llm = ChatOpenAI(callbacks=[MyCallback()])

当模型生成完内容时,系统会自动调用 on_llm_end(),你可以在里面做很多事情,比如:
• ✅ 把回答写入数据库
• ✅ 打日志、埋点
• ✅ 触发下一个流程(比如发送通知)

📌 总结一句话:

回调函数 = “事件发生后要执行的代码”,你提前写好,等系统时机一到自动调用。

2.补充类方法的说明

在LangChain中,这些名称主要涉及到两大类功能:聊天消息历史记录(Chat Message History)和记忆(Memory)。它们分别用于记录和管理聊天消息历史以及存储和处理对话中的记忆。以下是每个组件的详细介绍:

聊天消息历史记录(Chat Message History)

1.	AstraDBChatMessageHistory:
•	功能:存储聊天消息到AstraDB中。
•	用途:用于在AstraDB数据库中持久化聊天记录。
2.	CassandraChatMessageHistory:
•	功能:存储聊天消息到Cassandra数据库中。
•	用途:用于在Cassandra数据库中持久化聊天记录。
3.	ChatMessageHistory:
•	功能:通用的聊天消息历史记录接口。
•	用途:用于管理和存储聊天消息的历史记录。
4.	CosmosDBChatMessageHistory:
•	功能:存储聊天消息到Azure Cosmos DB中。
•	用途:用于在Cosmos DB中持久化聊天记录。
5.	DynamoDBChatMessageHistory:
•	功能:存储聊天消息到Amazon DynamoDB中。
•	用途:用于在DynamoDB中持久化聊天记录。
6.	ElasticsearchChatMessageHistory:
•	功能:存储聊天消息到Elasticsearch中。
•	用途:用于在Elasticsearch中持久化聊天记录,便于搜索和分析。
7.	FileChatMessageHistory:
•	功能:将聊天消息记录到文件中。
•	用途:用于将聊天记录持久化到本地文件系统。
8.	MomentoChatMessageHistory:
•	功能:集成Momento缓存服务进行聊天消息存储。
•	用途:用于在Momento缓存中存储聊天记录,提升访问速度。
9.	MongoDBChatMessageHistory:
•	功能:存储聊天消息到MongoDB中。
•	用途:用于在MongoDB数据库中持久化聊天记录。
10.	PostgresChatMessageHistory:
•	功能:存储聊天消息到PostgreSQL数据库中。
•	用途:用于在PostgreSQL数据库中持久化聊天记录。
11.	RedisChatMessageHistory:
•	功能:存储聊天消息到Redis数据库中。
•	用途:用于在Redis缓存中存储聊天记录,提升访问速度。
12.	SingleStoreDBChatMessageHistory:
•	功能:存储聊天消息到SingleStore数据库中。
•	用途:用于在SingleStore数据库中持久化聊天记录。
13.	SQLChatMessageHistory:
•	功能:通用的SQL数据库聊天消息历史记录接口。
•	用途:用于将聊天记录存储在任意SQL数据库中。
14.	StreamlitChatMessageHistory:
•	功能:在Streamlit应用中显示聊天消息历史记录。
•	用途:用于在Streamlit应用中展示和管理聊天记录。
15.	XataChatMessageHistory:
•	功能:存储聊天消息到Xata中。
•	用途:用于在Xata数据库中持久化聊天记录。
16.	ZepChatMessageHistory:
•	功能:存储聊天消息到Zep中。
•	用途:用于在Zep中持久化聊天记录。

记忆(Memory)

1.	CombinedMemory:
•	功能:组合多个记忆模块以实现复杂的记忆管理。
•	用途:用于同时管理和访问多个记忆源。
2.	ConversationBufferMemory:
•	功能:在缓冲区中存储对话历史。
•	用途:用于短期对话记忆,便于上下文管理。
3.	ConversationBufferWindowMemory:
•	功能:在滑动窗口中存储对话历史。
•	用途:用于在滑动窗口内管理对话上下文,适用于长期对话。
4.	ConversationEntityMemory:
•	功能:存储和管理对话中的实体信息。
•	用途:用于跟踪和管理对话中的实体(如人名、地点等)。
5.	ConversationKGMemory:
•	功能:使用知识图谱存储对话记忆。
•	用途:用于将对话内容存储在知识图谱中,便于复杂关系的管理。
6.	ConversationStringBufferMemory:
•	功能:使用字符串缓冲区存储对话历史。
•	用途:简单地将对话内容存储为字符串。
7.	ConversationSummaryBufferMemory:
•	功能:在缓冲区中存储对话摘要。
•	用途:用于对长对话进行摘要,保持上下文的一致性。
8.	ConversationSummaryMemory:
•	功能:存储对话的摘要。
•	用途:用于总结长对话内容,便于后续参考。
9.	ConversationTokenBufferMemory:
•	功能:使用令牌缓冲区存储对话历史。
•	用途:用于基于令牌数量管理对话记忆,适用于语言模型的上下文管理。
10.	InMemoryEntityStore:
•	功能:在内存中存储实体信息。
•	用途:用于快速访问和管理对话中的实体数据。
11.	MotorheadMemory:
•	功能:高效的内存管理模块。
•	用途:用于优化内存使用,提升系统性能。
12.	ReadOnlySharedMemory:
•	功能:只读的共享记忆模块。
•	用途:用于共享和访问全局只读记忆数据。
13.	RedisEntityStore:
•	功能:在Redis中存储实体信息。
•	用途:用于高效存储和访问对话中的实体数据。
14.	SQLiteEntityStore:
•	功能:在SQLite数据库中存储实体信息。
•	用途:用于持久化存储和管理对话中的实体数据。
15.	SimpleMemory:
•	功能:简单的内存存储模块。
•	用途:用于基本的记忆管理需求。
16.	VectorStoreRetrieverMemory:
•	功能:使用向量存储进行记忆检索。
•	用途:用于基于向量的相似度搜索,以实现记忆的高效检索。
17.	ZepMemory:
•	功能:存储对话记忆到Zep中。
•	用途:用于在Zep中持久化对话记忆。
18.	UpstashRedisEntityStore:
•	功能:在Upstash Redis中存储实体信息。
•	用途:用于高效存储和访问对话中的实体数据。
19.	UpstashRedisChatMessageHistory:
•	功能:在Upstash Redis中存储聊天消息。
•	用途:用于在Upstash Redis中持久化聊天记录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值