1137 字
3 分钟
Agent 记忆架构全景 — 从虚拟上下文管理到 MCP 驱动的 RAG
一、为什么需要专门的记忆架构?
| 症状 | 根本原因 | 直接后果 |
|---|---|---|
| 上下文窗口爆炸 | 长生命周期 Agent 累积数万 token 的对话历史 | 推理成本上升、延迟飙升 |
| 中间遗忘 | LLM 只能看到窗口内最近 N 条 | 关键信息被挤出 |
| 调试困难 | 无法回溯历史为何导致错误 | 维护成本高、可信度下降 |
目标:在 8K-128K token 的窗口内,仍能快速定位、更新、压缩关键记忆,让 Agent 像人一样”有记忆、会忘记、还能自我纠正”。
二、虚拟上下文管理
OS 类比
| OS 组件 | Agent 对应 | 功能说明 |
|---|---|---|
| RAM | 核心记忆 (Core Memory) | 常驻窗口,存放当前任务最关键的 300-500 token |
| 磁盘 | 归档记忆 (Archival Memory) | 向量库 + 对话日志,几乎无限容量 |
| 页面调度 | 记忆检索 + 注入 | 按需把归档片段装载到 Core Memory |
| MMU | 自我编辑机制 | 决定哪些片段保留、压缩或删除 |
双层记忆的工作流
flowchart TD
A[用户指令] --> B[Agent 思考]
B --> C{是否需要历史?}
C -->|是| D[检索归档 VectorDB]
D --> E[把检索结果注入 Core]
E --> F[压缩/更新 Core]
C -->|否| G[直接执行]
G --> H[返回答案]
F --> B
H --> I[结束循环]
核心记忆持续保持关键上下文(任务目标、重要约束)。当需要历史时,触发检索 → 注入 → 压缩,保证窗口不超限。自我编辑(压缩、更新、删除、重组)在每轮循环结束后自动执行。
三、上下文工程策略
| 策略 | 操作要点 | 示例 |
|---|---|---|
| 选择性包含 | 只把相关性 >= 0.8 的片段拉入 Core | if relevance(query, chunk) > 0.8 → ingest |
| 压缩与摘要 | 使用 summarize 将 10K token 缩成 50 token | summarize(text, maxTokens=50) |
| 结构化组织 | 按层级(任务目标 → 关键事实 → 约束)排序 | — |
| 按需检索 | 仅在查询时从归档加载相关片段 | — |
代码示例
class VirtualContext: CORE_LIMIT = 400
def __init__(self): self.core = [] self.archive = VectorDB()
def ingest(self, chunk): if chunk.importance < 0.2: self.archive.store(chunk) return if self.tokens(self.core) + chunk.tokens > self.CORE_LIMIT: self._compact() self.core.append(chunk)
def _compact(self): old = self.core[:3] merged = "\n".join(c.text for c in old) summary = summarize(merged, max_tokens=50) self.core = self.core[3:] + [Chunk( id=f"summary-{int(time.time())}", text=summary, importance=0.7, tokens=50 )]
def retrieve(self, query): hits = search_in_core(self.core, query) if hits: return hits results = self.archive.search(query, top_k=3) for r in results: self.ingest(r) return results代码展示了双层记忆、压缩、按需检索的完整闭环。
四、MCP 与 RAG 的协同工作
MCP 基础
- Client-Server 架构(MCP Client 嵌入在 AI 应用,MCP Server 提供工具/资源)
- 三类消息:Request、Response、Notification
- 工具定义使用 JSON-Schema 描述参数,统一调度
RAG 在 MCP 中的实现
| MCP 原语 | 对应 RAG 组件 | 示例 |
|---|---|---|
| Resources | 归档记忆(向量库、文档) | file:///knowledge/base.md |
| Tools | 检索、摘要、压缩等函数 | vector_search, summarize, compress |
| Prompts | 任务提示(注入 Core Memory) | You have the following core memory: … |
| Sampling | 多模型抽样用于 Self-Consistency | — |
MCP-RAG 完整循环
sequenceDiagram
participant Agent
participant Client as MCP Client
participant Server as MCP Server
participant DB as VectorDB
Agent->>Client: "Thought: 需要上一次的部署日志"
Client->>Server: "tools/call vector_search"
Server->>DB: search(query)
DB-->>Server: top_k results
Server-->>Client: "Observation: 2026-06-25 log..."
Client->>Agent: Observation
Agent->>Client: "Thought: 基于日志生成故障报告"
Client->>Server: "tools/call generate_report"
Server-->>Client: Final Answer
Client->>Agent: Final Answer
把检索结果写回记忆
{ "name": "rag_update_memory", "description": "检索归档并把结果压缩后注入核心记忆", "parameters": { "type": "object", "properties": { "query": { "type": "string" }, "top_k": { "type": "integer", "default": 3 } }, "required": ["query"] }}Skill 将检索 → 摘要 → 记忆编辑合并为一次调用,极大简化 Agent Prompt。
五、实践示例
import { MCPClient } from "@antigravity/mcp";import { embed } from "./embed";
const client = new MCPClient({ serverUrl: "https://mcp.mycompany.com" });
interface Chunk { id: string; text: string; importance: number; tokens: number;}
let coreMemory: Chunk[] = [];
export async function ingest(chunk: Chunk) { if (chunk.importance < 0.2) { await client.callTool("archive_store", { chunk }); return; }
const coreTokens = coreMemory.reduce((a, c) => a + c.tokens, 0); if (coreTokens + chunk.tokens > 400) await compactCore(); coreMemory.push(chunk);}
async function compactCore() { const oldest = coreMemory.splice(0, 3); const merged = oldest.map(c => c.text).join("\n"); const summary = await client.callTool("summarize", { text: merged, maxTokens: 50, }); coreMemory.push({ id: `summary-${Date.now()}`, text: summary, importance: 0.7, tokens: 50, });}
export async function retrieveAndInject(query: string) { const hits = coreMemory.filter(c => c.text.includes(query)); if (hits.length) return hits;
const vec = await embed(query); const results = await client.callTool("vector_search", { queryVector: vec, topK: 3, });
for (const r of results) { await ingest({ id: r.id, text: r.text, importance: 0.8, tokens: Math.round(r.text.split(/\s+/).length * 0.75), }); } return results;}关键步骤
| 步骤 | MCP 调用 | 记忆层动作 |
|---|---|---|
| 检索 | vector_search | 从归档拉回最相关片段 |
| 压缩 | summarize | 将多条记录浓缩为摘要 |
| 写入 | archive_store / ingest | 根据重要性决定 Core 还是归档 |
| 更新 | self_edit | 自动压缩、删除、重组 |
这样,一个 ReAct 循环里的 Thought → Action → Observation 就可以完整地完成”检索-记忆-生成”的闭环。
六、设计原则与常见坑
设计原则
- 最小化上下文:只把重要性 >= 0.6 的信息放入 Core
- 渐进式压缩:每次超限只压缩最旧的 2-3 条,防止一次性丢失太多
- 自我审计:每轮循环输出 MemoryReport(如
coreTokens: 378 / limit: 400),便于监控 - 安全审查:高危工具(如
file_delete)在 MCP Server 必须配置用户确认 - 日志可追溯:所有 ingest/compact 操作写入
memory.log,便于离线调试
常见坑
| 坑点 | 症状 | 防御措施 |
|---|---|---|
| 把所有检索结果直接塞进 Core | 上下文瞬间爆炸 | 重要性过滤 + 即时压缩 |
| 忽视摘要质量 | 关键细节消失 | 使用 Self-Consistency 生成多版本摘要 |
| 冲突信息未更新 | Agent 给出自相矛盾的答案 | self_edit 中加入冲突检测 |
| 未对高危工具进行确认 | 数据意外删除 | MCP Server 配置 approvalRequired: true |
| 日志不足 | 调试找不到根因 | 开启 memory.log 的 JSON 行格式 |
七、小结
虚拟上下文管理把记忆划分为核心与归档,并提供自我编辑能力,实现了”记忆不忘、忘记可控”。MCP 为工具调用与资源读取设定统一协议,使 RAG、Skills、Hooks 能在同一框架下协同工作。上下文工程(选择性包含、压缩、结构化、按需检索)是保证高效推理与低成本运行的关键手段。
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
Agent 记忆架构全景 — 从虚拟上下文管理到 MCP 驱动的 RAG
https://www.moonzj.com/posts/agent-memory-architecture/ 部分信息可能已经过时
相关文章 智能推荐
1
Claude和GPT的区别:从数据质量到实际反转
技术 深度对比 Claude 与 GPT 在编程、写作、debug 等场景的表现差异,以及 Constitutional AI 如何影响 AI 的"性格"。
2
一次 rm -rf 桌面,和它引发的 Claude Code 安全架构改造
技术 Claude Code 在 Windows 上因跨平台路径错误删掉整个桌面。事故复盘、根因分析,以及四层纵深防御安全架构的完整改造。
3
CLAUDE.md 使用指南:给 AI Agent 写一部行为宪法
技术 从零开始理解 CLAUDE.md——它是什么、解决什么问题、怎么设计、如何维护。附带完整 150 行实际案例。





