AI 的记忆分三层,主流工具做到了第几层

wescode · 2026-10-04 · 记忆 / 认知结算 / 对比

利益声明:本文作者参与了 wescode 的开发。文中涉及 wescode 的技术描述基于内部测试数据;涉及其他工具的描述基于各家公开文档和社区反馈。

你第 17 次打开新对话,输入这段话:

我们项目用 TypeScript + React,后端 Node.js + Express。
日期处理统一用 dayjs,不要用 moment.js。

你上周说过。上上周也说过。AI 回答得很好——但它不记得你说过。

不是模型笨。是工具没有给它记忆。每次新对话,上下文从零开始。你说的项目偏好、技术决策、历史纠正,全部清零。你花了 30 秒教 AI 一件事,下次还得花 30 秒再教一遍。一天开 10 个对话,你就是 AI 的人肉缓存。


记忆的三个层次

按持久性分,AI 编程工具的"记忆"有三层:

层次持久性内容用户负担
第一层:会话内记忆仅限当前对话这轮对话里你说了什么、AI 改了什么无——对话内天然保持
第二层:跨会话规则手动维护的文件.cursorrules、CLAUDE.md、.github/copilot-instructions.md你要写、你要改、你要记得更新
第三层:长期认知记忆自动积累 + 持久化偏好、纠正、决策、事实无——对话结束自动提炼

用一个具体例子说明三层的区别——同样一条"不要用 moment.js"在三层记忆里分别怎么运作。

第一层:只在这次对话里有效

// 第一轮
// 用户:帮我写一个日期格式化工具函数
// AI 输出:
import moment from 'moment'
export const formatDate = (d: Date) => moment(d).format('YYYY-MM-DD')

// 用户:不要用 moment.js,用 dayjs
// AI 修正:
import dayjs from 'dayjs'
export const formatDate = (d: Date) => dayjs(d).format('YYYY-MM-DD')

// 同一对话的第二轮
// 用户:再写一个日期范围选择器组件
// AI 自动用 dayjs——因为对话历史里有这条纠正

下一次新对话呢? AI 又会用 moment.js。因为上下文窗口清零了。你在上一次对话里教它的事,它完全不记得。

第二层:你手动写一条规则

你打开项目根目录的 .cursorrules 文件,加一行:

日期处理统一使用 dayjs,禁止 moment.js。

以后每次新对话,AI 都能看到这条规则——它被注入到系统提示词里。

但代价是你要维护这个文件。 项目里有 30 条这样的偏好——API 前缀用 /api/v2、错误处理用 neverthrow、测试框架用 vitest、import 按类型分组排序——你需要自己记住哪些该写进去,写进去之后规范变了要不要更新。本质上是把一部分记忆负担从"每次对话重复说"转移到了"维护一个配置文件"。

第三层:AI 自己记住

用户:帮我写日期格式化
AI:(用了 moment.js)
用户:不要用 moment.js,用 dayjs
AI:好的,已改为 dayjs。

──── 对话结束,认知结算自动触发 ────
AI 提炼出一条偏好:日期库使用 dayjs,不使用 moment.js
写入长期记忆(本地 SQLite)

──── 三天后,新对话 ────
用户:帮我写一个日期范围选择器
AI:(直接用 dayjs——因为长期记忆里已有这条偏好,被注入到了系统提示词)

你什么都不用做。 不用维护文件,不用重复说,不用记住自己说过什么。


各家做到第几层

Cursor — 第一层 + 第二层

对话内有完整上下文(第一层)。跨对话靠 .cursorrules 文件和 Notepad(第二层)。@Past Chats 可以引用历史对话——但这是手动搜索后手动 @,你得记住在哪次对话里说过什么。

没有第三层。 你上次纠正 AI"不要用 moment.js",下一次对话它不知道。除非你自己写进 .cursorrules。

Claude Code — 第一层 + 第二层

对话内记忆 + CLAUDE.md 规则文件。Claude 的长上下文窗口(200K tokens)意味着单次对话可以持续很多轮不丢信息——但这是第一层的增强,不是跨对话记忆。开一个新对话,仍然从零开始。

Claude Code 还有一个隐含的记忆机制:它会在对话中主动提议更新 CLAUDE.md,让有价值的发现写回规则文件。这比纯手动维护好一步——但本质仍然是第二层,只是降低了维护门槛。

GitHub Copilot — 第一层 + 部分第二层

对话内上下文 + .github/copilot-instructions.md(2024 年底推出,功能较新)。指令文件的支持度不如 .cursorrules 成熟——比如不支持按文件类型设置不同规则。没有第三层。

通义灵码 / Trae — 第一层

主要是对话内记忆。通义灵码有"代码风格学习"功能——可以从你的代码库中学习命名风格和模式,算隐性的第二层,但不如规则文件可控和透明。Trae 没有独立的跨会话规则机制。两者都没有第三层——你的偏好和纠正不会跨会话延续。

wescode — 第一层 + 第二层 + 第三层

wescode 在前两层之上,通过认知结算(Cognitive Settlement)实现了自动化的长期认知记忆。基于 VS Code Fork,你的扩展、快捷键、主题全部保留。第三层的记忆不需要你写任何配置文件——对话结束时自动提炼,下次新对话自动生效。


认知结算:怎么把对话变成记忆

认知结算的数据流向

认知结算的完整技术流程:

对话进行中(用户和 AI 来回对话,正常工作)
 │
对话结束,触发认知结算(Run 终态的强制阶段)
 │
主模型提炼认知产物
(和对话用的是同一个模型,不是辅助小模型)
 │
 ┌────┼────┬────┐
 事实 偏好 纠正 决策
 │ │ │ │
去重(ContentDedupKey)
同样内容不重复写入——你说了三次"用 dayjs"只存一条
 │
冲突检测(Supersession)
新记忆和旧记忆矛盾 → 标记旧记忆"已被取代"
 │
写入本地 SQLite
每个工作区(Cell)物理隔离
 │
下次新对话自动加载到系统提示词
不占上下文窗口

Before/After 对比——两天的真实场景:

时间没有第三层记忆有第三层记忆
Day 1 上午第 1 个对话教 AI"用 vitest 不要 jest"教 AI"用 vitest 不要 jest"
Day 1 上午第 2 个对话又要说一遍"用 vitest"AI 已经记住,自动用 vitest
Day 1 下午第 3 个对话又说一遍 + 教 AI"import 分三组排序"AI 记住了 vitest + 教 import 排序
Day 2 上午第 4 个对话两件事都要重复AI 记住所有偏好,直接按规范写
Day 2 下午第 5 个对话发现还要教"API 错误用 Result 类型"AI 记住前面的 + 教 Result 类型
一周后每次新对话重复 5+ 条偏好(~2min/次)所有偏好自动生效,0 重复
累计浪费一周 50+ 对话 × 2min = ~100 分钟0 分钟

结算完成后,下一次新对话的系统提示词里会自动多出这些内容:

# 系统提示词中注入的长期记忆(用户不可见,AI 可见)
# 格式类似于:

"""
[长期记忆 — 关于我]
- 日期库使用 dayjs,不使用 moment.js(偏好,来源:对话纠正)
- 测试框架使用 vitest(偏好,来源:对话纠正)
- import 排序:React 在前,第三方次之,本地在后(偏好,来源:认知结算)
- API 错误处理使用 neverthrow 的 Result 类型(决策,来源:认知结算)
"""

# 你看不到这些注入(它们在系统提示词里,不在对话界面里)
# 但 AI 能看到——所以新对话一开始就"记得"你的偏好

三个关键设计:

认知结算的架构设计

主模型做提炼,不是辅助模型。 用来提炼认知的是正在对话的那个模型本身——它完整参与了对话过程,理解上下文,提炼质量等于对话质量。不是事后用一个便宜的小模型做"总结"。

写入本地,不上传。 记忆存在本地 SQLite 数据库里,不上传到任何服务器。一个重度使用半年的项目,记忆数据通常在 1-5 MB(内部测试数据)。

按工作区隔离。 每个 VS Code 工作区对应一个独立的 Cell——A 项目的记忆不会串到 B 项目。前端项目的"用 Tailwind 不用 styled-components"不会影响后端项目。


七层记忆体系

wescode 的记忆不是一个扁平列表,按用途分成七层。日常使用不需要理解全部层——记忆中心(管理界面)会展示每条记忆属于哪一层。

层内容示例来源持久性隔离方式
环境信息macOS 15.3 / Node 22 / pnpm 已安装 / Go 1.23引擎感知器自动采集每次启动刷新按工作区(Cell)
部门共识团队规范:API 统一 RESTful + OpenAPI 文档admin 写入持久Cell 级共享
关于我偏好 tabs 缩进、dayjs、vitest、函数式风格认知结算自动提炼持久按用户(actor)隔离
角色记忆Agent "code-reviewer" 的审查清单和行为准则认知结算 / 手动写入持久按 agent 命名空间
会话记忆当前对话的工作上下文和进度运行时产生会话期间按 session
工作缓存临时计算中间状态、搜索结果片段运行时产生短期按 session
未识别未归入以上类别的条目兜底视情况无

日常开发最常触发的是第三层"关于我"——你在对话中表达的偏好、纠正、技术选型,都被认知结算自动提炼到这一层。

用 Java 类比理解记忆的层次隔离:

// 理解记忆隔离的类比——不是真实实现
public class MemoryIsolation {

    // 环境层:进程级,所有 Cell 共享宿主环境
    // SharedSnapshot(ctx) → 每进程感知一次,5min TTL
    static HostSnapshot sharedEnv;

    // 共识层:Cell 级,部门内所有人共享
    // 团队规范、架构约定
    Map<String, MemoryEntry> consensus; // key: Cell 全局

    // 关于我:Cell 内按 actor 隔离
    // 张三的偏好不会出现在李四的对话里
    Map<String, Map<String, MemoryEntry>> aboutMe;
    // aboutMe.get("zhangsan") → 张三的偏好列表
    // aboutMe.get("lisi") → 李四的偏好列表

    // 角色记忆:按 Agent 命名空间隔离
    // code-reviewer 的记忆和 architect 的记忆独立
    Map<String, Map<String, MemoryEntry>> agentMemory;
    // agentMemory.get("code-reviewer") → 审查经验
    // agentMemory.get("architect") → 架构决策
}

各工具记忆能力详细对比

技术债——记忆缺失的累积成本

不只看"有没有",看具体能记什么、怎么记、存在哪。

能力维度CursorClaude CodewescodeCopilot通义灵码Trae
会话内记忆✅ 标准✅ 长上下文强✅ 标准✅ 标准✅ 标准✅ 标准
跨会话规则文件✅ .cursorrules✅ CLAUDE.md✅ 支持✅ .github/⚠️ 隐性学习无
自动长期记忆无无支持(认知结算)无无无
记住偏好每次重说每次重说自动积累每次重说无无
记住纠正无无纠正存入记忆无无无
冲突处理——Supersession 检测———
过期清理——Digest 自动归档———
按项目隔离规则跟仓库规则跟仓库Cell 物理隔离规则跟仓库无无
存储位置——本地 SQLite———
引用历史✅ @Past Chats无✅ 自动注入无无无

Cursor 和 Claude Code 的前两层已经做得很好——尤其 Claude Code 的长上下文能力让单次对话体验非常强。差距在第三层:跨会话的自动记忆积累。


记忆有什么实际用处

场景一:偏好积累。 你连续三次纠正 AI "测试用 vitest 不要用 jest"。有第三层记忆后第四次不用说了——这条纠正已经存入长期记忆,每次新对话自动生效。

场景二:决策记录。 "上周我们决定把 REST API 迁移到 tRPC"——进入记忆后,之后所有新对话生成的代码都会用 tRPC,不用每次重复这个决定。

场景三:教训学习。 AI 上次在 utils/date.ts 里用了 moment.js,你纠正了。这个纠正被认知结算存入记忆后,AI 以后不会再犯同样的错——不管过多少天、隔多少次对话。

场景四:团队新人。 新同事接手项目,打开 wescode——"关于我"层有前任积累的偏好,"部门共识"层有团队的技术规范。新人不需要读完所有历史 PR 和 README 就能让 AI 按项目约定写代码。

场景五:技术选型变更。 你上周决定"把 Mocha 换成 vitest",这条决策被认知结算存入记忆。之后所有新对话生成测试代码都用 vitest——你不需要在每个对话里提醒 AI,也不需要去改规则文件。如果两个月后你又换回 jest,新的纠正会触发冲突检测,旧的"用 vitest"被标记为已被取代。


认知结算记不住什么

诚实说,不是所有对话内容都值得变成长期记忆:

记不住(不会进入长期记忆)为什么
一次性调试命令(console.log(data) 排查完就删)临时操作,下次无复用价值
临时变量名(const tempList = ...)上下文依赖太强,脱离当前代码段无意义
纯操作性步骤("先打开文件 A,再跳转到第 23 行")是操作不是认知——记住了下次也用不上
上下文依赖太强的片段和当前代码状态强耦合,代码一改就失效
跨项目知识A 项目的记忆不会串到 B 项目——物理隔离
引擎内部状态(Plan 步骤、任务编排中间态)被内容质量门控拦截,不允许写入记忆

这是设计选择:宁可少记,不要记错。 记错一条偏好(比如把临时尝试记成长期决策)比没记住要有害得多——记错了会持续影响后续每一次对话。

所有写入记忆的内容都经过内容质量门控和威胁模式扫描——引擎状态前缀、凭据片段都会被拦截。

换个角度理解:认知结算只记可迁移的认知——脱离当前对话、放到未来任何一次对话里仍然有用的东西。


记忆冲突和过期

认知结算的技术实现

两个机制保证记忆不会越积越乱:

冲突检测(Supersession)。 你三个月前说"用 REST API",上周说"迁移到 tRPC"。两条记忆矛盾——新记忆写入时自动检测冲突,标记旧记忆为"已被取代"。被取代的记忆不再注入到对话,但保留在记忆中心可查看和恢复。

过期归档(Digest)。 长时间未被召回的记忆自动标记为 stale,超过一定期限归档。归档不是删除,需要时可以恢复。淘汰算法不是简单的 LRU——用的是 recall-frequency weighted 评分(RetentionScore),被频繁使用的记忆不会因为"最近没用到"就被错误清理。

用 TypeScript 伪代码理解冲突检测的逻辑:

interface MemoryEntry {
  id: string;
  content: string;
  kind: 'preference' | 'correction' | 'decision' | 'fact';
  createdAt: Date;
  accessedAt: Date;
  recallCount: number;
  conflicted: boolean;  // 被 Supersession 标记
  stale: boolean;       // 被 Digest 标记
}

function detectSupersession(
  newEntry: MemoryEntry,
  existingEntries: MemoryEntry[]
): MemoryEntry[] {
  const conflicted: MemoryEntry[] = [];
  for (const old of existingEntries) {
    // 语义相似度超过阈值(0.4)且包含否定标记
    if (semanticSimilarity(old.content, newEntry.content) > 0.4
        && containsNegation(newEntry.content, old.content)) {
      old.conflicted = true;
      conflicted.push(old);
    }
  }
  return conflicted;
  // "用 dayjs 不要 moment" → 旧的 "用 moment" 被标记 conflicted
}

举个例子:"用 dayjs 不用 moment.js"这条偏好被召回了 40 次——RetentionScore 很高,即使三个月没碰日期相关代码也不会被归档。而"上次那个 API 返回了 502"只被召回过 1 次,30 天没再提起就进入 stale 状态。


常见问题

Q:我不想让 AI 记住某些东西怎么办?

A:记忆中心可以查看和删除任何一条记忆。支持按层筛选——比如只看"关于我"这一层的偏好记忆,或者只看"角色记忆"。七层芯片恒定渲染——即使某一层是空的也会显示 0,让你清楚知道"这层是空的"而不是"这层不存在"。删除操作是即时的,下一次对话就不会再看到被删的记忆。

Q:Cursor 的 Notepad 和 @Past Chats 算记忆吗?

A:Notepad 是手动写笔记供对话引用,@Past Chats 是手动搜索历史对话——本质上都是第二层(手动维护)的变体。你需要主动去写、去搜、去 @。和自动积累的第三层记忆是不同的东西。

Q:Claude Code 的对话内记忆那么强,还需要第三层吗?

A:Claude Code 单次对话确实很强——200K 上下文窗口让一次对话可以持续很多轮。但 AI 编程不是一次长对话。你一天开十几个对话、一周开上百个。第一层再强,也只在当次对话里有效。第三层解决的是跨越这些对话的知识延续。

Q:记忆会不会越积越乱?

A:两个机制防止这个问题。冲突检测:新旧记忆矛盾时,旧记忆自动标记"已被取代"、不再注入。过期归档:长期未被召回的记忆自动标记 stale 并归档。淘汰用 recall-frequency weighted 评分,不是简单的 LRU。此外,所有写入都经过内容质量门控——引擎状态前缀、纯操作步骤、凭据片段都会被拦截,从源头控制记忆的质量。

Q:规则文件(.cursorrules / CLAUDE.md)和第三层记忆冲突了怎么办?

A:规则文件是显式声明,长期记忆是对话中隐式积累。如果两者矛盾——比如 .cursorrules 写了"用 moment.js",但记忆里有一条"用 dayjs"——显式声明优先。规则文件是团队级别的约定,记忆是个人偏好的积累。


本文对各工具记忆能力的描述基于其 2026-09-20 的公开文档和功能。