AI Agent 记忆机制:让AI更懂你

人类的智能很大程度依赖于记忆。AI Agent 同样需要一个完整的记忆系统来保持上下文、积累知识、持续学习。

为什么 AI Agent 需要记忆?

大模型的上下文窗口是有限的(通常 128K-1M tokens)。当对话变长、任务变复杂时,AI 会面临:

  • 上下文溢出:塞不进去
  • 重要信息遗忘:早期关键信息被稀释
  • 无法跨会话学习:每次对话都是从零开始

记忆系统的核心目标

  1. 扩展有效上下文
  2. 选择性记住重要信息
  3. 跨会话积累知识

三层记忆架构

┌─────────────────────────────────────────────────────┐
│                   记忆系统分层                       │
├─────────────────────────────────────────────────────┤
│                                                     │
│  ┌─────────────┐    上下文窗口内的信息               │
│  │  短期记忆    │    当前对话、工作内存              │
│  │ Short-term  │    容量有限,随对话结束而消失       │
│  └─────────────┘                                    │
│           ↓ 摘要/压缩                               │
│  ┌─────────────┐    持久化存储,跨会话保持           │
│  │  长期记忆    │    用户偏好、长期目标、常识        │
│  │ Long-term   │    存储在外部数据库                 │
│  └─────────────┘                                    │
│           ↑ 检索                                     │
│  ┌─────────────┐    高效相似度检索                   │
│  │  向量记忆    │    用 Embedding 存储和搜索          │
│  │ Vector Mem  │    RAG 的核心基础设施               │
│  └─────────────┘                                    │
│                                                     │
└─────────────────────────────────────────────────────┘

短期记忆:工作上下文

短期记忆是模型当前上下文窗口中的信息。

核心机制:滑动窗口 + 摘要

class ShortTermMemory:
    def __init__(self, window_size=10):
        self.messages = []      # 最近的消息列表
        self.window_size = window_size  # 保留最近N条
    
    def add(self, role, content):
        self.messages.append({"role": role, "content": content})
        # 超过窗口大小时,移除最老的或压缩
        if len(self.messages) > self.window_size:
            self.messages.pop(0)
    
    def get_context(self):
        return self.messages[-self.window_size:]
    
    def summarize_old(self, llm):
        """对旧消息做摘要,释放上下文空间"""
        if len(self.messages) <= 3:
            return
        
        old_messages = self.messages[:-3]
        summary = llm.invoke(
            f"请简要总结以下对话要点:\n{old_messages}"
        )
        
        # 保留最近3条 + 摘要
        self.messages = [{"role": "system", "content": f"之前摘要:{summary}"}] \
                       + self.messages[-3:]

何时触发摘要?

  • 消息数量超过阈值(如 20 条)
  • token 数量接近上下文窗口 80%
  • 对话主题发生转换时

长期记忆:持久化知识

长期记忆存储在外部数据库,跨会话保持。

存储结构

class LongTermMemory:
    def __init__(self, vector_db):
        self.vector_db = vector_db  # Pinecone/Milvus/Chroma
        self.structured_db = {}    # 结构化记忆:用户偏好等
    
    def store(self, content, memory_type, metadata):
        """
        memory_type: 'preference' | 'fact' | 'goal' | 'skill'
        metadata: {'user': 'xxx', 'timestamp': '...'}
        """
        # 向量化存储
        embedding = embed_model.encode(content)
        self.vector_db.add(
            vectors=[{"id": generate_id(), "values": embedding,
                     "metadata": {"content": content, 
                                  "type": memory_type,
                                  **metadata}}]
        )
        
        # 结构化索引(快速查询)
        if memory_type == 'preference':
            self.structured_db[metadata['user']] = content
    
    def retrieve(self, query, top_k=5):
        """基于语义检索记忆"""
        query_embedding = embed_model.encode(query)
        results = self.vector_db.search(
            vector=query_embedding, top_k=top_k
        )
        return [r['metadata']['content'] for r in results]
    
    def update_preference(self, user, key, value):
        """更新用户偏好"""
        if user not in self.structured_db:
            self.structured_db[user] = {}
        self.structured_db[user][key] = value

记忆类型分类

类型 说明 示例 存储方式
偏好 用户喜欢什么 喜欢详细解释 KV 结构
事实 用户的客观信息 工作是程序员 向量 + 结构
目标 用户想达成什么 备考软考高项 向量
技能 用户会什么/学过什么 会 Python 向量

向量记忆:语义检索引擎

向量记忆是记忆系统的”搜索引擎”——用 Embedding 实现相似度检索。

核心原理

import chromadb

class VectorMemory:
    def __init__(self, collection_name="agent_memory"):
        self.client = chromadb.Client()
        self.collection = self.client.create_collection(
            collection_name,
            metadata={"hnsw:space": "cosine"}  # 余弦相似度
        )
    
    def add(self, text, memory_id=None, tags=None):
        embedding = embed_model.encode(text)
        self.collection.add(
            embeddings=[embedding.tolist()],
            documents=[text],
            ids=[memory_id or generate_id()],
            metadatas=[{"tags": tags or []}]
        )
    
    def search(self, query, top_k=5, filter_tags=None):
        query_embedding = embed_model.encode(query)
        result = self.collection.query(
            query_embeddings=[query_embedding.tolist()],
            n_results=top_k,
            where={"tags": {"$in": filter_tags}} if filter_tags else None
        )
        return result['documents'], result['distances']
    
    def delete(self, memory_id):
        self.collection.delete(ids=[memory_id])

检索优化策略

1. 混合检索:语义相似度 + 关键词匹配

def hybrid_search(query, top_k=10):
    # 语义检索
    semantic_results = vector_mem.search(query, top_k=20)
    
    # BM25 关键词检索
    keyword_results = bm25_index.search(query, top_k=20)
    
    # RRF 融合
    fused = reciprocal_rank_fusion(
        [semantic_results, keyword_results],
        k=60
    )
    return fused[:top_k]

2. 时间衰减:新记忆权重更高

def time_weighted_score(distance, timestamp, half_life_days=30):
    days_old = (now - timestamp).days
    decay = 0.5 ** (days_old / half_life_days)
    return distance * decay

3. 重要性加权:区分普通对话与关键决定

def importance_weighted检索(query, importance_hint=None):
    base_results = vector_mem.search(query, top_k=20)
    
    # 重要事件(如用户明确说"记住xxx")权重翻倍
    for r in base_results:
        if r.metadata.get('importance') == 'high':
            r.score *= 0.5  # 距离变小 = 更相关
    
    return sorted(base_results, key=lambda x: x.score)

记忆系统的完整流程

┌─────────────────────────────────────────────────────────────┐
│                      AI Agent 记忆流程                       │
└─────────────────────────────────────────────────────────────┘

用户输入
    │
    ▼
┌─────────────────┐
│  检索长期记忆   │ ◄──── 跨会话积累的相关信息
└────────┬────────┘
         │ 检索结果
         ▼
┌─────────────────┐
│  构建上下文     │ ◄──── 短期记忆 + 长期记忆 + 用户输入
└────────┬────────┘
         │ 完整上下文
         ▼
┌─────────────────┐
│  LLM 生成回复   │
└────────┬────────┘
         │ 回复内容
    ┌────┴────┐
    ▼         ▼
┌───────┐ ┌───────────┐
│ 评估   │ │ 更新记忆  │
│ 重要? │ │           │
└───┬───┘ └─────┬─────┘
    │ yes       │
    ▼           ▼
重要记忆 → 长期记忆存储 ──► 向量数据库
                 │
                 └──► 结构化存储(偏好/事实)

记忆更新策略

def should_remember(content, context) -> bool:
    """判断内容是否值得记忆"""
    
    # 1. 显式标记
    if "记住" in content or "重要" in content:
        return True
    
    # 2. 重复出现
    if content_similarity(content, recent_memories) > 0.9:
        return True  # 已经有类似记忆,更新而非新增
    
    # 3. 任务关键信息
    if contains_goal(context) and contains_fact(content):
        return True
    
    # 4. 用户偏好
    if contains_preference_signal(content):
        return True
    
    return False

实战:构建完整的 Agent 记忆系统

class MemFreeAgent:
    """MemGPT 风格的 Agent 记忆系统"""
    
    def __init__(self):
        # 三个层次的记忆
        self.short_term = ShortTermMemory(window_size=10)
        self.long_term = LongTermMemory(vector_db=chroma_client)
        self.summary = ""  # 对话摘要
    
    def think(self, user_input):
        # Step 1: 检索长期记忆
        relevant_memories = self.long_term.retrieve(user_input, top_k=5)
        
        # Step 2: 构建完整上下文
        context = {
            "recent": self.short_term.get_context(),
            "memory": relevant_memories,
            "summary": self.summary,
            "preferences": self.long_term.structured_db.get('preferences', {})
        }
        
        # Step 3: LLM 生成
        prompt = self.build_prompt(user_input, context)
        response = llm.invoke(prompt)
        
        # Step 4: 更新记忆
        self.short_term.add("user", user_input)
        self.short_term.add("assistant", response)
        
        # Step 5: 定期总结
        if len(self.short_term.messages) > 15:
            self._summarize_and_store()
        
        return response
    
    def _summarize_and_store(self):
        """总结旧对话,存入长期记忆"""
        old_messages = self.short_term.messages[:-5]
        summary = llm.invoke(f"总结以下对话的关键信息:\n{old_messages}")
        
        self.long_term.store(
            content=summary,
            memory_type="conversation_summary",
            metadata={"timestamp": now()}
        )
        
        self.short_term.messages = self.short_term.messages[-5:]

💡 小结

AI Agent 的记忆系统是三层结构:

层次 容量 持久性 速度 用途
短期记忆 窗口大小 对话内 最快 当前工作上下文
长期记忆 无限制 永久 检索+解码 跨会话知识积累
向量记忆 无限制 永久 毫秒级检索 语义相似匹配

核心设计原则

  1. 按需检索:不要把所有记忆都塞进上下文
  2. 重要性过滤:只记值得记的
  3. 定期整理:摘要、压缩、遗忘
  4. 混合检索:语义 + 关键词 + 结构化

相关阅读:AI Agent 原理与实践