Memory 基础概念

概述

Memory(记忆)是 LangChain 中用于存储和管理对话历史及状态信息的组件。它使得语言模型能够在多次交互中保持上下文,从而提供更加连贯和个性化的用户体验。

核心概念

什么是 Memory?

Memory 是 LangChain 中的一个抽象概念,用于存储对话历史、用户偏好、中间状态等信息。它允许应用程序在不同的交互之间保持一致性。

为什么需要 Memory?

  1. 上下文保持: 在多轮对话中维持话题连贯性
  2. 个性化体验: 根据用户历史行为提供定制化响应
  3. 状态管理: 跟踪任务执行状态和中间结果
  4. 知识累积: 积累和利用历史信息优化后续交互

Memory 的工作原理

基本架构

Memory 系统通常包含以下几个核心组件:

  1. 存储机制: 实际存储数据的方式(内存、数据库等)
  2. 加载逻辑: 如何从存储中检索相关信息
  3. 保存逻辑: 如何将新信息保存到存储中
  4. 清理策略: 何时以及如何清理过期信息

数据流示例

用户输入 → Chain/Agent → Memory保存 → 下次交互时Memory加载 → Chain/Agent处理

Memory 的基本操作

1. 保存信息

from langchain.memory import ConversationBufferMemory

# 创建记忆实例
memory = ConversationBufferMemory()

# 保存人类消息
memory.save_context({"input": "你好"}, {"output": "你好!有什么可以帮助你的吗?"})

# 保存AI消息
memory.save_context({"input": "今天天气怎么样?"}, {"output": "我无法获取实时天气信息,建议你查看天气应用。"})

2. 加载信息

# 加载记忆中的历史记录
history = memory.load_memory_variables({})
print(history)
# 输出: {'history': 'Human: 你好\nAI: 你好!有什么可以帮助你的吗?\nHuman: 今天天气怎么样?\nAI: 我无法获取实时天气信息,建议你查看天气应用。'}

3. 清理信息

# 清空记忆
memory.clear()

Memory 与 Chains 的集成

在 LLMChain 中使用 Memory

from langchain_openai import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory

# 创建提示词模板
template = """你是一个友好的助手,会记住之前的对话。
对话历史:
{history}
人类: {human_input}
助手:"""

prompt = PromptTemplate(
    input_variables=["history", "human_input"],
    template=template
)

# 创建记忆
memory = ConversationBufferMemory()

# 创建链
llm = OpenAI(temperature=0.7)
chain = LLMChain(
    llm=llm,
    prompt=prompt,
    memory=memory,
    verbose=True
)

# 使用链进行对话
# response1 = chain.run(human_input="我叫小明")
# response2 = chain.run(human_input="我刚才说了什么?")

Memory 与 Agents 的集成

在 Agent 中使用 Memory

from langchain.agents import AgentType, initialize_agent
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationBufferMemory

# 创建记忆
memory = ConversationBufferMemory(memory_key="chat_history")

# 创建 Agent
llm = ChatOpenAI(temperature=0.7)
agent = initialize_agent(
    tools=[],  # 可以添加工具
    llm=llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory,
    verbose=True
)

# 使用 Agent 进行对话
# response1 = agent.run("我最喜欢的编程语言是 Python")
# response2 = agent.run("我刚才说了我最喜欢的编程语言是什么?")

Memory 的配置选项

基本配置参数

from langchain.memory import ConversationBufferMemory

# 基本配置
memory = ConversationBufferMemory(
    memory_key="chat_history",      # 记忆键名
    input_key="input",              # 输入键名
    output_key="output",            # 输出键名
    return_messages=False           # 是否返回消息对象而不是字符串
)

高级配置选项

# 配置返回消息对象
memory_with_messages = ConversationBufferMemory(
    return_messages=True,           # 返回消息对象列表
    output_key="output"             # 指定输出键
)

# 配置自定义键名
custom_memory = ConversationBufferMemory(
    memory_key="conversation",      # 自定义记忆键名
    input_key="user_message",       # 自定义输入键名
    output_key="ai_response"        # 自定义输出键名
)

实际应用场景

1. 个性化聊天机器人

from langchain.memory import ConversationBufferMemory
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain

# 创建带记忆的对话链
llm = ChatOpenAI(temperature=0.7)
memory = ConversationBufferMemory()

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

# 模拟多轮对话
# response1 = conversation.predict(input="你好,我叫小红")
# response2 = conversation.predict(input="我喜欢画画和音乐")
# response3 = conversation.predict(input="你还记得我的名字吗?")

2. 任务状态跟踪

from langchain.memory import ConversationBufferMemory

# 创建任务跟踪记忆
task_memory = ConversationBufferMemory(
    memory_key="task_history"
)

# 保存任务状态
task_memory.save_context(
    {"input": "开始任务"}, 
    {"output": "任务已启动,当前进度0%"}
)

task_memory.save_context(
    {"input": "执行步骤1"}, 
    {"output": "步骤1完成,当前进度30%"}
)

# 查看任务历史
task_history = task_memory.load_memory_variables({})
print(task_history)

3. 用户偏好存储

from langchain.memory import ConversationBufferMemory

# 创建用户偏好记忆
preference_memory = ConversationBufferMemory(
    memory_key="user_preferences"
)

# 保存用户偏好
preference_memory.save_context(
    {"input": "用户偏好设置"}, 
    {"output": "偏好已记录:喜欢科技新闻,偏爱简洁回答"}
)

# 在后续交互中使用偏好信息
preferences = preference_memory.load_memory_variables({})
print(preferences)

Memory 的最佳实践

1. 合理选择记忆类型

# 根据使用场景选择合适的记忆类型
from langchain.memory import (
    ConversationBufferMemory,
    ConversationSummaryMemory,
    ConversationBufferWindowMemory
)

# 短对话使用缓冲记忆
short_conversation_memory = ConversationBufferMemory()

# 长对话使用摘要记忆
long_conversation_memory = ConversationSummaryMemory(
    llm=ChatOpenAI(temperature=0.3)
)

# 有限窗口使用窗口记忆
window_memory = ConversationBufferWindowMemory(k=5)

2. 内存管理

# 定期清理过期记忆
class ManagedMemory:
    """带管理功能的记忆系统"""
    
    def __init__(self, memory, max_entries=100):
        self.memory = memory
        self.max_entries = max_entries
    
    def save_context(self, inputs, outputs):
        """保存上下文并管理大小"""
        self.memory.save_context(inputs, outputs)
        
        # 检查并清理过期记忆
        self._manage_memory_size()
    
    def _manage_memory_size(self):
        """管理记忆大小"""
        # 实现记忆清理逻辑
        pass

# 使用管理记忆
# managed_memory = ManagedMemory(ConversationBufferMemory())

3. 错误处理

from langchain.memory import ConversationBufferMemory

class RobustMemory:
    """健壮的记忆系统"""
    
    def __init__(self):
        self.memory = ConversationBufferMemory()
    
    def safe_save_context(self, inputs, outputs):
        """安全保存上下文"""
        try:
            self.memory.save_context(inputs, outputs)
        except Exception as e:
            print(f"保存记忆时出错: {e}")
    
    def safe_load_memory(self):
        """安全加载记忆"""
        try:
            return self.memory.load_memory_variables({})
        except Exception as e:
            print(f"加载记忆时出错: {e}")
            return {}

# 使用健壮记忆
# robust_memory = RobustMemory()
# robust_memory.safe_save_context({"input": "测试"}, {"output": "结果"})
# history = robust_memory.safe_load_memory()

总结

Memory 是 LangChain 中实现连贯对话和状态管理的关键组件。通过合理使用和配置 Memory,我们可以创建出更加智能和用户友好的应用程序。关键要点包括:

  1. 理解 Memory 的基本概念和工作原理
  2. 根据使用场景选择合适的记忆类型
  3. 正确配置记忆参数以满足应用需求
  4. 实现适当的错误处理和内存管理
  5. 在 Chains 和 Agents 中有效集成记忆系统

Memory 类型详解

概述

LangChain 提供了多种不同类型的 Memory,每种都有其特定的用途和优势。了解这些不同类型的特点和适用场景,可以帮助我们为应用程序选择最合适 的记忆系统。

主要记忆类型

1. ConversationBufferMemory (对话缓冲记忆)

特点
  • 完整存储: 保存完整的对话历史
  • 简单直接: 实现简单,易于理解和使用
  • 内存密集: 随着对话增长,内存使用量线性增加
使用场景
  • 短对话场景
  • 需要完整历史记录的应用
  • 简单的聊天机器人
使用示例
from langchain.memory import ConversationBufferMemory

# 创建对话缓冲记忆
memory = ConversationBufferMemory()

# 保存对话
memory.save_context({"input": "你好"}, {"output": "你好!有什么可以帮助你的吗?"})
memory.save_context({"input": "今天天气怎么样?"}, {"output": "我无法获取实时天气信息。"})

# 加载记忆
history = memory.load_memory_variables({})
print(history)
# 输出完整的对话历史
配置选项
# 基本配置
basic_memory = ConversationBufferMemory(
    memory_key="chat_history",    # 记忆键名
    input_key="input",            # 输入键名
    output_key="output"           # 输出键名
)

# 返回消息对象
message_memory = ConversationBufferMemory(
    return_messages=True          # 返回消息对象列表
)

# 自定义键名
custom_memory = ConversationBufferMemory(
    memory_key="conversation_history",
    input_key="user_input",
    output_key="ai_response"
)

2. ConversationBufferWindowMemory (对话窗口记忆)

特点
  • 有限窗口: 只保存最近的K条消息
  • 内存友好: 控制内存使用量
  • 历史截断: 自动丢弃旧的对话历史
使用场景
  • 长时间对话场景
  • 内存资源有限的应用
  • 只需要近期上下文的场景
使用示例
from langchain.memory import ConversationBufferWindowMemory

# 创建窗口记忆,只保存最近3条消息
window_memory = ConversationBufferWindowMemory(k=3)

# 保存多条消息
for i in range(5):
    window_memory.save_context(
        {"input": f"问题{i}"}, 
        {"output": f"回答{i}"}
    )

# 加载记忆(只会显示最近3条)
history = window_memory.load_memory_variables({})
print(history)
配置选项
# 配置窗口大小
window_memory = ConversationBufferWindowMemory(
    k=5,                          # 保存最近5条消息
    memory_key="recent_history",  # 自定义键名
    return_messages=True          # 返回消息对象
)

3. ConversationSummaryMemory (对话摘要记忆)

特点
  • 智能摘要: 使用LLM生成对话摘要
  • 固定大小: 摘要大小相对固定
  • 语义保持: 保留对话的主要语义信息
使用场景
  • 非常长的对话历史
  • 需要保持对话主旨的场景
  • 内存严格受限的应用
使用示例
from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI

# 创建摘要记忆
summary_memory = ConversationSummaryMemory(
    llm=ChatOpenAI(temperature=0.3),
    memory_key="chat_summary"
)

# 保存多条对话
summary_memory.save_context(
    {"input": "我想了解人工智能"}, 
    {"output": "人工智能是计算机科学的一个分支..."}
)

summary_memory.save_context(
    {"input": "它有哪些应用领域?"}, 
    {"output": "人工智能广泛应用于医疗、金融、交通等领域..."}
)

# 加载摘要
summary = summary_memory.load_memory_variables({})
print(summary)
配置选项
# 配置摘要记忆
summary_memory = ConversationSummaryMemory(
    llm=ChatOpenAI(temperature=0.3),
    memory_key="conversation_summary",
    input_key="user_input",
    output_key="ai_output",
    return_messages=False
)

4. ConversationSummaryBufferMemory (对话摘要缓冲记忆)

特点
  • 混合模式: 结合缓冲和摘要的优点
  • 近期完整: 保存近期完整对话
  • 历史摘要: 对旧对话进行摘要
  • 平衡性能: 在内存使用和信息保留之间取得平衡
使用场景
  • 中等长度的对话历史
  • 需要近期详细信息和历史概要的场景
  • 平衡内存使用和信息完整性的应用
使用示例
from langchain.memory import ConversationSummaryBufferMemory
from langchain_openai import ChatOpenAI

# 创建摘要缓冲记忆
summary_buffer_memory = ConversationSummaryBufferMemory(
    llm=ChatOpenAI(temperature=0.3),
    max_token_limit=500  # 最大令牌限制
)

# 保存对话
for i in range(10):
    summary_buffer_memory.save_context(
        {"input": f"问题{i}"}, 
        {"output": f"详细回答{i},包含很多信息..."}
    )

# 加载记忆
memory_content = summary_buffer_memory.load_memory_variables({})
print(memory_content)

5. VectorStoreRetrieverMemory (向量存储检索记忆)

特点
  • 向量检索: 使用向量存储和检索相关信息
  • 语义搜索: 基于语义相似性检索记忆
  • 可扩展性: 适合大规模记忆存储
使用场景
  • 需要从大量历史中检索相关信息
  • 基于内容相似性的记忆检索
  • 知识库类型的对话系统
使用示例
from langchain.memory import VectorStoreRetrieverMemory
from langchain.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings

# 注意:这需要额外的依赖
# pip install faiss-cpu

# 创建向量存储
# embedding = OpenAIEmbeddings()
# vectorstore = FAISS.from_texts(["初始文本"], embedding)
# retriever = vectorstore.as_retriever()
# 
# # 创建向量检索记忆
# vector_memory = VectorStoreRetrieverMemory(retriever=retriever)
# 
# # 添加记忆
# vector_memory.save_context(
#     {"input": "重要信息"}, 
#     {"output": "这是需要记住的重要信息"}
# )

特殊记忆类型

1. CombinedMemory (组合记忆)

特点
  • 多重记忆: 同时使用多种记忆类型
  • 灵活组合: 可以根据需要组合不同记忆
  • 功能丰富: 提供更丰富的记忆管理功能
使用示例
from langchain.memory import CombinedMemory, ConversationBufferMemory, ConversationSummaryMemory
from langchain_openai import ChatOpenAI

# 创建不同类型的记忆
buffer_memory = ConversationBufferMemory(memory_key="chat_history")
summary_memory = ConversationSummaryMemory(
    llm=ChatOpenAI(temperature=0.3),
    memory_key="chat_summary"
)

# 组合记忆
combined_memory = CombinedMemory(memories=[buffer_memory, summary_memory])

# 使用组合记忆
combined_memory.save_context(
    {"input": "你好"}, 
    {"output": "你好!有什么可以帮助你的吗?"}
)

# 加载所有记忆
all_memories = combined_memory.load_memory_variables({})
print(all_memories)

2. ReadOnlySharedMemory (只读共享记忆)

特点
  • 只读访问: 提供对其他记忆的只读访问
  • 共享机制: 允许多个组件共享同一记忆
  • 安全性: 防止意外修改共享记忆
使用示例
from langchain.memory import ConversationBufferMemory, ReadOnlySharedMemory

# 创建基础记忆
base_memory = ConversationBufferMemory()

# 创建只读共享记忆
readonly_memory = ReadOnlySharedMemory(memory=base_memory)

# 可以读取
history = readonly_memory.load_memory_variables({})
print(history)

# 但不能直接保存(需要通过基础记忆)
# readonly_memory.save_context(...)  # 这会失败

记忆类型选择指南

选择标准

场景 推荐记忆类型 原因
短对话(<10轮) ConversationBufferMemory 简单直接,完整保留历史
中等对话(10-50轮) ConversationBufferWindowMemory 控制内存使用,保留近期历史
长对话(>50轮) ConversationSummaryMemory 固定内存使用,保持语义
复杂场景 ConversationSummaryBufferMemory 平衡近期细节和历史概要
知识检索 VectorStoreRetrieverMemory 基于语义的相关性检索

性能对比

import time
from langchain.memory import (
    ConversationBufferMemory,
    ConversationBufferWindowMemory,
    ConversationSummaryMemory
)
from langchain_openai import ChatOpenAI

# 性能测试函数
def test_memory_performance(memory, rounds=100):
    start_time = time.time()
    
    for i in range(rounds):
        memory.save_context(
            {"input": f"测试问题{i}"}, 
            {"output": f"测试回答{i}"}
        )
    
    end_time = time.time()
    return end_time - start_time

# 测试不同记忆类型的性能
# buffer_time = test_memory_performance(ConversationBufferMemory())
# window_time = test_memory_performance(ConversationBufferWindowMemory(k=10))
# summary_time = test_memory_performance(
#     ConversationSummaryMemory(llm=ChatOpenAI(temperature=0.3))
# )

# print(f"缓冲记忆时间: {buffer_time:.2f}秒")
# print(f"窗口记忆时间: {window_time:.2f}秒")
# print(f"摘要记忆时间: {summary_time:.2f}秒")

实际应用场景

1. 客服系统记忆管理

from langchain.memory import ConversationBufferWindowMemory

# 客服系统使用窗口记忆
customer_service_memory = ConversationBufferWindowMemory(
    k=10,  # 保存最近10轮对话
    memory_key="service_history"
)

# 模拟客服对话
customer_service_memory.save_context(
    {"input": "我的订单没有收到"}, 
    {"output": "很抱歉听到这个问题,请提供您的订单号。"}
)

customer_service_memory.save_context(
    {"input": "订单号是12345"}, 
    {"output": "正在查询订单12345的状态..."}
)

2. 教育辅导系统

from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI

# 教育系统使用摘要记忆
tutor_memory = ConversationSummaryMemory(
    llm=ChatOpenAI(temperature=0.3),
    memory_key="learning_history"
)

# 保存学习过程
tutor_memory.save_context(
    {"input": "请解释牛顿第一定律"}, 
    {"output": "牛顿第一定律也称为惯性定律..."}
)

tutor_memory.save_context(
    {"input": "能给我一个例子吗?"}, 
    {"output": "比如汽车突然刹车时,乘客会向前倾..."}
)

3. 个人助手应用

from langchain.memory import CombinedMemory, ConversationBufferMemory, ConversationSummaryMemory
from langchain_openai import ChatOpenAI

# 个人助手使用组合记忆
# 近期详细记忆
recent_memory = ConversationBufferMemory(
    memory_key="recent_conversation"
)

# 长期摘要记忆
long_term_memory = ConversationSummaryMemory(
    llm=ChatOpenAI(temperature=0.3),
    memory_key="conversation_summary"
)

# 组合记忆
personal_assistant_memory = CombinedMemory(
    memories=[recent_memory, long_term_memory]
)

最佳实践

1. 记忆类型选择

def choose_memory_type(conversation_length, memory_limit, importance_of_details):
    """根据需求选择合适的记忆类型"""
    if conversation_length < 10 and memory_limit == "unlimited":
        return "ConversationBufferMemory"
    elif conversation_length < 50 and memory_limit == "limited":
        return "ConversationBufferWindowMemory"
    elif conversation_length > 50 and importance_of_details == "low":
        return "ConversationSummaryMemory"
    else:
        return "ConversationSummaryBufferMemory"

# 使用示例
recommended_memory = choose_memory_type(30, "limited", "medium")
print(f"推荐的记忆类型: {recommended_memory}")

2. 记忆清理策略

class ManagedMemory:
    """带管理功能的记忆系统"""
    
    def __init__(self, memory, max_size=1000):
        self.memory = memory
        self.max_size = max_size
        self.current_size = 0
    
    def save_context(self, inputs, outputs):
        """保存上下文并管理大小"""
        # 保存前检查大小
        if self.current_size > self.max_size:
            self._cleanup_memory()
        
        self.memory.save_context(inputs, outputs)
        self.current_size += 1
    
    def _cleanup_memory(self):
        """清理记忆"""
        # 实现清理逻辑
        print("执行记忆清理")

3. 错误处理和恢复

from langchain.memory import ConversationBufferMemory
import logging

class RobustMemory:
    """健壮的记忆系统"""
    
    def __init__(self):
        self.memory = ConversationBufferMemory()
        self.logger = logging.getLogger(__name__)
    
    def safe_save_context(self, inputs, outputs):
        """安全保存上下文"""
        try:
            self.memory.save_context(inputs, outputs)
            return True
        except Exception as e:
            self.logger.error(f"保存记忆失败: {e}")
            return False
    
    def safe_load_memory(self):
        """安全加载记忆"""
        try:
            return self.memory.load_memory_variables({})
        except Exception as e:
            self.logger.error(f"加载记忆失败: {e}")
            return {"history": ""}

# 使用健壮记忆系统
# robust_memory = RobustMemory()
# success = robust_memory.safe_save_context({"input": "测试"}, {"output": "结果"})
# if success:
#     history = robust_memory.safe_load_memory()
#     print(history)

总结

LangChain 提供了丰富多样的记忆类型,每种都有其特定的用途和优势。选择合适的记忆类型对于构建高效、可靠的对话系统至关重要:

  1. 理解各种记忆类型的特点和适用场景
  2. 根据应用需求选择最合适的记忆类型
  3. 合理配置记忆参数以优化性能
  4. 实现适当的错误处理和内存管理
  5. 在必要时使用组合记忆来满足复杂需求

通过深入理解和正确使用这些记忆类型,我们可以构建出更加智能和用户友好的应用程序。

Memory 集成应用

概述

在实际应用中,Memory 需要与 Chains、Agents 等 LangChain 组件紧密集成,才能发挥其最大价值。本章将详细介绍如何在不同场景下有效地集成和使用 Memory 系统。

在 Chains 中集成 Memory

1. ConversationChain 集成

from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory

# 创建带记忆的对话链
llm = ChatOpenAI(temperature=0.7)
memory = ConversationBufferMemory()

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

# 使用对话链
# response1 = conversation.predict(input="你好,我叫小明")
# response2 = conversation.predict(input="我刚才说了什么?")
# print(response2)

2. 自定义 Chain 中集成 Memory

from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory
from langchain_openai import ChatOpenAI

# 创建自定义提示词模板
template = """你是一个友好的助手,会记住之前的对话。
对话历史:
{chat_history}
用户: {user_input}
助手:"""

prompt = PromptTemplate(
    input_variables=["chat_history", "user_input"],
    template=template
)

# 创建带记忆的自定义链
llm = ChatOpenAI(temperature=0.7)
memory = ConversationBufferMemory(memory_key="chat_history")

custom_chain = LLMChain(
    llm=llm,
    prompt=prompt,
    memory=memory,
    verbose=True
)

# 使用自定义链
# result = custom_chain.run(user_input="我最喜欢的编程语言是 Python")
# result = custom_chain.run(user_input="我刚才说了什么?")

3. 复杂 Chain 中的 Memory 管理

from langchain.chains import SequentialChain
from langchain.memory import ConversationBufferMemory
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain.chains import LLMChain

# 创建多个链
llm = ChatOpenAI(temperature=0.7)

# 第一个链:理解用户需求
understand_template = PromptTemplate(
    input_variables=["user_input", "conversation_history"],
    template="基于对话历史理解用户需求:\n历史: {conversation_history}\n当前: {user_input}\n需求:"
)
understand_chain = LLMChain(
    llm=llm,
    prompt=understand_template,
    output_key="understood_need"
)

# 第二个链:生成响应
respond_template = PromptTemplate(
    input_variables=["understood_need"],
    template="基于理解的需求生成友好响应:\n需求: {understood_need}\n响应:"
)
respond_chain = LLMChain(
    llm=llm,
    prompt=respond_template,
    output_key="final_response"
)

# 创建共享记忆
shared_memory = ConversationBufferMemory(memory_key="conversation_history")

# 创建顺序链
sequential_chain = SequentialChain(
    chains=[understand_chain, respond_chain],
    input_variables=["user_input"],
    output_variables=["final_response"],
    memory=shared_memory,
    verbose=True
)

# 使用顺序链
# result = sequential_chain({"user_input": "我想学习Python编程"})
# print(result["final_response"])

在 Agents 中集成 Memory

1. 基础 Agent Memory 集成

from langchain.agents import AgentType, initialize_agent
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationBufferMemory
from langchain.tools import Tool

# 创建工具
def calculator_func(expression):
    """计算器工具"""
    try:
        result = eval(expression)
        return str(result)
    except:
        return "计算出错"

calculator_tool = Tool(
    name="Calculator",
    func=calculator_func,
    description="用于执行数学计算的工具"
)

# 创建带记忆的 Agent
llm = ChatOpenAI(temperature=0.7)
memory = ConversationBufferMemory(memory_key="chat_history")

agent = initialize_agent(
    tools=[calculator_tool],
    llm=llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=memory,
    verbose=True
)

# 使用 Agent
# result = agent.run("我叫小红,15岁,计算一下我的年龄的平方")
# result = agent.run("我刚才说了我叫什么?")

2. 高级 Agent Memory 配置

from langchain.agents import AgentType, initialize_agent
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationSummaryMemory
from langchain.tools import Tool

# 创建工具
def web_search(query):
    """网络搜索工具"""
    return f"关于'{query}'的搜索结果显示:这是一个示例搜索结果。"

search_tool = Tool(
    name="WebSearch",
    func=web_search,
    description="用于搜索网络信息的工具"
)

# 创建带摘要记忆的高级 Agent
llm = ChatOpenAI(temperature=0.3)
summary_memory = ConversationSummaryMemory(
    llm=llm,
    memory_key="chat_history",
    input_key="input"
)

advanced_agent = initialize_agent(
    tools=[search_tool],
    llm=llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=summary_memory,
    verbose=True,
    max_iterations=5
)

# 使用高级 Agent
# result = advanced_agent.run("请搜索人工智能的最新发展")
# result = advanced_agent.run("刚才搜索了什么内容?")

3. 多 Agent 协作中的 Memory 共享

from langchain.agents import AgentType, initialize_agent
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationBufferMemory
from langchain.tools import Tool

# 创建共享记忆
shared_memory = ConversationBufferMemory(memory_key="shared_context")

# 创建多个 Agent
llm = ChatOpenAI(temperature=0.7)

# 技术专家 Agent
tech_expert = initialize_agent(
    tools=[],  # 技术相关工具
    llm=llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=shared_memory,
    verbose=True
)

# 商业专家 Agent
business_expert = initialize_agent(
    tools=[],  # 商业相关工具
    llm=llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=shared_memory,
    verbose=True
)

# 协调者 Agent
coordinator = initialize_agent(
    tools=[],  # 可以调用其他 Agent
    llm=llm,
    agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
    memory=shared_memory,
    verbose=True
)

Memory 与外部系统的集成

1. 数据库存储集成

from langchain.memory import ConversationBufferMemory
import sqlite3
import json

class DatabaseMemory:
    """基于数据库的记忆系统"""
    
    def __init__(self, db_path="memory.db"):
        self.db_path = db_path
        self._init_db()
    
    def _init_db(self):
        """初始化数据库"""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS conversations (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                session_id TEXT,
                role TEXT,
                content TEXT,
                timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        conn.commit()
        conn.close()
    
    def save_message(self, session_id, role, content):
        """保存消息到数据库"""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cursor.execute(
            "INSERT INTO conversations (session_id, role, content) VALUES (?, ?, ?)",
            (session_id, role, content)
        )
        conn.commit()
        conn.close()
    
    def load_conversation(self, session_id):
        """从数据库加载对话历史"""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        cursor.execute(
            "SELECT role, content FROM conversations WHERE session_id = ? ORDER BY timestamp",
            (session_id,)
        )
        messages = cursor.fetchall()
        conn.close()
        
        # 格式化为对话历史
        history = ""
        for role, content in messages:
            history += f"{role}: {content}\n"
        
        return history

# 使用数据库记忆
# db_memory = DatabaseMemory()
# db_memory.save_message("session_001", "Human", "你好")
# db_memory.save_message("session_001", "AI", "你好!有什么可以帮助你的吗?")
# history = db_memory.load_conversation("session_001")
# print(history)

2. Redis 缓存集成

# 注意:需要安装 redis
# pip install redis

import redis
import json
from langchain.memory import ConversationBufferMemory

class RedisMemory:
    """基于 Redis 的记忆系统"""
    
    def __init__(self, host='localhost', port=6379, db=0):
        self.redis_client = redis.Redis(host=host, port=port, db=db)
        self.memory_key_prefix = "conversation:"
    
    def save_context(self, session_id, inputs, outputs):
        """保存上下文到 Redis"""
        key = f"{self.memory_key_prefix}{session_id}"
        
        # 创建消息记录
        message = {
            "input": inputs.get("input", ""),
            "output": outputs.get("output", ""),
            "timestamp": __import__('time').time()
        }
        
        # 将消息添加到列表中
        self.redis_client.lpush(key, json.dumps(message))
        
        # 限制列表长度(只保留最近100条)
        self.redis_client.ltrim(key, 0, 99)
    
    def load_memory_variables(self, session_id):
        """从 Redis 加载记忆"""
        key = f"{self.memory_key_prefix}{session_id}"
        
        # 获取所有消息
        messages = self.redis_client.lrange(key, 0, -1)
        
        # 构建对话历史
        history = ""
        for message_json in reversed(messages):  # 反向以获得正确顺序
            message = json.loads(message_json)
            history += f"Human: {message['input']}\nAI: {message['output']}\n"
        
        return {"history": history}
    
    def clear_session(self, session_id):
        """清空会话记忆"""
        key = f"{self.memory_key_prefix}{session_id}"
        self.redis_client.delete(key)

# 使用 Redis 记忆
# redis_memory = RedisMemory()
# redis_memory.save_context("session_001", {"input": "你好"}, {"output": "你好!"})
# memory_vars = redis_memory.load_memory_variables("session_001")
# print(memory_vars)

多用户记忆管理

1. 会话隔离

from langchain.memory import ConversationBufferMemory
from typing import Dict

class MultiUserMemoryManager:
    """多用户记忆管理器"""
    
    def __init__(self):
        self.user_memories: Dict[str, ConversationBufferMemory] = {}
    
    def get_user_memory(self, user_id: str) -> ConversationBufferMemory:
        """获取用户记忆"""
        if user_id not in self.user_memories:
            self.user_memories[user_id] = ConversationBufferMemory(
                memory_key=f"user_{user_id}_history"
            )
        return self.user_memories[user_id]
    
    def save_user_context(self, user_id: str, inputs: dict, outputs: dict):
        """保存用户上下文"""
        memory = self.get_user_memory(user_id)
        memory.save_context(inputs, outputs)
    
    def load_user_memory(self, user_id: str) -> dict:
        """加载用户记忆"""
        memory = self.get_user_memory(user_id)
        return memory.load_memory_variables({})
    
    def clear_user_memory(self, user_id: str):
        """清空用户记忆"""
        if user_id in self.user_memories:
            self.user_memories[user_id].clear()
            del self.user_memories[user_id]

# 使用多用户记忆管理器
# memory_manager = MultiUserMemoryManager()
# memory_manager.save_user_context("user_001", {"input": "你好"}, {"output": "你好!"})
# memory_manager.save_user_context("user_002", {"input": "Hi"}, {"output": "Hi there!"})
# 
# user1_memory = memory_manager.load_user_memory("user_001")
# user2_memory = memory_manager.load_user_memory("user_002")
# 
# print("用户1记忆:", user1_memory)
# print("用户2记忆:", user2_memory)

2. 用户记忆持久化

import json
import os
from langchain.memory import ConversationBufferMemory

class PersistentUserMemory:
    """持久化用户记忆"""
    
    def __init__(self, storage_dir="./user_memories"):
        self.storage_dir = storage_dir
        os.makedirs(storage_dir, exist_ok=True)
    
    def _get_memory_file_path(self, user_id: str) -> str:
        """获取用户记忆文件路径"""
        return os.path.join(self.storage_dir, f"{user_id}_memory.json")
    
    def save_user_memory(self, user_id: str, memory: ConversationBufferMemory):
        """保存用户记忆到文件"""
        file_path = self._get_memory_file_path(user_id)
        
        # 获取记忆内容
        memory_content = memory.load_memory_variables({})
        
        # 保存到文件
        with open(file_path, 'w', encoding='utf-8') as f:
            json.dump(memory_content, f, ensure_ascii=False, indent=2)
    
    def load_user_memory(self, user_id: str) -> ConversationBufferMemory:
        """从文件加载用户记忆"""
        file_path = self._get_memory_file_path(user_id)
        
        # 创建新的记忆实例
        memory = ConversationBufferMemory()
        
        # 如果文件存在,加载内容
        if os.path.exists(file_path):
            with open(file_path, 'r', encoding='utf-8') as f:
                memory_content = json.load(f)
                # 这里需要根据具体实现恢复记忆状态
                # 简化处理:直接设置历史
                if "history" in memory_content:
                    # 注意:这只是一个示例,实际实现可能需要更复杂的逻辑
                    pass
        
        return memory
    
    def delete_user_memory(self, user_id: str):
        """删除用户记忆文件"""
        file_path = self._get_memory_file_path(user_id)
        if os.path.exists(file_path):
            os.remove(file_path)

# 使用持久化用户记忆
# persistent_memory = PersistentUserMemory()
# user_memory = ConversationBufferMemory()
# user_memory.save_context({"input": "你好"}, {"output": "你好!"})
# 
# # 保存记忆
# persistent_memory.save_user_memory("user_001", user_memory)
# 
# # 加载记忆
# loaded_memory = persistent_memory.load_user_memory("user_001")

记忆的高级应用

1. 个性化记忆系统

from langchain.memory import ConversationBufferMemory
from typing import Dict, Any
import json

class PersonalizedMemory:
    """个性化记忆系统"""
    
    def __init__(self, user_id: str):
        self.user_id = user_id
        self.conversation_memory = ConversationBufferMemory()
        self.user_preferences = {}
        self.user_profile = {}
    
    def save_conversation_context(self, inputs: dict, outputs: dict):
        """保存对话上下文"""
        self.conversation_memory.save_context(inputs, outputs)
    
    def update_user_preferences(self, preferences: Dict[str, Any]):
        """更新用户偏好"""
        self.user_preferences.update(preferences)
    
    def update_user_profile(self, profile: Dict[str, Any]):
        """更新用户画像"""
        self.user_profile.update(profile)
    
    def get_personalized_context(self) -> Dict[str, Any]:
        """获取个性化上下文"""
        return {
            "conversation_history": self.conversation_memory.load_memory_variables({}),
            "user_preferences": self.user_preferences,
            "user_profile": self.user_profile
        }
    
    def save_to_file(self, file_path: str):
        """保存到文件"""
        context = self.get_personalized_context()
        with open(file_path, 'w', encoding='utf-8') as f:
            json.dump(context, f, ensure_ascii=False, indent=2)
    
    def load_from_file(self, file_path: str):
        """从文件加载"""
        if os.path.exists(file_path):
            with open(file_path, 'r', encoding='utf-8') as f:
                context = json.load(f)
                # 恢复各个部分的状态
                # 这里需要根据具体实现进行恢复

# 使用个性化记忆系统
# personalized_memory = PersonalizedMemory("user_001")
# personalized_memory.save_conversation_context(
#     {"input": "我喜欢科技新闻"}, 
#     {"output": "好的,我会为你推荐更多科技相关内容"}
# )
# personalized_memory.update_user_preferences({
#     "news_categories": ["科技", "互联网"],
#     "response_style": "简洁"
# })
# 
# context = personalized_memory.get_personalized_context()
# print(json.dumps(context, ensure_ascii=False, indent=2))

2. 记忆分析和优化

from langchain.memory import ConversationBufferMemory
from typing import List, Dict
import re

class MemoryAnalyzer:
    """记忆分析器"""
    
    def __init__(self, memory: ConversationBufferMemory):
        self.memory = memory
    
    def analyze_conversation_patterns(self) -> Dict[str, Any]:
        """分析对话模式"""
        history = self.memory.load_memory_variables({})
        history_text = history.get("history", "")
        
        # 统计信息
        stats = {
            "total_exchanges": 0,
            "total_words": 0,
            "avg_words_per_exchange": 0,
            "most_common_words": [],
            "conversation_topics": []
        }
        
        # 分析对话交换次数
        exchanges = re.findall(r'Human: .*?\nAI: .*?(?=\nHuman: |\Z)', history_text, re.DOTALL)
        stats["total_exchanges"] = len(exchanges)
        
        # 分析词汇数量
        words = re.findall(r'\b\w+\b', history_text)
        stats["total_words"] = len(words)
        
        if stats["total_exchanges"] > 0:
            stats["avg_words_per_exchange"] = stats["total_words"] / (stats["total_exchanges"] * 2)
        
        # 简单的关键词提取
        common_words = ["你好", "什么", "怎么", "可以", "需要"]
        stats["most_common_words"] = [word for word in common_words if word in history_text]
        
        return stats
    
    def suggest_memory_optimization(self) -> List[str]:
        """建议记忆优化策略"""
        stats = self.analyze_conversation_patterns()
        suggestions = []
        
        if stats["total_exchanges"] > 50:
            suggestions.append("考虑使用 ConversationSummaryMemory 来控制内存使用")
        
        if stats["avg_words_per_exchange"] > 100:
            suggestions.append("对话内容较长,建议使用窗口记忆限制历史长度")
        
        return suggestions

# 使用记忆分析器
# memory = ConversationBufferMemory()
# memory.save_context({"input": "你好"}, {"output": "你好!有什么可以帮助你的吗?"})
# memory.save_context({"input": "我想了解人工智能"}, {"output": "人工智能是..."})
# 
# analyzer = MemoryAnalyzer(memory)
# patterns = analyzer.analyze_conversation_patterns()
# optimizations = analyzer.suggest_memory_optimization()
# 
# print("对话模式分析:", patterns)
# print("优化建议:", optimizations)

实际应用场景

1. 智能客服系统

from langchain.memory import ConversationBufferWindowMemory
from langchain_openai import ChatOpenAI
from langchain.agents import AgentType, initialize_agent

class CustomerServiceSystem:
    """智能客服系统"""
    
    def __init__(self):
        self.llm = ChatOpenAI(temperature=0.3)
        self.memory = ConversationBufferWindowMemory(
            k=10,  # 保存最近10轮对话
            memory_key="service_history"
        )
        
        self.agent = initialize_agent(
            tools=[],  # 客服相关工具
            llm=self.llm,
            agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
            memory=self.memory,
            verbose=True
        )
    
    def handle_customer_inquiry(self, customer_id: str, inquiry: str) -> str:
        """处理客户咨询"""
        # 可以在这里集成用户识别和个性化逻辑
        response = self.agent.run(inquiry)
        return response

# 使用客服系统
#客服系统 = CustomerServiceSystem()
# response1 = 客服系统.handle_customer_inquiry("customer_001", "我的订单状态如何?")
# response2 = 客服系统.handle_customer_inquiry("customer_001", "刚才我问了什么?")

2. 教育辅导系统

from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain

class TutoringSystem:
    """教育辅导系统"""
    
    def __init__(self):
        self.llm = ChatOpenAI(temperature=0.3)
        self.memory = ConversationSummaryMemory(
            llm=self.llm,
            memory_key="learning_history"
        )
        
        self.tutor = ConversationChain(
            llm=self.llm,
            memory=self.memory,
            verbose=True
        )
    
    def provide_tutoring(self, student_id: str, question: str) -> str:
        """提供辅导"""
        # 可以根据学生历史调整教学策略
        response = self.tutor.predict(input=question)
        return response
    
    def get_learning_summary(self, student_id: str) -> str:
        """获取学习总结"""
        history = self.memory.load_memory_variables({})
        return history.get("history", "暂无学习记录")

# 使用辅导系统
# 教学系统 = TutoringSystem()
# response1 = 教学系统.provide_tutoring("student_001", "请解释牛顿第二定律")
# response2 = 教学系统.provide_tutoring("student_001", "能再详细说明一下吗?")
# summary = 教学系统.get_learning_summary("student_001")

3. 个人助手应用

from langchain.memory import CombinedMemory, ConversationBufferMemory, ConversationSummaryMemory
from langchain_openai import ChatOpenAI
from langchain.agents import AgentType, initialize_agent

class PersonalAssistant:
    """个人助手"""
    
    def __init__(self):
        self.llm = ChatOpenAI(temperature=0.7)
        
        # 组合记忆:近期详细 + 长期摘要
        recent_memory = ConversationBufferMemory(
            memory_key="recent_conversation"
        )
        long_term_memory = ConversationSummaryMemory(
            llm=ChatOpenAI(temperature=0.3),
            memory_key="conversation_summary"
        )
        
        self.combined_memory = CombinedMemory(
            memories=[recent_memory, long_term_memory]
        )
        
        self.agent = initialize_agent(
            tools=[],  # 个人助手工具
            llm=self.llm,
            agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
            memory=self.combined_memory,
            verbose=True
        )
    
    def assist_user(self, user_id: str, request: str) -> str:
        """协助用户"""
        response = self.agent.run(request)
        return response

# 使用个人助手
# 助手 = PersonalAssistant()
# response1 = 助手.assist_user("user_001", "提醒我明天下午3点开会")
# response2 = 助手.assist_user("user_001", "我刚才让你提醒我什么?")

最佳实践

1. 记忆系统设计原则

class MemoryDesignPrinciples:
    """记忆系统设计原则"""
    
    @staticmethod
    def choose_appropriate_memory_type(conversation_length: int, memory_limit: str) -> str:
        """根据需求选择合适的记忆类型"""
        if conversation_length < 10:
            return "ConversationBufferMemory"
        elif conversation_length < 50:
            return "ConversationBufferWindowMemory"
        else:
            return "ConversationSummaryMemory"
    
    @staticmethod
    def implement_error_handling():
        """实现错误处理"""
        try:
            # 记忆操作
            pass
        except Exception as e:
            print(f"记忆操作出错: {e}")
            # 降级处理或恢复机制
    
    @staticmethod
    def optimize_memory_usage():
        """优化内存使用"""
        # 定期清理过期记忆
        # 使用适当的记忆类型
        # 实现内存监控
        pass

2. 性能监控和优化

import time
from typing import Callable

class MemoryPerformanceMonitor:
    """记忆性能监控器"""
    
    def __init__(self):
        self.performance_metrics = {
            "save_operations": [],
            "load_operations": [],
            "memory_usage": []
        }
    
    def monitor_operation(self, operation_name: str):
        """监控操作性能"""
        def decorator(func: Callable):
            def wrapper(*args, **kwargs):
                start_time = time.time()
                try:
                    result = func(*args, **kwargs)
                    end_time = time.time()
                    duration = end_time - start_time
                    
                    # 记录性能指标
                    self.performance_metrics[operation_name].append(duration)
                    
                    return result
                except Exception as e:
                    end_time = time.time()
                    duration = end_time - start_time
                    self.performance_metrics[operation_name].append(duration)
                    raise e
            return wrapper
        return decorator
    
    def get_performance_report(self) -> dict:
        """获取性能报告"""
        report = {}
        for operation, times in self.performance_metrics.items():
            if times:
                report[operation] = {
                    "total_calls": len(times),
                    "avg_duration": sum(times) / len(times),
                    "min_duration": min(times),
                    "max_duration": max(times)
                }
        return report

# 使用性能监控器
# monitor = MemoryPerformanceMonitor()
# 
# @monitor.monitor_operation("save_context")
# def save_context_with_monitoring(memory, inputs, outputs):
#     memory.save_context(inputs, outputs)
# 
# # 使用监控函数
# memory = ConversationBufferMemory()
# save_context_with_monitoring(memory, {"input": "测试"}, {"output": "结果"})
# 
# # 获取性能报告
# report = monitor.get_performance_report()
# print(report)

3. 安全和隐私考虑

from langchain.memory import ConversationBufferMemory
import hashlib

class SecureMemory:
    """安全记忆系统"""
    
    def __init__(self, encryption_key: str = None):
        self.memory = ConversationBufferMemory()
        self.encryption_key = encryption_key
    
    def _encrypt_data(self, data: str) -> str:
        """加密数据"""
        if self.encryption_key:
            # 简化的加密示例(实际应用中应使用强加密算法)
            return hashlib.sha256((data + self.encryption_key).encode()).hexdigest()
        return data
    
    def _decrypt_data(self, encrypted_data: str) -> str:
        """解密数据(简化示例)"""
        # 实际应用中需要实现真正的解密逻辑
        return encrypted_data
    
    def save_secure_context(self, inputs: dict, outputs: dict):
        """安全保存上下文"""
        # 加密敏感信息
        encrypted_inputs = {k: self._encrypt_data(str(v)) for k, v in inputs.items()}
        encrypted_outputs = {k: self._encrypt_data(str(v)) for k, v in outputs.items()}
        
        self.memory.save_context(encrypted_inputs, encrypted_outputs)
    
    def load_secure_memory(self) -> dict:
        """安全加载记忆"""
        # 注意:这里返回的是加密数据,实际应用中需要解密
        return self.memory.load_memory_variables({})

# 使用安全记忆系统
# secure_memory = SecureMemory(encryption_key="my_secret_key")
# secure_memory.save_secure_context({"input": "敏感信息"}, {"output": "机密回复"})
# secure_data = secure_memory.load_secure_memory()

总结

Memory 在 LangChain 应用中的集成是构建智能对话系统的关键环节。通过本章的学习,我们了解了:

  1. 在 Chains 和 Agents 中正确集成 Memory 的方法
  2. 与外部存储系统(数据库、Redis等)的集成方式
  3. 多用户记忆管理和个性化记忆系统的设计
  4. 记忆系统的高级应用和优化策略
  5. 实际应用场景中的最佳实践

关键要点包括:

  • 根据应用需求选择合适的记忆类型
  • 实现适当的错误处理和恢复机制
  • 考虑性能优化和内存管理
  • 关注安全和隐私保护
  • 建立监控和分析机制

通过合理设计和实现记忆系统,我们可以创建出更加智能、个性化和用户友好的应用程序。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐