Skip to content

LangChain Memory — 对话记忆管理

记忆类型概览

类型特点适用场景
ConversationBufferMemory保存完整历史短对话
ConversationBufferWindowMemory保留最近 K 轮长对话节省 token
ConversationSummaryMemory自动摘要历史超长对话
ConversationSummaryBufferMemory摘要+近期完整生产推荐
VectorStoreRetrieverMemory向量检索相关记忆知识密集型

ConversationBufferWindowMemory

python
from langchain.memory import ConversationBufferWindowMemory
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain

llm = ChatOpenAI(model="qwen-turbo", ...)

memory = ConversationBufferWindowMemory(
    k=5,                    # 保留最近 5 轮对话
    return_messages=True    # 返回 Message 对象而非字符串
)

conversation = ConversationChain(
    llm=llm,
    memory=memory,
    verbose=True
)

conversation.predict(input="我想申请一笔 50 万的企业贷款")
conversation.predict(input="我们公司成立 3 年,年营收 200 万")
conversation.predict(input="需要什么材料?")  # 模型记得上下文

ConversationSummaryBufferMemory(生产推荐)

python
from langchain.memory import ConversationSummaryBufferMemory

memory = ConversationSummaryBufferMemory(
    llm=llm,
    max_token_limit=1000,   # 超过此 token 数则压缩为摘要
    return_messages=True
)

# 手动添加历史
memory.save_context(
    {"input": "我是招商银行的客户经理"},
    {"output": "您好!请问有什么可以帮助您?"}
)

# 查看当前记忆
print(memory.load_memory_variables({}))

自定义记忆(Redis 持久化)

python
import redis
import json
from langchain_core.memory import BaseMemory
from typing import Dict, List, Any

class RedisMemory(BaseMemory):
    """基于 Redis 的持久化对话记忆"""
    
    redis_client: Any
    session_id: str
    max_history: int = 20
    
    class Config:
        arbitrary_types_allowed = True
    
    @property
    def memory_variables(self) -> List[str]:
        return ["history"]
    
    def load_memory_variables(self, inputs: Dict) -> Dict:
        key = f"chat_history:{self.session_id}"
        history = self.redis_client.lrange(key, -self.max_history * 2, -1)
        messages = [json.loads(m) for m in history]
        return {"history": messages}
    
    def save_context(self, inputs: Dict, outputs: Dict) -> None:
        key = f"chat_history:{self.session_id}"
        self.redis_client.rpush(
            key,
            json.dumps({"role": "user", "content": inputs["input"]}),
            json.dumps({"role": "assistant", "content": outputs["output"]})
        )
        self.redis_client.expire(key, 86400)  # 24小时过期

# 使用
r = redis.Redis(host="localhost", port=6379, decode_responses=True)
memory = RedisMemory(redis_client=r, session_id="user_123")

LCEL 中的记忆管理

python
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import RedisChatMessageHistory

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是专业的金融客服助手"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{input}")
])

chain = prompt | llm

# 包装为带历史的链
chain_with_history = RunnableWithMessageHistory(
    chain,
    lambda session_id: RedisChatMessageHistory(
        session_id,
        url="redis://localhost:6379"
    ),
    input_messages_key="input",
    history_messages_key="history"
)

# 调用时传入 session_id
config = {"configurable": {"session_id": "user_456"}}
response = chain_with_history.invoke(
    {"input": "我想了解理财产品"},
    config=config
)

本站内容由 褚成志 整理编写,仅供学习参考