第 13 期:赋予长期记忆 — Window Buffer Memory 与对话状态持久化

⏱ 预计阅读 10 分钟 更新于 2026/4/9

为什么 AI Agent 需要记忆?

大模型本身是无状态的——每次调用都是全新的,它不记得上一秒你说了什么。如果不引入 Memory,你的 AI 对话将变成:

sequenceDiagram
    participant User as 👤 用户
    participant AI as 🤖 无记忆 Agent
    
    User->>AI: 我叫张三
    AI-->>User: 你好张三!有什么需要帮助的?
    User->>AI: 我刚才告诉你我叫什么?
    AI-->>User: 抱歉,我不知道你叫什么。😅
    Note over AI: 完全失忆!每次对话都是独立的

Memory 节点的作用就是在每次 LLM 调用前,把历史对话注入到 Prompt 中,让模型"看起来"记得之前说过的话。


1. Window Buffer Memory

最常用的记忆策略。它维护一个固定大小的"滑动窗口",只保留最近 N 条消息。

graph TB
    subgraph "Window Buffer Memory (窗口大小 = 6)"
        direction LR
        
        subgraph "第1轮"
            M1["👤 你好"]
            M2["🤖 你好!"]
        end
        
        subgraph "第2轮"
            M3["👤 天气如何?"]
            M4["🤖 北京今天晴"]
        end
        
        subgraph "第3轮"
            M5["👤 明天呢?"]
            M6["🤖 明天多云"]
        end
        
        subgraph "第4轮 (窗口滑动!)"
            M7["👤 后天呢?"]
            M8["🤖 后天有雨"]
        end
    end
    
    M1 -.->|"❌ 被移出窗口"| Trash[🗑️]
    M2 -.->|"❌ 被移出窗口"| Trash
    
    style Trash fill:#ef4444,stroke:#dc2626,color:#fff
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// Window Buffer Memory 配置详解
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

// 📝 参数说明:
// - Context Window Length: 10
//   含义: 保留最近 10 条消息 (= 5 轮对话,每轮 1 问 + 1 答)
//   ⚠️ 窗口太大 → Token 消耗高,成本增加
//   ⚠️ 窗口太小 → Agent 很快忘记上文

// - Session ID Key: sessionId
//   含义: 用于隔离不同用户/不同聊天窗口的记忆
//   引用: {{ $json.sessionId }}
//   效果: 用户 A 的记忆不会泄露给用户 B

// - Session ID: {{ $json.sessionId }}
//   来源: 通常从 Chat Trigger 的输出中获取

窗口大小选择指南

场景 推荐窗口大小 理由
快速问答 (FAQ) 4-6 条 用户通常只需 2-3 轮就能得到答案
技术支持 10-20 条 需要记住问题描述与排查过程
深度咨询 30-50 条 需要完整的对话上下文
闲聊 / 陪伴 20-30 条 保持人格一致性

2. Session 隔离机制

graph TB
    subgraph "多用户场景的 Session 隔离"
        CT[💬 Chat Trigger]
        
        CT -->|"sessionId: user_alice"| Agent
        CT -->|"sessionId: user_bob"| Agent
        CT -->|"sessionId: user_carol"| Agent
        
        Agent[🤖 AI Agent]
        Agent --> Memory[💾 Window Buffer Memory]
        
        Memory --> S1["📂 Session: user_alice
[你好, 查天气, ...]"] Memory --> S2["📂 Session: user_bob
[帮我写代码, ...]"] Memory --> S3["📂 Session: user_carol
[产品报价, ...]"] end style Memory fill:#22c55e,stroke:#16a34a,color:#fff
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// Session ID 的生成策略
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

// 策略 1: 使用 Chat Trigger 自动生成的 ID (最简单)
// {{ $json.sessionId }}

// 策略 2: 基于用户身份 (适合多渠道)
// {{ $json.platform + '_' + $json.userId }}
// 例: "telegram_12345" 或 "web_67890"

// 策略 3: 基于对话主题 (适合工单系统)
// {{ $json.ticketId }}
// 同一工单的所有对话共享记忆

3. Memory 在 LLM 调用中的实际效果

理解 Memory 的本质:它只是在每次调用 LLM 时,把历史消息注入到消息数组中

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 无 Memory 时,发给 LLM 的消息:
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const messagesWithoutMemory = [
  { role: "system", content: "你是一个 AI 助手" },
  { role: "user", content: "明天天气怎么样?" }    // 只有当前消息
];
// → 模型不知道用户之前问的是北京还是上海

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 有 Memory 时,发给 LLM 的消息:
// Memory 自动注入历史对话到消息数组中
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const messagesWithMemory = [
  { role: "system", content: "你是一个 AI 助手" },
  
  // ↓↓↓ Memory 自动注入的历史 ↓↓↓
  { role: "user", content: "帮我查一下北京的天气" },     // 历史消息 1
  { role: "assistant", content: "北京今天晴,28°C" },     // 历史消息 2
  // ↑↑↑ Memory 注入结束 ↑↑↑
  
  { role: "user", content: "明天呢?" }                   // 当前消息
];
// → 模型看到完整上下文,知道"明天呢"指的是"北京明天的天气"

4. 记忆清除与管理

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 在工作流中主动清除某个 Session 的记忆
// 适用场景: 用户说"重新开始" / 工单关闭时清理
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

// 方法: 在 Code 节点中通过 n8n 内部 API 操作
// 或者在 Agent System Prompt 中定义:
// "当用户说'重新开始'时,回复'好的,让我们重新开始吧!'并忽略之前的对话内容。"

// ⚠️ 注意: Memory 默认存储在 n8n 的内存中
// 容器重启后所有 Memory 会丢失!
// 生产环境建议使用外部存储 (如 Redis)

Memory 类型对比

Memory 类型 原理 优点 缺点
Window Buffer 保留最近 N 条消息 简单可靠、开箱即用 窗口外的内容完全丢失
Token Buffer 按 Token 数量截断 精确控制 LLM 上下文 配置略复杂
Summary 用 LLM 生成历史摘要 能保留更长历史要点 摘要可能丢细节,额外调用成本
Vector Store 将历史嵌入向量数据库 实现真正的"长期记忆" 需要配置向量数据库

下一步

在 Ep 14 中,我们将给 Agent 配备真正的外部工具 (Tools)——让它不仅能"说",还能"做":计算、搜索、调用 API。