Mem0 Plugin Peek 技能解析:/mem0:peek 快速记忆检索、短 ID 直查与紧凑引文输出
Mem0 Plugin 为 Claude Code、Cursor、Codex、OpenCode、Antigravity 等 AI 编码环境提供持久化语义记忆,其中 peek 技能(/mem0:peek)是面向「快速查证」场景的轻量检索命令:既支持按关键词做双通道语义搜索,也支持通过短 ID 或 [mem0:id] 引文直查单条记忆,并以每行一条的紧凑格式返回结果。读完本文,你能完整掌握 peek 的三步执行流程(解析 → 并行搜索 → 去重展示)、其背后的身份与项目作用域解析机制(user_id / app_id 从何而来),以及 rerank 参数在平台 REST 接口上的真实行为,从而在 Agent 工作流中可靠地用它来核对「某个决策是否被记录下来」或解析记忆引文。
1. peek 在插件技能体系中的定位
peek 技能定义在 skills/peek/SKILL.md,其元信息声明的用途是:
Searches memories and displays compact one-liner results, or looks up a specific memory by ID. Use for quick memory lookups, checking if a decision was recorded, resolving
[mem0:id]citations, or browsing memories without full category detail.
也就是说,它解决的是四个具体场景:快速记忆检索、确认某个决策是否已被记录、解析 [mem0:<id>] 形式的记忆引文、以及不想展开完整分类详情的轻量浏览。原文档明确将它与 /mem0:tour 做了区分——「Quick search with compact output. Lighter than /mem0:tour」。两者对比可以理解为:
| 维度 | /mem0:peek |
/mem0:tour(SKILL.md) |
|---|---|---|
| 触发方式 | 带搜索词,如 /mem0:peek auth middleware |
无参数(全量分类浏览)或带 --all-projects(跨项目) |
| 数据获取 | 2 次并行 search_memories |
1 次 get_memories(page_size=100)+ 3 次补充语义搜索 |
| 输出形态 | 每行一条的记忆引文(content 截断 80 字符) | 按类别分组、展示完整记忆文本 |
| 附加能力 | 支持裸 ID / [mem0:<hex>] 直查单条 |
支持跨项目模式 |
值得注意的是,tour 技能文档中本身就内置了一段「Peek mode」流程:当 /mem0:tour 带搜索词且不带 --all-projects 时,会退化为与 peek 完全相同的紧凑搜索流程。这说明 peek 实质上是插件记忆检索的「紧凑显示协议」,两个入口共用同一套双路搜索策略。
2. Step 1:解析查询与 Memory ID 检测
用户提供搜索查询,例如 /mem0:peek auth middleware。若未提供查询词,技能要求 Agent 反问 "What should I search for?",而不是凭空搜索。
关键的工程细节是 Memory ID 检测。如果查询词命中以下任一模式,技能会把它当作「直接按 ID 查单条记忆」而不是搜索:
- 裸十六进制短 ID:
^[a-f0-9]{8}$(8 位 hex 短 ID) - 完整 UUID:
^[a-f0-9]{8}-[a-f0-9-]+$ - 引文引用:
[mem0:<hex>]—— 提取其中的 hex 部分
检测到 ID 后的处理策略是三层降级:
- 直接调用 MCP 工具
get_memory(<id>)(如果是短 ID,则作为完整 UUID 的前缀尝试匹配); - 命中则跳过 Step 2 的搜索,直接进入 Step 3 展示这一条结果;
- 未命中则回落到正常搜索——把这个 ID 当作文本 query 去检索。
这个设计对应了 README 中提到的「17 个 /mem0: 命令」体系:peek 输出的 [mem0:<short_id>] 标记是全局记忆引用协议的一部分,后续 /mem0:forget(按 ID 删除)、/mem0:pin(保护)等命令都以同一 ID 体系为操作对象,而 peek 是其中最常用来「验证引文指向哪条记忆」的入口。
3. Step 2:双通道并行搜索(Broad + Targeted)
未命中 ID 检测时,peek 要求发起 2 个并行的 search_memories 调用:
1. Broad(宽召回):
query=<用户查询词>
filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}
top_k=10
rerank=true
2. Targeted(定向召回):
query=<用户查询词>
filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}, {"metadata": {"type": "decision"}}]}
top_k=5
rerank=true
设计意图很清晰:
- Broad 通道在
user_id+app_id双约束下取 top 10,保证召回面——任何类别的记忆(决策、约定、反模式、工具链配置)都可能命中; - Targeted 通道额外叠加
metadata.type == "decision"过滤,专门捞「架构决策」类记忆——因为 peek 的典型用例之一就是「确认某个决策是否被记录过」; - 两路都显式设置
rerank=true,让平台侧用 reranker 重排而不是只按原始向量相似度截断。
3.1 作用域参数从哪里来:user_id 与 app_id 的解析链
filters 里的 <id> 和 <pid> 并非手填,而是插件共享脚本在会话期自动解析的身份与项目作用域:
user_id:见 scripts/_identity.py 的resolve_user_id()——优先读MEM0_USER_ID环境变量,否则取$USER,再兜底"default";app_id:见 scripts/_project.py 的resolve_project_id(),解析优先级为:MEM0_PROJECT_ID环境变量(显式覆盖,对应/mem0:switch-project的能力);~/.mem0/project_map.json按当前工作目录查找;- 按 git remote URL 的 SHA-256 哈希键查找(目录被移动/重命名后的自愈回退,并会回填新的 cwd 键);
- git remote slug(如
git@github.com:mem0ai/mem0.git→mem0ai-mem0); - 兜底:当前目录 basename。
这解释了为什么 peek 的每次搜索都被严格限定在「某用户 × 某项目」的格子内——同一台机器上多个仓库的记忆互不串扰,这也是空结果提示里出现 for project <project_id> 的原因。
3.2 rerank 参数在平台接口上的真实语义
peek 两次搜索都要求 rerank=true,这个要求在插件的共享搜索助手 scripts/_search.py 中有明确的源码级解释:
The REST search endpoint does not rerank when
rerankis omitted, so auto-injected context is ordered by raw vector similarity and the single most relevant memory can fall outside the injected top_k window.
也就是说,Mem0 的 REST 搜索端点(POST /v3/memories/search/,见 scripts/_search.py 的 SEARCH_URL)在省略 rerank 字段时不重排,结果只按原始向量相似度排序,唯一最相关的记忆可能掉出 top_k 窗口。为此插件提供了 should_rerank():默认开启 rerank(额外约 150–200ms 延迟在 hook 的 curl 预算内),并允许用户通过 MEM0_RERANK 环境变量关闭——取值 0、false、no、off(大小写不敏感)禁用,未设置或其他值均启用。
这些行为不是口说无凭,仓库中有成体系的回归测试(tests/test_search.py):
test_search_memories_omits_rerank_by_default(#L138-L155):不传rerank时请求体中不得出现rerank字段(回归 issue #5684,避免「默认重排」造成意外的额外延迟/配额消耗);test_search_memories_forwards_rerank_true(#L158-L176):rerank=True必须真实到达请求体,否则端点不会重排;test_should_rerank_defaults_true/test_should_rerank_opt_out_values(#L179-L196):锁定MEM0_RERANK的默认开启与全部关闭取值。
此外,search_memories() 的健壮性也有测试覆盖:API key 为空直接返回空列表而不发请求(test_search_memories_no_api_key_returns_empty);网络异常时向 stderr 输出错误并返回 [],而 429 限流必须留下可区分的错误日志(test_search_memories_logs_rate_limit_error,注释标注 "Bug bash #22: a 429 must not look identical to a genuine empty result")——这对 peek 使用者是个实用提示:当 peek 返回「无结果」而会话恰好遇到限流时,应先检查是否刚被 429。
从源码结构看,hook 自动注入路径走的是这个 Python 助手(带 5 秒超时的 urllib 直连),而 /mem0:peek 命令本身由 Agent 通过 MCP 工具 search_memories 发起;两者最终打到同一个平台搜索端点,参数语义(filters 的 AND 子句、top_k、threshold、rerank)是一致的。
4. Step 3:去重与紧凑一行式展示
两路结果合并后,先按记忆 ID 去重(Broad 的 top 10 与 Targeted 的 top 5 必然重叠),再按固定模板输出:
## mem0 peek: "<query>" (<N> results)
1. [decision] Auth module uses JWT with RS256 keys (2025-05-15) [mem0:a3f8b2c1]
2. [anti_pattern] Don't use symmetric HS256 — leaked in env (2025-05-10) [mem0:7e2d9f4a]
3. [convention] All middleware in src/middleware/ (2025-05-08) [mem0:c4d5e6f7]
每行的格式契约是:
<number>. [<type>] <content, 80 chars> (<date>) [mem0:<short_id>]
<type>:记忆类别,来自metadata.type(如decision、anti_pattern、convention);<content>:记忆正文,截断到 80 字符——这是「紧凑」的关键,保证 Agent 上下文里一条记忆只占一行;<date>:记忆日期;[mem0:<short_id>]:8 位 hex 短 ID 引文,即 Step 1 中可被再次用于直查的引用标记。
无结果时的空状态输出是确定性的:
No memories matching "<query>" for project <project_id>.
这套一行式引文格式并非 peek 独有,插件的自动注入路径也使用同一族格式:scripts/_search.py 中的 format_results_for_context() 把搜索结果渲染为 - [<category>] <text[:200]> [mem0:<id 前 8 位>] 注入 prompt。可以推断,[mem0:xxxxxxxx] 短 ID 引文是插件「记忆 → Agent 上下文 → 后续按 ID 操作」闭环的通用货币:peek 打印它、hook 注入它、Agent 用 get_memory / forget / pin 消费它。
5. 运行前提与相关组件
peek 不是独立程序,它依赖插件整体的三层组件(见 integrations/mem0-plugin/README.md 与 plugin.json 的声明):
- MCP Server:插件通过 mcp_config.json 接入 Mem0 远程 MCP 端点(
https://mcp.mem0.ai/mcp/,Authorization: Token ${MEM0_API_KEY}在会话启动时做环境变量插值)。search_memories与get_memory正是 MCP 工具表中的两个工具; - API Key:
MEM0_API_KEY(以m0-开头)必须已在 shell 环境或客户端本地环境中设置——scripts/_identity.py 的resolve_api_key()会按「环境变量 → Claude Code userConfig 注入 → shell profile 文件提取」的顺序兜底解析; - 生命周期 Hooks(可选但推荐):hooks.json 将
SessionStart、UserPromptSubmit、PreToolUse、Stop、PostToolUse等事件接到scripts/下的脚本,自动捕获记忆并强制user_id/app_id元数据——UserPromptSubmit钩子(on_user_prompt.sh,超时 8 秒)内部就调用 §3 所述的search_memories()助手做相关记忆注入。peek 之所以「有东西可查」,很大程度依赖这些钩子在会话过程中持续写入记忆。
典型验证链路也写在 README 中:/mem0:health(连通性)→ /mem0:stats(计数)→ /mem0:remember "we use TypeScript" → /mem0:tour 或 /mem0:peek 查看。
6. 小结:何时用 peek,何时用 tour
从这份技能文档可以提炼出一条清晰的决策准则:
- 用
/mem0:peek <query>:你只需要答案本身——「JWT 的决策记过没有?」「a3f8b2c1这条记忆写的什么?」——需要的是带引文的一行式结果,可以直接粘进对话或 commit message; - 用
/mem0:tour:你要审视图景——按类别浏览全部记忆、查看完整正文、在新项目 onboarding 时建立整体认知; - 两者共享同一套双路搜索协议(Broad
top_k=10+ Targeted decisiontop_k=5,均rerank=true),因此检索质量一致,差异只在展示密度。
配合 MEM0_RERANK 调优重排开销、MEM0_PROJECT_ID 固定项目作用域,peek 就成为 Agent 编码工作流中「记忆可查证性」的最小可用单元:每条输出都带 [mem0:<id>] 引文,任何一条结果都可以被后续命令精确追踪、引用、更新或删除。
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 StartedRust0622
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