ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Mem0 Plugin switch-project 技能详解:项目作用域覆盖与全局搜索模式

Mem0 Plugin switch-project 技能详解:项目作用域覆盖与全局搜索模式 Mem0 Plugin switch-project 技能详解项目作用域覆盖与全局搜索模式【免费下载链接】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 插件mem0-plugin中的switch-project技能展开讲解它如何用一条/mem0:switch-project斜杠命令覆盖当前目录 → project_id的自动探测结果或切换为跨用户、跨项目的全局搜索模式。读完本文你将掌握三种用法指定项目名、--global、--no-global背后的两个本地配置文件~/.mem0/project_map.json与~/.mem0/settings.json的完整格式以及插件源码中 project_id 解析优先级、app_id过滤器注入和会话级生效机制的实现细节。1. switch-project 的三种用法switch-project 技能定义文件 的 frontmatter 将其定位为覆盖自动探测的项目作用域以读取/写入另一个 project ID 下的记忆或启用全局搜索访问所有用户和项目下的记忆。适用于跨多个项目工作、访问其他仓库的记忆、开启团队级记忆访问或自动探测解析到错误项目的场景。文档定义了三种调用形式命令作用/mem0:switch-project project-name切换到指定项目作用域将当前目录映射到该 project_id/mem0:switch-project --global启用全局搜索跨所有用户、所有项目返回全部记忆/mem0:switch-project --no-global关闭全局搜索回到按项目隔离的作用域模式三种模式分别落到两个本地文件上项目名模式写入~/.mem0/project_map.json全局模式修改~/.mem0/settings.json中的global_search键。下面逐一说清每种模式的完整操作步骤与底层实现。2. 先理解覆盖的对象project_id 自动解析优先级switch-project覆盖的不是任意配置而是插件在每次 hook 运行时自动推导的project_id。scripts/_project.py 的resolve_project_id()实现了一套四级解析优先级该文件头部 docstring 与 scripts/_project.sh 的注释一致环境变量MEM0_PROJECT_ID显式覆盖优先级最高~/.mem0/project_map.json按当前目录cwd查表这正是switch-project project-name写入的文件查表失败的补充路径按 remote 哈希键回退remote:sha256(remote_url)[:16]形式的主键用于目录被移动/重命名后自动修复映射self-healing fallback命中后还会把新的 cwd 键写回映射文件以便后续快速命中Git remote slug取git remote get-url origin的输出剥掉协议前缀与.git后缀保留最后两段路径并拼成owner-repo例如gitgithub.com:mem0ai/mem0.git - mem0ai-mem0兜底取 cwd 的 basename仍为空则返回unknown。因此switch-project的项目名模式写入的是第 2 优先级——它高于 git slug 和 basename 兜底但低于环境变量MEM0_PROJECT_ID。这一点在 tests/test_project.py 的test_resolve_project_id_priority_order中有明确断言env var project_map git remote basename。值得注意save_project_mapping() 每次写入时会同时落两个键——cwd - project_id和remote:16位hex - project_id这样即使你把仓库目录改名或换盘映射仍然能通过 remote URL 哈希命中。测试test_save_project_mapping_writes_remote_key与test_resolve_project_id_remote_hash_fallback分别验证了这两点。3. 模式一/mem0:switch-project project-name切换项目作用域3.1 文档定义的执行步骤按照 SKILL.md 的定义当用户提供项目名且不带任何 flag时技能执行四步若用户没有给出项目名先询问What project_id should this directory use?通过 Bash 工具将映射写入~/.mem0/project_map.jsonpython3 -c import json, os map_file os.path.expanduser(~/.mem0/project_map.json) mapping {} if os.path.isfile(map_file): with open(map_file) as f: mapping json.load(f) mapping[os.getcwd()] PROJECT_NAME os.makedirs(os.path.dirname(map_file), exist_okTrue) with open(map_file, w) as f: json.dump(mapping, f, indent2) print(fMapped {os.getcwd()} - PROJECT_NAME) 其中PROJECT_NAME替换为用户选择的项目名。该文件最终形如{ /absolute/path/to/your/dir: my-project }验证搜索该项目下是否已有记忆。调用search_memories工具参数为queryproject、filters{AND: [{user_id: active_user_id}, {app_id: PROJECT_NAME}]}、top_k1——即带上目标项目的app_id过滤条件做一次最小检索确认作用域内确有数据。打印结果Switched to project PROJECT_NAME. N memories found for this project. Note: This override persists across sessions for this directory.3.2 源码视角映射如何被消费Python 侧resolve_project_id() 在 hook 脚本中按os.getcwd()精确查project_map.json命中即返回不再走 git slug 逻辑。由于键是完整绝对路径这条覆盖只对这一个目录生效对应文档中 persists across sessions for this directory 的表述。Shell 侧各 hook 实际执行时 source 的是 _project.sh其_mem0_resolve_project_id()用jq -r --arg cwd $PWD .[$cwd] // empty做同样的查表依赖系统装有jq并把解析出的值export为MEM0_PROJECT_ID供后续脚本使用。写入路径的小差异技能文档里的 python3 单行命令只写 cwd 键而库函数save_project_mapping()_project.sh第 3 级解析命中后自动调用、以及测试直接调用还会额外写入remote:hash键。也就是说手动执行技能命令后若该目录的 git slug 随后被解析命中shell 路径的自愈逻辑会补写 remote 哈希键映射仍然稳定。验证检索为何有效scripts/enforce_metadata_defaults.sh 会在 Agent 发起search_memories/get_memories时自动把app_id取自MEM0_PROJECT_ID注入filters.AND[]add_memory/delete_all_memories则注入顶层参数。切换项目后同一条queryproject检索会自动落到新的app_id作用域下验证步骤本质上是在确认注入链路已指向新项目。3.3 如何选择 project-name技能文档没有内置项目列表。仓库中提供了配套技能 list-projects由于平台没有专门的列出项目接口它通过两次get_memories并行查询null 作用域与app_id存在的作用域合并去重从顶层app_id或旧格式metadata.project_id/metadata.project中归纳出当前用户已有的全部项目名及记忆数量。实际使用时可先跑list-projects找到目标项目名再执行switch-project。4. 模式二/mem0:switch-project --global启用全局搜索4.1 文档定义的执行步骤带--global时技能只做两件事通过 Bash 工具在~/.mem0/settings.json中设置global_search: truepython3 -c import json, os settings_file os.path.expanduser(~/.mem0/settings.json) settings {} if os.path.isfile(settings_file): with open(settings_file) as f: settings json.load(f) settings[global_search] True with open(settings_file, w) as f: json.dump(settings, f, indent2) print(Global search enabled) 打印提示Global search enabled. Searches now return all memories across all users and projects. Writes still use the current user_id and app_id. Restart the session for the change to take effect.注意两点语义边界读取变全局写入不变——写记忆仍使用当前user_id和app_id且配置在会话启动时才加载需重启会话生效。4.2 源码视角global_search如何改变检索行为配置加载scripts/load_settings.py 定义了默认值表global_search: False是默认值load_settings()只合并文件里已知键DEFAULTS白名单拼写错误的键会被忽略unknown_keys()可列出这些键。测试 tests/test_load_settings.py 断言了global_search缺失时回落到默认False。检索过滤器scripts/_search.py 的search_memories()中global_searchTrue时 filters 变为{OR: [{user_id: *}]}——即不再叠加app_id通配全部用户否则构造{AND: [{user_id: user_id}, {app_id: project_id}, ...]}的项目级过滤。这就是跨所有用户和项目在 API 层的直接体现。会话级生效scripts/on_session_start.sh 在会话启动时读取设置并把global_search转为环境变量MEM0_GLOBAL_SEARCHscripts/_identity.sh 第 73 行同样执行该解析随后file_context.py、session_timeline.py、enforce_metadata_defaults.sh等脚本依据该环境变量决定预取上下文、会话时间线、元数据注入是否走全局分支。这解释了文档中Restart the session for the change to take effect——配置在会话启动阶段被快照进环境变量中途改文件不会改变当前会话的行为。5. 模式三/mem0:switch-project --no-global关闭全局搜索带--no-global时步骤与模式二对称在~/.mem0/settings.json中设置global_search: falsepython3 -c import json, os settings_file os.path.expanduser(~/.mem0/settings.json) settings {} if os.path.isfile(settings_file): with open(settings_file) as f: settings json.load(f) settings[global_search] False with open(settings_file, w) as f: json.dump(settings, f, indent2) print(Global search disabled) 打印提示Global search disabled. Searches now return only memories scoped to the current project. Restart the session for the change to take effect.生效后检索回到user_id app_id的 AND 过滤_search.py的非全局分支且app_id的取值就是第 2 节解析出的 project_id——因此如果此前用模式一改过项目作用域--no-global之后检索落在哪个项目取决于project_map.json/ git slug / basename 的解析结果。6. 底层机制小结app_id 注入与全局分支把三种模式串起来看插件的记忆读写链路是这样的依据 enforce_metadata_defaults.sh 的头部注释与实现add_memory/delete_all_memorieshook 在调用前注入顶层user_id与app_idapp_id取自解析后的MEM0_PROJECT_IDsearch_memories/get_memories把user_id、app_id追加进filters.AND[]已存在的同名字段不会重复注入全局模式下_MEM0_GLOBAL_SEARCHtrue脚本走全局分支不再按项目收紧过滤器与_search.py的{OR: [{user_id: *}]}逻辑一致。这也解释了 SKILL.md 验证步骤中 filters 的写法与 hook 自动注入完全同构文档让技能显式传app_id而日常使用中 hook 会自动传两者指向同一套过滤语义。7. 行为验证仓库中的测试覆盖tests/test_project.py 为解析链路提供了完整回归test_resolve_project_id_from_project_map/test_save_project_mapping_creates_file验证project_map.json查表命中与文件落盘正是模式一的行为基础test_resolve_project_id_from_env验证MEM0_PROJECT_ID环境变量优先于映射表test_remote_url_to_slug_various_formats覆盖 HTTPS / SSH /ssh:/// 子路径仓库 / 非 GitHub 主机等多种 remote URL 到owner-reposlug 的转换test_remote_hash_key_format/test_save_project_mapping_writes_remote_key/test_resolve_project_id_remote_hash_fallback验证remote:16位hex键的生成、双键写入以及目录移动后经 remote 哈希回退仍能解析出原项目名。tests/test_load_settings.py 则验证了settings.json缺键时的默认值回落含global_search默认False对应模式二/三写一个键、其余键保持默认的合并语义。8. 实践要点与适用前提生效时机全局模式改动需要重启会话配置在会话启动时快照为环境变量项目映射改动对下一次 hook 解析即时可见但当前会话已注入的上下文不会自动刷新。作用域粒度project_map.json的键是绝对路径覆盖只对写入时的 cwd 生效同一台机器不同目录可映射到不同项目。优先级提醒如果环境中已设置MEM0_PROJECT_ID环境变量它会覆盖映射表——switch-project写入的映射不生效时可先排查该变量。候选项目名配合 list-projects 技能 查询当前用户已有的项目作用域与记忆数量避免手敲错项目名。插件形态该插件为 Mem0 平台的 MCP 插件见 plugin.json版本 0.1.7依赖 Mem0 Platform 的 MCP 工具search_memories、get_memories等与本地python3shell 查表路径另需jq本文所有配置文件均位于用户主目录下~/.mem0/可直接手动查看或编辑未知键会被安全忽略。参考文件switch-project SKILL.md、_project.py、_project.sh、load_settings.py、_search.py、on_session_start.sh、enforce_metadata_defaults.sh、test_project.py、test_load_settings.py、list-projects SKILL.md。【免费下载链接】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),仅供参考
返回列表