LangChain大模型应用开发:消息管理与聊天历史存储

介绍

大家好,博主又来给大家分享知识了。今天要给大家分享的是LangChain中的消息管理与聊天历史存储。
LangChain里,消息管理可精细区分用户、助手、系统等不同角色消息,有序调度处理,让交互更顺畅。而聊天历史存储则赋予模型 “记忆”,多轮对话时能参考过往记录,理解意图更精准,回复更连贯。二者相辅相成,为构建智能对话应用筑牢基础。希望大家能通过我本次的分享,对它们有更清晰的认知。

消息存储在内存

LangChain的应用场景中,消息存储是保障多轮对话连贯性的关键环节。它主要负责留存聊天过程中的历史信息,使得模型在后续交互时能够参考过往对话,更精准地理解用户意图并生成回复。

内存存储是消息存储的方式之一。将消息存储在内存里,数据访问速度快,能即时响应对话需求,适用于一些对实时性要求高、会话规模相对较小的场景。不过,它也存在局限性,如内存容量有限,可能因数据量过大导致性能问题。

下面我们展示一个简单的示例,其中聊天历史保存在内存中,此处通过全局Python字典实现。

我们构建一个名为get_session_history的可调用对象,引用此字典以返回ChatMessageHistory实例。通过在运行时向RunnableWithMessageHistory传递配置,可以指定可调用对象的参数。默认情况下,期望配置参数是一个字符串session_id 。可以通过history_factory_config关键字参数进行调整。

开启新会话

此次调用开启了一个新的会话。用户询问了 "行列式是什么意思?",由于是新会话,消息历史为空,模型会基于系统提示和当前问题进行回复。

完整代码

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

# 用于存储不同会话的聊天消息历史
store = {}

# 初始化OpenAI的聊天模型,使用gpt-3.5-turbo
chat_model = ChatOpenAI(model_name="gpt-3.5-turbo")

# 创建聊天提示模板,包含系统指令、消息历史占位和用户输入
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一名得力助手并且非常擅长{ability}"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{input}"),
])

# 将提示模板和聊天模型组合成一个可执行链
chain = prompt | chat_model


# 定义函数,根据会话ID获取对应的聊天消息历史,若不存在则创建
def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]


# 创建带消息历史管理功能的可运行对象
with_message_history = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="input",
    history_messages_key="history",
)

# 调用带消息历史管理的对象,传入用户问题和会话配置并获取结果
result = with_message_history.invoke(
    {"ability": "数学", "input": "行列式是什么意思?"},
    config={"configurable": {"session_id": "qaz123"}},
)

# 打印聊天模型针对用户问题给出的回复结果
print(result)

运行结果

content='在线性代数中,行列式是一个针对一个方阵的函数,它将一个方阵映射到一个标量。行列式可以通过方阵的元素来定义,用来描述方阵的性质和特征。行列式的值可以提供有关于方阵是否可逆、方阵的秩以及方阵的特征值等信息。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 105, 'prompt_tokens': 40, 'total_tokens': 145, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': 'fp_0165350fbb', 'finish_reason': 'stop', 'logprobs': None} id='run-e5230a21-a183-4df5-9a1f-2aedeef4fba0-0' usage_metadata={'input_tokens': 40, 'output_tokens': 105, 'total_tokens': 145, 'input_token_details': {}, 'output_token_details': {}}

进程已结束,退出代码为 0

在同一会话中进行追问

再次使用相同的会话ID,用户询问 "什么?"。此时模型会结合之前的消息历史,也就是第一次询问的 "行列式是什么意思?" 以及对应的回复,来理解用户的追问意图并给出基于上下文的回答。

完整代码

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

# 用于存储不同会话的聊天消息历史
store = {}

# 初始化OpenAI的聊天模型,使用gpt-3.5-turbo
chat_model = ChatOpenAI(model_name="gpt-3.5-turbo")

# 创建聊天提示模板,包含系统指令、消息历史占位和用户输入
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一名得力助手并且非常擅长{ability}"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{input}"),
])

# 将提示模板和聊天模型组合成一个可执行链
chain = prompt | chat_model


# 定义函数,根据会话ID获取对应的聊天消息历史,若不存在则创建
def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]


# 创建带消息历史管理功能的可运行对象
with_message_history = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="input",
    history_messages_key="history",
)

# 调用带消息历史管理的对象,传入用户问题和会话配置并获取结果
result = with_message_history.invoke(
    {"ability": "math", "input": "行列式是什么意思?"},
    config={"configurable": {"session_id": "qaz123"}},
)

# 打印聊天模型针对用户问题给出的回复结果
print(result)

# 记住
result = with_message_history.invoke(
    {"ability": "数学", "input": "什么?"},
    config={"configurable": {"session_id": "qaz123"}},
)

print(result)

 运行结果

content='在线性代数中,行列式是一个针对一个方阵的函数,它将一个方阵映射到一个标量。行列式可以通过方阵的元素来定义,用来描述方阵的性质和特征。行列式的值可以提供有关于方阵是否可逆、方阵的秩以及方阵的特征值等信息。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 105, 'prompt_tokens': 40, 'total_tokens': 145, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': 'fp_0165350fbb', 'finish_reason': 'stop', 'logprobs': None} id='run-e5230a21-a183-4df5-9a1f-2aedeef4fba0-0' usage_metadata={'input_tokens': 40, 'output_tokens': 105, 'total_tokens': 145, 'input_token_details': {}, 'output_token_details': {}}
content='抱歉,我的回答可能有点复杂了。简单来说,行列式就是一个针对方阵的数学工具,用来描述和分析方阵的性质和特征。行列式的值可以提供有关方阵性质的重要信息。' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 79, 'prompt_tokens': 156, 'total_tokens': 235, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-3.5-turbo-0125', 'system_fingerprint': 'fp_0165350fbb', 'finish_reason': 'stop', 'logprobs': None} id='run-2dbeed9e-9ab6-4910-a220-c9aadf83bfba-0' usage_metadata={'input_tokens': 156, 'output_tokens': 79, 'total_tokens': 235, 'input_token_details': {}, 'output_token_details': {}}

进程已结束,退出代码为 0

再次开启新会话

使用新的会话ID,用户再次询问 "什么?"。由于是新会话,消息历史为空,模型无法获取之前关于行列式的对话信息,会将此次询问当作全新的问题进行处理,回复可能与之前不同。

完整代码

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

# 用于存储不同会话的聊天消息历史
store = {}

# 初始化OpenAI的聊天模型,使用gpt-3.5-turbo
chat_model = ChatOpenAI(model_name="gpt-3.5-turbo")

# 创建聊天提示模板,包含系统指令、消息历史占位和用户输入
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一名得力助手并且非常擅长{ability}"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{input}"),
])

# 将提示模板和聊天模型组合成一个可执行链
chain = prompt | chat_model


# 定义函数,根据会话ID获取对应的聊天消息历史,若不存在则创建
def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        st
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老赵爱学习

您的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值