🇺🇸 EN

AI Agent 记忆系统全解析:RAG 与上下文工程的对比与选择

RAG 和上下文工程是 AI Agent 记忆系统的两大主流方案。本文深入对比两者的原理、优劣和适用场景,并提供实战落地方案,帮你为 LLM Agent 构建高效的持久化记忆。

Bruce

AI AgentRAGContext EngineeringClaude CodeLLM Memory

AI Guides

1019  字

2026-02-21 02:00 +0000


AI Agent 记忆系统对比:RAG 检索管线与上下文工程方案的架构差异

每一个 AI 编程 Agent 都面临一个根本性的问题:失忆。打开一个新的 Claude Code、Cursor 或任何 LLM 驱动工具的会话,它对昨天的工作一无所知。你花了两小时讨论的架构决策、终于定位到的 Bug、精心建立的编码规范——全部归零。

这不是 Bug,而是大语言模型的工作原理。每次会话都从空白的上下文窗口开始,当窗口被填满或者会话结束时,一切都会蒸发殆尽。

问题来了:我们该如何赋予 AI Agent 记忆能力?

目前有两种主流方案——RAG(检索增强生成)上下文工程(Context Engineering)——它们从根本上以不同的方式解决这个问题。本文将深入剖析两种方案,进行正面对比,并展示在实际 AI Agent 工作流中的落地实践。

为什么 AI Agent 需要记忆

在深入解决方案之前,先从技术层面理解这个问题。

上下文窗口的约束

现代 LLM 在固定的上下文窗口内运行。Claude Sonnet 4 支持 200K token,GPT-4o 支持 128K,Gemini 1.5 Pro 则可达 2M token。这些数字听起来很大,但实际使用中消耗极快。

以一个典型的 Claude Code 会话为例。每次工具调用——读取文件、运行命令、编写代码——消耗 1,000 到 10,000 个 token。一个中等复杂度的开发任务涉及 50 次以上的工具调用。token 消耗以 二次方 增长,因为每次新的工具调用都必须包含之前所有的上下文。大约在 50 次工具调用后,200K 的上下文窗口就会被耗尽。

会话失忆症

更大的问题不在单次会话内,而在跨会话之间。当你关闭一次对话并开始新的对话时,Agent 对以下内容一无所知:

  • 昨天做出的架构决策
  • 已调查的 Bug 及其根因
  • 你偏好和反感的代码模式
  • 项目特有的约定和约束
  • 通过反复试错发现的第三方 API 坑点

你不得不反复重复自己,既浪费时间又容易出错。更糟的是,Agent 可能做出与之前约定矛盾的决策,仅仅因为它对那些约定没有任何记忆。

AI Agent 记忆的三个层次

要解决这个问题,我们需要从三个层次来思考记忆:

记忆类型类比持续时间示例
短期记忆工作记忆当前会话上下文窗口中的内容
长期记忆参考资料库持久化向量数据库、RAG 系统
持久化配置规则手册永久CLAUDE.md、Cursor Rules、项目文档

每种类型服务于不同的目的,最有效的 AI Agent 配置会同时使用这三者。RAG 和上下文工程之间的争论,本质上是关于如何最有效地实现长期记忆和持久化配置。

RAG 方案:动态检索

RAG——检索增强生成——是业界最成熟的让 LLM 访问外部知识的方案。核心思路很直接:不把所有内容塞进提示词,而是将信息存储在外部,在查询时只检索相关的部分。

RAG 的工作原理

RAG 管线有四个阶段:

文档 → 向量嵌入 → 向量存储 → 检索 → 注入
                             用户查询

1. 分块与嵌入

源文档(代码文件、文档、对话日志)被分割成块,并转换为向量嵌入——捕获语义含义的数值表示。语义相似的概念在向量空间中会彼此靠近。

2. 向量存储

嵌入向量存储在向量数据库中,如 ChromaDB、Pinecone、Weaviate 或 pgvector。这些数据库针对相似度搜索做了优化——能快速找到与查询向量最接近的向量。

3. 检索

当 Agent 需要信息时,用户的查询被向量化,并与存储的向量进行比较。语义最相似的块会被检索出来,通常取 Top 5-20 条结果。

4. 上下文注入

检索到的内容块被注入到 LLM 的提示词中作为补充上下文,让模型无需将所有内容存储在上下文窗口中就能访问相关信息。

AI Agent 记忆的 RAG 实践:Claude-Mem

RAG 式 Agent 记忆中最精巧的实现是 Claude-Mem,一个为 Claude Code 提供持久化跨会话记忆的插件。

Claude-Mem 的架构展示了生产级 RAG 记忆的实际形态:

五层架构:

┌─────────────────────────────────────┐
│         Claude Code 会话            │
│  SessionStart → UserPrompt → Tools  │
│         (Hook 系统)                 │
└──────────────┬──────────────────────┘
┌─────────────────────────────────────┐
│     Worker 服务 (Port 37777)        │
│  Context Builder │ Session Manager  │
│  Search Manager  │ SSE Broadcaster  │
└──────┬──────────────────┬───────────┘
       │                  │
       ▼                  ▼
┌──────────────┐  ┌───────────────┐
│ SQLite + FTS5│  │   ChromaDB    │
│ (结构化存储)  │  │  (向量存储)    │
└──────────────┘  └───────────────┘

记忆捕获机制: Claude-Mem 使用 Claude Code Hooks 拦截每一次工具调用、用户提示和会话事件。PostToolUse hook 捕获原始的工具输出(文件读取、代码修改、命令执行结果),然后 AI Agent 将这些信息压缩为约 500 token 的结构化观察——实现 10:1 到 100:1 的压缩比。

记忆检索机制: 在会话启动时,SessionStart hook 查询数据库获取近期会话中的相关观察。SearchManager 运行混合搜索策略:

  • 向量相似度搜索(ChromaDB)——找到语义相关的记忆(“上周那个认证 Bug”)
  • 关键词搜索(SQLite FTS5)——精确匹配(“401 错误”、“JWT token”)
  • 混合排序——融合两种策略的结果

渐进式披露: Claude-Mem 不会将所有检索到的记忆一股脑注入上下文,而是采用三级方案:

  1. 索引搜索(每条结果约 50-100 token)——返回标题、日期、类型
  2. 时间线上下文——展示前后事件,帮助理解因果关系
  3. 完整详情(每条结果约 500-1000 token)——仅在需要时加载完整观察

相比简单粗暴的 RAG 注入,这种渐进式方案大约节省 10 倍 token。

RAG 的优势与不足

优势:

  • 可扩展到海量知识库(数千份文档)
  • 语义搜索即使措辞不同也能找到概念相关的信息
  • 管线搭建完成后全自动运行,无需人工策划
  • 新信息自动索引,动态更新

不足:

  • 检索质量不稳定——有时会检索到无关内容
  • 嵌入模型可能无法捕捉细微的技术差异
  • 基础设施开销大——需要向量数据库、嵌入服务、分块逻辑
  • 过时或错误的信息被注入上下文可能"毒化"模型输出
  • 检索到的内容块占用 token,压缩了实际工作的空间

上下文工程方案:结构化设计

上下文工程采取了截然不同的理念。它不是动态检索信息,而是 精心设计和策划进入上下文窗口的信息

这个术语因斯坦福 CS146S 课程和 Anthropic 的内部实践而广为人知。核心洞察是:AI Agent 的输出质量不取决于模型的能力,而取决于它接收到的上下文。正如一位实践者所说,“好的代码是好的上下文的副产品。”

上下文工程包含什么

上下文工程从五个维度展开:

维度描述示例
信息选择展示什么,隐藏什么只加载相关源文件,而非整个代码库
信息结构如何组织展示的内容分层文档:设计 → 计划 → 代码
信息质量确保没有错误或矛盾清理过时的注释和文档
信息时序何时提供何种信息先给架构概览,再给实现细节
工具配置通过工具扩展感知能力通过 MCP 连接数据库 schema、API 文档

CLAUDE.md:上下文工程的基石

最简单也最广泛使用的上下文工程工具是 CLAUDE.md——一个 Claude Code 在每次会话开始时读取的 Markdown 文件,充当持久化的、人工策划的记忆。

一个结构良好的 CLAUDE.md 通常包含:

## 项目概述
基于 FastAPI + SQLAlchemy 的电商 API 服务

## 技术栈
- 后端:FastAPI + SQLAlchemy
- 数据库:PostgreSQL 15
- 缓存:Redis
- 消息队列:RabbitMQ

## 编码规范
- 使用 pydantic v2 做数据验证
- 所有 API 端点必须有类型注解
- 错误处理使用自定义异常类

## 禁止事项
- 不要使用 ORM 懒加载
- 不要在 API handler 中写原始 SQL
- 不要用 print 调试——使用 structlog

这种方案优势明显:版本可控、人类可读、团队可共享,且完全确定性。Agent 每次看到的都是你放进去的内容,不多不少。

但它也有显著的局限性:

局限性影响
手动维护你必须决定添加什么、删除什么
静态内容无法自动捕获工作会话中的新发现
没有搜索文件越大,所有内容都会被加载到上下文中,无论是否相关
上下文预算文件越大,占用有限上下文窗口的空间越多

CLAUDE.md 之外:其他上下文工程工具

多种工具实现了上下文工程的模式:

Cursor Rules —— Cursor 的 CLAUDE.md 等价物,存放在 .cursor/rules/ 目录。支持 glob 模式匹配,为不同文件类型加载不同规则。backend.mdc 规则可能只应用于 Python 文件,而 frontend.mdc 应用于 TypeScript。

Kiro Steering Files —— Amazon 的 Kiro 使用 specs/ 目录存放结构化的规格文件。它不止于规则,还包含完整的产品需求、设计文档和实现计划。核心创新在于将规格视为版本控制的工件,直接驱动 AI 代码生成。

Agentic Docs 目录 —— 一种在团队中流行的模式:维护一个专门为 AI 消费而设计的 docs/ 层级结构:

docs/
├── designs/    → 产品需求、高层目标
├── plans/      → 详细实现计划
├── guides/     → API 教程、上手指南
schema.sql      → 数据结构定义
CLAUDE.md       → AI 专用指导

每一层都有明确的受众和用途。整个结构充当 Agent 可以导航的上下文,而非一个巨大的单体文件。

上下文的四种失败模式

上下文工程不仅关乎包含什么——同样关乎排除什么以及如何维护质量。研究表明有四种失败模式会降低 LLM 的表现:

1. 上下文毒化(Context Poisoning) —— 上下文中的错误信息会被放大。如果你的 CLAUDE.md 写着"使用 React class 组件"但代码库实际使用 hooks,Agent 会忠实地遵循过时的规则。一旦错误信息进入上下文,Agent 就会反复引用和强化它。

2. 上下文干扰(Context Distraction) —— 当上下文超过 32K token 时,模型倾向于重复近期的模式,而非合成新的策略。模型并非遗忘了早期的信息,而是被更近的内容 分散了注意力,导致决策质量下降。

3. 上下文混乱(Context Confusion) —— 过多的工具定义或无关信息会损害判断力。Berkeley 的函数调用基准测试显示,所有模型的表现都随着工具数量增加而下降。即使是 GPT-4 级别的模型,面对 40 个以上的工具时也会性能退化。

4. 上下文冲突(Context Conflict) —— 来自多个来源的矛盾信息会导致性能急剧下降。微软和 Salesforce 的研究发现,先提供部分错误答案再提供正确信息,会导致平均 39% 的性能下降——早期的错误信息会挥之不去,干扰最终判断。

实践启示:上下文不是"越多越好",而是"越精准越好"。 你给 AI Agent 的每一条信息都有成本——不仅是 token 的消耗,更是注意力的消耗。

RAG vs 上下文工程:正面对比

理解了两种方案之后,让我们直接比较。

维度RAG上下文工程
搭建成本高(向量数据库、嵌入服务、管线)低到中(Markdown 文件、目录结构)
维护方式基本自动需要人工策划
可扩展性可处理数千份文档最适合聚焦的项目级知识
精确度不稳定——取决于检索质量高——你完全控制包含什么
Token 效率中等——检索的内容块消耗 token高——策划过的内容更紧凑
团队共享复杂(共享向量数据库)简单(提交文件到 git)
动态性自动索引新信息需要手动更新
确定性不确定(检索结果会变化)确定性(同一文件,同一上下文)
毒化风险较高(过时的嵌入会持续存在)较低(人工审查内容)

何时选择 RAG

以下场景适合 RAG:

  • 你有 大规模且持续增长的知识库(数百份文档、API 参考、历史对话)
  • 你需要跨多样化内容的 语义搜索(“找到两周前关于限流的讨论”)
  • 你希望 自动捕获记忆,无需人工干预
  • 你的场景涉及 跨项目知识,单个配置文件装不下
  • 你在构建需要从交互中 持续学习 的系统

实际案例:Claude-Mem 的方案非常适合在多个项目间切换的个人开发者,让 AI Agent 记住数周以来的调试会话、架构决策和发现的模式。

何时选择上下文工程

以下场景适合上下文工程:

  • 你需要 确定性、可复现 的 Agent 行为
  • 团队需要 共享的、版本控制的 Agent 配置
  • 上下文质量比数量更重要——你追求 精确度而非覆盖度
  • 你在一个 单一项目 上工作,有明确的规范
  • 你想 完全掌控 Agent 知道和不知道什么

实际案例:维护生产级代码库的团队使用 CLAUDE.md 来强制执行编码标准、架构边界和部署流程。每个团队成员的 Agent 会话都从相同的策划过的上下文开始。

最佳实践:两者结合

最有效的策略是将两种方案组合成分层架构:

第 1 层:CLAUDE.md(静态规则)
  → 技术栈、编码规范、架构决策
  → 版本控制、团队共享、每次加载

第 2 层:结构化文档(上下文工程)
  → 设计文档、实现计划、API 指南
  → 根据任务上下文选择性加载

第 3 层:RAG 记忆(动态知识)
  → 对话历史、调试会话、新发现
  → 通过语义搜索动态检索

第 4 层:实时上下文(会话级别)
  → 当前文件内容、测试结果、错误信息
  → 会话中实时采集

可以这样理解:CLAUDE.md 是员工手册,结构化文档是项目 Wiki,RAG 是可搜索的工作日志,实时上下文是你面前的白板。四者缺一不可。

实战落地方案

方案一:极简配置(纯上下文工程)

对大多数个人开发者来说,从这里起步:

第 1 步: 在项目根目录创建 CLAUDE.md,写入技术栈、编码规范和关键架构决策。详细模板参见 CLAUDE.md 最佳实践指南

第 2 步: 维护一个 docs/ 目录,存放设计文档和实现计划。在 CLAUDE.md 中引用这些文档,让 Agent 知道去哪里找详细上下文。

第 3 步: 养成上下文卫生习惯:

  • 每周审查和更新 CLAUDE.md
  • 一次对话聚焦一个任务
  • 新话题开新会话,而非延续旧会话
  • 只启用当前任务需要的 MCP 服务

这个方案零基础设施投入,即刻生效。

方案二:RAG 增强记忆

当你需要跨会话记忆时:

第 1 步: 安装 Claude-Mem 或类似的记忆插件。它会钩入 AI Agent 的生命周期,自动捕获观察结果。

第 2 步: 配置上下文注入参数。从保守值开始——注入最近 10 次会话的观察,最多 50 条。

第 3 步: 使用渐进式披露。不要在会话开始时倾倒所有记忆。让 Agent 在需要时搜索特定记忆,使用索引优先的检索方式来减少 token 浪费。

第 4 步: 定期审计存储的记忆。RAG 系统随时间积累过时信息。审查并清理不再相关的记忆。

方案三:团队级上下文工程

适合使用 AI Agent 构建生产软件的团队:

第 1 步: 建立分层文档结构,同时服务于人类和 AI Agent:

CLAUDE.md              → Agent 专用规则和规范
docs/designs/          → 产品需求(做什么)
docs/plans/            → 实现计划(怎么做)
docs/guides/           → API 文档(如何使用)
schema.sql             → 数据库 schema(数据真相源)
.cursor/rules/         → 按文件类型的规则(Cursor 用户适用)

第 2 步: 像对待代码一样对待上下文文件。通过 Pull Request 审查对 CLAUDE.md 和设计文档的修改。上下文来源之间的矛盾会严重降低 Agent 的表现。

第 3 步: 实现动态上下文加载。不是每个任务都需要所有上下文。使用文件模式匹配(Cursor Rules)或任务专属的上下文注入,保持上下文窗口的聚焦。

第 4 步: 建立反馈循环。当 Agent 产出不符合预期时,分析是否是上下文问题——信息缺失、来源矛盾,还是上下文过载。据此调整你的上下文策略。

方案四:用 Python 构建自定义记忆

如果你想 从零构建自己的 AI Agent 并为其添加记忆功能,以下是一个最小化的 RAG 记忆实现:

import chromadb
from datetime import datetime

class AgentMemory:
    def __init__(self, collection_name="agent_memory"):
        self.client = chromadb.PersistentClient(path="./memory_db")
        self.collection = self.client.get_or_create_collection(
            name=collection_name,
            metadata={"hnsw:space": "cosine"}
        )

    def store(self, content: str, metadata: dict = None):
        """存储一条记忆,自动生成向量嵌入。"""
        doc_id = f"mem_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
        self.collection.add(
            documents=[content],
            ids=[doc_id],
            metadatas=[metadata or {}]
        )

    def recall(self, query: str, n_results: int = 5) -> list:
        """通过语义相似度检索相关记忆。"""
        results = self.collection.query(
            query_texts=[query],
            n_results=n_results
        )
        return results["documents"][0]

    def forget(self, older_than_days: int = 30):
        """清理过时记忆,防止上下文毒化。"""
        # 具体实现取决于你的 metadata schema
        pass

这是基础框架。生产系统还需要加上压缩(将原始观察总结为紧凑记忆)、混合搜索(结合向量相似度与关键词匹配)和渐进式披露(先返回摘要,按需加载详情)。

AI Agent 记忆的未来

记忆问题是 AI 工具链中最活跃的研发领域之一。以下几个趋势正在塑造未来走向:

记忆成为一等公民功能。 Anthropic、OpenAI 和 Google 都在将记忆能力直接嵌入模型和平台。像 CLAUDE.md 这样的上下文工程模式有望在各种工具中成为标准。

混合架构。 RAG 和上下文工程之间的界限正在模糊。Claude-Mem 已经将向量检索与结构化上下文注入相结合。未来的系统将无缝融合静态规则、动态检索和实时上下文。

上下文压缩。 随着模型压缩能力的提升,我们将看到更多系统选择总结和提炼上下文而非存储原始内容。Claude-Mem 的 Endless Mode——将工具输出的 token 增长从 O(N^2) 压缩到 O(N)——预示了这个未来。

团队记忆。 当前的记忆方案都是个人维度的。下一个前沿是共享团队记忆——一个开发者的调试会话可以自动惠及整个团队的 Agent 上下文。Anthropic 在 Claude Code Agent 团队协作 上的工作预示了这个方向。

核心要点

  1. AI Agent 深受会话失忆之苦 —— 会话之间丢失所有上下文,导致重复劳动和行为不一致。

  2. RAG 和上下文工程解决问题的不同部分。 RAG 通过语义搜索处理大规模动态知识库。上下文工程提供确定性的、策划过的、版本可控的 Agent 配置。

  3. 上下文的四种失败模式 —— 毒化、干扰、混乱和冲突——意味着更多的上下文并不总是更好。精准比数量更重要。

  4. 两种方案搭配使用。 用 CLAUDE.md 存放静态规则,用结构化文档提供设计上下文,用 RAG 实现跨会话记忆,用实时上下文处理当前任务。

  5. 从简单开始。 一份维护良好的 CLAUDE.md 文件就能以 20% 的投入获得 80% 的收益。只在需要跨会话知识检索时才引入 RAG 记忆。

  6. 像对待代码一样对待上下文。 对上下文文件做版本控制、审查变更、保持来源间的一致性。上下文腐化和代码腐化一样危险。

常见问题

RAG 和上下文工程在 AI Agent 记忆系统中有什么区别?

RAG 通过向量嵌入和向量数据库,在查询时动态检索相关信息。上下文工程则侧重于结构化地组织和策划上下文文件、类型系统以及策略性的提示词设计,在交互前就提供正确的信息。RAG 擅长处理大规模知识库,而上下文工程更适合项目级别的规则和约定。

为什么 AI 编程 Agent 需要记忆系统?

像 Claude Code 这样的 AI Agent 在会话结束时会丢失所有上下文——之前讨论的架构决策、调试发现和编码规范全部消失。记忆系统通过在会话之间持久化重要信息来解决这个"会话失忆症",减少重复的上下文设置工作,并持续提升 Agent 的表现。

CLAUDE.md 如何作为 AI Agent 的记忆系统运作?

CLAUDE.md 是一个放置在项目根目录的 Markdown 文件,Claude Code 在每次会话开始时都会读取它。它相当于持久化的、人工策划的记忆,包含项目规则、技术栈详情、编码规范和架构决策。与 RAG 不同,它需要手动维护,但能完全控制 Agent 所接收的信息。

可以同时使用 RAG 和上下文工程吗?

当然可以,而且这是推荐做法。使用 CLAUDE.md 存放静态的项目规则和规范(上下文工程),使用结构化文档管理设计上下文,再用 Claude-Mem 这样的 RAG 系统来处理动态的跨会话记忆。每一层服务于不同的目的,彼此互补。

什么是 AI Agent 中的上下文毒化?

上下文毒化是指错误或过时的信息进入 Agent 的上下文并被放大。例如,CLAUDE.md 中有一条过时的规则写着"使用 React class 组件",即使代码库已经迁移到 hooks,Agent 也会生成旧式代码。定期审计上下文文件可以预防这种失败模式。

相关阅读

Comments

Join the discussion — requires a GitHub account