在构建智能对话系统时,消息管理和聊天历史存储是关键环节,它们直接影响到对话的连贯性、用户体验以及系统的性能。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_message
和 add_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 提供了强大的工具和接口,用于高效地管理消息和存储聊天历史。通过使用 ChatMessageHistory
和 RedisChatMessageHistory
类,开发者可以在内存或 Redis 中存储聊天消息历史。通过使用 trim_messages
函数和 SummaryMemory
类,开发者可以裁剪和总结聊天历史,确保对话的连贯性和系统的性能。希望本文能够帮助你更好地理解和应用 LangChain 的消息管理与聊天历史存储功能,提升你的智能对话系统性能。