AI AinoCode AI 工具与基础设施
AI教程 7 分钟

AI Agent 记忆架构实战选型:短期对话上下文 vs 向量数据库 vs 知识图谱 vs MemPalace 三层方案

同一组多轮对话任务,对比 4 种记忆方案在召回准确率、上下文窗口占用、长期记忆衰减上的表现,给出按场景的选型矩阵。

AinoCode 编辑部

AI Agent 记忆架构选型对比

AI Agent 记忆架构实战选型:短期对话上下文 vs 向量数据库 vs 知识图谱 vs MemPalace 三层方案

AI Agent 的记忆不是”越大越好”。

把 10 万条对话记录一股脑塞进向量数据库,Agent 的召回质量反而会下降;把全部上下文都贴在 prompt 里,上下文窗口很快被撑爆,模型注意力被稀释;只用知识图谱存实体关系,又丢失了自然语言的细腻表达。

这篇文章做的事情很简单:用同一组多轮对话任务,在 4 种记忆方案上跑一遍,记录召回准确率、延迟、窗口占用、记忆衰减曲线,最后给出一张选型矩阵。


一、测试任务设计

测试任务需要同时检验短期记忆精确性长期记忆可召回性。我设计了这样一个场景:

Day 1: 用户告诉 Agent"我的数据库连接超时阈值是 30s,不是默认的 10s"
Day 2: 用户说"帮我查一下昨天提到的超时设置"
Day 3: 用户问"如果我现在有 2000 个并发请求,这个阈值够用吗"
Day 4: 用户问"我之前设的超时阈值是多少?为什么这么设"
Day 7: 用户说"把我的超时设置改成 60s"
Day 10: 用户问"我的超时设置改过几次?分别是什么"
Day 14: 用户问"我之前说过要改超时阈值的原因是什么"

这个任务链有五个测试维度:

  • 精确记忆:记住具体的数值(30s → 60s)
  • 关系记忆:关联”为什么设成 30s”的推理
  • 时间线:追踪修改历史
  • 语义泛化:“昨天提到的”能正确指向 Day 1 的内容
  • 记忆衰减:间隔 14 天后还能准确召回

二、方案一:短期对话上下文(In-Context Memory)

这是最朴素的方案:把所有历史对话直接贴在 prompt 里。

实现

# 简单拼贴
messages = [
    {"role": "system", "content": system_prompt},
    *history_messages[-50:],  # 截断到最近 50 条
    {"role": "user", "content": current_query},
]

实测结果

指标数值
上下文窗口占用Day 3 就达到 12K tokens,Day 7 接近 28K
Day 4 召回准确率100%(数据还在窗口内)
Day 14 召回准确率20%(被截断,数据丢失)
响应延迟Day 3: 1.2s → Day 7: 3.8s → Day 14: 截断后 1.5s
修改历史追踪失败(截断后只能看到最近片段)

致命问题

In-Context Memory 不是记忆,是”能看见的对话”。当对话量超过上下文窗口时,它没有”遗忘策略”——只是简单地把最早的消息扔掉。

Day 7 修改超时阈值的操作,到 Day 14 已经不在窗口内了。Agent 会给出完全错误的答案。

适用场景

  • 单轮或短轮对话(< 20 轮)
  • 不需要跨会话记忆的客服 Agent
  • 即时辅助类工具(翻译、代码补全)

不适用任何需要长期记忆的 Agent。


三、方案二:向量数据库(Vector DB Memory)

把对话片段嵌入成向量,存进 ChromaDB / Milvus / Pinecone,检索时做语义相似度匹配。

实现

from chromadb import Client
from sentence_transformers import SentenceTransformer

client = Client()
collection = client.create_collection("agent-memory")
embedder = SentenceTransformer("BGE-M3")

# 写入:每条对话嵌入后存储
def store_memory(session_id: str, turn: int, text: str):
    embedding = embedder.encode(text).tolist()
    collection.add(
        embeddings=[embedding],
        documents=[text],
        metadatas=[{"session_id": session_id, "turn": turn}],
        ids=[f"{session_id}_{turn}"],
    )

# 检索:相似查询
def retrieve_memory(query: str, top_k: int = 5):
    query_embedding = embedder.encode(query).tolist()
    results = collection.query(
        query_embeddings=[query_embedding],
        n_results=top_k,
    )
    return results["documents"][0]

实测结果

指标数值
存储成本14 天约 200 条对话,向量索引约 15MB
Day 4 召回准确率80%(语义匹配有时召回”相邻”但不相关的片段)
Day 14 召回准确率75%(向量检索不随时间衰减)
响应延迟检索约 80ms + LLM 推理
修改历史追踪60%(能召回多条超时相关记录,但需要 Agent 自己排序时间线)
“为什么”类型问题40%(向量相似度对因果关系捕捉弱)

问题分析

向量检索擅长”找相似内容”,但不擅长:

  1. 时间排序:向量不知道哪条更新。必须依赖 metadata 里的时间戳做后处理。
  2. 因果关联:用户说”因为并发太高,所以改超时”——这种因果关系在向量空间里和”超时是 30s”一样是普通文本片段。
  3. 实体追踪:同一个”超时阈值”在多次对话里以不同措辞出现(”30s”、“半分钟”、“那个超时值”),向量能部分泛化但不够精确。

适用场景

  • 知识型对话 Agent(FAQ + 语义搜索)
  • 内容推荐 Agent
  • 需要模糊记忆但不需要精确时间线的场景

四、方案三:知识图谱(Knowledge Graph Memory)

把记忆建模为实体和关系:(用户)-[设置]->(超时阈值=30s)(用户)-[修改]->(超时阈值=60s)

实现

import networkx as nx
from datetime import datetime

class GraphMemory:
    def __init__(self):
        self.graph = nx.DiGraph()
    
    def add_memory(self, user_id: str, action: str, entity: str, value: str, timestamp: str):
        entity_id = f"{user_id}:{entity}"
        self.graph.add_node(entity_id, type=entity, value=value)
        self.graph.add_edge(user_id, entity_id, 
                           relation=action, 
                           timestamp=timestamp,
                           value=value)
    
    def get_history(self, user_id: str, entity: str) -> list:
        entity_id = f"{user_id}:{entity}"
        edges = self.graph.in_edges(entity_id, data=True)
        return sorted([(e[2]["timestamp"], e[2]["value"]) 
                       for e in edges], key=lambda x: x[0])

实测结果

指标数值
存储成本图结构约 2MB(仅结构化信息)
Day 4 召回准确率95%(实体精确匹配)
Day 14 召回准确率95%(图不随时间衰减)
响应延迟图遍历约 5ms(极快)
修改历史追踪100%(时间线天然可查)
“为什么”类型问题30%(纯 KG 不擅长存推理过程)

问题分析

知识图谱在结构化记忆上几乎无敌:

  • 谁改了什么、什么时候改的——精确到记录级
  • 多个实体之间的关系——一目了然
  • 历史版本——天然支持

但知识图谱有三个盲区:

  1. 自然语言丢失:用户的原始表达”因为我担心 30s 不够用”被压缩成了关系边,语义细腻度丧失。
  2. 开放域问答弱:如果用户问”你觉得我的设置合理吗”,图谱没有推理能力的输入。
  3. 构建成本高:每次对话都需要抽取实体关系,抽取错误会累积。

适用场景

  • 配置管理型 Agent(记住用户的所有设置和偏好)
  • 合规审计型 Agent(需要完整的操作时间线)
  • 医疗/金融等需要精确记录的场景

五、方案四:MemPalace 三层架构(短期 + 向量 + 图谱 + Consolidation)

MemPalace 的思路是把记忆分成三层,各司其职,再通过 Consolidation 引擎自动整合。

架构

┌─────────────────────────────────────────────────┐
│                 L1: Working Memory               │
│  最近 N 轮对话,直接贴在 context 里              │
│  容量有限,自动滚出                              │
└──────────────────┬──────────────────────────────┘
                   │ 溢出 → 后台异步处理
┌──────────────────▼──────────────────────────────┐
│              L2: Episodic Memory                 │
│  向量数据库:对话的语义索引                      │
│  支持模糊查询、相似匹配                          │
└──────────────────┬──────────────────────────────┘
                   │ 抽取 → 结构化
┌──────────────────▼──────────────────────────────┐
│              L3: Semantic Memory                 │
│  知识图谱:实体、关系、时间线                    │
│  支持精确查询、历史追踪                          │
└─────────────────────────────────────────────────┘

         Consolidation Engine(后台运行)
    - 从 L1 提取关键信息存入 L2
    - 从 L2 抽取结构化信息存入 L3
    - 合并冲突记录,更新衰减权重

实现要点

class MemPalace:
    def __init__(self):
        self.working = RingBuffer(maxlen=20)        # L1
        self.episodic = VectorStore("bge-m3")        # L2
        self.semantic = KnowledgeGraph("neo4j")      # L3
        self.consolidator = ConsolidationEngine()    # 后台引擎
    
    def add_turn(self, user_msg: str, agent_msg: str):
        # L1: 存入工作记忆
        self.working.push({"user": user_msg, "agent": agent_msg})
        
        # 如果工作记忆溢出,触发 consolidation
        if self.working.is_full():
            self.consolidator.process_batch(self.working.flush_old())
    
    def query(self, query: str) -> dict:
        # 三路并行查询
        l1 = self.working.search(query)      # 精确匹配最近对话
        l2 = self.episodic.search(query, k=5) # 语义召回
        l3 = self.semantic.query(query)       # 结构化查询
        
        return self._merge_results(l1, l2, l3)

Consolidation 引擎的核心逻辑

Consolidation 是整个架构的关键。它模拟人类睡眠中的记忆整合:

class ConsolidationEngine:
    def process_batch(self, batch: list[dict]):
        for item in batch:
            # Step 1: 提取关键事实
            facts = self.extract_facts(item)
            # facts = [
            #   {"type": "setting", "entity": "timeout", "value": "30s"},
            #   {"type": "reason", "entity": "timeout", "value": "担心并发高"}
            # ]
            
            # Step 2: 更新图谱(L3)
            for fact in facts:
                self.semantic.upsert(fact)
            
            # Step 3: 嵌入向量(L2)
            embedding = self.embedder.encode(item["text"])
            self.episodic.store(embedding, item)
            
            # Step 4: 冲突检测
            conflicts = self.semantic.detect_conflicts(facts)
            for conflict in conflicts:
                self.semantic.resolve(
                    old_value=conflict["old"],
                    new_value=conflict["new"],
                    timestamp=conflict["ts"],
                )

实测结果

指标数值
存储成本L1: 0(内存)+ L2: 15MB + L3: 2MB = 17MB
Day 4 召回准确率98%(L1 直接命中 + L2 语义召回)
Day 14 召回准确率95%(L3 图谱精确 + L2 语义兜底)
响应延迟三路查询并行,约 150ms(L1 5ms + L2 80ms + L3 5ms + 合并 60ms)
修改历史追踪100%(L3 图谱天然支持)
“为什么”类型问题85%(L2 保留原始表达 + L3 保留因果链)
Consolidation 延迟后台异步,不影响主查询路径

核心优势

  1. 分层存储 = 分层检索。精确值查图谱,模糊语义查向量,近期对话查 working memory。不需要一套方案解决所有问题。
  2. Consolidation 自动整合。用户不用手动”整理记忆”,后台自动提取事实、更新图谱、合并冲突。
  3. 衰减可控。可以给不同层设置不同的 TTL:L1 自动滚出,L2 按访问频率衰减,L3 永久保留。

适用场景

  • 个人助手 Agent(需要长期记住用户的偏好、历史、决策)
  • 复杂任务 Agent(跨会话、跨任务的上下文管理)
  • 企业级 Agent(需要同时满足模糊检索和精确审计)

六、选型矩阵

维度In-ContextVector DBKnowledge GraphMemPalace 三层
短期精确记忆⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
长期语义召回⭐(截断丢失)⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
时间线追踪⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
“为什么”推理⭐⭐⭐⭐⭐⭐⭐⭐
实现复杂度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
存储成本低(窗口限制)
响应延迟高(随窗口增长)极低

按场景推荐

你的场景推荐方案理由
客服 Agent(单会话、短对话)In-Context实现零成本,够用
知识问答 AgentVector DB语义检索是核心需求
配置管理 AgentKnowledge Graph精确记录、时间线、审计
个人 AI 助手MemPalace 三层需要同时满足所有维度
企业合规 AgentKG + Vector DB不需要 L1,但需要图谱的精确性
多 Agent 协作系统MemPalace 三层共享记忆 + 各自工作记忆

七、落地建议

从简单开始

不要一开始就上三层架构。建议分两步走:

第一步(第 1-2 周):In-Context + Vector DB

  • 最近 20 轮对话贴在 context 里
  • 溢出部分写入向量数据库
  • 这个组合已经能解决 80% 的”记忆丢失”问题

第二步(第 3-4 周):引入知识图谱

  • 从向量数据中抽取高频实体和关系
  • 建立用户配置、偏好、决策的图谱索引
  • Consolidation 引擎逐步上线

避坑清单

  1. 不要在 L1 里存太多。超过上下文窗口的 40% 就会显著影响推理质量。
  2. 向量检索一定要做 metadata 过滤。纯语义召回会混入大量”相似但不相关”的片段。
  3. 图谱抽取需要人工校验初期输出。自动抽取的错误会随时间累积,前期至少手动 review 前 100 条。
  4. Consolidation 必须异步运行。不要在用户等待响应时做记忆整理,这会让延迟翻倍。
  5. 给记忆设置 TTL。永远保留所有对话会拖慢检索速度,也会增加隐私风险。

八、总结

Agent 的记忆不是一个组件,而是一个系统。

In-Context Memory 是”眼前的记忆”,Vector DB 是”模糊的记忆”,Knowledge Graph 是”精确的记忆”。每一层都有不可替代的价值,但也都有致命的盲区。

MemPalace 的三层架构之所以有效,不是因为技术更先进,而是因为它承认了一个基本事实:不同类型的记忆需要不同的存储和检索方式

如果你的 Agent 只能记住最近 5 轮对话,它永远只是一个临时工具。如果你能让它记住用户三个月前做过什么决策、为什么这么选、后来改了几次——它才真正开始像一个”助手”。