【教程】为AI助手打造持久记忆系统:基于CodeBuddy的分层记忆架构设计与实践

摘要

本文详细介绍如何为AI编程助手构建一套完整的持久化记忆系统。通过分层记忆模型、即时写入策略和自动化提炼机制,让AI助手在跨会话场景下真正"记住你"。文章包含完整的架构设计、文件结构、提炼脚本和踩坑经验,适合对AI工具链定制感兴趣的开发者阅读。

思维导图

1. 为什么AI助手需要记忆系统

1.1 无状态对话的痛点

大多数AI助手都是"金鱼记忆"——每次新开一个会话,它就把你忘得干干净净。

说白了,你上午花了半小时跟AI解释你的项目架构、技术栈偏好、代码风格要求,下午开新会话又得重来一遍。更痛苦的是,AI不记得你之前做过的决策、踩过的坑、正在进行的工作。

打个比方:想象你有一个助手,每天上班都失忆,你得重新自我介绍、重新解释公司业务、重新说明你的习惯。

1.2 什么场景需要记忆

不是所有对话都需要记忆。以下场景是记忆系统的核心价值所在:

场景 痛点 记忆能解决什么
跨会话项目开发 每次重新解释项目背景 自动加载项目上下文和历史决策
多项目并行 搞混不同项目的配置 按项目分类存储和检索记忆
长期偏好 反复强调"用中文注释"“别问我要不要写” 一次记住,永久生效
踩坑记录 同一个坑踩两次 碎片记忆自动检索,避免重复
工作交接 昨天做到哪了? 临时记忆按天记录,次日自动加载

2. 记忆系统架构设计

2.1 整体架构概览

整个记忆系统分为 6 层,从最稳定(几乎不变)到最易变(每次对话都在更新),各层各司其职:

┌─────────────────────────────────────────────┐
│              记忆分层模型(6层)               │
├─────────────────────────────────────────────┤
│  L1  SOUL.md       AI行为准则      极低频更新  │
│  L2  USER.md       用户画像        低频更新    │
│  L3  CODEBUDDY.md  全局配置        低频更新    │
│  L4  MEMORY.md     永久记忆        每日自动    │
│  L5  daily-memories/ 临时记忆      每次对话    │
│  L6  .memories/    碎片记忆        按需更新    │
└─────────────────────────────────────────────┘

首先,L1 到 L3 是手动维护的,定义了"AI是谁"、“用户是谁”、“全局怎么配置”。

其次,L4 到 L6 是自动运转的——临时记忆实时写入,永久记忆每晚提炼,碎片记忆按需触发。

2.2 文件系统布局

~/Library/Application Support/CodeBuddyExtension/Data/Public/
├── SOUL.md                 # L1: AI 行为准则(灵魂文件)
├── USER.md                 # L2: 用户画像与偏好
├── CODEBUDDY.md            # L3: 全局配置中心
├── MEMORY.md               # L4: 永久记忆(每晚自动提炼)
├── daily-memories/          # L5: 临时记忆(按天划分)
│   ├── 2026-02-28.md       # 今天的记忆
│   ├── 2026-02-27.md       # 昨天的记忆
│   ├── 2026-02-26.md
│   ├── ...
│   └── archive/            # 超过7天的自动归档
│       └── 2026-02-13.md
├── .memories/               # L6: 碎片记忆(系统托管)
│   ├── 11391733.mdc
│   ├── 24252772.mdc
│   └── ...                 # 每条记忆一个文件,ID 为唯一标识
└── internal-rules/          # 全局规则
    └── *.mdc

这套目录结构参考了 ClawdBot 的分层记忆架构,但做了不少定制化调整——比如增加了 daily-memories/archive/ 归档机制和按天自动切割。

3. 各层记忆详解

3.1 SOUL.md — AI 行为准则(灵魂文件)

这是整个系统的"宪法",定义了AI的核心身份和行为模式。每次会话启动时第一个被读取

核心内容

## 核心身份

我是 **用户的 AI 编程助手**,基于 Claude 构建,运行在 CodeBuddy IDE 中。

### 核心原则

主动 > 被动
行动 > 询问
完整 > 片段
深度 > 表面

不过,SOUL.md 不只是空洞的口号,它还定义了非常具体的 SOP(标准作业程序)

  1. 会话启动 SOP:自检 → 识别用户 → 加载上下文 → 主动加载记忆 → 执行任务
  2. 代码输出准则:直接写完整代码,不问"要我写吗?"
  3. 信息搜索顺序:iWiki → 互联网 → 代码库
  4. Git 操作准则:本地修改自由执行,推送远程必须确认

说实话,SOUL.md 的核心价值在于让AI保持一致性。没有它,AI在不同会话中的行为模式可能天差地别。

更新频率:极低频,只有当你发现AI的行为准则需要调整时才改。

3.2 USER.md — 用户画像

这个文件让AI知道"我在帮谁干活"。

包含的信息

类别 示例内容
基本信息 姓名、公司、职位、技术领域
技术栈偏好 Go⭐⭐⭐⭐⭐、Java⭐⭐⭐⭐、MySQL⭐⭐⭐⭐⭐
代码风格 中文注释、完整可运行、显式错误处理
写作风格 直白坦诚、代码驱动、深度优先
交互偏好 直接高效、不需要客套、推送前确认
生活背景 (可选)非工作相关的背景信息

关键是,USER.md 是可自动更新的。当AI在对话中检测到用户偏好变化时,会自动同步更新这个文件。

比如用户说"以后代码注释用英文",AI会立即更新 USER.md 中的"注释语言"字段,而不是等用户手动去改。

3.3 CODEBUDDY.md — 全局配置中心

类似于一个 config.yaml,但用 Markdown 写的——因为AI读 Markdown 比读 YAML 更自然。

核心配置

## 环境信息
| 配置项 | 值 |
|--------|-----|
| 操作系统 | macOS (darwin) |
| Shell | zsh |
| 用户名 | your_username |
| CodeBuddy 数据目录 | ~/Library/Application Support/CodeBuddyExtension/Data/Public |

## MCP 服务配置
| 服务器 | 用途 |
|--------|------|
| cvm_shell | CVM 命令执行 |
| cynosdb_mysql | MySQL 数据库查询 |
| gongfeng | 代码仓库操作 |

## 数据库环境配置
| 环境名 | Host | 数据库 |
|--------|------|--------|
| DEV | x.x.x.x | your_dev_database |
| TEST | x.x.x.x | your_test_database |

CODEBUDDY.md 还包含了项目快捷入口——列出所有活跃项目的路径、技能、规则,让AI快速定位到正确的项目上下文。

3.4 MEMORY.md — 永久记忆(自动提炼)

这是整个系统最有意思的部分。MEMORY.md 不是手动维护的,而是由定时任务每晚 23:00 自动从临时记忆中提炼生成。

提炼策略

临时记忆(7天内) → 去重 → 过滤琐碎 → 优先级排序 → 按项目分类 → MEMORY.md

实际效果:

## 近期活动摘要

### 活跃项目
| 项目 | 最近活动 | 主要工作 |
|------|----------|----------|
| aiagent | 2026-02-28 | AI Agent 集群集成 Claude Internal |
| mariadb | 2026-02-28 | MDEV-33814 修复完成 |
| goloangsdk | 2026-02-26 | 5个CL等待审核 |

### ⭐ 核心要点(优先级排序)
- **[2026-02-28]** 新增主会话拆分模式(execute/execute_step),性能提升 ~3x
- **[2026-02-26]** 记忆系统重构为子 Agent 架构 v2
- **[2026-02-27]** 完成单元测试编写并全部通过

说白了,MEMORY.md 就是AI的"每周工作总结",只不过是自动生成的。

3.5 daily-memories/ — 临时记忆(按天划分)

这是记忆系统的主力写入层。每次对话完成有意义的工作后,AI 会立即写入当天的记忆文件。

文件格式

# 2026-02-28 每日记忆

## 会话记录

### 会话 1: AI Agent 集群集成
- **时间**: 2026-02-28 上午
- **项目**: /path/to/project
- **工作内容**:
  1. 实现了 xxx 功能
  2. 端到端测试成功

### 会话 2: 另一个任务
- **时间**: 2026-02-28 下午
- **工作内容**: ...

## 今日要点
- 完成了 xxx
- 修复了 xxx

## 待办
- [ ] 待完成的任务

生命周期

创建 → 7天内在线(可被AI加载) → 7天后归档到 archive/ → 核心信息已提炼到 MEMORY.md

3.6 .memories/ — 碎片记忆(系统托管)

碎片记忆是由 CodeBuddy 内置的 update_memory 工具自动管理的。每条记忆一个 .mdc 文件,文件名是唯一 ID。

文件格式

---
enabled: true
updatedAt: 2026-02-26T07:49:57.791Z
---

当内置的 web_fetch 工具无法抓取动态渲染的 SPA 页面时,
应使用 playwright MCP 工具的无头浏览器来获取页面内容。

碎片记忆的特点是短小精悍——一条记忆不超过一段话,但非常具体。AI 在需要时会自动检索相关的碎片记忆。

典型的碎片记忆内容

  • 某个项目的特定配置(数据库连接信息、API 格式等)
  • 某个工具的使用注意事项
  • 某个决策的记录(“更新 TAPD 缺陷时用评论而不是修改描述”)

当前系统中有 45 条碎片记忆在运行,涵盖了从项目配置到工具使用技巧的方方面面。

4. 记忆的读写机制

4.1 会话启动:记忆加载流程

每次新开一个会话,AI 必须完成以下加载流程——这是在 SOUL.md 中用 SOP 强制规定的:

会话启动
    │
    ├── 并行读取 ──────────────────────────────────────┐
    │   1. SOUL.md(行为准则)                          │
    │   2. USER.md(用户画像)                          │
    │   3. MEMORY.md(永久记忆摘要)                     │
    │   4. daily-memories/今天.md                       │
    │   5. daily-memories/昨天.md                       │
    │                                                   │
    └── 同时处理用户请求(不阻塞)<────────────────────────┘

关键设计点:记忆加载和用户请求并行。用户不需要等 AI 读完所有文件才开始干活。

4.2 子 Agent 架构(v2)

这是经过多次迭代后的架构。最初的 v1 是主 Agent 直接读写所有记忆文件,但这有两个问题:

  1. token 膨胀:读取 5 个文件的完整内容会占用大量上下文窗口(约 3000+ token)
  2. 职责不清:读取、写入、索引混在一起

v2 拆分为三个子 Agent:

Agent 触发时机 职责 token 开销
memory-indexer 会话启动(自动) 读取所有记忆,返回 200 字精简摘要 ~200 token
memory-reader 对话中按需 查阅特定记忆,返回 300 字相关摘要 ~300 token
memory-writer 完成工作后 写入 daily-memories,同步 USER.md 0 (写入)

核心原则

  • 主会话不直接读记忆文件,通过子 Agent 代理(节省 token)
  • 记忆加载与用户请求并行,不阻塞首次响应
  • 记忆写入与用户回复并行,不阻塞交互

不过,v2 还踩了一个坑——子 Agent 没有写入权限。所以 v2.2 做了修正:写入操作回归主 Agent 执行,子 Agent 只负责读取。

4.3 写入时机与策略

这是整个系统最关键的设计决策,也是踩坑最多的地方。

v1 策略(失败的):会话结束时写入。

问题是——AI 无法感知"会话何时结束"。用户可能直接关闭窗口、切换项目、或者就是不再说话了。结果是从 2 月 13 号到 2 月 24 号,整整 11 天没有任何 daily-memories 文件产生。定时任务每晚 23:00 正常运行,但因为没有新记忆文件可以提炼,所以一直在空跑。

v2 策略(当前方案):即时写入——完成有意义的工作后立即写入。

什么时候写:
  ✅ 完成一个代码修改/修复
  ✅ 重要决策(选了方案A不选方案B)
  ✅ 代码提交/部署
  ✅ 发现用户新偏好
  ✅ 排查/修复问题

什么时候不写:
  ❌ 纯闲聊
  ❌ 简单查询("这个函数什么意思?")
  ❌ 格式修复/typo

防遗漏三道防线

  1. 即时写入:完成工作 = 写入记忆,不等"对话结束"
  2. 自检机制:每次回复前自检是否有未写入的有意义工作
  3. 跨轮续传兜底:新会话启动时,如果 Summary 中有已完成工作但今日记忆无记录,立即补写

4.4 记忆冲突处理

当新信息与已有记忆冲突时(比如用户改了偏好),处理逻辑是:

  1. 使用 update_memorydelete action 删除旧碎片记忆
  2. 创建新记忆或更新对应文件
  3. 永远不要同时保留冲突的记忆

5. 自动化提炼与归档

5.1 定时任务设计

使用 macOS 的 launchd 配置定时任务,每晚 23:00 自动执行:

# 手动执行提炼(用于调试)
python tools/memory_consolidator.py consolidate

# 查看记忆系统状态
python tools/memory_consolidator.py status

# 手动归档超过7天的记忆
python tools/memory_consolidator.py archive 7

5.2 提炼策略详解

提炼脚本 memory_consolidator.py 实现了 5 层过滤管道:

第一层:信息提取

从 daily-memories 的 Markdown 文件中提取结构化数据:

def extract_key_info(content: str, date_str: str) -> Dict:
    info = {
        'date': date_str,
        'projects': [],      # 项目列表
        'decisions': [],     # 关键决策
        'todos': [],         # 待办事项
        'highlights': [],    # 今日要点
        'tasks': [],         # 工作内容
        'completed': []      # 已完成项
    }
    # 通过正则匹配 **项目**: xxx、**任务**: xxx 等格式
    # ...

第二层:去重

基于文本相似度的智能去重——先标准化文本(去掉 Markdown 格式、日期前缀、emoji),然后用 Jaccard 相似度判断是否重复:

def deduplicate_items(items, similarity_threshold=0.8):
    # 精确去重 + 模糊去重(相似度 > 0.8 视为重复)
    # ...

实际效果:决策从 14 条去重到 12 条,已完成从 14 条去重到 8 条。

第三层:过滤琐碎

过滤掉不值得长期记忆的信息:

def is_trivial(text: str) -> bool:
    trivial_patterns = [
        r'^测试.*$',           # 测试相关
        r'^修复.*typo.*$',     # 拼写错误修复
        r'^调整.*格式.*$',     # 格式调整
        r'^临时.*$',           # 临时任务
    ]
    # 太短的信息(< 5字符)也过滤
    # ...

第四层:优先级排序

按关键词权重排序——“架构”、“设计”、"决策"这类词权重最高,“学习”、"理解"权重最低:

priority_keywords = [
    '架构', '设计', '决策', '重要', '关键', '核心',  # 高权重
    '问题', '修复', 'bug', '故障',                    # 中权重
    '完成', '上线', '发布', '合并',                    # 中权重
    '学习', '理解', '掌握',                            # 低权重
]

第五层:按项目分类

决策和要点按项目归类,便于 AI 快速检索特定项目的历史信息。

5.3 归档机制

超过 7 天的 daily-memories 文件会被自动移动到 archive/ 目录:

daily-memories/
├── 2026-02-28.md    ← 在线(可被AI加载)
├── 2026-02-27.md    ← 在线
├── ...
├── 2026-02-22.md    ← 即将归档
└── archive/
    └── 2026-02-13.md  ← 已归档(但核心信息已提炼到 MEMORY.md)

归档不是删除——归档文件仍然保留在磁盘上,只是不再被 AI 主动加载。如果需要查阅历史,memory-reader 子 Agent 可以按需读取归档文件。

6. 实际效果展示

6.1 daily-memories 示例

以下是一个真实的每日记忆文件(敏感信息已脱敏):

# 2026-02-28 每日记忆

## 会话记录

### 会话 1: AI Agent 集群集成
- **时间**: 2026-02-28 上午
- **项目**: /path/to/aiagent
- **工作内容**:
  1. 实现了 ClaudeInternalClient,通过 CLI 模式实现 LLMClient 接口
  2. 端到端测试成功:task → planTask(LLM分析) → executeStep(LLM执行) → 返回结果

### 会话 2: 新增 execute / execute_step 工具
- **时间**: 2026-02-28 上午(会话1之后)
- **工作内容**:
  1. 新增 execute MCP 工具——主会话直接传入执行计划,跳过 planTask
  2. 端到端测试:execute_step ~13.7s(vs delegate ~40s),性能提升 ~3x

## 今日要点
- AI Agent 集群成功集成新的 LLM 后端
- 新增主会话拆分模式(execute/execute_step),省掉内部规划的 LLM 调用
- 支持三种 MCP 传输模式:stdio / SSE / Streamable HTTP

## 待办
- [ ] 探索进程池复用,避免每次调用都启动新进程
- [ ] 探索 A2A 协议支持

6.2 碎片记忆示例

碎片记忆是最小粒度的记忆单元,通常是某个具体的技术细节或操作规范:

---
enabled: true
updatedAt: 2026-02-26T07:49:57.791Z
---

当内置的 web_fetch 工具无法抓取动态渲染的 SPA 页面
(如 Gerrit Code Review 等 JavaScript 动态加载的页面)时,
应使用 playwright MCP 工具的无头浏览器来获取页面内容。
---
enabled: true
updatedAt: 2026-02-13T06:44:27.739Z
---

搜索信息时,优先搜索 iWiki(使用 aiSearchDocument 工具),
如果 iWiki 没有相关内容,再搜索互联网(使用 web_search 工具)。

当前系统中运行着 45 条碎片记忆,涵盖了项目配置、工具使用技巧、开发流程规范等方方面面。

6.3 MEMORY.md 提炼效果

自动提炼后的永久记忆,按项目分类、按优先级排序:

## 近期活动摘要

### ⭐ 核心要点(优先级排序)
- **[2026-02-26]** 修复记忆系统写入权限和跨轮遗漏问题(v2.2)
- **[2026-02-27]** 完成单元测试编写并全部通过
- **[2026-02-26]** 记忆系统重构为子 Agent 架构 v2(indexer/reader/writer)

## 💡 关键决策记录(按项目分类)

### 记忆系统
- **[2026-02-24]** 采用方案 A(即时写入),琐碎记录由定时任务去重/提炼兜底

## 📝 待办事项(未完成)
- [ ] **[2026-02-24]** 改进记忆系统,确保每次会话都能写入临时记忆

提炼统计:原始数据 14 条决策 → 去重后 3 条,14 条已完成 → 去重后 0 条(已归档),15 条待办 → 去重后 2 条。

7. 踩坑记录与优化

7.1 记忆写入遗漏问题(最大的坑)

问题:2 月 13 号搭建完记忆系统后,直到 2 月 24 号才发现——整整 11 天,daily-memories 目录是空的。

根因:最初的设计是"会话结束时写入",但AI根本无法感知会话何时结束。用户可能直接关闭IDE、切换项目、或者就是不回消息了。

修复:改为"即时写入"策略——完成有意义的工作后立即写入。同时在规则文件中加了强制约束:

> ⚠️ **不要等会话结束!完成有意义的工作后立即写入!**

这个教训很深刻:不要假设AI知道什么时候"该做某事",要用规则明确告诉它时机。

7.2 子 Agent 架构的演进

版本 架构 问题
v1 主 Agent 直接读写 token 膨胀(~3000 token)
v2 三个子 Agent(indexer/reader/writer) writer 子 Agent 无文件写入权限
v2.2 两读一写(reader/indexer 为子 Agent,writer 回归主 Agent) 目前稳定运行

v2 到 v2.2 的修复看起来很小,但踩坑过程很痛苦。子 Agent 是在沙箱中运行的,没有文件系统的写入权限,所以所有写入操作必须回到主 Agent 执行。

7.3 定时任务空跑问题

问题:定时任务每晚 23:00 正常执行,但一直输出"没有找到最近的临时记忆"。

根因:就是 7.1 提到的写入遗漏问题。定时任务本身没有 bug,是上游没有数据喂进来。

教训监控不能只看"任务是否运行",还要看"任务是否有实际产出"。后来在 status 命令中增加了更详细的统计:

$ python tools/memory_consolidator.py status

📊 记忆系统状态

🗂️ 核心文件:
   ✅ USER.md (5120 bytes)
   ✅ SOUL.md (8192 bytes)
   ✅ MEMORY.md (2560 bytes)

📅 临时记忆 (daily-memories/):
   ✅ 2026-02-28.md (3072 bytes) 📍 今天
   ✅ 2026-02-27.md (1024 bytes) 📍 昨天
   ✅ 2026-02-26.md (4096 bytes)

🗃️ 归档记忆:
   共 1 个归档文件

📝 今天的记忆:
   会话数: 4
   待办: 6 个未完成, 0 个已完成

8. 总结

搭建这套记忆系统前前后后折腾了大半个月,从最初的"会话结束写入"到现在的"即时写入 + 子 Agent + 自动提炼",中间踩了不少坑。但效果确实很明显——现在每次开新会话,AI 都能在几秒内加载完所有上下文,知道我是谁、在做什么项目、昨天做到哪了。

回顾一下核心设计决策:

  1. 分层存储:6 层记忆各司其职,从极低频的行为准则到每次对话的临时记忆
  2. 即时写入:不要等"合适的时机",完成工作就写,琐碎的交给定时任务去重
  3. 子 Agent 隔离:读取操作通过子 Agent 代理,节省主会话 token
  4. 自动提炼:定时任务每晚提炼,去重 → 过滤 → 排序 → 分类,保持永久记忆精简

这套系统目前还在持续迭代中,比如碎片记忆的检索效率、跨项目记忆的关联等,都有优化空间。不过对于日常使用来说,已经够用了。

以后还需要继续努力。加油!

参考资料

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐