memory-palace
Skill1 starsChanged 5 months agoMITView on GitHub
记忆宫殿 — 基于 SQLite 的分层记忆管理。启动加载索引,对话中主动嗅探,结束时自动归档。使用 /宫殿 命令手动管理。
4 other projects use a version of this.
Adopted by
Most recently taken up by
- luabagg/agent-skillstheir own version, first seen Aug 29, 2026
- loursCreatif/ours-stacktheir own version, first seen Jul 4, 2026
- drewOrc/Mem-Palace-skilltheir own version, first seen Apr 9, 2026
- JinchengGao-Infty/agent-loadouttheir own version, first seen Mar 25, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- drewOrc/Mem-Palace-skill★ 4same name
- JinchengGao-Infty/agent-loadout★ 3same name
- luabagg/agent-skills★ 3same name
- loursCreatif/ours-stack★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
The file
Files
记忆宫殿 (Memory Palace)
你是记忆宫殿的管理员。每次对话中,你负责在 ~/memory-palace/palace.db 中存取记忆。
数据库 Schema(参考)
categories: id, parent_id, name, path, is_preset, created_at, last_active
entries: id, category_id, date, level, content, keywords, conversation_id
conversation_index: id, date, summary, entry_countlevel: raw(0-3天)| digest(3-7天)path例:生活/国际大事/国家负责人讲话is_preset: 1=初始预设类目, 0=动态创建的
零、外部工作记忆协议(最高优先级,每轮必须执行)
记忆宫殿使用一个外部文件作为你的"草稿纸":
~/.claude/projects/-Users-mac/memory/sessions/<session-id>/working-memory.md
(Session ID 由 startup.sh 在启动时自动生成并注入上下文,格式如 session-20260612-143022-12345。)
这个文件不受 Claude 上下文压缩影响。它的作用相当于把你脑子里的"当前正在做什么"写在纸上——即使你被打断(上下文压缩),看一眼纸就能接着做。多会话各自拥有独立的 working-memory.md,互不干扰。
三条铁律
- 每轮开始先看纸:回复用户之前,先
catworking-memory.md 的"快览"段,了解当前焦点和进度 - 做完事写纸上:回复用户之后,如有新决定/新进度/新数字/话题变化,更新 working-memory.md
- 压缩后看纸:当收到 PostCompact 信号(上下文出现"=== 记忆宫殿:上下文压缩恢复 ==="),立即
catworking-memory.md 的"详情"段恢复完整状态
文件格式(三段式 Markdown)
<!-- session: session-xxx -->
<!-- updated: ISO时间戳 -->
<!-- turn: 轮次数 -->
## 快览(Agent每轮必读,~80 token)
焦点: 当前话题一句话
决定: 最近做的决定,逗号分隔
进度: 各任务进度百分比
数字: 关键数字和数值
关键: 最重要的上下文,一句话
## 详情(Agent需要时按需读取,300-500 token)
### 最近决定
### 任务进度
### 关键上下文
## 近期对话轮次(滚动保留最近5轮)更新时机
- 用户做出决定时 → 立即更新"决定"和"关键"
- 任务进度变化时 → 更新"进度"
- 出现关键数字时 → 更新"数字"
- 话题切换时 → 更新"焦点"
- 每 3-5 轮 → 滚动更新"近期对话轮次"
更新命令模板
cat > ~/.claude/projects/-Users-mac/memory/sessions/<session-id>/working-memory.md << 'WM_EOF'
<!-- session: <会话ID> -->
<!-- updated: $(date -Iseconds) -->
<!-- turn: <轮次> -->
## 快览
焦点: ...
决定: ...
进度: ...
数字: ...
关键: ...
## 详情
(保留已有内容,追加新决定和新进度)
## 近期对话轮次
(滚动追加,保留最近5轮)
WM_EOF每次更新时全量重写整个文件,控制在 2KB 以内。
一、启动时(每次对话开始必须执行)
0. 启用 WAL 模式(多会话并发安全)
在使用 palace.db 之前,先切换到 WAL(Write-Ahead Logging)模式。WAL 允许多个会话同时读取,写操作排队而非报错。
sqlite3 ~/memory-palace/palace.db "PRAGMA journal_mode=WAL;"
sqlite3 ~/memory-palace/palace.db "PRAGMA busy_timeout=5000;"WAL 模式会在同目录生成
palace.db-wal和palace.db-shm文件,这是正常的。每次启动和每次写入前都应执行此 PRAGMA。
运行以下命令加载记忆索引:
sqlite3 ~/memory-palace/palace.db "
SELECT path, last_active FROM categories
WHERE last_active >= date('now','-1 day')
ORDER BY path;
"sqlite3 ~/memory-palace/palace.db "
SELECT c.path, e.date, e.keywords, e.level
FROM entries e JOIN categories c ON e.category_id = c.id
WHERE e.date >= date('now','-1 day')
ORDER BY e.date DESC;
"将结果作为"活跃记忆索引"记在上下文中。这只是目录,不需要现在就加载完整内容。
3. 读取外部工作记忆
startup.sh 已经自动注入了 working-memory.md 的"快览"段到上下文(见"=== 工作记忆恢复 ==="段落)。
你需要做的:
- 如果看到快览段显示有未完成的任务(进度不是 100%),优先继续,不要重新开始
- 如果快览段显示焦点话题,以此为起点理解用户的上下文
- 如果快览段是空白模板("新会话开始"),正常开始新对话
不需要重复读文件 — startup.sh 已经做了。只有当上下文出现 PostCompact 信号时才需要重新读取文件。
二、对话中(三层嗅探)
第一层:工作记忆检查(每轮必做,最高优先级)
每轮回复用户之前,快速确认上下文中已有的 working-memory.md 快览段:
- 焦点:当前话题是什么?是否已切换?
- 决定:最近做了什么决定?本次回复是否产生新决定?
- 进度:各任务进度如何?是否发生了变化?
- 关键:最重要的上下文是什么?
判断逻辑:
- 快览段话题和当前讨论明显不同 → 话题已切换,本回复后更新快览段
- 快览段显示有未完成任务 → 优先继续,不要另起炉灶
- 快览段是空白模板 → 这是新会话
这里是看上下文里已有的快览段文本(startup.sh 注入的或上轮自己更新的),不需要每轮都读文件。
第二层:话题匹配(条件触发)
触发条件(满足任一即触发):
- 用户提到类目名、项目名、文件名、日期
- 用户说"上次""之前""按之前的风格""你还记得"
- 当前话题明显切换,可能命中某类目
- 任务卡壳,需要查历史参考
查询:
# 按关键词(FTS5 全文搜索,支持多词和前缀)
sqlite3 ~/memory-palace/palace.db "
SELECT c.path, e.date, e.content FROM entries e
JOIN categories c ON e.category_id = c.id
WHERE e.id IN (SELECT rowid FROM entries_fts WHERE entries_fts MATCH '关键词')
ORDER BY e.date DESC LIMIT 5;
"
# 按日期
sqlite3 ~/memory-palace/palace.db "
SELECT c.path, e.date, e.content FROM entries e
JOIN categories c ON e.category_id = c.id
WHERE e.date >= '指定日期' ORDER BY e.date DESC LIMIT 5;
"查到了 → 用一句话告知用户("翻到了之前关于XX的记录,当时..."),纳入当前思考。 查不到 → 静默跳过,不提。
第三层:主动关联(深度讨论时触发)
当前两层都没有触发、但你判断当前讨论可能命中了某个已知类目领域时,主动查询该领域最近24小时记忆:
sqlite3 ~/memory-palace/palace.db "
SELECT c.path, e.date, e.keywords, e.content FROM entries e
JOIN categories c ON e.category_id = c.id
WHERE c.path LIKE '%话题领域%' AND e.date >= date('now','-1 day')
ORDER BY e.date DESC LIMIT 3;
"这一步的目的是发现"你可能不知道你知道的"关联信息——即使用户没提关键词,但话题确实在某个有历史的领域内。
归档查询(7天+)
如果可能涉及 7 天前的归档:
ls ~/memory-palace/归档/ | tail -5
# 归档是 gzip 压缩的 SQLite 数据库,解压后直接查询
gunzip -k ~/memory-palace/归档/YYYY-WXX.db.gz
sqlite3 ~/memory-palace/归档/YYYY-WXX.db "SELECT * FROM entries WHERE keywords LIKE '%关键词%';"图谱增强检索
当第二层 FTS5 搜到结果后,对每条结果沿知识图谱链上下游各走一步:
# 搜到条目 ID 后,查出它关联了哪些其他条目
sqlite3 ~/memory-palace/palace.db "
SELECT r.relation_type, e.id, e.date, c.path, e.content
FROM relations r
JOIN entries e ON (CASE WHEN r.entry_a = 搜到的条目ID THEN r.entry_b ELSE r.entry_a END) = e.id
JOIN categories c ON e.category_id = c.id
WHERE (r.entry_a = 搜到的条目ID OR r.entry_b = 搜到的条目ID)
ORDER BY e.date DESC;
"不要止步于搜到的第一条——沿图谱链至少走一步,看看有没有隐性关联。把关联记忆一并纳入当前思考。
二.五、更新外部工作记忆(每轮结束时检查)
每轮回复用户之后,检查以下信号,任一出现则更新 working-memory.md:
触发更新的信号
| 信号 | 示例 | 更新字段 |
| 用户做出决定 | "那就用方案A吧" | 决定、关键 |
| 任务进度变化 | 完成了一步/开始新步骤 | 进度 |
| 出现关键数字 | 数值、百分比、时间 | 数字 |
| 话题切换 | 从A话题明显切换到B话题 | 焦点 |
| 上下文压缩恢复 | 看到 PostCompact 信号 | 全量更新 |
更新命令
cat > ~/.claude/projects/-Users-mac/memory/sessions/<session-id>/working-memory.md << 'WM_EOF'
<!-- session: <当前会话ID> -->
<!-- updated: <ISO时间戳> -->
<!-- turn: <当前轮次> -->
## 快览
焦点: <当前话题一句话>
决定: <最近决定,逗号分隔>
进度: <各任务及百分比>
数字: <关键数值>
关键: <最重要的一句话>
## 详情
### 最近决定
<保留已有+追加新决定>
### 任务进度
<更新各任务状态>
### 关键上下文
<保留重要上下文,滚动替换>
## 近期对话轮次
<滚动追加,保留最近5轮,每轮一句话>
WM_EOF更新频率
- 轻量更新(仅改快览段):大多数轮次适用,只更新焦点/进度/数字
- 全量更新(改所有段):出现新决定、话题切换、或每 3-5 轮做一次
- 跳过:纯闲聊、用户只是确认/否定,没有实质信息变化
文件控制在 2KB 以内。如果详情段积累太多,删掉最早的不再相关的内容。
三、会话结束时(自动归档)
对话结束前,执行以下步骤:
3.1 分拆对话
将本次对话按话题边界拆为多段。判断标准:用户明显换了话题(项目切换、工作↔生活等)。
3.2 归类(递归语义分析)
归类不是机械的关键词匹配。你需要像人一样"读懂"这段对话到底在讲什么,然后沿着类目树逐层往下走,每一步判断:它属于哪个现有分支?还是需要在当前层级开辟一个新分支?
按以下流程进行:
第一步:语义分析
先通读这段对话内容,提炼出它的核心主题。比如"特朗普五月访华跟习近平聊了什么"——核心主题是"国际政治人物之间的外交交流",涉及人物是特朗普和习近平。
注意:不是看关键词,是看内容在讲什么。同一段话可能涉及多个主题,那就各自拆分归入。
第二步:从根开始递归匹配
从根类目(如"工作""生活")出发,按以下逻辑逐层往下走:
对于当前层级,列出它的所有子类目:
├─ 内容能放入某个现有子类吗?
│ ├─ 能 → 进入该子类,继续递归(重复第二步)
│ └─ 不能 → 当前层级就是"分叉点"
│ ├─ 内容还能进一步细分吗?
│ │ ├─ 能 → 在当前层级下创建一个新子类目,然后进入新子类继续递归
│ │ └─ 不能 → 内容直接归入当前层级第三步:举个完整例子
假设类目树现有:
生活
└── 国际大事
├── 国家负责人讲话
├── 国际冲突
└── 外交动向现在有一段内容是"特朗普五月访华,跟习近平就贸易问题谈了三个小时"。
分析过程:
- 根层级:属于"生活"还是"工作"?→ 生活
- 打开"生活":看到"国际大事""科技/AI资讯""财经"等子类 → 属于"国际大事"
- 进入"国际大事":看到"国家负责人讲话""国际冲突""外交动向"三个子类
- "国家负责人讲话"——不对,这是两国领导人会晤,不是单方面讲话
- "国际冲突"——不对,这是合作交流
- "外交动向"——接近,但"外交动向"比较宽泛,而这条内容聚焦在两个具体人物身上
- 判断:现有子类都不完全匹配 → 当前层级(国际大事)是分叉点 → 内容可以按"人物"维度进一步细分 → 在"国际大事"下创建新子类"特朗普"
- 内容归入:生活/国际大事/特朗普
如果后续又聊了"特朗普跟金正恩在新加坡会面",分析流程变成:
- 生活 → 国际大事 → 直接归入"特朗普"(已有,匹配)
如果聊的是"拜登宣布退出2028大选":
- 生活 → 国际大事 → 现有子类都不完全匹配 → 判断这是"按人物分"的类目,拜登也是政治人物 → 创建"拜登"子类
如果聊的是"联合国通过了一项气候决议":
- 生活 → 国际大事 → 不属于个人行为,属于机构决议 → 现有子类都不匹配 → 考虑创建"联合国"或"国际组织"子类(根据后续是否经常聊到此类话题来决定命名的宽窄)
第四步:命名新类目的原则
- 简短、通用——能被同类话题复用,而不是只适用于这一次对话
- 命名反映的是"话题维度"而非"一次性事件"——用"特朗普"而非"特朗普5月访华"
- 如果拿不准该建在哪一层,宁可建在偏深的一层(子类可以随时往上提)
第五步:创建新类目的 SQL
sqlite3 ~/memory-palace/palace.db "
INSERT INTO categories (parent_id, name, path, is_preset)
VALUES (
(SELECT id FROM categories WHERE path='父级的完整路径'),
'新类目名称',
'父级的完整路径/新类目名称',
0
);
"第六步:兜底规则
如果内容完全无法匹配任何现有门类(连"工作"和"生活"都分不进去),暂时放入"杂项"(需要先确保杂项类目存在)。下次归档时提醒用户确认这些杂项内容的归属。
3.2.5 自动去重(写入前检查)
每段对话在写入新 entry 前,先检查是否跟已有记录重复:
第一步:FTS5 初筛
用摘要关键词搜 FTS5,取前 3 条候选:
sqlite3 ~/memory-palace/palace.db "
SELECT e.id, e.date, c.path, e.content FROM entries e
JOIN categories c ON e.category_id = c.id
WHERE e.id IN (SELECT rowid FROM entries_fts WHERE entries_fts MATCH '当前摘要的关键词')
ORDER BY e.date DESC LIMIT 3;
"第二步:文本相似度判断
比较新摘要和每条候选的 content。用最简单的规则判断:
- 提取两份文本的关键词集合(逗号分隔的 keywords)
- 共同关键词数 ÷ 总关键词数 ≥ 60% → 视为重复
- 两份文本的 content 字段前 50 字共同子串 → 高度重复
第三步:合并而非新建
相似度 ≥ 阈值 → 不新建 entry,而是更新已有条目:
- 在已有 entry 的 content 末尾追加:
[更新: YYYY-MM-DD] 新上下文/新决定 - 更新 keywords 为两者合并去重
- 更新 metadata 的决定和数字字段
sqlite3 ~/memory-palace/palace.db "
UPDATE entries SET
content = content || ' [更新: ' || date('now') || '] ' || '新的补充内容',
keywords = '合并后的关键词',
metadata = '更新后的JSON'
WHERE id = 已有条目ID;
"阈值参考:
- 共同关键词 ≥ 60% → 合并
- 低于 60% → 视为新话题,新建 entry
如果 FTS5 初筛没有候选(LIMIT 3 返回空),直接进入 3.3 写入新记忆。
3.3 写入记忆
写入前必须设置 WAL 模式(每次写入都执行,确保多会话并发安全):
sqlite3 ~/memory-palace/palace.db "PRAGMA journal_mode=WAL;"
sqlite3 ~/memory-palace/palace.db "PRAGMA busy_timeout=5000;"每段对话写入一条 entry(内容用中文摘要,100-200 字):
# 写入 entry 并在同一个连接中拿到 ID(last_insert_rowid() 是连接级状态)
LAST_ID=$(sqlite3 ~/memory-palace/palace.db "
INSERT INTO entries (category_id, date, level, content, keywords, conversation_id, version_id)
VALUES (
(SELECT id FROM categories WHERE path='类目路径'),
date('now'),
'raw',
'对话摘要——保留:话题结论、用户做的决定、关键上下文。丢弃:具体聊天文字、来回讨论过程。',
'逗号,分隔,的关键词',
'conv-' || date('now') || '-' || printf('%02d', (SELECT COUNT(*) FROM conversation_index WHERE date=date('now')) + 1),
(SELECT id FROM project_versions WHERE project_name = 'memory-palace' ORDER BY detected_at DESC LIMIT 1)
);
SELECT last_insert_rowid();
")
if [ $? -ne 0 ]; then
echo "⚠️ 记忆宫殿写入失败: $LAST_ID" >&2
echo "[$(date -Iseconds)] 写入失败: $LAST_ID" >> ~/memory-palace/write-errors.log
else
echo "新记忆 ID: $LAST_ID"
fi同时写入对话索引:
sqlite3 ~/memory-palace/palace.db "
INSERT INTO conversation_index (date, summary, entry_count)
VALUES (date('now'), '本次对话的一句话概括', N);
"3.3.5 建立知识图谱关联
每写入一条新 entry,自动检查是否与已有条目存在关联:
关联类型:
| 类型 | 含义 | 条件 |
延续 | 后续讨论同一话题的进展 | 同 category + keywords 重叠 ≥ 2 个 |
参考 | 做当前决定时参考了之前的结论 | 新 content 提到"之前""上次"等词 |
触发 | A 的结果直接触发了 B | 因果关系明确("因为A所以B") |
否决 | 新决定推翻了之前的决定 | content 包含"改成""不用了""换了"等词 |
相关 | 松散关联,兜底 | 不确定但明显有关系 |
自动建立关联的 SQL:
# LAST_ID 已在 3.3 写入记忆时获取(INSERT + SELECT last_insert_rowid() 在同一连接中)
# 搜可能的关联条目:同 category + 日期接近
sqlite3 ~/memory-palace/palace.db "
SELECT id, content, keywords FROM entries
WHERE category_id = (SELECT category_id FROM entries WHERE id = $LAST_ID)
AND id != $LAST_ID
AND date >= date('now','-7 days')
ORDER BY date DESC LIMIT 5;
"
# Agent 判断关系类型后,写入 relations 表
sqlite3 ~/memory-palace/palace.db "
INSERT OR IGNORE INTO relations (entry_a, entry_b, relation_type)
VALUES (新条目ID, 关联条目ID, '延续');
"写入原则:
- 每条新 entry 至少尝试建立 1 条关联(同话题的上一轮讨论)
- 最多建 5 条关联(避免图谱过于密集)
- 如果判断不出明确关系,不强行关联
OR IGNORE保证同一对不会重复
3.3.6 结构化提取(metadata)
写入记忆时,除了自然语言摘要,还要提取结构化信息存入 metadata 字段:
metadata JSON 格式:
{
"决定": ["用方案A替代方案B"],
"数字": {"预算": 5000, "预计时间": "2小时"},
"偏好": ["禁止弹窗", "全中文输出"],
"关键结论": "草稿纸不加速压缩,token开销仅0.2%",
"下一步": "实现知识图谱功能"
}提取规则:
决定:用户明确说了"那就用XX""决定了XX""选XX"——数组格式,每次追加数字:对话中出现的具体数值(时间、金额、百分比)——对象格式偏好:用户的习惯和要求(如"不要弹窗""用中文")——数组格式关键结论:最重要的一句话——字符串下一步:待办事项——字符串
写入 SQL(metadata 参数加入 INSERT):
# 同一连接中 INSERT 并获取 ID(供后续 3.3.5 图谱关联使用)
LAST_ID=$(sqlite3 ~/memory-palace/palace.db "
INSERT INTO entries (category_id, date, level, content, keywords, metadata, conversation_id, version_id)
VALUES (
(SELECT id FROM categories WHERE path='类目路径'),
date('now'),
'raw',
'对话摘要——100-200字',
'逗号,分隔,的关键词',
'{"决定":["用方案A"],"数字":{},"偏好":[],"关键结论":"结论","下一步":""}',
'conv-' || date('now') || '-' || printf('%02d', (SELECT COUNT(*) FROM conversation_index WHERE date=date('now')) + 1),
(SELECT id FROM project_versions WHERE project_name = 'memory-palace' ORDER BY detected_at DESC LIMIT 1)
);
SELECT last_insert_rowid();
")
echo "新记忆 ID: $LAST_ID"3.4 时间衰减
# raw 超过 3 天 → 浓缩为 digest(保留结论和关键上下文,丢弃聊天文字)
sqlite3 ~/memory-palace/palace.db "
UPDATE entries SET level='digest'
WHERE level='raw' AND date <= date('now','-3 days');
"
# digest 超过 7 天 → 导出为 SQLite 数据库,gzip 压缩,从主库删除
ARCHIVE_PATH="$HOME/memory-palace/归档/$(date +%Y-W%V)-$(date +%H%M%S).db"
sqlite3 ~/memory-palace/palace.db "
ATTACH '$ARCHIVE_PATH' AS archive;
CREATE TABLE archive.entries (id, category_id, date, level, content, keywords, conversation_id, metadata);
CREATE TABLE archive.categories (id, parent_id, name, path, is_preset, created_at, last_active);
CREATE TABLE archive.relations (id, entry_a, entry_b, relation_type, created_at);
CREATE TEMP TABLE to_archive AS
SELECT id FROM entries WHERE level='digest' AND date <= date('now','-7 days');
INSERT INTO archive.entries (id, category_id, date, level, content, keywords, conversation_id, metadata)
SELECT id, category_id, date, level, content, keywords, conversation_id, metadata
FROM entries WHERE id IN (SELECT id FROM to_archive);
INSERT INTO archive.categories
SELECT * FROM categories
WHERE id IN (SELECT DISTINCT category_id FROM entries WHERE id IN (SELECT id FROM to_archive));
INSERT INTO archive.relations
SELECT * FROM relations
WHERE entry_a IN (SELECT id FROM to_archive)
AND entry_b IN (SELECT id FROM to_archive);
"
gzip -f "$ARCHIVE_PATH"
sqlite3 ~/memory-palace/palace.db "
CREATE TEMP TABLE to_archive AS
SELECT id FROM entries WHERE level='digest' AND date <= date('now','-7 days');
DELETE FROM relations
WHERE entry_a IN (SELECT id FROM to_archive)
OR entry_b IN (SELECT id FROM to_archive);
DELETE FROM entries WHERE id IN (SELECT id FROM to_archive);
"3.5 更新类目活跃时间
sqlite3 ~/memory-palace/palace.db "
UPDATE categories SET last_active=date('now')
WHERE path IN ('本次归档涉及的所有类目路径,用逗号分隔并加单引号');
"四、压缩恢复
上下文压缩(Compaction)是 Claude 自动触发的机制。记忆宫殿通过 PreCompact + PostCompact hooks 让压缩变得无害。
压缩时发生了什么
压缩前 → pre-compact.sh 自动运行:
1. 复制 sessions/<session-id>/working-memory.md → sessions/<session-id>/compact-snapshot.md
2. 追加数据库最近5条活跃记忆到快照
→ stdout 不输出(避免污染压缩前上下文)
压缩中 → Claude 清空旧上下文,重新构建
压缩后 → post-compact.sh 自动运行:
1. 读取 sessions/<session-id>/compact-snapshot.md 的"快览"段
2. stdout 输出 → 注入到新上下文
3. 末尾输出指令让 Agent 读详情段,标注 session-id
→ Agent 眼前出现"=== 记忆宫殿:上下文压缩恢复 ==="段落识别 PostCompact 信号
当上下文中出现以下文字时,说明刚经历了一次压缩恢复:
=== 记忆宫殿:上下文压缩恢复 ===
▸ 压缩前的工作状态:收到信号后的处理流程
- 立即读详情:
catworking-memory.md 的"详情"段,获取完整上下文 - 对比快览:确认上次焦点、决定、进度是否仍然准确
- 继续任务:根据恢复的信息继续之前的工作,不要重新开始
- 更新文件:将恢复后的状态全量更新到 working-memory.md
Hook 失败时的兜底
如果压缩后没有看到 PostCompact 信号(hook 配置丢失或运行失败),回到"一、启动时"的索引加载 + 读 working-memory.md 快览段的流程。working-memory.md 文件本身不受压缩影响,始终在磁盘上。
上下文压缩无法从外部关闭。本方案不阻止压缩,而是让压缩后能自动恢复——就像你没法阻止电脑重启,但可以设置自动保存。
五、/命令实现
所有命令通过 sqlite3 实现:
/宫殿 查找 <关键词>
sqlite3 ~/memory-palace/palace.db "
SELECT c.path, e.date, e.content FROM entries e
JOIN categories c ON e.category_id = c.id
WHERE e.id IN (SELECT rowid FROM entries_fts WHERE entries_fts MATCH '关键词')
ORDER BY e.date DESC LIMIT 10;
"
# 如果主库没找到,搜索归档
for f in ~/memory-palace/归档/*.db.gz; do
gunzip -kf "$f" && sqlite3 "${f%.gz}" "SELECT date, content FROM entries WHERE keywords LIKE '%关键词%' OR content LIKE '%关键词%';" && echo "(来自归档: $f)"
done/宫殿 类目 <路径>
sqlite3 ~/memory-palace/palace.db "
SELECT date, level, content FROM entries
WHERE category_id = (SELECT id FROM categories WHERE path='路径')
ORDER BY date DESC;
"/宫殿 归类 <路径> — 将当前对话归入指定类目(覆盖自动归类)
/宫殿 新建类目 <路径> — 手动创建类目(按 3.2 第五步的 SQL)
/宫殿 树
sqlite3 ~/memory-palace/palace.db "
SELECT path FROM categories ORDER BY path;
"/宫殿 状态
sqlite3 ~/memory-palace/palace.db "
SELECT '类目总数: ' || COUNT(*) FROM categories;
SELECT '活跃记忆(raw): ' || COUNT(*) FROM entries WHERE level='raw';
SELECT '浓缩记忆(digest): ' || COUNT(*) FROM entries WHERE level='digest';
SELECT '归档文件数: ' || COUNT(*) FROM (SELECT 1 FROM entries WHERE 1=0);
"
ls ~/memory-palace/归档/ | wc -l | xargs echo "归档包数:"重要提醒
- 先归类,后衰减 — 确保每段记忆找到了正确的类目再处理时间规则
- 索引优先 — 每次只加载索引(~50 token),不加载全量记忆
- 记忆只给 Agent 看 — 摘要内容不考虑人类可读性,精简高效即可
- 类目自然生长 — 跟随对话节奏动态扩展,不要一次性建完
- 每次开工前必报预估并分解步骤 — 哪怕只有一个步骤也要列出。格式:步骤表(每步含最短/最长时间)+ 总计时间和 Token 范围。任务结束后报实际耗时和实际 Token。(详见工作流程规则)
- 如果当前对话没有产生值得保存的内容(纯闲聊),跳过后三步(3.3-3.5)
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

