LangChain 会话记忆

本文最后更新于 2026年8月11日

记忆缓存是对话系统中的重要组件,用于存储和管理对话的上下文信息,让AI助手能记住之前的对话内容,从而提供连贯而个性化的回复。

实现会话记忆,需要将历史信息全部发送给大模型,langchain就提供了记忆的功能,能够在发出消息前追加历史消息和用户输入一并发送给大模型,收到回复时将大模型输出一并写进历史消息。

langchain早期版本使用ConversationBufferMemory,但是现在的0.3.x+版本已经逐步采用了RunnableWithMessageHistory来替代,RunnableWithMessageHistory也是和很多组件一样的继承Runnable,能与很多组件配合使用。


例:

  1. RunnableWithMessageHistory为对话链自动加上记忆,以session_id进行隔离,自动维护历史消息,与BaseChatMessageHistory配合使用,参数有:

    • runnable 对话链
    • get_session_history 历史记录函数
    • input_messages_key 输入字段
    • history_messages_key 历史记录字段
  2. RunnableWithMessageHistory必须与ChatPromptTemplateMessagesPlaceholder以及get_session_history()函数一起使用

  3. BaseChatMessageHistory是一个基类,派生很多实现类,用于保存对话记录,比如InMemoryChatMessageHistory就是将记录保存在内存中,其主要成员:

    • messages: list[BaseMessage] 用于接收和读取历史
    • def add_message(self, message: BaseMessage) -> None: 添加一条消息
    • def add_messages(self, messages: Sequence[BaseMessage]) -> None: 批量添加消息
    • async def aclear(self) -> None: 清空

实际场景中,应该选择保存进Redis/ES等数据库的实现类


import os

from langchain.chat_models import init_chat_model
from langchain_core.chat_history import BaseChatMessageHistory, InMemoryChatMessageHistory
from langchain_core.prompts import  MessagesPlaceholder, ChatPromptTemplate
from langchain_core.runnables import RunnableWithMessageHistory

store = {}


def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = InMemoryChatMessageHistory()
    return store[session_id]




prompt_template = ChatPromptTemplate.from_messages(
    [
        ('system', '你是一个AI助手,名字叫小美'),
        MessagesPlaceholder('history'),
        ('human', '{input}')
    ]
)

llm = init_chat_model(
    model = 'deepseek-chat',
    model_provider = 'openai',
    api_key = os.getenv('DSKEY'),
    base_url = 'https://api.deepseek.com'
)



chain_with_history = RunnableWithMessageHistory(
    runnable=prompt_template | llm,
    get_session_history=get_session_history,
    input_messages_key='input',
    history_messages_key='history'
)



resp = chain_with_history.invoke(
    input={'input': '1加1等于几呀'},
    config={'session_id': 1}
)
print(resp.content)
print('#'*30)
resp = chain_with_history.invoke(
    input={'input': '那加2呢'},
    config={'session_id': 1}
)
print(resp.content)

InMemoryChatMessageHistory可以lambda进行简写

history = InMemoryChatMessageHistory()

chain_with_history = RunnableWithMessageHistory(
    runnable=prompt_template | llm,
    get_session_history=lambda session_id: history,
    input_messages_key='input',
    history_messages_key='history'
)
1加1等于2哦!这是一个非常基础的数学问题,如果你有其他问题,也可以问我!😊
##############################
1加2等于3!如果是指“1加1再加2”,那结果是1+1+2=4。需要我帮你算其他数吗?😊

例:redis永久保存会话,程序结束后再次发问能够衔接,但是session_id的值需要修改为字符串类型。

截至成文,langchain-community#RedisChatMessageHistory已经不再被推荐,:0: LangChainDeprecationWarning: RunnableWithMessageHistory is deprecated. Use LangGraph’s built-in persistence instead.

pip install redis==5.3.1    
pip install langchain-community  
import os

from langchain.chat_models import init_chat_model
from langchain_core.prompts import  MessagesPlaceholder, ChatPromptTemplate
from langchain_core.runnables import RunnableWithMessageHistory, RunnableConfig
from langchain_community.chat_message_histories import RedisChatMessageHistory
from dotenv import load_dotenv

load_dotenv(encoding='utf-8')

prompt_template = ChatPromptTemplate.from_messages(
    [
        ('system', '你是一个AI助手,名字叫小美'),
        MessagesPlaceholder('history'),
        ('human', '{input}')
    ]
)

llm = init_chat_model(
    model = 'deepseek-chat',
    model_provider = 'openai',
    api_key = os.getenv('DSKEY'),
    base_url = 'https://api.deepseek.com'
)

REDIS_PASSWORD=os.getenv('REDIS_PASSWORD')
REDIS_HOST=os.getenv('REDIS_HOST')
REDIS_PORT=os.getenv('REDIS_PORT')
REDIS_INDEX=os.getenv('REDIS_INDEX')

def get_message_history(session_id):
    return RedisChatMessageHistory(
        session_id=session_id,
        # url='redis://:your_password@host:port/index'
        url=f'redis://:{REDIS_PASSWORD}@{REDIS_HOST}:{REDIS_PORT}/{REDIS_INDEX}'
    )


chain_with_history = RunnableWithMessageHistory(
    runnable=prompt_template | llm,
    get_session_history=get_message_history,
    input_messages_key='input',
    history_messages_key='history'
)



resp = chain_with_history.invoke(
    input={'input': '1加1等于几呀'},
    config=RunnableConfig(configurable={'session_id': '2'})
)

print(resp.content)

print('#'*30)

resp = chain_with_history.invoke(
    input={'input': '那加2呢'},
    config=RunnableConfig(configurable={'session_id': '2'})
)
print(resp.content)

在redis中,会话数据被按照列表形式保存

127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "message_store:2"
2) "message_store:1"
127.0.0.1:6379[1]> type message_store:2
list
127.0.0.1:6379[1]> lindex message_store:2 0
"{\"type\": \"ai\", \"data\": {\"content\": \"1\\u52a02\\u7b49\\u4e8e3\\u5440\\uff01\\u770b\\u6765\\u4f60\\u5f88\\u559c\\u6b22\\u7b97\\u672f\\u9898\\u5462\\uff5e\\u5c0f\\u7f8e\\u968f\\u65f6\\u6b22\\u8fce\\u4f60\\u6765\\u201c\\u8003\\u8bd5\\u201d\\u54e6\\uff01\\u8fd8\\u6709\\u5176\\u4ed6\\u95ee\\u9898\\u5417\\uff1f\\ud83d\\ude0a\", \"additional_kwargs\": {\"refusal\": null}, \"response_metadata\": {\"token_usage\": {\"completion_tokens\": 30, \"prompt_tokens\": 133, \"total_tokens\": 163, \"completion_tokens_details\": null, \"prompt_tokens_details\": {\"audio_tokens\": null, \"cached_tokens\": 0}, \"prompt_cache_hit_tokens\": 0, \"prompt_cache_miss_tokens\": 133}, \"model_provider\": \"openai\", \"model_name\": \"deepseek-v4-flash\", \"system_fingerprint\": \"fp_8b330d02d0_prod0820_fp8_kvcache_20260402\", \"id\": \"b39e6f6d-6942-4822-8f9e-0aa0a6e96445\", \"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": \"lc_run--019fb3a3-0808-74d1-99ca-25b42bb2ef96-0\", \"tool_calls\": [], \"invalid_tool_calls\": [], \"usage_metadata\": {\"input_tokens\": 133, \"output_tokens\": 30, \"total_tokens\": 163, \"input_token_details\": {\"cache_read\": 0}, \"output_token_details\": {}}}}"

"如果文章对您有帮助,可以请作者喝杯咖啡吗?"

微信二维码

微信支付

支付宝二维码

支付宝


LangChain 会话记忆
https://blog.liuzijian.com/post/2026/01/19/langchain-memory/
作者
Liu Zijian
发布于
2026年1月19日
更新于
2026年8月11日
许可协议