【带你 langchain 双排系列教程】5. LangChain 消息管理与聊天历史存储:构建智能对话系统的核心要素

在构建智能对话系统时,消息管理和聊天历史存储是关键环节,它们直接影响到对话的连贯性、用户体验以及系统的性能。LangChain 提供了强大的工具和接口,用于高效地管理消息和存储聊天历史。本文将详细介绍 LangChain 中的消息存储在内存、消息持久化到 Redis、修改聊天历史、裁剪消息以及总结记忆的方法和实践。

一、消息存储在内存

1. 使用 ChatMessageHistory

LangChain 提供了 ChatMessageHistory 类,用于在内存中存储聊天消息历史。这种方式适用于短期的、不需要持久化的聊天会话。

Python复制

from langchain_core.chat_history import ChatMessageHistory

# 创建一个聊天消息历史实例
chat_history = ChatMessageHistory()

# 添加消息
chat_history.add_user_message("你好,我有一个问题。")
chat_history.add_ai_message("你好,很高兴为你解答。")

# 获取聊天历史
messages = chat_history.messages
print(messages)

2. 使用 RunnableWithMessageHistory

RunnableWithMessageHistory 类允许将消息历史与 LangChain 的运行单元(Runnable)结合,实现更灵活的消息管理。

Python复制

from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_openai.chat_models import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# 定义一个聊天模型
model = ChatOpenAI()

# 定义一个提示模板
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个友好的助手。"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{input}")
])

# 创建一个可调用的运行单元
runnable = prompt | model

# 定义一个会话历史工厂函数
def get_session_history(session_id: str) -> ChatMessageHistory:
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]

# 创建一个带有消息历史的运行单元
with_message_history = RunnableWithMessageHistory(
    runnable,
    get_session_history,
    input_messages_key="input",
    history_messages_key="history"
)

# 调用运行单元
response = with_message_history.invoke(
    {"input": "你好,我有一个问题。"},
    config={"configurable": {"session_id": "123"}}
)
print(response)

二、消息持久化到 Redis

1. 使用 RedisChatMessageHistory

LangChain 支持将聊天消息历史存储到 Redis,以实现持久化和跨会话的存储。

Python复制

from langchain_community.chat_message_histories import RedisChatMessageHistory

# 创建一个 Redis 聊天消息历史实例
redis_chat_history = RedisChatMessageHistory(session_id="123", url="redis://localhost:6379")

# 添加消息
redis_chat_history.add_user_message("你好,我有一个问题。")
redis_chat_history.add_ai_message("你好,很高兴为你解答。")

# 获取聊天历史
messages = redis_chat_history.messages
print(messages)

2. 使用 RunnableWithMessageHistory

RunnableWithMessageHistory 类也可以与 RedisChatMessageHistory 结合使用,实现更灵活的消息管理。

Python复制

from langchain_core.runnables.history import RunnableWithMessageHistory

# 定义一个会话历史工厂函数
def get_redis_session_history(session_id: str) -> RedisChatMessageHistory:
    return RedisChatMessageHistory(session_id=session_id, url="redis://localhost:6379")

# 创建一个带有消息历史的运行单元
with_redis_message_history = RunnableWithMessageHistory(
    runnable,
    get_redis_session_history,
    input_messages_key="input",
    history_messages_key="history"
)

# 调用运行单元
response = with_redis_message_history.invoke(
    {"input": "你好,我有一个问题。"},
    config={"configurable": {"session_id": "123"}}
)
print(response)

三、修改聊天历史

1. 使用 ChatMessageHistory

ChatMessageHistory 类提供了 add_user_messageadd_ai_message 方法,用于添加新的消息到聊天历史中。如果需要修改已有的消息,可以通过直接访问 messages 属性来实现。

Python复制

# 修改聊天历史中的消息
chat_history.messages[0].content = "你好,我有一个新问题。"
print(chat_history.messages)

2. 使用 RedisChatMessageHistory

RedisChatMessageHistory 类也提供了类似的方法,可以通过直接访问 messages 属性来修改消息。

Python复制

# 修改 Redis 聊天历史中的消息
redis_chat_history.messages[0].content = "你好,我有一个新问题。"
print(redis_chat_history.messages)

四、裁剪消息

1. 使用 trim_messages 函数

LangChain 提供了 trim_messages 函数,用于裁剪聊天历史中的消息,以确保消息数量或 token 数量不超过指定的限制。

Python复制

from langchain_core.messages.utils import trim_messages

# 定义裁剪参数
max_tokens = 56
strategy = "last"
token_counter = ChatOpenAI(model="gpt-4o")
include_system = True
allow_partial = True

# 裁剪消息
trimmed_messages = trim_messages(
    messages=chat_history.messages,
    max_tokens=max_tokens,
    strategy=strategy,
    token_counter=token_counter,
    include_system=include_system,
    allow_partial=allow_partial
)

print(trimmed_messages)

2. 使用 RunnableWithMessageHistory

RunnableWithMessageHistory 类也可以与 trim_messages 函数结合使用,实现自动裁剪消息的功能。

Python复制

from langchain_core.runnables.history import RunnableWithMessageHistory

# 定义一个裁剪函数
def trim_messages_func(messages):
    return trim_messages(
        messages=messages,
        max_tokens=56,
        strategy="last",
        token_counter=ChatOpenAI(model="gpt-4o"),
        include_system=True,
        allow_partial=True
    )

# 创建一个带有消息历史和裁剪功能的运行单元
with_trim_message_history = RunnableWithMessageHistory(
    runnable,
    get_session_history,
    input_messages_key="input",
    history_messages_key="history",
    trim_messages_func=trim_messages_func
)

# 调用运行单元
response = with_trim_message_history.invoke(
    {"input": "你好,我有一个问题。"},
    config={"configurable": {"session_id": "123"}}
)
print(response)

五、总结记忆

1. 使用 SummaryMemory

LangChain 提供了 SummaryMemory 类,用于总结聊天历史中的关键信息,以便在后续对话中使用。

Python复制

from langchain_core.memory import SummaryMemory

# 创建一个总结记忆实例
summary_memory = SummaryMemory()

# 添加消息
summary_memory.add_message(chat_history.messages[0])
summary_memory.add_message(chat_history.messages[1])

# 获取总结
summary = summary_memory.summary
print(summary)

2. 使用 RunnableWithMessageHistory

RunnableWithMessageHistory 类也可以与 SummaryMemory 结合使用,实现自动总结聊天历史的功能。

Python复制

from langchain_core.runnables.history import RunnableWithMessageHistory

# 定义一个总结函数
def summarize_messages_func(messages):
    return SummaryMemory().summary

# 创建一个带有消息历史和总结功能的运行单元
with_summary_message_history = RunnableWithMessageHistory(
    runnable,
    get_session_history,
    input_messages_key="input",
    history_messages_key="history",
    summarize_messages_func=summarize_messages_func
)

# 调用运行单元
response = with_summary_message_history.invoke(
    {"input": "你好,我有一个问题。"},
    config={"configurable": {"session_id": "123"}}
)
print(response)

六、总结

LangChain 提供了强大的工具和接口,用于高效地管理消息和存储聊天历史。通过使用 ChatMessageHistoryRedisChatMessageHistory 类,开发者可以在内存或 Redis 中存储聊天消息历史。通过使用 trim_messages 函数和 SummaryMemory 类,开发者可以裁剪和总结聊天历史,确保对话的连贯性和系统的性能。希望本文能够帮助你更好地理解和应用 LangChain 的消息管理与聊天历史存储功能,提升你的智能对话系统性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值