Pensieve

AI Agent 的项目记忆系统 — 深度架构解析

v1.3.0 · by kingkongshot

🧠 1. 问题:AI Agent 的失忆症

大语言模型(LLM)驱动的 AI Agent 在编码场景中面临一个根本性矛盾:模型有卓越的推理能力,但没有持久记忆。每次新会话开始,Agent 对项目的认知归零——它不知道上周为什么选择了方案 A 而不是方案 B,不知道这个模块有哪些坑,不知道哪些规则必须遵守。

这导致三个反复出现的问题:

🔄

重复探索

每次都要重新 grep 代码、重新理解模块边界、重新推导调用链路。相同的问题被反复"发现"。

💀

决策遗忘

"上次为什么这样设计来着?" 架构决策的上下文丢失,后人(或后会话)推翻前人决策却不自知。

🎲

行为不一致

没有可复用的工作流。commit 时该检查什么、refactor 时该遵循什么——每次都是临场发挥。

Pensieve 的核心命题: 项目级的"经验"如何从一次会话传递到下一次会话?不是靠模型记忆,而是靠结构化的外部知识库

💡 2. 设计哲学

Pensieve 的名字来自《哈利波特》中的冥想盆(Pensieve)——一个可以存储和提取记忆的容器。但它的设计思想更接近于人类的长期记忆系统

📌 经验不是参数,是结构

Fine-tuning 改变模型的参数,但无法精确传递"这个项目的 API 必须幂等"这类具体知识。Pensieve 选择符号化、可编辑、可版本控制的 Markdown 文件作为记忆载体,而不是向量数据库中的浮点数。

📌 分层治理,而非一锅煮

不是所有知识都同等重要。一个跨越项目、跨越语言的工程原则("消除特殊情况")和一个特定文件的调用链路,需要不同的管理策略。Pensieve 用四层语义模型区分知识的"硬度"。

📌 短期缓冲,长期沉淀

新结论不直接写入长期目录——先进入 short-term/ 缓冲区,7 天后由人工或 Agent 审查。这避免了噪声积累,确保长期知识库的质量。

📌 系统代码与用户数据物理隔离

Pensieve 的引擎代码(.src/)和项目知识数据(.pensieve/)完全分离。git pull 更新引擎永远不会触碰你的项目数据。

🏗️ 3. 双层架构:系统代码 vs 项目数据

Pensieve 采用两级锚点设计,将"引擎"和"数据"物理隔离:

┌─────────────────────────────────────────────────────────────────┐
│                    系统级 (User-Level, Global)                   │
│                                                                 │
│  ~/.claude/skills/pensieve/          ← 全局 git clone,只读引擎  │
│  ├── SKILL.md                        ← 静态路由声明              │
│  ├── .src/                           ← 核心引擎                 │
│  │   ├── core/                      ← Python 核心 (schema, 分类)│
│  │   ├── scripts/                   ← Shell 脚本 (hooks, 维护)  │
│  │   ├── templates/                 ← 种子模板                  │
│  │   ├── references/                ← 规范文档                  │
│  │   └── tools/                     ← 七工具规范                │
│  └── agents/                         ← Agent 元数据              │
│                                                                 │
│  一次安装,所有项目共享                                          │
└─────────────────────────────────────────────────────────────────┘
                              ↕ 读取模板 / 执行脚本
┌─────────────────────────────────────────────────────────────────┐
│                   项目级 (Project-Level, Per-Project)            │
│                                                                 │
│  /.pensieve/                ← 每个项目独立的知识库      │
│  ├── maxims/                         ← 工程铁律 (MUST)          │
│  ├── decisions/                      ← 架构决策 (WANT)          │
│  ├── knowledge/                      ← 探索缓存 (IS)            │
│  ├── pipelines/                      ← 可复用工作流 (HOW)       │
│  ├── short-term/                     ← 短期缓冲区 (STAGING)     │
│  │   ├── maxims/  decisions/  knowledge/  pipelines/            │
│  ├── state.md                        ← 动态生命周期状态          │
│  └── .state/                         ← 运行时产物 (gitignored)  │
│      └── pensieve-user-data-graph.md ← 知识图谱 (Mermaid)       │
│                                                                 │
│  可提交到 git,随项目版本控制                                    │
└─────────────────────────────────────────────────────────────────┘
关键设计决策: .src/manifest.json 是定位技能根目录的锚点。任何包含此文件的目录就是系统技能根。脚本通过它自举,不依赖硬编码路径。

🧱 4. 四层语义模型

Pensieve 的核心创新之一是将知识按"硬度"分为四层,每层有不同的准入标准、生命周期和管理策略:

语义 目录 准入标准 例子
MUST Maxim(铁律) maxims/ 跨项目、跨语言仍成立;违反则回归风险剧增;可一句话说完 "消除特殊情况优于增加条件判断"
WANT Decision(决策) decisions/ 去掉后未来更易犯错;三个月后能帮后人少走弯路 "选择浮窗工作台而非内联 tab"
IS Knowledge(事实) knowledge/ 可验证、可追溯;不写会反复拖慢执行 "diagnosis provider 的 CLI 边界"
HOW Pipeline(工作流) pipelines/ 同类型任务已复现 3 次以上;步骤不可互换;每步可验证 "run-when-committing.md"

为什么是四层而不是一层?

如果所有知识都扔进一个目录,Agent 无法区分"这是必须遵守的铁律"和"这是上次探索的缓存"。四层模型让 Agent 在读取知识时天然获得优先级信号

🔴 MUST — 不可违反

违反这些规则的代码不应该被提交。Agent 在 code review 时可以直接引用 maxim 作为拒绝理由。

🟠 WANT — 应该遵循

架构决策有上下文和被拒绝的替代方案。Agent 可以理解"为什么这样做"而不只是"怎么做"。

🔵 IS — 参考事实

探索结果的缓存。可能过时,需要验证。Agent 可以先查缓存,miss 时再 grep。

🟣 HOW — 执行流程

标准化的工作流。Agent 不需要临场发挥,按 pipeline 步骤执行即可。

short-term/ — 短期缓冲机制

新结论不直接写入长期目录。先进入 short-term/,结构与长期目录镜像:

1

self-improve 捕获

Agent 从会话 + diff 中提取 insight,写入 short-term/{type}/

2

7 天 TTL 计时

基于 created 日期 + 7 天。过期后触发提醒(session hook / doctor / commit pipeline)

3

refine 审查

五问决策法:删除?合并?提升到长期目录?填缺后保留?

4

提升或删除

mv short-term/{type}/file.md {type}/file.md,链接零更新(因为 [[...]] 不含 short-term 前缀)

5. 双系统决策:快思考与慢思考

Pensieve 的知识检索 Agent(pensieve-wand)受 Daniel Kahneman《思考,快与慢》启发,实现了双系统决策

⚡ System 1:直觉匹配(零工具调用)

  • 触发条件:查询关键词命中 MEMORY.md 中的路由条目
  • 成本:零工具调用,纯上下文匹配
  • 精度:高(人工筛选过的路由)
  • 适用:高频问题、已知领域

🧠 System 2:预算探索(有约束的深度搜索)

  • 触发条件:System 1 未命中,或条目标记为 [slow]
  • 预算:图节点 ≤ 5 个文件,Grep ≤ 2 次,总工具调用 ≤ 10
  • 终止:问题有定论 / 预算耗尽 / 连续 2 次搜索无新信息
  • 适用:新领域、复杂问题

知识升级路径

  新查询
    │
    ├─→ MEMORY.md 关键词命中 ─→ System 1:零工具调用直接回答
    │     └─ 需要细节?最多读 1 个路由文件或 pensieve 条目
    │
    ├─→ MEMORY.md [slow] 命中 ─→ System 2:从已知线索出发,预算约束
    │
    └─→ 全 miss ─→ System 2:完整图谱探索,预算约束
         │
    调查结束
    ├─→ 答案确定 ─→ 写入 MEMORY.md 内联条目(升级为 System 1)
    ├─→ 线索不完整 ─→ 写 slow_{topic}.md + 标记 [slow]
    └─→ 一次性查询 ─→ 不写入
核心思想: 快速的 80% 回答优于缓慢的 100% 回答。大多数高频问题应该在 System 1 就解决。System 2 有严格的认知预算,防止 Agent 陷入无限探索。

🔧 6. 七大工具

Pensieve 提供七个职责分明的工具,每个工具有明确的边界——"负责什么"和"不负责什么":

工具 职责 触发场景 关键约束
init 初始化项目数据目录,播种种子文件 首次集成 Pensieve / 重装后 幂等;不覆盖已有用户数据
upgrade 刷新全局技能源码(git pull) 更新 Pensieve 版本 不迁移结构,不发 PASS/FAIL
migrate 迁移遗留数据,对齐目录结构和关键文件 旧路径清理、关键文件漂移 不更新版本,不发 PASS/FAIL
doctor 只读健康扫描,输出固定格式报告 init/upgrade/migrate 后验证 不修改业务代码
self-improve 从会话 + diff 提取 insight,写入 short-term 任务轮次结束 / commit 前 新条目进 short-term;已有文件原地编辑
refine 五问审查 + 压缩知识库 short-term 过期 / 定期维护 压缩产生的新条目走 short-term
sync-instructions 将 pipeline 短路由写入 CLAUDE.md / AGENTS.md pipeline 变更后同步 不生成项目摘要,不内联完整 pipeline

工具路由

SKILL.md 作为路由入口,根据用户请求的关键词将请求分发到正确的工具。Agent 不需要记住所有工具的用法,只需要把请求交给 Pensieve,它自己会路由。

⚙️ 7. Pipeline 工作流引擎

Pipeline 是 Pensieve 中 HOW 层的具体实现。它不是简单的任务列表,而是带有信号判断、验证循环和失败兜底的可执行工作流

Pipeline 的三个创建条件

不要滥用 Pipeline! 只有同时满足以下三个条件时才创建:
1. 同类型任务已复现 3 次以上
2. 步骤顺序不可互换
3. 每个步骤有可验证的完成标准

内置 Pipeline

Pensieve 初始化时播种三个核心 Pipeline:

📝

run-when-committing

commit 前自动提取 insight 并捕获。三步:信号判断 → 自动捕获 → 原子提交。

🔨

run-when-refactoring

重构前确认真实问题,先修上游数据权威性,分步交付,删除旧路径。

🔍

run-when-reviewing-code

从 git 历史和热点文件出发,验证候选问题,只报告高信号发现。

Pipeline 骨架

---
id: run-when-xxx
type: pipeline
title: Pipeline Name
status: active
description: [触发场景, 跳过代价, 触发关键词]
---

## Signal Rules
- 只保留可复现、可定位、有证据支撑的结果

## Task Blueprint
### Task 1: [目标]
- Input: [文件/路径]
- Steps: [编号、具体、可执行]
- Completion criteria: [可验证]

### Task 2: ...

## Failure Fallback
1. 输入缺失时停止
2. 证据不足时过滤
3. 无高信号结果时明确声明

🕸️ 8. 知识图谱与链接系统

Pensieve 的知识不是孤立的文件——它们通过 [[...]] 链接形成有向图

链接规则

链接类型 指向 例子
Based on: 前置知识或决策 [[knowledge/auth-flow/content]]
Leads to: 后续流程或决策 [[decisions/2026-03-16-api-design]]
Related: 并行主题 [[maxims/reduce-complexity]]

图谱生成

generate-user-data-graph.sh 扫描所有 [[...]] 链接,生成 Mermaid 格式的知识图谱,输出到 .pensieve/.state/pensieve-user-data-graph.md。图谱按目录分组(subgraph),每个节点 ID(如 n80)对应一个条目。

short-term 链接的巧妙设计

零成本提升: [[...]] 链接不含 short-term/ 前缀。图谱解析器在处理 short-term 文件时自动剥离前缀,与长期文件共享节点 ID。这意味着 mv 提升条目时,所有引用它的链接零更新

🔄 9. 生命周期管理

Pensieve 用一个明确的状态机管理项目数据的生命周期:

  ┌──────────┐     init      ┌──────────┐    doctor PASS    ┌──────────┐
  │  EMPTY   │ ──────────→   │  SEEDED  │ ──────────────→   │ ALIGNED  │
  │          │               │          │                   │          │
  │ 缺根目录 │               │ 缺关键文件│                   │ 健康状态  │
  └──────────┘               └──────────┘                   └────┬─────┘
                                                                 │
                                                          doctor FAIL
                                                                 │
                                                            ┌────▼─────┐
                                                            │ DRIFTED  │
                                                            │          │
                                                            │ 结构漂移  │
                                                            └──────────┘
                                                                 │
                                                              migrate
                                                                 │
                                                            ┌────▼─────┐
                                                            │ ALIGNED  │
                                                            └──────────┘

状态由 pensieve_core.pyclassify_state() 函数确定:

def classify_state(*, has_missing_root, has_missing_directories,
                   has_missing_critical_files, must_fix_count):
    if has_missing_root or has_missing_directories:
        return "EMPTY"
    if has_missing_critical_files:
        return "SEEDED"
    if must_fix_count == 0:
        return "ALIGNED"
    return "DRIFTED"

state.md 是动态生成的,由 maintain-project-state.sh 在每次生命周期事件(install/upgrade/migrate/doctor/self-improve/sync)后刷新。

🪝 10. Hook 机制

Pensieve 通过 Claude Code 的 Hook 系统注入自动化行为:

Hook 时机 脚本 作用
SessionStart pensieve-session-marker.sh 会话启动时标记,检查 short-term 过期提醒
PreToolUse (Explore/Plan) explore-prehook.sh 在探索前注入 SKILL.md + state.md 提示,让 Agent 先查 Pensieve
PostToolUse (Write/Edit) sync-project-skill-graph.sh 文件修改后自动同步知识图谱

Hook 配置写入 ~/.claude/settings.json,对所有项目全局生效。没有 .pensieve/ 的项目不受影响(Hook 静默退出)。

⚖️ 11. 对比:为什么不用 RAG / Vector DB

✅ Pensieve 方案

  • Markdown 文件 = 人类可读、可 diff、可 merge
  • 语义分层 = 知识硬度可区分
  • git 版本控制 = 完整审计轨迹
  • 链接系统 = 显式关系,不依赖向量相似度
  • 零依赖 = 不需要 embedding 模型 / 向量数据库
  • Agent 可直接编辑 = 自改进闭环

❌ RAG / Vector DB 方案

  • 向量 = 人类不可读、不可 diff
  • 扁平存储 = 无法区分"铁律"和"缓存"
  • embedding 漂移 = 模型更新后向量不可比
  • 相似度检索 = 语义相近 ≠ 语义相关
  • 外部依赖 = 需要维护向量数据库
  • 黑盒 = Agent 无法自解释检索过程
Pensieve 的赌注: 在项目级知识管理的场景下,结构化 > 向量化。知识的价值不在于"语义相似",而在于"结构正确"——正确的分层、正确的链接、正确的生命周期。

🚀 12. 实践指南

快速开始

# 1. 全局安装(一次性)
git clone -b main https://github.com/kingkongshot/Pensieve.git ~/.claude/skills/pensieve

# 2. 安装 Hooks(一次性)
bash ~/.claude/skills/pensieve/.src/scripts/install-hooks.sh

# 3. 初始化项目(每个项目)
cd <your-project>
bash ~/.claude/skills/pensieve/.src/scripts/init-project-data.sh

# 4. 验证
bash ~/.claude/skills/pensieve/.src/scripts/run-doctor.sh --strict

日常使用

开始编码前

Agent 自动通过 pensieve-wand 检索项目知识。你不需要手动触发。

Commit 时

run-when-committing pipeline 自动运行:判断是否有 insight → 捕获 → 原子提交。

定期维护

运行 refine 清理过期的 short-term 条目,压缩知识库。

更新 Pensieve

cd ~/.claude/skills/pensieve && git pull --ff-only,然后跑 doctor

refine 的五问决策法

这是 Pensieve 知识质量管理的核心算法:

# 问题 否 → 是 →
Q1 删除后,未来是否会重复犯错或重复探索? DELETE → Q2
Q2 有证据支撑吗(代码、文档、实验结果)? DELETE → Q3
Q3 是否已被现有条目覆盖? → Q4 DELETE(合并后删除)
Q4 写作时的上下文现在还成立吗? DELETE → Q5
Q5 是否符合目标层的内容规范? 补齐缺失或 DELETE KEEP / PROMOTE

三种压缩技术

🔼 向上抽象

多个条目展现同一模式 → 提炼更高层抽象,删除原始条目。例:三个"API 必须幂等" → 一条 maxim "所有外部 API 必须幂等"。

🔗 提取共享

多个条目重复引用同一事实 → 提取为独立条目 + [[...]] 引用。例:三个决策都描述同一流程 → 提取为 knowledge 条目。

💎 消除特殊情况

看似不同的条目实际是同一深层原则的特例 → 写深层原则,删除表面规则。例:"不在 handler 操作 DB" + "Service 层管理事务" → "关注点分离"。