langchain_community.chat_message_histories
模块是 LangChain 社区库中用于管理聊天消息历史的工具集,包含多个类(如 ChatMessageHistory
、SQLChatMessageHistory
、RedisChatMessageHistory
等),用于存储和跟踪对话消息(用户输入和模型响应),支持多轮对话和上下文管理。
本文基于 LangChain 0.3.x ,详细介绍 chat_message_histories
模块的结构、核心类及其功能,并提供一个独立示例,展示如何结合 RedisChatMessageHistory
和 ChatOpenAI
实现人工智能主题的多轮对话,示例突出模块的持久化消息历史管理能力。
langchain_community.chat_message_histories
模块概览
langchain_community.chat_message_histories
模块是 LangChain 社区库的一部分,提供一系列消息历史管理类,用于存储和管理对话中的消息(HumanMessage
、AIMessage
等)。这些类支持不同存储后端(如内存、SQL 数据库、Redis 等),满足从临时测试到生产级应用的各种需求。模块中的类继承自 langchain_core.chat_history.BaseChatMessageHistory
,提供标准化的消息管理接口。
核心功能:
- 存储对话消息,支持多轮上下文保留。
- 按会话 ID 组织消息,支持多用户或多会话。
- 提供添加、获取、清除消息的接口。
- 支持内存和持久化存储,适配不同场景。
适用场景:
- 构建聊天机器人或问答系统,需跟踪对话历史。
- 多用户应用,管理每个用户的会话上下文。
- 生产级系统,需持久化或高并发消息存储。
- 测试 LLM 的上下文理解能力。
模块位置:
- 源码路径:
langchain_community/chat_message_histories/
- 文档参考:LangChain Community API
模块中的主要类
以下是 chat_message_histories
模块中的核心类(基于 LangChain 0.3.x),包括功能和典型用法。
1. ChatMessageHistory
- 功能:在内存中存储消息历史,轻量级,适合临时使用。
- 参数:无额外参数。
- 使用场景:快速原型开发、测试对话逻辑。
- 示例:
from langchain_community.chat_message_histories import ChatMessageHistory history = ChatMessageHistory() history.add_user_message("什么是 AI?") history.add_ai_message("AI 是人工智能的缩写。")
2. SQLChatMessageHistory
- 功能:将消息存储到 SQL 数据库(如 SQLite、PostgreSQL),支持持久化。
- 参数:
session_id
(str
):会话 ID。connection_string
(str
):数据库连接字符串。table_name
(str
):存储表名。
- 使用场景:需要长期保存对话历史的单机或小型应用。
- 示例:
from langchain_community.chat_message_histories import SQLChatMessageHistory history = SQLChatMessageHistory( session_id="ai_chat_001", connection_string="sqlite:///chat_history.db" )
3. RedisChatMessageHistory
- 功能:将消息存储到 Redis,支持高并发和持久化。
- 参数:
session_id
(str
):会话 ID。redis_url
(str
):Redis 连接 URL。key_prefix
(str
):键前缀。ttl
(Optional[int]
):消息生存时间。
- 使用场景:高并发、分布式聊天机器人或生产级应用。
- 示例:
from langchain_community.chat_message_histories import RedisChatMessageHistory history = RedisChatMessageHistory( session_id="ai_chat_001", redis_url="redis://localhost:6379/0" )
4. CassandraChatMessageHistory
- 功能:将消息存储到 Apache Cassandra,适合分布式数据库环境。
- 参数:
session_id
(str
):会话 ID。session
(cassandra.cluster.Session
):Cassandra 会话。keyspace
(str
):键空间。table_name
(str
):表名。ttl_seconds
(Optional[int]
):消息生存时间。
- 使用场景:大规模分布式系统。
- 示例:
from langchain_community.chat_message_histories import CassandraChatMessageHistory from cassandra.cluster import Cluster cluster = Cluster(["localhost"]) session = cluster.connect() history = CassandraChatMessageHistory( session_id="ai_chat_001", session=session, keyspace="chat" )
5. MongoDBChatMessageHistory
- 功能:将消息存储到 MongoDB,适合 NoSQL 环境。
- 参数:
session_id
(str
):会话 ID。connection_string
(str
):MongoDB 连接字符串。database_name
(str
):数据库名。collection_name
(str
):集合名。
- 使用场景:需要灵活 schema 的大规模应用。
- 示例:
from langchain_community.chat_message_histories import MongoDBChatMessageHistory history = MongoDBChatMessageHistory( session_id="ai_chat_001", connection_string="mongodb://localhost:27017/", database_name="chat_db", collection_name="messages" )
其他类
DynamoDBChatMessageHistory
:使用 AWS DynamoDB 存储消息。FirestoreChatMessageHistory
:使用 Google Firestore 存储消息。CosmosDBChatMessageHistory
:使用 Azure Cosmos DB 存储消息。
基类:
- 所有类继承自
langchain_core.chat_history.BaseChatMessageHistory
,提供标准接口:add_message
:添加消息。add_user_message
:添加用户消息。add_ai_message
:添加 AI 消息。clear
:清除历史。messages
:获取消息列表。
使用方式
以下是使用 chat_message_histories
模块的通用步骤。
1. 安装依赖
pip install --upgrade langchain langchain-openai langchain-community redis sqlalchemy pymongo
2. 设置 OpenAI API 密钥
export OPENAI_API_KEY="your-api-key"
或在代码中:
import os
os.environ["OPENAI_API_KEY"] = "your-api-key"
3. 初始化消息历史
from langchain_community.chat_message_histories import RedisChatMessageHistory
history = RedisChatMessageHistory(
session_id="ai_chat_001",
redis_url="redis://localhost:6379/0"
)
4. 构建对话链
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
llm = ChatOpenAI(model="gpt-3.5-turbo")
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个人工智能专家,回答用户问题。"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}")
])
chain = prompt | llm
5. 集成消息历史
from langchain_core.runnables.history import RunnableWithMessageHistory
chain_with_history = RunnableWithMessageHistory(
runnable=chain,
get_session_history=lambda session_id: RedisChatMessageHistory(
session_id=session_id,
redis_url="redis://localhost:6379/0"
),
input_messages_key="input",
history_messages_key="history"
)
response = chain_with_history.invoke(
{"input": "什么是人工智能?"},
config={"configurable": {"session_id": "ai_chat_001"}}
)
使用 chat_message_histories
的示例
以下是一个独立示例,展示如何使用 chat_message_histories
模块中的 RedisChatMessageHistory
结合 ChatOpenAI
实现人工智能主题的多轮对话,持久化存储消息历史。示例使用 Redis 作为存储后端,突出模块的高并发和持久化能力。
准备环境:
- 获取 OpenAI API 密钥:OpenAI Platform。
- 设置环境变量:
export OPENAI_API_KEY="your-api-key"
- 安装依赖:
pip install --upgrade langchain langchain-openai langchain-community redis
- 启动 Redis 服务器:
redis-server
- 验证 Redis 连接:
redis-cli ping # 输出: PONG
代码:
from langchain_community.chat_message_histories import RedisChatMessageHistory
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables.history import RunnableWithMessageHistory
# 初始化 ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)
# 定义提示模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个人工智能专家,回答用户问题。"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}")
])
# 定义输出解析器
parser = StrOutputParser()
# 创建对话链
chain = prompt | llm | parser
# 包装链以支持消息历史
chain_with_history = RunnableWithMessageHistory(
runnable=chain,
get_session_history=lambda session_id: RedisChatMessageHistory(
session_id=session_id,
redis_url="redis://localhost:6379/0",
ttl=3600 # 消息保留 1 小时
),
input_messages_key="input",
history_messages_key="history"
)
# 测试 chat_message_histories 和对话链
print("测试 chat_message_histories 和对话链:")
try:
session_id = "ai_chat_001"
# 第一轮对话
question1 = "什么是人工智能?"
result1 = chain_with_history.invoke(
{"input": question1},
config={"configurable": {"session_id": session_id}}
)
print(f"问题 1: {question1}")
print(f"回答 1: {result1}")
# 第二轮对话(依赖上下文)
question2 = "它有哪些应用?"
result2 = chain_with_history.invoke(
{"input": question2},
config={"configurable": {"session_id": session_id}}
)
print(f"\n问题 2: {question2}")
print(f"回答 2: {result2}")
# 显示消息历史
history = RedisChatMessageHistory(session_id=session_id, redis_url="redis://localhost:6379/0")
print("\n消息历史:")
for i, msg in enumerate(history.messages):
print(f"消息 {i+1} ({msg.__class__.__name__}): {msg.content}")
except Exception as e:
print(f"错误: {e}")
输出示例(实际输出取决于模型和 API 响应):
测试 chat_message_histories 和对话链:
问题 1: 什么是人工智能?
回答 1: 人工智能(AI)是计算机科学的一个分支,旨在模拟人类智能,如学习、推理和问题解决。
问题 2: 它有哪些应用?
回答 2: 人工智能的应用包括医疗诊断、自动驾驶、语音识别、推荐系统和金融分析等领域。
消息历史:
消息 1 (HumanMessage): 什么是人工智能?
消息 2 (AIMessage): 人工智能(AI)是计算机科学的一个分支,旨在模拟人类智能,如学习、推理和问题解决。
消息 3 (HumanMessage): 它有哪些应用?
消息 4 (AIMessage): 人工智能的应用包括医疗诊断、自动驾驶、语音识别、推荐系统和金融分析等领域。
代码说明
- RedisChatMessageHistory:
- 使用 Redis(
redis://localhost:6379/0
)存储消息。 - 设置
session_id="ai_chat_001"
和ttl=3600
(1 小时)。
- 使用 Redis(
- LLM 初始化:
- 使用
ChatOpenAI
调用gpt-3.5-turbo
,设置temperature=0.7
。
- 使用
- 提示模板:
ChatPromptTemplate
包含系统消息、历史占位符和用户输入。MessagesPlaceholder
注入历史消息。
- 对话链:
- 使用 LCEL 组合
prompt
、llm
和parser
。 RunnableWithMessageHistory
包装链,动态加载RedisChatMessageHistory
。
- 使用 LCEL 组合
- 测试:
- 进行两轮对话:定义 AI 和询问应用。
- 使用
session_id
确保上下文一致。 - 显示 Redis 中的消息历史。
- 错误处理:
- 使用
try-except
捕获 API 或 Redis 错误。
- 使用
运行要求:
- 有效的 OpenAI API 密钥:
export OPENAI_API_KEY="your-api-key"
- 安装依赖:
pip install --upgrade langchain langchain-openai langchain-community redis
- 运行 Redis 服务器:
redis-server
- 网络连接:访问
https://api.openai.com
和本地 Redis(localhost:6379
)。
注意事项
- API 密钥:
- 确保
OPENAI_API_KEY
已设置:echo $OPENAI_API_KEY
- 或在代码中设置:
llm = ChatOpenAI(api_key="your-api-key")
- 确保
- 存储后端选择:
- 内存(
ChatMessageHistory
):临时测试。from langchain_community.chat_message_histories import ChatMessageHistory history = ChatMessageHistory()
- SQL(
SQLChatMessageHistory
):单机持久化。history = SQLChatMessageHistory(session_id="ai_chat_001", connection_string="sqlite:///chat_history.db")
- Redis(
RedisChatMessageHistory
):高并发。history = RedisChatMessageHistory(session_id="ai_chat_001", redis_url="redis://localhost:6379/0")
- 内存(
- 会话 ID:
- 唯一
session_id
区分对话:session_id="ai_chat_001"
- 验证历史:
print(history.messages)
- 唯一
- 性能优化:
- 异步调用:使用
ainvoke
:result = await chain_with_history.ainvoke(input, config)
- 限制历史长度:避免上下文过长:
max_messages = 10 history.messages = history.messages[-max_messages:]
- Redis 连接池:提高并发:
import redis pool = redis.ConnectionPool.from_url("redis://localhost:6379/0") history = RedisChatMessageHistory(session_id="ai_chat_001", redis_url="redis://localhost:6379/0")
- 异步调用:使用
- 错误调试:
- 连接错误:
- 检查 Redis:
redis-cli ping
- 检查 SQL:
import sqlalchemy engine = sqlalchemy.create_engine("sqlite:///chat_history.db") engine.connect()
- 检查 Redis:
- API 错误:
- 检查密钥:
print(os.environ.get("OPENAI_API_KEY"))
- 增加超时:
llm = ChatOpenAI(timeout=30)
- 检查密钥:
- 消息丢失:
- 检查历史:
print(history.messages)
- 验证
session_id
:print(session_id)
- 检查历史:
- 连接错误:
常见问题
Q1:如何选择合适的消息历史类?
A:根据需求:
- 临时测试:
ChatMessageHistory
。 - 单机持久化:
SQLChatMessageHistory
。 - 高并发生产:
RedisChatMessageHistory
。 - 分布式 NoSQL:
MongoDBChatMessageHistory
。
Q2:如何清理消息历史?
A:调用 clear
:
history.clear()
或删除存储:
- Redis:
redis-cli DEL message_store:ai_chat_001
- SQL:
DELETE FROM message_store WHERE session_id = 'ai_chat_001';
Q3:如何与 RAG 结合?
A:添加检索上下文:
from langchain.vectorstores import FAISS
vectorstore = FAISS.from_documents(docs, OpenAIEmbeddings())
retriever = vectorstore.as_retriever()
prompt = ChatPromptTemplate.from_messages([
("system", "根据上下文和历史回答:\n{context}"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}")
])
chain = {"context": retriever, "history": lambda x: history.messages, "input": lambda x: x["input"]} | prompt | llm
Q4:如何支持开源模型?
A:使用 ChatOllama
:
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3")
chain = prompt | llm | parser
chain_with_history = RunnableWithMessageHistory(
runnable=chain,
get_session_history=lambda session_id: RedisChatMessageHistory(
session_id=session_id,
redis_url="redis://localhost:6379/0"
),
input_messages_key="input",
history_messages_key="history"
)
总结
langchain_community.chat_message_histories
模块是 LangChain 中管理对话历史的工具集,包含以下关键类:
ChatMessageHistory
:内存存储,适合测试。SQLChatMessageHistory
:SQL 数据库,适合单机持久化。RedisChatMessageHistory
:Redis 存储,适合高并发。MongoDBChatMessageHistory
:MongoDB 存储,适合 NoSQL。CassandraChatMessageHistory
:Cassandra 存储,适合分布式。