memU memu-cli npm 启动器:文件化个人记忆 CLI(commit / retrieve / list-files)与底层实现剖析
【免费下载链接】memUPersonal memory across agents项目地址: https://gitcode.com/GitHub_Trending/mem/memU
本文以 npm/README.md 为主体,系统讲解 memU 项目在 npm 上的发布形态memu-cli:一个只有几 kB、零依赖的 Node 启动器,负责把commit(持久化记忆)、retrieve(纯 embedding 检索)、list-files(列出全部记忆/技能文件)三个命令委派给 PyPI 上的 Python 引擎。读完后你可以独立完成本地 SQLite 与 MemU Cloud 两种模式下的安装、配置与调用,并理解启动器回退策略、环境变量解析顺序与云端客户端的底层行为。
memu-cli 的定位:Python 引擎之上的薄启动层
memU 是一个"个人记忆即文件"(personal memory as files)的项目:由外部 Agent 准备好记忆与技能文档,memU 负责持久化这些文档,并在后续对话中用 embedding 相似度检索出紧凑、排序好的上下文,替代"把每个 prompt 重新塞满"的粗放做法。一个关键设计约束是embedding-only——memU 内部不发生任何 LLM 调用,因此检索路径快速且无额外推理成本(见 npm/README.md 开头说明与 src/memu/cli.py 的模块注释)。
项目有两种安装面:
| 形态 | 包 | 说明 |
|---|---|---|
npm 包memu-cli | npm/package.json | 薄启动器(bin 入口 npm/bin/memu.js),几 kB、无第三方依赖,要求 Node >= 18 |
PyPI 包memu-cli | pyproject.toml | memU 引擎本体,提供memu可执行入口与MemoryService库 API,预构建 wheel 覆盖 Linux(x86_64/aarch64)、macOS(Intel/Apple Silicon)与 Windows |
npm 与 PyPI 两个包同名但职责不同,当前仓库中 npm 侧版本为0.2.0,PyPI 侧引擎版本为0.11.0-beta.3(requires-python = ">=3.11",支持 3.11/3.12/3.13)。启动器把"如何找到 Python 运行时"这一麻烦封装掉,用户只需npx memu-cli <command>。
快速开始:唯一前置依赖是 uv
官方快速开始要求只预装 uv ——它会同时拉取 Python 3.13 运行时和 memU 引擎本身,无需其他预装:
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS / Linux # Windows: powershell -c "irm https://astral.sh/uv/install.ps1 | iex"然后设置 embedding 服务的密钥并执行三个基本命令:
export OPENAI_API_KEY=sk-... # 持久化准备好的记忆:{"recall_files": [...], "resource": [...]} npx memu-cli commit results.json # 列出所有已存储的记忆/技能文件 npx memu-cli list-files # 单发 embedding 检索 —— 无 LLM、速度快 npx memu-cli retrieve "deploy checklist"默认情况下,状态持久化在本地 SQLite 数据库./data/memu.sqlite3。
三个核心命令
commit <payload.json>:持久化外部准备好的记忆
commit接收一个 JSON 文件(-表示从 stdin 读取),把外部流程(例如 Agent 会话)准备好的召回文件(recall files)和工作区资源(resources)写入存储。从 src/memu/cli.py 的_cmd_commit可以看到,payload 支持三个可选顶层字段:
recall_files:召回文件数组(记忆与技能两个 track 的文件);resource:工作区资源数组;user:用户/Agent 作用域字段。
提交成功后,默认输出形如committed N recall file(s) and M resource(s),并逐行列出track/name;加--json则输出原始 JSON 响应。文件不存在时命令返回退出码 2 并打印error: no such file: ...。
retrieve <query>(别名search):零 LLM 调用的单发检索
retrieve对记忆分段、文件与资源按 embedding 相似度排序并返回,全程不调用 LLM。命令实现见 src/memu/cli.py:构建后端后直接调用progressive_retrieve(query),打印 JSON 结果。该协议在 src/memu/agentic_backend.py 中以 Protocol 形式定义,本地MemoryService与云端CloudMemoryClient都满足同一接口,保证两条执行路径行为一致。
list-files:跨 track 列出全部召回文件
list-files会遍历 memory 与 skill 两个 track 的全部召回文件。从 src/memu/cli.py 的实现可以看出,它并非一次拉取:而是跟随next_cursor逐页请求list_all_recall_files(对应 docs/adr/0014-paginated-list-all-recall-files.md 的分页设计),拼齐全量后再打印N recall file(s)与每行- {track}/{name}: {description};加--json输出完整{"recall_files": [...]}。
公共选项与环境变量映射
每个子命令都挂载了同一组"本地服务选项"(在 cloud 模式下被忽略),来自 src/memu/cli.py 的_add_common_options。每个命令行参数都有对应的MEMU_*环境变量,CI 或 Agent 只需配置一次环境即可:
| 选项 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
--provider | MEMU_EMBED_PROVIDER | openai | embedding 提供商标识,如openai、jina、voyage |
--embed-model | MEMU_EMBED_MODEL | 取 provider 默认模型 | 覆盖 embedding 模型 |
--base-url | MEMU_BASE_URL | 取 provider 端点 | API base URL 覆盖 |
--api-key | MEMU_API_KEY | 取 provider 的密钥变量(如OPENAI_API_KEY) | API key 值或环境变量名 |
--db | MEMU_DB | ./data/memu.sqlite3 | SQLite 文件路径、postgres://DSN 或:memory: |
--json | — | 关 | 打印原始 JSON 响应 |
关于--db,src/memu/env.py 的database_config说明了取值范围:裸 SQLite 路径、完整 SQLAlchemy URL(sqlite:///…、postgres://…)或内存哨兵值(:memory:/inmemory)。裸路径会自动创建父目录。
本地与云端双模式
本地模式(默认)
不设任何记忆模式变量时,引擎在本地构建MemoryService:embedding 在客户端计算,元数据与向量写入MEMU_DB指定的 SQLite(或 Postgres DSN)。这里有一个容易踩坑的点,src/memu/env.py 的模块注释解释得很清楚:写入侧(record)与检索侧(inject)必须使用同一个 DSN 和同一个 embedding provider,否则查询向量与被比较向量处于"不同的向量空间",检索会静默返回空结果。因此配置解析遵循三级顺序:
- 进程环境变量(
MEMU_DB=… memu retrieve …可一次性覆盖,无需改文件); ~/.memu/config.env(安装时写入的 dotenv,可用MEMU_CONFIG_ENV改路径)——定时任务没有可靠的工作目录,也不继承交互式 shell,绝对路径下的文件是唯一稳健的载体;- 代码内默认值。
Cloud 模式
设置两个变量即可让完全相同的命令改走 MemU Cloud:
export MEMU_MEMORY_MODE=cloud export MEMU_CLOUD_API_KEY=<memu-api-key>- API key 需在 memu.so 注册后获取;
- 生产 API base 默认为
https://api.memu.so/api/v4/memory/,可用MEMU_CLOUD_BASE_URL覆盖以对接兼容部署(见 src/memu/cloud.py 的DEFAULT_CLOUD_BASE_URL与 src/memu/env.py); - 本地 embedding 配置(
MEMU_EMBED_PROVIDER、MEMU_EMBED_MODEL、MEMU_DB等)与云端凭证完全独立、互不复用,cloud 模式下本地专用选项被忽略(见build_agentic_memory_backend_from_env,src/memu/env.py); - 能力边界:Cloud 目前持久化 memory 与 skill 召回文件,但不持久化提交的工作区资源;
MEMU_MEMORY_MODE只接受local/cloud,其他取值直接抛ConfigError;cloud 模式下缺少MEMU_CLOUD_API_KEY同样显式报错而不是猜测。
从 src/memu/cloud.py 的CloudMemoryClient还可以看到几个实现细节,对排障很有用:
- 三个操作(
list_all_recall_files/progressive_retrieve/commit_results)分别映射为GET(带cursor分页参数)、POST search、POST(payload 为{user, recall_files, resource}),鉴权头为Authorization: Bearer <key>; - 默认 3 次尝试、超时 30s(连接 5s),对可重试状态码做指数退避重试(
max_attempts最小为 1); - 作用域(where)只支持
user_id与agent_id的精确过滤,缺省值为"default";user字段仅支持user_id、agent_id、user_name、agent_name,其他字段会抛出配置错误; - 错误按状态码分类:401 认证失败、403 授权失败、400/409/422 请求被拒、429 限流,其余归为服务错误;
- 支持
MEMU_HTTP_PROXY显式代理,未设置时默认绕过代理的 mount 规则;~/.memu/config.env中的NO_PROXY/no_proxy会被透传进进程环境(src/memu/env.py)。
embedding 配置:memU 唯一的模型能力
因为 memU 内部没有 LLM,MEMU_EMBED_PROVIDER命名的就是"唯一剩下的模型能力"。src/memu/embedding/defaults.py 是 provider 知识的单一来源,内置五个后端(均在 src/memu/embedding/backends/ 下有真实实现):
| provider | 默认模型 | 端点 | 密钥环境变量 |
|---|---|---|---|
openai | text-embedding-3-small | (字段默认值) | OPENAI_API_KEY |
jina | jina-embeddings-v3 | https://api.jina.ai/v1 | JINA_API_KEY |
voyage | voyage-3.5 | https://api.voyageai.com/v1 | VOYAGE_API_KEY |
doubao | doubao-embedding-large-text-250515 | https://ark.cn-beijing.volces.com | ARK_API_KEY |
openrouter | openai/text-embedding-3-small | https://openrouter.ai | OPENROUTER_API_KEY |
provider 的解析还带一个兼容性细节:MEMU_LLM_PROVIDER作为MEMU_EMBED_PROVIDER的后备被读取,让旧版~/.memu/config.env继续可用(见 src/memu/env.py)。
npm shim 如何拉起 Python:四级回退策略
npm/package.json 声明了bin入口memu -> bin/memu.js,且files只包含bin目录——整个 npm 包就是 npm/bin/memu.js 这一个几十行的 Node 脚本。它按优先级依次探测并委派:
$MEMU_PYTHON -m memu——显式解释器覆盖,适合自定义虚拟环境;uvx --from memu-cli memu——无需安装、由 uv 缓存(官方推荐路径);pipx run --spec memu-cli memu——无需安装、由 pipx 缓存;python3 -m memu——要求已执行pip install memu-cli。
探测逻辑本身也很直接:has(cmd)用spawnSync(cmd, ["--version"])判断可执行文件存在且退出码为 0;第 4 级还会先python3 -c "import memu"确认包已安装才使用。若四级全部落空,脚本打印安装指引(安装 uv / pipx / 或 pip 安装,或用MEMU_PYTHON指向已装 memU 的解释器)并以退出码 1 结束。子进程的退出码会原样透传给用户,stdio 直接继承。
已经使用 Python 的用户:可以完全跳过 npm
npm 层只是分发糖。若环境中已有 Python,可以:
uvx --from memu-cli memu --help # 无需安装,uv 缓存 # 或 pip install memu-cli同一个 PyPI 包还携带库 API(MemoryService、Postgres 后端)——一次安装同时覆盖 CLI、宿主适配器与库调用。从 pyproject.toml 的[project.scripts]可以看到完整的可执行入口面:除核心memu(算法面)外,还有memu-codex、memu-claude-code、memu-cursor、memu-openclaw、memu-hermes、memu-workbuddy、memu-cola、memu-pi等宿主适配器二进制,以及用于任意 Agent 的memu-agent通用适配器(ADR 0008/0009/0010/0011 描述的设计)。核心memu二进制的retrieve/list-files/commit用法与npx memu-cli完全一致。
小结
npx memu-cli的价值在于把"Python 引擎 + 运行时管理"封装成一条 npx 命令:npm 启动器(npm/bin/memu.js)负责按MEMU_PYTHON→uvx→pipx→python3的顺序找到可用运行时,PyPI 引擎(入口memu.cli:main)负责实际的 commit/retrieve/list-files 语义,MEMU_*环境变量统一了本地与云端两条路径的配置面。对 CI 与 Agent 集成而言,"配置一次环境、只传命令"正是这套设计的直接收益;而 embedding-only、零 LLM 调用的检索路径,则是它可以在低延迟、低成本前提下被高频调用的原因。项目采用 Apache-2.0 许可(见 LICENSE.txt)。
【免费下载链接】memUPersonal memory across agents项目地址: https://gitcode.com/GitHub_Trending/mem/memU
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考