MemPalace Antigravity Recall Skill:「先搜索再回答」回忆协议的完整实现解析
本文围绕 MemPalace 的 Antigravity 插件中的召回技能文件 .antigravity-plugin/skills/mempalace-recall/SKILL.md 展开,完整解读「Search-before-answer(先搜索、再回答)」回忆协议的触发时机、六步流程、MCP 工具选择表与失败处理策略,并结合插件安装结构、PreInvocation 唤醒钩子脚本与 MCP 服务器源码,说明该协议在 IDE Agent 集成中的落地机制。读完后你将掌握:如何在 Agent 集成中定义回忆协议、如何通过钩子在会话首轮注入记忆、以及如何在召回、时间知识与日记续写之间正确选择 MCP 工具。
技能定位:一个只做「召回」的 Agent Skill
MemPalace 是一个面向 AI 的本地优先、逐字(verbatim)存储的记忆宫殿系统。它的 Antigravity 插件目录 .antigravity-plugin/ 在仓库中即安装到 ~/.gemini/config/plugins/mempalace/ 时的内容源头,目录结构如下:
.antigravity-plugin/
├── plugin.json # marker manifest(最小 schema,name: "mempalace")
├── mcp_config.json # 自动注册 mempalace-mcp stdio 服务器
├── hooks.json.tmpl # 钩子模板,安装器渲染为 hooks.json
├── skills/
│ ├── mempalace/
│ │ └── SKILL.md # 运维技能:安装 / mine / status / CLI 委托
│ └── mempalace-recall/
│ └── SKILL.md # 召回技能:search-before-answer 协议(本文主角)
├── rules/
│ └── mempalace-recall.md # 可选召回规则(与技能互补)
└── README.md
其中 plugin.json 仅包含 {"name": "mempalace"} 这一最小清单,mcp_config.json 则以 stdio 方式注册 mempalace-mcp 二进制:
{
"mcpServers": {
"mempalace": {
"command": "mempalace-mcp"
}
}
}
mempalace-recall 技能文件的 YAML frontmatter 定义了技能的触发语义——name: mempalace-recall,描述中明确指出:当用户询问「当时决定了什么、之前发生过什么、某人是谁、上次讨论过什么」,或任何可能已归档进记忆宫殿的内容时应应用该技能;它补充覆盖 mempalace 技能(后者负责安装 / mine / status),自身只覆盖召回(recall)这一件事。
插件 README 总结了 MemPalace 的「三层召回」设计,从急切到按需递进,本文的技能是第二层:
- 唤醒钩子(Wake hook):
hooks/antigravity/mempal_wake_hook_antigravity.sh,挂在PreInvocation事件上、门禁为invocationNum == 1。会话第一次模型调用时运行mempalace wake-up,通过 Antigravity 的injectSteps[].ephemeralMessage输出逐字注入宫殿内容——与 Cursor 的sessionStartadditional_context语义相当,区别在于它交付的是记忆本身,而非「去取记忆」的指令。 - 召回技能:即本文主角
skills/mempalace-recall/SKILL.md,定义 Agent 在某个回合具备召回相关性时遵循的搜索协议——工具选择、失败路径、反模式。 - 可选召回规则:rules/mempalace-recall.md,一个轻量 markdown 规则,在 Antigravity 的匹配器判定回合具有召回相关性时「轻推」Agent 先搜索。它刻意只做召回作用域(而非全局常开规则),避免给无记忆相关性的绿色场(greenfield)工作增加延迟,遵守 MemPalace「记忆应当感觉瞬时」的预算约束。
三层都指向同一份规范协议 integrations/shared/recall-protocol.md,保证技能与规则永不漂移。
Step 0 — 先验证 MemPalace 可用
技能的第一条规则是:在依赖召回之前,确认 MemPalace 已安装且可达。原文档给出的检查命令是:
mempalace --version
这里有一条重要的原则性约束:不要假设版本——当前构建的 MCP 工具集才是该安装版本支持什么的事实来源(source of truth)。这一设计与 mempalace 技能 中的「动态、版本正确的指令」思路一致:CLI 提供 mempalace instructions <command> 按操作返回与安装版本匹配的完整指引,技能文档明确要求「当 CLI 输出与技能文本不一致时,以 CLI 为准」。
失败路径同样被写死:如果 mempalace_* MCP 工具不可用,必须明确告诉用户服务器未连接,并指引其使用 mempalace 技能完成配置——绝不允许悄悄退化为用模型记忆作答。
Identity — 角色设定:资深 AI 记忆系统工程师
技能文档中用一段「Identity」为 Agent 设定行为人格:
扮演一名拥有数十年经验的资深 AI 记忆系统工程师,精通逐字召回、语义检索与时序知识图谱。来自宫殿的逐字召回永远胜过来自模型记忆的自信猜测——错误比慢更糟(Wrong is worse than slow)。
这句「Wrong is worse than slow」是整个协议的价值底座:宁可多花一次工具调用的延迟去查宫殿,也不要用可能过时的模型记忆生成一个自信的错误答案。
何时召回、何时不召回
这是协议中最容易被忽视但最影响体验的部分。技能文档规定,只要用户问到的内容可能已归档,就在回答前搜索:
- 过往工作或先前决策——「我们当时决定 / 尝试 / 做了什么?」
- 某个人的、项目的、实体的——「谁是谁」「这是什么」
- 更早的会话——「记得我们……」「上次……」「我们讨论过的那个」
- 可能随时间变化的偏好、事实或关系
反过来,纯绿色场工作不做召回(如「重命名这个变量」「修这个错别字」)。原文档的表述很关键:
Recall is question-driven, not reflexive — a search on every turn wastes latency and violates MemPalace's "memory should feel instant" budget.
(召回是问题驱动的,不是反射性的——每一轮都搜索会浪费延迟,并违反 MemPalace「记忆应当感觉瞬时」的预算。)
这与可选规则文件 rules/mempalace-recall.md 的结尾呼应:「Skip recall for pure greenfield work with no memory relevance... Recall is question-driven, not reflexive.」两者共享同一条 规范协议,该协议同样声明自己是跨所有 MemPalace 集成(Cursor、Antigravity、Claude Code、Codex、OpenClaw)的单一事实来源,服务于「100% recall, verbatim, never guess」的基础承诺。
六步召回协议(Protocol)
技能文档的核心是六步协议,规范协议中逐条对应:
- 唤醒注入(On wake-up):MemPalace 的 PreInvocation 钩子在会话第一次模型调用时,通过
injectSteps[].ephemeralMessage注入逐字的宫殿内容。如果记忆已被注入,先从它出发,再决定是否进一步搜索。 - 回答前搜索(Before responding):在回答任何关于人物、项目、历史事件或先前决策的问题之前,先调用
mempalace_search。对于关系型或时间型事实(「三月时谁向谁汇报」「当时什么状态是真的」),改用mempalace_kg_query或同时使用。 - 不确定时(If unsure):对事实(姓名、年龄、关系、偏好)拿不准时,说出「let me check the palace」然后查询。错误比慢更糟。
- 逐字返回(Return verbatim):引用抽屉(drawer)存储的原始文字。绝不总结、改写或有损压缩宫殿返回的内容——这正是整个系统的意义所在。
- 实质性会话之后:用
mempalace_diary_write记录会话连续性。注意括号里的告诫:后台钩子可能已经做了这件事——不要重复归档(do not double-file)。 - 事实变化时:选择能保留时间历史的写操作:
mempalace_kg_supersede—— 单值事实替换(型号、雇主、所有者、地址、当前状态);mempalace_kg_invalidate—— 无替代地结束的事实;mempalace_kg_add—— 相互独立 / 共存的事实。
唤醒注入的源码级实现
第 1 步并非纸面协议。hooks/antigravity/mempal_wake_hook_antigravity.sh 展示了完整实现,其中有几个值得注意的工程细节:
- 门禁:
PreInvocation事件在每次模型调用前触发,脚本通过invocationNum == 1判定「会话第一次模型调用」,并用原子mkdir标记(antigravity_woke_${CONVERSATION_ID})保证每个会话只注入一次,避免逐轮注入带来的开销与视觉噪音; - 逐字保证:脚本以内嵌 Python 以
subprocess.run([sys.executable, "-m", "mempalace", "wake-up", "--wing", wing], timeout=0.5)调用 CLI,把 stdout 原样包进{"injectSteps": [{"ephemeralMessage": body}]}输出——json.dumps负责正确转义,不做任何改写; - 500ms 硬超时与 fail-open:超时、非零退出、解析失败一律输出
{}并放行——错过注入预算严格优于阻塞用户(脚本注释中说明:比 100ms 的启动注入预算更宽松,因为冷 ChromaDB 连接可能占大头); - Wing 推断:从 stdin 的
workspacePaths[0](第一个绝对工作区路径)推断 wing 作用域,多工作区会话以第一个为准; - 防护:脚本刻意不启用
set -e(fail-open 是强制要求),并有一条防御性检查——PreInvocation 钩子绝不输出 Stop 事件专用的decision字段,防止未来编辑引入 Stop 形状的 JSON 导致 Agent 陷入死循环。
该钩子与 Stop 钩子在 hooks.json.tmpl 中注册,安装器把 __PLUGIN_DIR__ 占位符渲染为绝对安装路径:
{
"mempalace-save": {
"Stop": [
{ "type": "command",
"command": "__PLUGIN_DIR__/hooks/mempal_save_hook_antigravity.sh",
"timeout": 30 }
]
},
"mempalace-wake": {
"PreInvocation": [
{ "type": "command",
"command": "__PLUGIN_DIR__/hooks/mempal_wake_hook_antigravity.sh",
"timeout": 5 }
]
}
}
其中 Stop 钩子(mempalace-save)负责后台挖掘会话记录——这解释了协议第 5 步「不要 double-file」:保存钩子可能已经替你归档了。
MCP 工具选择表(Tool Selection)
技能文档给出了一张明确的「需求 → 工具」映射表,这是 Agent 选工具的唯一依据:
| 你需要 | 工具 |
|---|---|
| 按语义找任意记忆 | mempalace_search(从这里开始) |
| 关于实体的关系型 / 时间约束事实 | mempalace_kg_query |
| 替换单值事实 | mempalace_kg_supersede |
| 一个实体的时间线故事 | mempalace_kg_timeline |
| 近期会话连续性 | mempalace_diary_read |
| 有哪些 wings / rooms(作用域未知时) | mempalace_list_wings, mempalace_list_rooms |
| 记录本次会话 | mempalace_diary_write |
关于 mempalace_search 的入参,技能文档特别强调了 query 的写法:短小的自然语言(关键词或一个问句——不是系统提示词、不是粘贴的整段对话),外加可选的 wing / room 过滤器和 limit(默认 5)。
从 mempalace/mcp_server.py 源码看,工具面比这张表更大:除召回技能列出的工具外,服务器还提供只读的 mempalace_status(总抽屉数与 wing/room 分布)、mempalace_get_taxonomy(完整 wing → room → count 树)、mempalace_check_duplicate(归档前查重),以及写工具 mempalace_add_drawer、mempalace_delete_drawer、mempalace_delete_by_source 和维护工具 mempalace_reconnect。召回技能刻意只暴露「回忆路径」上需要的子集,写路径则由技能/规则与钩子分工承担。另外从源码结构看,MCP 服务器在导入重依赖(chromadb → onnxruntime 等)前会把 stdout 重定向到 stderr——因为 MCP 协议在 stdio 上多路复用 JSON-RPC,任何第三方库打印到 stdout 的横幅都会破坏解析器;这一细节解释了「工具报错时应原样上报而不是猜测」背后服务器可能存在的 stdio 健壮性设计。
失败路径(Unhappy Paths)
技能文档把三类失败情形显式写成协议的一部分,每条都给出「不该做什么」:
- 空结果(Empty results):如实说宫殿里没有这条记忆;不要编造答案来填空。可以建议放宽搜索(去掉 wing 过滤)或把新信息归档进去。
- MCP 不可用 / 工具报错(MCP unavailable / tool error):把错误原样呈现,建议用户检查服务器状态(
mempalace status,或重跑安装器hooks/antigravity/install.sh)。不要悄悄退化为模型记忆猜测。 - 过时或冲突事实(Stale or conflicting facts):优先采用知识图谱的时间有效答案;按事实类型选择
mempalace_kg_supersede(单值替换)、mempalace_kg_invalidate(无替代地结束)、mempalace_kg_add(独立共存)。
共享的 规范协议文档 在此基础上还多覆盖了一类失败:宫殿索引损坏 / 压缩器错误。当服务器返回涉及 HNSW segment writer、ChromaDB 压缩失败或写后卡死在「Not connected」状态的错误时,磁盘向量索引已与 chroma.sqlite3 失同步——但抽屉行完好保存在 SQLite 中。恢复方式是引导用户走 CLI 重建(停掉 MCP 服务器 → 可选备份宫殿目录 → mempalace repair --mode from-sqlite --archive-existing --yes → mempalace repair-status 确认 divergence 为 0 → 重启服务器),而不是重新挖掘(re-mining 会丢掉经 MCP 服务器和日记写入、没有源文件的抽屉),也不要在 Agent 进程内自行修复(可能破坏其他活跃客户端)。这一节说明失败处理是分层设计的:技能层保持简洁,深层恢复流程由规范协议统一承载。
反模式清单(Anti-patterns — never do these)
技能文档末尾给出四条「绝不做」清单,与规范协议及规则文件逐条一致:
- 宫殿可能知道时,用模型记忆回答过往工作、人物或决策——应该先搜索;
- 对存储内容做改写或总结,而不是逐字引用;
- 每一轮都反射性搜索,包括无记忆相关性的纯绿色场编码;
- 把整段对话或系统提示词粘进
query参数——保持查询短小、关键词驱动。
这四条与前文的协议步骤互为镜像:第 2 条对应第 4 步的 verbatim 要求,第 3 条对应「何时不召回」一节,第 4 条对应 mempalace_search 入参约束。
安装、验证与延伸阅读
技能文件本身不携带安装逻辑——它属于 mempalace 技能 的职责(uv tool install mempalace 或 pip install mempalace,mempalace --version 验证)。但召回协议的生效依赖插件整体安装,用户侧入口为:
bash hooks/antigravity/install.sh # 安装(幂等)
bash hooks/antigravity/install.sh --dry-run # 预演
bash hooks/antigravity/install.sh --uninstall
安装器幂等(cmp 门控的复制跳过内容一致的文件,可安全用于 CI),卸载器按 basename 匹配并有双重防护(目录名必须恰为 mempalace 且 plugin.json 的 name 为 "mempalace"),防止误删无关目录。
完整用户文档见 website/guide/antigravity.md,其中还涵盖:钩子如何解析 mempalace 安装所用的 Python 解释器(MEMPAL_PYTHON → console 脚本 shebang → python3 的解析顺序)、kill switch 开关表(MEMPAL_DISABLE_HOOK、MEMPALACE_HOOKS_AUTO_SAVE、~/.mempalace/config.json 的 hooks.auto_save 等)、性能预算(kill switch 触发或门禁失败时钩子应 <100ms 返回;wake 钩子 500ms 硬上限)以及安装后的验证命令(mempalace-mcp --version、检查 ~/.mempalace/hook_state/antigravity_hook.log 中 [event=preInvocation] 日志行)。
进一步深入时,建议按以下路径阅读:
- integrations/shared/recall-protocol.md —— 全部集成共享的规范召回协议(本文技能的上位文档);
- hooks/antigravity/README.md 与 hooks/antigravity/STDIN_SHAPE.md —— Antigravity 钩子的文档与两个事件的确切 stdin 线格式;
- mempalace/mcp_server.py —— MCP 服务器实现与完整工具面;
- integrations/openclaw/SKILL.md —— 规范协议蒸馏来源的完整协议技能;
- integrations/shared/coordination-protocol.md —— 共享大脑伴生协议:Agent 之间委派工作时走 logstream(
mempalace_event_append/mempalace_event_wait)而非抽屉——「Recall 回答问题;logstream 推动工作」。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00