Mem0 插件 tour 技能解析:按类别浏览、语义检索与跨项目汇总 AI 代理项目记忆
【免费下载链接】embedchainThe Memory Layer for AI Agents - Drop-in memory infrastructure for AI agents and apps. Context that persists. Built for production.项目地址: https://gitcode.com/GitHub_Trending/em/embedchain
本文以 Mem0 插件中的tour技能文档为核心,完整拆解/mem0:tour命令的三种运行模式(单项目完整漫游、peek 紧凑检索、跨项目汇总)及其背后的get_memories/search_memories调用规范、过滤器构造与类别分组规则;并结合插件源码中的身份解析、项目 ID 解析、类别体系与共享检索脚本,说明这些参数在真实实现中如何被填充与消费,帮助读者在 Claude Code、Cursor、Codex 等 AI 编码环境中把 tour 作为项目记忆审阅、团队 onboarding 与知识盘点的主要入口。
一、tour 技能是什么:定位与入口
tour是 Mem0 插件(位于 integrations/mem0-plugin 目录)内置的 17 个 slash 技能之一,定义在 skills/tour/SKILL.md。技能文件的 frontmatter 明确其用途:
Browses all stored memories grouped by category with full content display. Use when reviewing all project memories, exploring stored knowledge, onboarding to a project, or getting an overview of captured decisions, conventions, and learnings.
翻译过来即:按类别浏览当前项目已存储的全部记忆并完整展示内容,典型场景是审阅项目记忆、探索已沉淀的知识、新项目 onboarding,或总览已捕获的决策、约定与经验教训。插件 README 的技能表把它描述为/mem0:tour—— "Browse all memories grouped by category",并将其列为安装验证步骤之一("Try/mem0:remember "we use TypeScript"then/mem0:tourto see it stored"),即写完一条记忆后立刻用 tour 验证它是否落库。
tour 与同目录下的 skills/peek/SKILL.md 是"重/轻"互补关系:peek 是带查询词的紧凑单行检索("Lighter than/mem0:tour"),tour 则是无查询词时的全量类别化浏览。tour 本身也吸收了 peek 的紧凑模式(见下文 peek mode),因此 tour 技能文档实际上覆盖了三条执行路径。
二、三条执行路径:tour 的模式路由
tour技能文档把调用参数解析为互斥的三种模式,路由规则非常明确:
| 调用形式 | 模式 | 数据范围 | 输出形态 |
|---|---|---|---|
/mem0:tour | 完整漫游 | 当前项目全部记忆 | 按类别分组、完整内容、降序计数 |
/mem0:tour <query> | Peek mode | 当前项目语义检索 | 紧凑单行结果 |
/mem0:tour --all-projects [query] | 跨项目模式 | 全部项目 | 按app_id再按类别分组 |
文档中的路由原文:"If--all-projectsis NOT present, use the standard single-project flow below"(无跨项目标志时走单项目流程);"If no query argument and no--all-projectsflag, use the full tour flow below"(既无查询词也无标志时走完整漫游)。即:先判--all-projects,再判 query 是否存在,最后才落到完整漫游。
三种模式共同依赖两个 MCP 工具——get_memories(带过滤与分页的记忆列表)和search_memories(带过滤与重排的语义搜索)。这两个工具来自插件连接到的 Mem0 远端 MCP 服务器,连接配置见 mcp_config.json(以MEM0_API_KEY环境变量插值Authorization: Token ${MEM0_API_KEY}请求头),工具全集见 README 的 "MCP Tools" 表:add_memory、search_memories、get_memories、get_memory、update_memory、delete_memory、delete_all_memories、delete_entities、list_entities。
三、完整漫游:六步执行流程
无参数调用/mem0:tour时,技能文档定义了六步流程。
Step 1:拉取项目全量记忆
调用get_memories,过滤条件与分页参数固定:
filters={"AND": [{"user_id": "<active_user_id>"}, {"app_id": "<active_project_id>"}]} page_size=100这里的两个占位符不是装饰。user_id与app_id正是 Mem0 平台给记忆打的两级作用域:记忆按"用户 × 项目"归属,所有检索都必须显式声明范围。插件侧对这两个值有确定性的解析规则(见第五节源码剖析):user_id默认取MEM0_USER_ID环境变量,缺失时回退到系统$USER,再回退到default;app_id(项目 ID)优先取MEM0_PROJECT_ID,其次查~/.mem0/project_map.json的本地映射,再回退到 git remote 的 slug(如owner-repo形式),最后才是当前目录 basename。这意味着 tour 的"当前项目"边界是可预测、可覆写的——/mem0:switch-project技能正是通过覆写这一解析来切换作用域。
Step 2:三个并行的补充语义检索
在拉取全量的同时,并行发起三条search_memories调用,针对关键主题拿一份按相关性排序的结果:
query="architecture decisions design choices" query="bugs errors failures anti-patterns" query="project setup tooling conventions preferences"三者统一参数:filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}、top_k=10、rerank=true。
文档中有一条关键警告:
Do NOT filter by
metadata.typein these calls.The platform auto-assignscategories— filtering onmetadata.typemisses memories that were auto-categorized but don't have an explicitmetadata.type.
即不要在这三个调用里按metadata.type过滤:Mem0 平台会自动给记忆分配categories字段,而自动归类出来的记忆往往没有显式的metadata.type,一旦加了该过滤条件,这部分记忆就会被漏掉。这是 tour 文档中最容易踩的坑,也解释了为什么 Step 3 的分组规则把平台categories字段放在第一优先级。
Step 3:合并去重与类别归组
所有结果(全量列表 + 三路检索)按记忆 ID 合并去重,然后为每条记忆确定分组,优先级为:
- 平台
categories字段(每条记忆上的数组,由 Mem0 自动分配),取第一个类别值; metadata.type字段(如存在,通常由 hooks/agent 显式写入),作为无categories时的回退;- 两者皆无则归入"other"桶。
类别名到显示名的映射表(需完整继承):
| Platform category / metadata.type | Display name |
|---|---|
architecture decisions、architecture_decisions、decision | Architecture Decisions |
anti patterns、anti_patterns、anti_pattern | Anti-Patterns |
task learnings、task_learnings、task_learning | Task Learnings |
coding conventions、coding_conventions、convention | Coding Conventions |
user preferences、user_preferences、user_preference | User Preferences |
project profile、project_profile | Project Profile |
tooling setup、tooling_setup、environmental | Tooling & Setup |
technology、professional_details | Tooling & Setup |
session_state | Session State |
compact_summary | Compact Summaries |
| 其他任何值 | Other |
注意这张表同时兼容空格/下划线/单复数/中文命名习惯的多种写法——因为categories(平台自动分配,自然语言风格)与metadata.type(hook 写入,蛇形命名)两种来源的取值风格并不统一,映射表就是两者的归一化层。
Step 4:展示规则
分组按记忆数降序排列;每个非空组输出:
## <display_name> (<count> memories) - <full_memory_content> (score: <similarity_score_if_available>) - ...三条展示纪律:
- 每条记忆展示完整文本,不截断(与 peek 模式的 80 字符截断形成对比);
- 某组超过 10 条时,按新近度(来自检索调用的则按相似度分)展示前 10 条,并标注
... and <N> more; - 空组整组跳过,不打印空标题。
Step 5 / Step 6:汇总行与空态
结尾输出总数行:
<N> memories across <M> categories — project: <project_id>, branch: <active_branch>若本项目零记忆,输出空态提示:
No memories stored yet for project <project_id>. Run /mem0:onboard to import project files, or start working — mem0 captures learnings automatically.这里把空态直接引向/mem0:onboard(项目文件导入向导)——tour 因此同时承担了"记忆系统是否在工作"的健康检查职能,与/mem0:health、/mem0:stats一起构成 README 推荐的三步验证链。
四、Peek 模式与跨项目模式:紧凑检索与多项目汇总
Peek mode(带 query、无--all-projects)
/mem0:tour auth middleware这类调用走紧凑模式,执行两个并行的search_memories:
- 宽检索:
query=<query>,filters={"AND": [{"user_id": "<id>"}, {"app_id": "<pid>"}]}、top_k=10、rerank=true; - 定向检索:在宽检索基础上追加
{"metadata": {"type": "decision"}}过滤,top_k=5、rerank=true。
注意与完整漫游 Step 2 的差别:peek 模式允许按metadata.type=decision做定向召回(它只要紧凑的 top 结果,丢一点自动归类记忆无妨),而完整漫游的三路补充检索则禁止该过滤(要保证类别全景)。两路结果按 ID 去重后,以固定格式输出:
## mem0 search: "<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>]——内容截断 80 字符,[mem0:<short_id>]是 8 位十六进制短引用,与 peek 技能的"引用解析"能力打通:/mem0:peek或 tour 结果中的[mem0:a3f8b2c1]可以直接作为参数回查单条记忆的全文。无结果时输出No memories matching "<query>" for project <project_id>.。
Cross-project 模式(--all-projects)
/mem0:tour --all-projects [query]跨全部项目搜索,核心变化只有一个:去掉app_id过滤。
get_memories用filters={"AND": [{"user_id": "<active_user_id>"}]}、page_size=200——无app_id;- 若同时给了 query,再跑
search_memories,top_k=20,同样无app_id; - 结果先按
app_id分组,再在每个项目内按类别分组; - 展示模板:
## <app_id_1> (<N> memories) ← current **Architecture Decisions** — <memory content> ... ## <app_id_2> (<N> memories) ... <N> memories across <M> projects- 当前项目在标题行以
← (current)标记。
app_id过滤的有/无,就是"单项目"与"跨项目"的全部区别,这与第五节中_search.py的过滤器构造逻辑完全一致。
五、源码纵深:tour 参数背后的解析与消费链路
tour 文档中的占位符(<active_user_id>、<active_project_id>、rerank、filters结构)在插件脚本里都有确定的实现,理解它们能预判 tour 的边界行为。
user_id 与 API key 的解析
scripts/_identity.py 给出两级解析链:
- API key 按序取:
MEM0_API_KEY环境变量 →CLAUDE_PLUGIN_OPTION_API_KEY(Claude Code userConfig 注入)→ 旧版CLAUDE_PLUGIN_OPTION_MEM0_API_KEY→ 正则扫描~/.zshrc、~/.bashrc等 profile 文件(专门覆盖桌面应用不继承 shell 环境变量的场景); resolve_user_id():MEM0_USER_ID显式覆写 →$USER→ 字面量"default"。
所以 tour 的<active_user_id>在多数机器上就是系统用户名;多身份协作场景用MEM0_USER_ID切换即可,且该覆写同时影响remember、peek等所有技能的读写作用域。
app_id 的四级回退
scripts/_project.py 的resolve_project_id()实现了四级回退:MEM0_PROJECT_ID环境变量 →~/.mem0/project_map.json按 cwd 查表(附带按 remote hash 的"自愈"查表,目录改名后仍能命中并回写新 key)→git remote get-url origin转 slug → cwd 的 basename。这意味着:tour 末尾汇总行里的project: <project_id>对 git 仓库通常是owner-repo形式;同一仓库被 clone 到不同路径不会分裂成两个项目(只要 remote 一致),而纯本地目录则以目录名作为项目 ID。resolve_branch()则从 git 解析当前分支,对应汇总行尾的branch: <active_branch>。
过滤器构造与 rerank 默认值
scripts/_search.py 是所有预取 hook 共享的检索助手,把POST https://api.mem0.ai/v3/memories/search/封装为一次函数调用,其构造逻辑与 tour 文档的 filter 写法一一对应:
- 非全局检索时,过滤条件组装为
{"AND": [{"user_id": ...}, {"app_id": ...}, (可选 "metadata": {"type": ...})]}——与 tour Step 1/2 的写法一致,也印证了"追加metadata.type会收窄结果"的原因; - 全局模式使用
{"OR": [{"user_id": "*"}]}且不含app_id,即跨项目语义; should_rerank()(第 18-33 行)说明:REST 搜索端点在省略rerank时不会重排,此时结果按原始向量相似度排序,最相关记忆可能掉出top_k窗口,因此 hook 注入路径默认开启 rerank,并可用MEM0_RERANK=0/false/no/off关闭。tour 文档中每个search_memories调用都显式写rerank=true,正是为了在类别展示前拿到可靠的相关性排序;- 该助手还带有 5 秒超时与失败静默(返回空列表并打 stderr 日志),这是 hook 场景的容错设计;tour 本身走 MCP 工具调用,但该文件说明了平台搜索端点的行为前提。
类别体系:tour 分组的供给侧
tour 的显示名映射表(第三节)对应插件自动安装的"编码优化类别体系"。scripts/setup_coding_categories.py 定义了 17 个编码类别——architecture_decisions、anti_patterns、task_learnings、tooling_setup、bug_fixes、coding_conventions、user_preferences、dependency_decisions、performance_findings、security_constraints、testing_patterns、data_model、api_contracts、deployment_runbook、team_norms、domain_glossary、experiment_results——每个类别附一段描述文本,供平台在自动归类时参照。脚本行为:python setup_coding_categories.py干跑对比现状与提案,--apply才真正调用client.project.update(custom_categories=[...]),且project.update总是整体替换类别列表;幂等性由_categories_match()的键集比对保证。该配置在会话启动时由生命周期钩子后台执行一次并缓存于~/.mem0/categories_setup.json。
这解释了 tour 分组表的来源:hook/agent 显式写入的metadata.type用的是这套蛇形命名(如architecture_decisions),而平台自动分配的categories可能是自然语言风格(如architecture decisions),tour 的映射表同时覆盖两套命名,保证两侧记忆都落入正确的显示分组;project_profile、session_state、compact_summary等则对应 hooks.json 中会话启动、Stop、PreCompact 等生命周期钩子自动写入的记忆类型。
与生命周期钩子的关系
hooks.json 声明了SessionStart(加载既有记忆作为引导上下文)、UserPromptSubmit(注入相关记忆)、PreToolUse(阻止直接写 MEMORY.md、对mcp__mem0__*工具调用强制user_id/app_id元数据、读文件时扫描相关记忆)、Stop(提醒代理在回合结束前持久化学习)、PostToolUse(统计与 bash 错误扫描)等事件处理器。其中PreToolUse的mem0-enforce-metadata钩子(scripts/enforce_metadata_defaults.sh)正是 tour Step 3 中metadata.type回退来源的写入方:它保证记忆写入时带上类型元数据,让 tour 的三级分组规则有稳定的回退层可用。
六、实战要点与边界
- 验证记忆落库的首选动作:README 推荐的验证链是
/mem0:remember写入 →/mem0:tour查看,配合/mem0:health检查连通性、/mem0:stats看计数。tour 输出为空时,按空态提示先跑/mem0:onboard。 - 作用域可预测:tour 看到什么,取决于
user_id×app_id两级作用域;怀疑"看不到某些记忆"时,先确认MEM0_USER_ID、MEM0_PROJECT_ID覆写与~/.mem0/project_map.json映射,而不是怀疑检索本身。 - 全量漫游禁用
metadata.type过滤:这是 tour 文档明确写出的平台行为差异(自动categoriesvs 显式metadata.type),在自定义任何 tour 变体时都应当保留这一约束。 - rerank 的代价与收益:每个
search_memories都开rerank=true,换取类别展示内的相关性排序;hook 注入路径的默认实现与MEM0_RERANK开关说明平台侧对重排延迟有明确预算意识,tour 的三路并行检索把这部分延迟摊薄了。 - 跨项目模式的容量参数:跨项目
get_memories用page_size=200(单项目为 100)、检索top_k=20(peek 为 10/5),分组先按app_id再按类别,当前项目以← (current)标记。
七、参考文件索引
| 内容 | 路径 |
|---|---|
| tour 技能定义(本文主体文档) | integrations/mem0-plugin/skills/tour/SKILL.md |
| peek 技能(紧凑检索对照) | integrations/mem0-plugin/skills/peek/SKILL.md |
| 插件总览、MCP 工具表、17 技能列表 | integrations/mem0-plugin/README.md |
| MCP 服务器连接配置 | integrations/mem0-plugin/mcp_config.json |
| 生命周期钩子声明 | integrations/mem0-plugin/hooks.json |
| 身份(API key / user_id)解析 | integrations/mem0-plugin/scripts/_identity.py |
| 项目 ID / 分支解析 | integrations/mem0-plugin/scripts/_project.py |
| 共享检索助手(filters / rerank) | integrations/mem0-plugin/scripts/_search.py |
| 编码类别体系(17 类) | integrations/mem0-plugin/scripts/setup_coding_categories.py |
| 元数据强制钩子脚本 | integrations/mem0-plugin/scripts/enforce_metadata_defaults.sh |
| 插件清单(版本/描述) | integrations/mem0-plugin/plugin.json |
需要说明的适用前提:tour 依赖已安装 Mem0 插件并连通远端 MCP 服务器、MEM0_API_KEY已配置(见 README 的安装步骤);类别自动归类的效果依赖插件的编码类别体系是否已随会话启动脚本应用。除技能文档明确给出的page_size/top_k参数外,本文所有行为结论均来自上述仓库文件,未引入外部数据。
【免费下载链接】embedchainThe Memory Layer for AI Agents - Drop-in memory infrastructure for AI agents and apps. Context that persists. Built for production.项目地址: https://gitcode.com/GitHub_Trending/em/embedchain
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考