本文详细介绍了LangChain中的历史消息管理方法,主要讲解了如何使用ChatMessageHistory和RedisChatMessageHistory来管理和存储对话历史,以保持对话的连续性和上下文。内容涵盖了单参数和多参数的消息记录管理,以及如何使用Redis进行消息持久化存储。此外,还介绍了如何裁剪消息以适应LLM和聊天模型的有限存储能力。对于想要学习LangChain并实现对话历史管理的开发者来说,本文提供了实用的代码示例和详细的解释,是小白程序员的入门指南。


在上篇文章我们学习了LangChain教程——工具,这篇我们学习LangChain教程——历史消息管理(ChatMessageHistory)。

历史消息管理

在与LLM对话中,LLM一般是无状态的,不会保留对话记录,因此每次对话之间独立不受干扰。

在LangChain中,主要有两种方式来实现对对话历史消息管理:

  • ChatMessageHistory;
  • Memory类;

ChatMessageHistory

ChatMessageHistory是最基础的历史消息管理方法,可以用于管理和存储对话历史的具体实现,帮助提供保持对话的连续性和上下文。

单参数

首先我们创建chain链,示例代码如下:

from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai import ChatOpenAI

# 加载model
model = ChatOpenAI(openai_api_key="google/gemma-3-12b", openai_api_base='http://127.0.0.1:1234/v1')

# 创建聊天提示词模版
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "你是个很有能力的助手。用20个字或更少的字回答。"),
        MessagesPlaceholder(variable_name='history'),  # 历史消息占位符
        ("human", "{input}")
    ]
)
# 创建chain链
runnable = prompt | model

接下来创建获取消息记录的函数,示例代码如下:

store = {}  # 存储会话历史记录
def get_session_history(session_id: str) -> BaseChatMessageHistory:
if session_id not in store:
        store[session_id] = ChatMessageHistory()  // 获取历史消息
return store[session_id]

这里创建了名为get_session_history,其参数为session_id,返回一个字典消息记录。

接下来通过RunnableWithMessageHistory方法为链添加消息历史记录功能,示例代码如下:

with_message_history = RunnableWithMessageHistory(
    runnable,  # 基础链
    get_session_history,  # 历史记录获取函数
    input_messages_key='input', # 输入消息键
    history_messages_key='history'# 历史消息键
)

这样就完成了内存存储消息,接下来尝试发送信息,看看能不能根据历史记录来回答问题,示例代码如下:

response = with_message_history.invoke( {"input": "什么是langchain"}, config={"configurable": {"session_id": "abc123"}} )
print(response)

response = with_message_history.invoke( {"input": "什么?"}, config={"configurable": {"session_id": "abc123"}} )
print(response)

response = with_message_history.invoke( {"input": "什么?"}, config={"configurable": {"session_id": "def234"}} )
print(response)

运行结果如下:

由于前两个response传递的session_id相同,所以langchain知道第二个response提出的问题是什么。

多参数

可以使用history_factory_config参数添加多个参数对消息记录进行管理,这里我们修改上面的get_session_history,示例代码如下:

from langchain_core.runnables import ConfigurableFieldSpec

def get_session_history(user_id: str,conversation_id:str) -> BaseChatMessageHistory:
if (user_id,conversation_id) not in store:
        store[(user_id,conversation_id)] = ChatMessageHistory()
return store[(user_id,conversation_id)]

接着修改在上面的with_message_history:

with_message_history = RunnableWithMessageHistory(
    runnable,
    get_session_history,
    input_messages_key='input',
    history_messages_key='history',
    history_factory_config=[
        ConfigurableFieldSpec(
            id="user_id",
            annotation=str,
            name="User ID",
            description="用户的唯一标识符",
            default="",
            is_shared=True,
        ),
        ConfigurableFieldSpec(
            id="conversation_id",
            annotation=str,
            name="Conversation ID",
            description="对话的唯一标识符",
            default="",
            is_shared=True,
        )
    ]
)

这样就完成了多个参数管理消息记录,接下来我们发送信息,示例代码如下:

response = with_message_history.invoke(
    {"input": "什么是langchain?"},
    config={"configurable": {"user_id": "abc123","conversation_id":'1'}}
)
print(response)

response = with_message_history.invoke(
    { "input": "什么?"},
    config={"configurable": {"user_id": "abc123","conversation_id":'1'}}
)
print(response)

response = with_message_history.invoke(
    {"input": "什么?"},
    config={"configurable": {"user_id": "abc123","conversation_id":'2'}}
)
print(response)

运行结果如下:

redis消息持久化

为了消息能持久化存储,我们可以使用ChatMessageHistory和RedisChatMessageHistory进行更持久存储。

执行如下代码安装redis:

pip install redis

这里我们下载windows系统redis安装包,

通过网盘分享的文件:Redis-x64-3.2.100.zip
链接: https://pan.baidu.com/s/1VX7DhPgcbyJbNiFf6sX5rw?pwd=bqkl 提取码: bqkl

下载完成后,直接解压打开里面的redis-cli.exe,查看当前数据库所有键,如下图所示:

与内存存储消息类似,这里我们还是只需要修改get_session_history函数即可,示例代码如下:

from langchain_community.chat_message_histories import RedisChatMessageHistory

# 本地Redis服务接口
REDIS_URL='redis://127.0.0.1:6379/0'

# 使用RedisChatMessageHistory返回并保存数据到redis中
def get_session_history(session_id: str) -> RedisChatMessageHistory:
return RedisChatMessageHistory(session_id,url=REDIS_URL)

接下来直接运行即可,如下图所示:

接下来我们在Redis-cli中查看,如下图所示:

这样就把聊天记录存储在Redis数据库里面了。

裁剪消息

LLM和聊天模型是有限的,我们可以只加载和存储最近的n条消息,首先我们在消息历史记录添加几条对话,示例代码如下:

from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI

# 加载model
model = ChatOpenAI(openai_api_key="google/gemma-3-12b", openai_api_base='http://127.0.0.1:1234/v1')

temp_chat_history = ChatMessageHistory()
temp_chat_history.add_user_message("我叫白巧克力,你好")  // 向历史记录中添加用户消息对象
temp_chat_history.add_ai_message("你好")     // 向历史记录中添加AI消息对象
temp_chat_history.add_user_message("我下午准备打篮球")
temp_chat_history.add_ai_message("加油哦")
temp_chat_history.add_user_message("打篮球需要注意什么")
temp_chat_history.add_ai_message("注意别那么帅,要不然会有很多女生注意到您")
temp_chat_history.messages

接下来创建chain链,示例代码如下:

# 创建聊天提示词模版
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "你是个很有能力的助手。用20个字或更少的字回答"),
        MessagesPlaceholder(variable_name='history'),  # 历史消息占位符
        ("human", "{input}")
    ]
)
# 创建链
chain = prompt | model

接着创建trim_messages函数,设置只保留前两条消息记录,示例代码如下:

def trim_messages(chain_input):
    stored_messages=temp_chat_history.messages
if len(stored_messages)<=2:
return False
    temp_chat_history.clear()
for message in stored_messages[-2:]:
        temp_chat_history.add_message(message)
return True

接下来通过RunnableWithMessageHistory方法为链添加消息历史记录功能,示例代码如下:

chain_with_message_history = RunnableWithMessageHistory(
    chain,
    lambda session_id:temp_chat_history,        # 获取消息记录
    input_messages_key='input',    # 输入消息键
    history_messages_key='history'# 历史消息键
)

接下来通过RunnablePassthrough方法直接传递输入消息给函数trim_messages进行修剪,再通过管道符“ | ”将修剪后的消息传递给chain_with_message_history继续处理带历史上下文的对话逻辑,示例代码如下:

chain_with_trimming=(
    RunnablePassthrough.assign(messages_trimmed=trim_messages)
    | chain_with_message_history
)

接下来执行如下代码就可以看到效果了:

response=chain_with_trimming.invoke(
    {"input":"我叫什么名字"},
    {"configurable":{"session_id":"unused"}}
)

print(response.content)
print(temp_chat_history.messages)

运行结果如下:

好了,LangChain教程——历史消息管理(ChatMessageHistory)就学到这里了,下篇学习LangChain教程——历史消息管理(Memory类)

如何学习AI大模型 ?

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。【保证100%免费】🆓

CSDN粉丝独家福利

这份完整版的 AI 大模型学习资料已经上传CSDN,朋友们如果需要可以扫描下方二维码&点击下方CSDN官方认证链接免费领取 【保证100%免费】

读者福利: 👉👉CSDN大礼包:《最新AI大模型学习资源包》免费分享 👈👈

(👆👆👆安全链接,放心点击)

对于0基础小白入门:

如果你是零基础小白,想快速入门大模型是可以考虑的。

一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以根据这些资料规划好学习计划和方向。

👉1.大模型入门学习思维导图👈

要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。

对于从来没有接触过AI大模型的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。(全套教程文末领取哈)
在这里插入图片描述

👉2.AGI大模型配套视频👈

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,每个章节都是当前板块的精华浓缩。
在这里插入图片描述

在这里插入图片描述

👉3.大模型实际应用报告合集👈

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。(全套教程文末领取哈)

在这里插入图片描述

👉4.大模型实战项目&项目源码👈

光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战项目来学习。(全套教程文末领取哈)
在这里插入图片描述

👉5.大模型经典学习电子书👈

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。(全套教程文末领取哈)
在这里插入图片描述

👉6.大模型面试题&答案👈

截至目前大模型已经超过200个,在大模型纵横的时代,不仅大模型技术越来越卷,就连大模型相关的岗位和面试也开始越来越卷了。为了让大家更容易上车大模型算法赛道,我总结了大模型常考的面试题。(全套教程文末领取哈)
在这里插入图片描述

为什么分享这些资料?

只要你是真心想学AI大模型,我这份资料就可以无偿分享给你学习,我国在这方面的相关人才比较紧缺,大模型行业确实也需要更多的有志之士加入进来,我也真心希望帮助大家学好这门技术,如果日后有什么学习上的问题,欢迎找我交流,有技术上面的问题,我是很愿意去帮助大家的!

这些资料真的有用吗?

这份资料由我和鲁为民博士共同整理,鲁为民博士先后获得了北京清华大学学士和美国加州理工学院博士学位,在包括IEEE Transactions等学术期刊和诸多国际会议上发表了超过50篇学术论文、取得了多项美国和中国发明专利,同时还斩获了吴文俊人工智能科学技术奖。目前我正在和鲁博士共同进行人工智能的研究。

资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。

在这里插入图片描述
在这里插入图片描述

CSDN粉丝独家福利

这份完整版的 AI 大模型学习资料已经上传CSDN,朋友们如果需要可以扫描下方二维码&点击下方CSDN官方认证链接免费领取 【保证100%免费】

读者福利: 👉👉CSDN大礼包:《最新AI大模型学习资源包》免费分享 👈👈

(👆👆👆安全链接,放心点击)
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐