Agent 分层存储架构设计:从记忆方法到中间件选型
1. 为什么 Agent 需要分层存储
一个 Agent 在单轮对话中看起来像是“模型 + Prompt + 工具”。但当它需要跨会话工作、长期学习、恢复任务、审计行为、管理多个用户,问题很快会变成一个存储系统问题:
- 当前任务执行到了哪一步?
- 最近调用了哪些工具?哪些结果必须保留在上下文中?
- 用户偏好、业务事实和历史事件如何跨会话复用?
- 旧事实被新事实推翻时,如何避免检索出过期答案?
- Agent 是否可以从失败中总结经验,并在下一次执行时复用?
- 原始证据如何留存,以便复盘、合规审计和重新构建索引?
- 数据规模增长后,如何控制检索延迟、Token 成本和存储成本?
如果把所有数据都塞进上下文窗口,成本和噪声会持续上升;如果把所有数据都写进向量库,事务状态、时间关系、权限隔离和审计又会变得脆弱。
正确的设计思路是:用分层存储管理 Agent 的上下文、状态、记忆、技能和证据,并让数据在层级之间按策略流动。
2. 主流设计方法全景
业界和研究界已经形成了一组互补的方法。它们不是互斥方案,而是可以组合使用的设计积木。
2.1 上下文窗口:最昂贵但最快的“寄存器”
模型当前可见的 Prompt、最近消息、工具结果和临时草稿,构成 Agent 的即时上下文。它的特点是:
- 延迟最低,因为数据已经在推理输入中。
- 成本最高,因为每次推理都可能重复携带。
- 容量有限,而且信息越多不一定效果越好。
- 适合保存当前任务必须立即使用的数据,不适合保存完整历史。
工程上应把上下文窗口视为一个有严格预算的缓存,而不是数据库。
2.2 MemGPT / Letta:借鉴操作系统的虚拟内存
MemGPT 论文把长对话问题类比为操作系统的虚拟内存管理:有限的上下文窗口类似内存,外部存储类似磁盘,系统需要在快层和慢层之间移动数据。
Letta 文档进一步将其产品化为两大层:
- In-context memory:系统指令、始终可见的 memory blocks、最近消息。
- Out-of-context memory:可搜索的历史消息和长期归档记忆。
其中,memory blocks适合保存用户画像、Agent 身份、当前工作状态和共享规则;archival memory适合保存需要按需搜索的大规模长期信息。
这套方法给出的关键启示是:高价值、低容量信息应固定在上下文中;大容量信息应留在上下文外按需召回。
2.3 Generative Agents:观察、反思、计划
Generative Agents 论文提出了一条影响广泛的记忆链路:
- 保存 Agent 的观察记录。
- 按相关性、时效性和重要性检索记忆。
- 将多条低层观察综合成高层反思。
- 使用记忆和反思支持后续计划。
它解决的不是简单的“聊天历史搜索”,而是如何从大量经历中提炼更稳定、更有复用价值的认知。
2.4 Reflexion:把失败复盘写入情景记忆
Reflexion 论文提出:Agent 不一定要通过训练更新模型权重,也可以把任务反馈转化为文字反思,写入 episodic memory(情景记忆),供后续尝试复用。
适合保存的内容包括:
- 哪种执行路径失败了,为什么失败。
- 哪个工具在什么条件下不可靠。
- 哪个验收条件被遗漏。
- 下次遇到类似任务时应先检查什么。
这类记忆应当带上任务类型、失败原因、验证证据和适用范围,而不是简单保存一段自由文本。
2.5 Voyager:把成功经验固化为技能库
Voyager 论文将长期学习实现为可复用的技能库:Agent 从环境反馈和执行错误中改进代码技能,再在后续任务中检索并组合技能。
这给生产系统一个重要启示:成功经验不应只留在对话摘要中,还应升级为程序记忆。
程序记忆可以是:
- 版本化 Prompt。
- 可调用工具定义。
- SOP 和检查清单。
- 经过验证的代码片段或工作流模板。
- 适用条件、输入输出 Schema 和评估结果。
2.6 LangGraph:区分 thread 状态和跨会话记忆
LangGraph 持久化文档通过 checkpointer 保存图执行过程中的状态快照,并按 thread 组织。LangChain 长期记忆文档则把跨会话记忆保存为按 namespace 和 key 组织的 JSON 文档。
LangGraph memory 文档进一步借用了人类记忆分类:
- Semantic memory:事实、概念和偏好。
- Episodic memory:过去发生过的事件和任务经历。
- Procedural memory:完成任务的方法、规则和 Prompt。
这套划分非常适合作为业务数据模型,而不是只把所有记忆统一存成文本块。
2.7 LlamaIndex:FIFO 短期记忆 + 可组合长期记忆块
LlamaIndex Memory 文档提供了一个工程化实现:
- 短期记忆默认是按 Token 限制的 FIFO 消息队列。
- 队列超出阈值后,较旧消息被 flush 到长期 memory blocks。
- 长期块可以保存静态信息、抽取事实,或把消息写入向量库供语义检索。
- 获取记忆时,再将短期和长期内容合并,并确保不超过 Token 限制。
对于已有 LlamaIndex 项目,这种模型很适合作为内存管理入口,但底层数据库仍需要独立设计。
2.8 Mem0:抽取、整合、召回与实体关联
Mem0 论文强调从持续对话中动态抽取、整合和召回关键记忆,以减少全量上下文带来的延迟和 Token 成本。
Mem0 Memory Types 文档按作用域进一步区分:
- Conversation memory:单轮交互中的即时信息。
- Session memory:当前任务或频道中的短期状态。
- User memory:与用户绑定的长期知识。
- Organizational memory:多个 Agent 或团队共享的组织知识。
需要特别注意版本变化:Mem0 OSS 迁移文档显示,开源 SDK 的新算法已从外部图存储转向向量库内的 entity linking 和混合检索。因此,选型时不能只依据旧博客或旧示例。
2.9 时间图谱:处理“谁在什么时候知道什么”
Zep 论文提出用 Graphiti 构建时间感知知识图谱,将非结构化对话和结构化业务数据整合起来,同时保留历史关系。
时间图谱适合处理:
- 用户以前喜欢 A,现在改为喜欢 B。
- 某个项目负责人在不同时间段发生变化。
- 多个实体之间存在多跳关系。
- 需要回答“截至某一天,当时的事实是什么”。
向量检索擅长找“相似内容”,图谱更擅长表达“实体关系、有效时间和演化历史”。两者解决的问题不同。
2.10 遗忘、衰减和强化
MemoryBank 论文引入了受遗忘曲线启发的更新机制:记忆可随时间衰减,也可因重要性和重复访问而强化。
生产系统不必机械复制心理学模型,但应实现类似能力:
- TTL:过期即删除。
- Decay:降低召回分数。
- Reinforcement:被频繁命中或被用户确认后提高权重。
- Supersede:新事实替代旧事实,但保留历史。
- Archive:低频原始证据转移到低成本对象存储。
3. 设计原则:不要按数据库分层,要按数据职责分层
常见错误是先列数据库,再想每个数据库存什么。更稳妥的方法是先定义 Agent 数据的职责和访问模式。
| 数据类别 | 典型内容 | 访问特点 | 一致性要求 |
|---|---|---|---|
| 即时上下文 | 当前问题、最近消息、当前工具结果 | 每轮必读,容量小 | 与当前推理严格一致 |
| 工作状态 | 计划、待办、游标、临时变量、锁 | 高频读写,可恢复 | 强一致或可接受的乐观并发 |
| 事件流水 | 消息、工具调用、结果、审批、错误 | 追加写、可回放 | 不可丢失,可审计 |
| 语义事实 | 用户偏好、项目知识、归纳结论 | 跨会话按需召回 | 可更新、可追溯来源 |
| 情景记忆 | 成功任务、失败案例、反思总结 | 相似任务召回 | 保留上下文与结果 |
| 程序记忆 | Prompt、技能、SOP、工具 Schema | 版本化、受控发布 | 强审计,支持回滚 |
| 关系与时间事实 | 实体、关系、有效期、变更历史 | 多跳查询、时间推理 | 保留历史版本 |
| 原始证据 | 完整对话、文件、网页、截图、日志 | 低频读取、容量大 | 不可变、低成本保存 |
4. 推荐的六层存储架构
下面是一套适合从 MVP 演进到生产环境的六层架构。
flowchart TB
A["Agent Runtime"] --> L0["L0 上下文缓存<br/>Prompt / recent messages / tool results"]
A <--> L1["L1 工作状态层<br/>session / checkpoint / locks / TTL"]
A --> E["追加写事件流<br/>message / tool / approval / feedback"]
E --> L2["L2 事实与情景记忆层<br/>canonical records + vector retrieval"]
E --> L3["L3 时间关系层(按需)<br/>entities / relations / valid time"]
E --> L4["L4 程序记忆层<br/>skills / prompts / SOP / evaluations"]
E --> L5["L5 原始证据与冷归档<br/>immutable objects / logs / snapshots"]
L1 --> A
L2 --> A
L3 --> A
L4 --> A
4.1 L0:上下文缓存层
保存内容
- 系统指令。
- 当前任务摘要。
- 最近若干轮消息。
- 当前步骤必须使用的工具结果。
- 少量始终可见的用户偏好和约束。
设计建议
- 明确 Token 预算,不允许无限追加。
- 按优先级装配上下文:系统规则 > 当前任务 > 工作状态 > 召回记忆 > 最近消息 > 可选证据。
- 对超长工具输出做结构化摘要,同时保留原始结果引用。
- 固定块应短小、稳定、可审计,避免频繁变化的大段文本常驻。
存储位置
- 主要由 Agent Runtime 在内存中装配。
- 可从 Redis 或 PostgreSQL 恢复。
4.2 L1:热状态与检查点层
保存内容
session_id、thread_id、task_id。- 当前计划、步骤状态、游标、重试次数。
- 工具调用中的临时结果引用。
- 分布式锁、租约、幂等键。
- 短期对话缓存和 TTL。
推荐中间件
- 默认:Redis。
- 必须可靠恢复的最终状态:同步或异步落入 PostgreSQL。
Redis 适合承载 TTL、缓存、锁和短期会话。Redis 官方的 Agent Memory 文档也采用了工作记忆和长期记忆两层模型,并支持在上下文变长时自动摘要旧消息。Redis Cloud Agent Memory 文档进一步支持 TTL 生命周期和异步抽取长期记忆。
边界
- Redis 不是所有业务事实的唯一真相源。
- Agent 任务完成后,关键状态必须有持久记录。
- 锁必须有过期时间,任务必须有租约和心跳。
4.3 L2:事实、事件和情景记忆层
这是系统的核心长期记忆层,建议拆成两个物理职责:
- Canonical Store:保存权威事实、事件、作用域、时间、来源和版本。
- Retrieval Index:保存 embedding、关键词索引和可过滤 metadata,用于快速召回。
推荐中间件
- Canonical Store:PostgreSQL。
- Retrieval Index:中小规模可用 PostgreSQL + pgvector;更高检索吞吐或更复杂混合检索可使用 Qdrant。
pgvector 官方仓库支持精确与近似最近邻检索、HNSW、IVFFlat、过滤条件,以及 PostgreSQL 原有的 ACID、JOIN 和时间点恢复能力。对于 MVP 和中等规模系统,它能显著减少中间件数量。
Qdrant 官方文档提供向量检索、过滤、量化、多租户和高级搜索能力。Hybrid Queries 文档支持多阶段和混合查询,Payload 文档允许保存 JSON metadata 并在搜索时过滤。对于 LlamaIndex 项目,QdrantVectorStore 文档提供了直接集成入口。
推荐 metadata
memory_id
tenant_id
user_id
agent_id
session_id
task_id
memory_type # semantic / episodic / reflection / document
scope # user / agent / project / organization
content
summary
source_event_ids
source_object_uri
valid_from
valid_to
created_at
updated_at
importance
confidence
reinforcement_count
last_accessed_at
decay_policy
superseded_by
embedding_model
embedding_version
prompt_version
4.4 L3:时间关系与知识图谱层
保存内容
- 实体:用户、组织、项目、系统、文档、任务。
- 关系:负责、依赖、偏好、批准、属于、替代。
- 时间:
valid_from、valid_to、observed_at。 - 来源:由哪些事件和证据推导而来。
推荐中间件
- 默认不引入图数据库,先用 PostgreSQL 关系表建模。
- 当多跳关系和时间推理成为核心需求时,引入 Neo4j。
Neo4j Semantic Indexes 文档说明 Neo4j 同时支持全文索引和向量索引,可用于混合检索。Neo4j Vector Search 文档指出,向量搜索适合语义相似性,而精确术语、标识符和图结构需要结合其他检索信号。
什么时候值得引入图数据库
- 经常出现“谁与谁在何时有什么关系”的查询。
- 需要多跳路径推理。
- 同一事实频繁变化,必须回答历史时点问题。
- 向量召回能找到文本,但无法稳定回答关系问题。
什么时候不值得
- 主要需求只是文档问答或用户偏好召回。
- 数据量小,关系查询可以用 PostgreSQL JOIN 解决。
- 团队没有图模型治理能力。
4.5 L4:程序记忆与自我进化层
保存内容
- Prompt 模板和版本。
- Agent policy。
- 工具定义、输入输出 Schema。
- 成功技能、失败反思、SOP。
- 技能适用条件、依赖、风险等级。
- 评估集、评估结果和发布记录。
推荐中间件
- Git 仓库:适合 Markdown 技能、Prompt、SOP 和配置。
- PostgreSQL:适合保存技能索引、版本元数据、评估记录和发布状态。
- 对象存储:适合保存大体积产物和评估附件。
- 向量索引:适合按任务相似度召回技能,但不能取代版本管理。
这里必须避免一个危险误区:所谓“自我进化”不应等于 Agent 可以绕过审核直接修改生产 Prompt 或代码。更合理的闭环是:
flowchart LR
A["任务执行"] --> B["收集反馈与证据"]
B --> C["生成反思候选"]
C --> D["抽取技能或 Prompt 修改候选"]
D --> E["离线评估"]
E --> F{"通过阈值与审核?"}
F -- "否" --> G["保留为实验候选"]
F -- "是" --> H["版本化发布"]
H --> I["灰度验证与回滚监控"]
4.6 L5:原始证据与冷归档层
保存内容
- 完整对话。
- 工具原始输出。
- 上传文件、网页快照、截图。
- Agent 生成产物。
- 事件日志快照。
- 数据导出和审计证据。
推荐中间件
- 云环境:Amazon S3。
- 自建环境:MinIO 或兼容 S3 API 的对象存储。
对象存储适合不可变大对象和低成本长期保存。AWS 官方 S3 Lifecycle 文档支持按生命周期将对象转移到 Standard-IA、Intelligent-Tiering 和 Glacier 等存储类别,以平衡访问延迟和成本。
设计建议
- 原始证据尽量追加写,不覆盖。
- 数据库中保存 URI、哈希、媒体类型、大小、权限和保留期。
- 摘要、embedding 和图谱都应能追溯到原始证据。
- 冷归档删除必须遵循租户、合规和用户撤回规则。
5. 写入链路:先保留事实,再异步提炼记忆
推荐采用“在线轻写入,异步重加工”的方式。
sequenceDiagram
participant U as User
participant A as Agent Runtime
participant R as Redis
participant P as PostgreSQL
participant Q as Qdrant
participant G as Graph Store
participant O as Object Storage
participant W as Memory Worker
U->>A: 新消息或任务
A->>R: 更新 session / checkpoint / TTL
A->>P: 追加 message_event
A->>O: 保存超长原始内容或附件
A-->>U: 在线响应
P-->>W: 触发异步记忆加工
W->>P: 抽取事实、情景、反思与来源
W->>Q: 写入 embedding 与 metadata
opt 需要时间关系
W->>G: 更新实体、关系和有效时间
end
在线链路只做必要工作:
- 保留原始事件。
- 更新热状态。
- 保存大对象引用。
- 在预算内召回少量相关记忆。
异步 Worker 再完成:
- 事实抽取。
- 去重和合并。
- 冲突检测。
- embedding。
- 关键词索引。
- 重要度计算。
- 关系抽取。
- 旧记忆降权或归档。
这样可以避免把 LLM 抽取和复杂索引更新放进用户请求的关键路径。
6. 读取链路:混合检索比单一向量搜索更可靠
只做向量相似度搜索通常不够。生产环境建议至少组合五类信号:
- Scope filter:租户、用户、Agent、项目、会话权限。
- Semantic similarity:向量相似度。
- Lexical match:关键词、标识符、错误码、文件名。
- Recency / temporal validity:时间衰减和事实有效期。
- Importance / confidence:重要度、置信度和强化次数。
可使用如下概念评分:
score =
semantic_similarity * 0.40 +
lexical_relevance * 0.20 +
recency * 0.15 +
importance * 0.15 +
confidence * 0.10
实际权重应通过评估集调优。对于关系型问题,再增加图查询结果,并通过 Reciprocal Rank Fusion 或 reranker 合并结果,而不是直接比较不同检索器的原始分数。
检索结果进入上下文前还要做三件事:
- 去重:避免多个摘要重复表达同一事实。
- 冲突裁决:优先使用当前仍有效、来源可信的新事实。
- Token 压缩:只注入回答当前问题必要的内容。
7. 推荐的中间件组合
7.1 默认推荐:适合大多数团队
| 职责 | 推荐中间件 | 原因 |
|---|---|---|
| 热状态、TTL、锁、短期缓存 | Redis | 低延迟,适合短生命周期状态 |
| 权威事实、事件、版本、权限、任务状态 | PostgreSQL | ACID、JOIN、JSON、事务、成熟治理 |
| 语义检索与 metadata 过滤 | Qdrant | 专门的向量检索能力,适合 LlamaIndex 集成 |
| 原始证据和冷归档 | MinIO 或 S3 | 低成本保存大对象,支持生命周期 |
| Prompt、技能、SOP | Git + PostgreSQL 元数据 | 版本审计、评估和可回滚发布 |
| 关系与时间推理 | 初期 PostgreSQL,必要时 Neo4j | 延迟引入复杂度,按需求升级 |
| 事件总线 | 初期 PostgreSQL Outbox,必要时 Kafka | 先保证简单可靠,再扩展吞吐 |
这套组合适合已经使用 LlamaIndex 和 Qdrant 的项目:它保留现有技术栈,同时补齐热状态、权威存储和冷归档。
7.2 极简 MVP:减少运维组件
| 职责 | 推荐中间件 |
|---|---|
| 任务状态、事实、事件、权限 | PostgreSQL |
| 向量检索 | PostgreSQL + pgvector |
| 短期缓存 | 进程内缓存,必要时再加 Redis |
| 文件与原始证据 | 本地对象目录或 MinIO |
| 程序记忆 | Git |
适用于:
- 单机或小团队。
- 向量规模尚小。
- 吞吐量不高。
- 当前目标是先验证数据模型和记忆策略。
7.3 规模化版本:增加事件驱动和专用组件
| 职责 | 推荐中间件 |
|---|---|
| 热状态 | Redis Cluster |
| 权威业务数据 | PostgreSQL 高可用集群 |
| 事件总线 | Kafka |
| 向量检索 | Qdrant 集群或同级专用向量数据库 |
| 图谱 | Neo4j 或企业现有图数据库 |
| 冷归档 | S3 + Lifecycle |
| 可观测性 | OpenTelemetry + 指标、日志和 Trace 平台 |
Apache Kafka 文档将 Kafka 定位为可持久、可靠保存事件流,并支持实时和回溯处理的平台。Kafka Log Compaction 文档说明压缩日志能够为每个 key 至少保留最新状态。因此 Kafka 很适合在多 Worker、异步加工、可回放重建和跨系统同步成为核心需求时引入。
但 Kafka 不应成为早期 MVP 的默认依赖。只要 PostgreSQL Outbox + Worker 足够满足吞吐和恢复需求,先保持简单。
8. 中间件选型矩阵
8.1 向量检索层
| 方案 | 适用场景 | 优点 | 局限 |
|---|---|---|---|
| PostgreSQL + pgvector | MVP、中小规模、强事务需求 | 组件少,事实与向量可放在同一数据库,易于 JOIN 和备份 | 大规模专用检索能力和独立扩展能力较弱 |
| Qdrant | 通用生产 Agent、LlamaIndex 项目 | Payload 过滤、混合查询、多租户、专用检索能力 | 多一个需要运维的组件 |
| Redis Vector Search | 已深度使用 Redis、希望热数据和检索靠近 | 低延迟,Redis 官方已有 Agent Memory 能力 | 需要谨慎控制内存成本和持久化策略 |
| Neo4j Vector Index | 已经以图谱为中心 | 图、全文和向量检索可组合 | 不应只为了普通向量检索引入图数据库 |
8.2 图谱层
| 方案 | 适用场景 | 建议 |
|---|---|---|
| PostgreSQL 关系表 | 关系较简单、团队熟悉 SQL | 默认从这里开始 |
| Neo4j | 多跳关系、时间图谱、图可视化和图查询成为核心 | 需求明确后引入 |
| 不建图,仅 entity linking | 主要目的是增强实体命中,不需要复杂路径推理 | 可参考 Mem0 OSS 新算法思路 |
8.3 托管记忆服务
如果团队希望快速验证,也可以使用托管记忆层,例如 Mem0 Platform、Redis Agent Memory 或 Zep。它们能减少自建抽取、召回和生命周期管理的工作量。
但要先确认:
- 数据是否允许交给外部服务。
- 是否支持租户隔离、删除、导出和审计。
- 是否可以追溯到原始证据。
- 是否允许替换底层存储。
- SDK 和开源版本是否存在能力差异。
- 成本是否会随 Token、记忆数量和检索次数快速增长。
9. 建议的数据表
9.1 事件表:不可变追加写
create table agent_events (
event_id uuid primary key,
tenant_id text not null,
agent_id text not null,
user_id text,
session_id text,
task_id text,
event_type text not null,
payload jsonb not null,
object_uri text,
created_at timestamptz not null default now()
);
事件类型可以包括:
message_received
message_sent
tool_requested
tool_completed
tool_failed
checkpoint_saved
approval_requested
approval_granted
feedback_received
memory_promoted
memory_superseded
skill_candidate_created
skill_published
9.2 长期记忆表:可演化但可追溯
create table agent_memories (
memory_id uuid primary key,
tenant_id text not null,
scope_type text not null,
scope_id text not null,
memory_type text not null,
content text not null,
summary text,
importance numeric not null default 0.5,
confidence numeric not null default 0.5,
valid_from timestamptz,
valid_to timestamptz,
superseded_by uuid references agent_memories(memory_id),
source_event_ids uuid[] not null default '{}',
source_object_uri text,
metadata jsonb not null default '{}',
created_at timestamptz not null default now(),
updated_at timestamptz not null default now()
);
9.3 技能表:把“学到的经验”纳入发布流程
create table agent_skills (
skill_id uuid primary key,
name text not null,
version text not null,
status text not null, -- candidate / evaluated / approved / published / retired
repository_path text not null,
applicability jsonb not null,
risk_level text not null,
evaluation_report_uri text,
created_from_event_ids uuid[] not null default '{}',
created_at timestamptz not null default now(),
published_at timestamptz
);
10. 多租户、安全与治理
Agent 的长期记忆天然带有隐私和越权风险。必须把治理放在数据模型中,而不是只依赖 Prompt。
10.1 作用域隔离
每次写入和检索都必须显式携带:
tenant_id
user_id
agent_id
project_id
session_id
检索时先做权限过滤,再做相似度召回。不能先召回再在应用层“尽量过滤”。
PostgreSQL 可用 Row-Level Security实施行级访问控制;Qdrant 可用 payload 过滤实现租户和作用域限制。Qdrant 的 LlamaIndex 多租户示例建议对大量独立用户使用单 collection,并通过 payload 分区隔离。
10.2 敏感数据
- Secret 不写入长期记忆。
- PII 在写入前做识别、脱敏和最小化。
- 用户长期偏好需要明确保留期和删除能力。
- embedding 也属于敏感派生数据,删除原文时要同步删除索引。
- 原始证据、摘要、向量、图谱和缓存需要统一执行删除流程。
10.3 可解释性
每条记忆至少应回答:
- 从哪些事件或证据提取而来?
- 由哪个 Prompt 和模型版本生成?
- 当前是否仍然有效?
- 为什么这次被召回?
- 是否被用户确认或推翻过?
11. 自我总结与进化:受控闭环
设计“会进化的 Agent”时,可以将经验升级分为四级:
| 等级 | 产物 | 是否自动生效 |
|---|---|---|
| L1 | 本次任务摘要 | 可以,用于恢复当前任务 |
| L2 | 情景记忆和失败反思 | 可以,但只作为检索上下文 |
| L3 | 技能候选和 Prompt 修改候选 | 不应直接生效,必须评估 |
| L4 | 发布后的技能、SOP、Prompt | 经过评估、审核和版本化后生效 |
11.1 推荐的总结触发器
- 上下文即将压缩。
- 任务完成。
- 工具连续失败。
- 用户明确纠正 Agent。
- 相似任务累计达到阈值。
- 定时批处理。
11.2 推荐的总结模板
任务类型:
目标:
关键约束:
采取的步骤:
成功证据:
失败步骤:
根因:
可复用经验:
不适用条件:
建议升级为技能:
来源事件:
11.3 发布前评估
技能或 Prompt 候选发布前至少检查:
- 在历史任务集上的成功率。
- 成本和延迟变化。
- 是否导致越权工具调用。
- 是否引入数据泄露。
- 是否能回滚。
- 是否只在明确适用范围内启用。
真正可靠的“进化”不是让 Agent 无限制修改自己,而是建立一个可追溯、可评估、可审核、可灰度、可回滚的知识发布流程。
12. 分阶段实施路线
阶段一:单机可用
目标:先跑通记忆闭环,不追求复杂组件。
- PostgreSQL 保存任务、事件和长期记忆。
- pgvector 保存 embedding。
- Git 保存 Prompt、技能和 SOP。
- 本地目录或 MinIO 保存原始证据。
- Agent Runtime 严格限制上下文 Token。
- 使用后台 Worker 做摘要、事实抽取和 embedding。
阶段二:团队生产
目标:提升在线性能、隔离和可观测性。
- 增加 Redis 保存 session、TTL、锁和热状态。
- 向量检索迁移到 Qdrant,保留 PostgreSQL 作为权威来源。
- 使用 PostgreSQL Outbox 驱动异步 Worker。
- 增加租户隔离、删除流程、审计事件和检索 Trace。
- 建立离线评估集,调优召回和上下文装配。
阶段三:规模化平台
目标:支持多 Worker、大量事件和复杂关系。
- 当 Outbox 消费成为瓶颈时,引入 Kafka。
- 当多跳关系和时间问题成为核心时,引入 Neo4j。
- S3 配置生命周期和冷归档。
- 技能候选进入自动评估、人工审核、灰度和回滚流程。
- 对每类记忆设置 TTL、衰减、强化和删除策略。
13. 常见反模式
13.1 把向量库当成唯一数据库
向量库适合召回,不适合独自承担事务状态、版本控制、审计和复杂权限。
13.2 保存所有对话,却不抽取事实
完整历史是证据,不是高质量记忆。需要异步提炼、去重、冲突检测和有效期管理。
13.3 每轮都把全部记忆塞入 Prompt
上下文越大,成本越高,噪声也越多。应先过滤、召回、重排和压缩。
13.4 一开始就引入 Kafka、图数据库和多套向量库
复杂度本身会吞噬团队精力。中间件必须由明确瓶颈驱动。
13.5 让 Agent 自动修改生产 Prompt 和代码
反思可以自动生成,生产发布必须经过评估、审核和版本控制。
13.6 忽略删除和撤回
长期记忆、embedding、缓存、图谱和对象存储中的派生数据都必须支持统一删除。
14. 最终建议
如果现在开始搭建一个通用 Agent 的分层存储,我会采用以下默认方案:
L0 上下文缓存:
Agent Runtime 内存装配,严格 Token 预算
L1 热状态:
Redis
L2 权威事实、任务状态、事件流水:
PostgreSQL
L2 语义检索:
Qdrant
如果仍处于 MVP,则先用 PostgreSQL + pgvector
L3 时间关系:
初期 PostgreSQL
多跳与时间推理成为核心需求后再引入 Neo4j
L4 程序记忆:
Git + PostgreSQL 元数据 + 离线评估
L5 原始证据和冷归档:
MinIO 或 S3
异步加工:
初期 PostgreSQL Outbox + Worker
吞吐量和回放需求增长后再引入 Kafka
这套架构的核心不是组件数量,而是边界清晰:
- Redis 管快而短的数据。
- PostgreSQL 管权威状态和可审计事实。
- Qdrant 管高效召回。
- Neo4j 只在复杂关系值得付出成本时加入。
- Git 管可审查、可回滚的程序记忆。
- S3 / MinIO 管大而冷的原始证据。
- Kafka 只在事件规模和异步解耦需求明确后加入。
Agent 的能力会持续演进,但存储架构必须保持一个不变原则:每一条被 Agent 使用的记忆,都应该有明确作用域、来源、生命周期、版本和删除路径。
15. 参考资料
研究论文
- MemGPT: Towards LLMs as Operating Systems
- Generative Agents: Interactive Simulacra of Human Behavior
- Reflexion: Language Agents with Verbal Reinforcement Learning
- Voyager: An Open-Ended Embodied Agent with Large Language Models
- MemoryBank: Enhancing Large Language Models with Long-Term Memory
- Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory
- Zep: A Temporal Knowledge Graph Architecture for Agent Memory
官方文档
- Letta Agent memory & architecture
- Letta Memory blocks
- Letta Archival memory
- LangGraph Persistence
- LangChain Long-term memory
- LangGraph Memory overview
- LlamaIndex Memory
- LlamaIndex QdrantVectorStore
- Mem0 Memory Types
- Mem0 OSS migration guide
- Redis Agent Memory
- pgvector
- Qdrant Documentation
- Qdrant Hybrid Queries
- Qdrant Payload
- Neo4j Semantic Indexes
- Neo4j Vector Search
- PostgreSQL Row Security Policies
- Apache Kafka Introduction
- Apache Kafka Log Compaction
- Amazon S3 Lifecycle transitions