Mem0 多语言 Monorepo 协作工程指南:AGENTS.md 体系、逐包工具链与贡献双门机制
本文以 Mem0 仓库根目录的 AGENTS.md 为主体,系统拆解这套面向 AI 编码助手(Claude Code、Cursor、Copilot、Codex)与人类贡献者共享的工程约定体系:逐包工具链矩阵、仓库目录地图、开发环境搭建、全局编码规范,以及决定 PR 生死的“双门”机制与 CLA 规则。读完后,你可以在这个 Python/TypeScript/Node 混合的 monorepo 中精准定位每个包应使用的 linter、测试运行器与构建工具,理解各目录的职责边界与依赖关系,并掌握一条能让 PR 通过 CI 门禁、进入评审队列的完整贡献路径。
Mem0("mem-zero")是一个面向 AI Agent 的记忆层:通过托管平台 API 与自托管开源 SDK 提供持久化、个性化记忆,采用 Apache-2.0 协议。它是一个多语言 monorepo,根 AGENTS.md 给出的核心警告是:每个包都有自己的规则(every package sets its own rules)——在编辑任何文件之前,必须先阅读距离目标文件最近的那个 AGENTS.md,因为 linter、formatter、测试运行器、行宽限制在各包之间真实地不同,用错工具会导致 CI 失败或产生满屏噪声 diff。仓库中 CLAUDE.md 是指向 AGENTS.md 的符号链接,二者内容一致;除根目录外,mem0/、tests/、mem0-ts/、cli/python/、cli/node/、integrations/、server/、docs/、skills/、.github/ 下均有各自的 AGENTS.md。
红线清单:Do NOT
根 AGENTS.md 开篇即列出一组不可触碰的禁区,这是整个仓库约定中最强硬的部分,逐条继承如下:
- 不要在没有签署 CLA 的情况下开 PR——它不会被评审,详见下文 CLA 不可省略;
- 不要开没有链接
accepted标签 issue 的 PR——机器人会在一分钟内关闭它,详见下文 双门机制; - 未经维护者明确批准,不要修改
.github/workflows/——发布凭证与 workflow 文件名绑定; - 不要提交
.env文件、API key 或任何凭证; - 不要跳过 pre-commit hooks;
- TypeScript 包中不要使用 npm 或 yarn——本仓库 pnpm-only(
.opencode-plugin/例外使用 Bun); - TypeScript 中不要使用
require()——只允许 ES moduleimport语法; - 不要搞混 linter 配置——根 Python 是 ruff(行宽 120),
cli/python/是 ruff(行宽 100),cli/node/是 Biome,mem0-ts/是 Prettier,integrations/vercel-ai-sdk/是 ESLint; - 不要把 Python 依赖加进 pyproject.toml 的核心
dependencies——必须放入 optional 依赖组; - 不要在不更新
docs/的情况下变更公开 API; - 不要在没有讨论的情况下引入新框架或新抽象——遵循你正在编辑的文件里已有的模式。
其中两条可以直接在仓库中验证其来源:核心依赖组最小化的规则对应 pyproject.toml 中 dependencies 仅包含 qdrant-client、pydantic、openai、httpx、posthog、pytz、sqlalchemy、protobuf 八个包,而向量库、LLM 等全部依赖都位于 vector-stores、llms、extras 等 [project.optional-dependencies] 组中;ruff 行宽 120 的配置则写在 pyproject.toml 的 [tool.ruff] 段(line-length = 120),isort 采用 profile = "black" 且 first-party 为 mem0 与 mem0_cli。
Where to look:逐包工具链矩阵
这是 AGENTS.md 的核心路由表:你要改什么,就读哪份文档,用哪套工具链。所有链接已从仓库根目录解析:
| 编辑目标 | 先读 | 工具链 |
|---|---|---|
mem0/ |
mem0/AGENTS.md | hatch、ruff 120、pytest |
tests/ |
tests/AGENTS.md | pytest |
mem0-ts/ |
mem0-ts/AGENTS.md | pnpm、tsup、Prettier、jest |
cli/python/ |
cli/python/AGENTS.md | ruff 100、pytest |
cli/node/ |
cli/node/AGENTS.md | pnpm、tsup、Biome、vitest |
integrations/ |
integrations/AGENTS.md | 逐集成各不相同 |
server/ |
server/AGENTS.md | Docker Compose、FastAPI |
docs/ |
docs/AGENTS.md | Mintlify |
skills/ |
skills/AGENTS.md | markdown,有体量预算 |
.github/ |
.github/AGENTS.md | GitHub Actions |
这张表的价值在于消除“共享配置”的幻觉。例如同样是 TypeScript 包:mem0-ts/ 用 Prettier 格式化、jest 跑测试,cli/node/ 用 Biome、vitest 跑测试,integrations/vercel-ai-sdk/ 又改用 ESLint、jest;mem0-ts/AGENTS.md 甚至明确要求“不要假设各包共享同一套配置”。同理,Python 侧 mem0/ 与 tests/ 使用 ruff 120,而 cli/python/ 是 ruff 100——mem0/AGENTS.md 特意警告“不要把那份(100 行)配置带过来”。
Repository map:仓库目录地图
根 AGENTS.md 给出的目录职责表完整如下:
| 目录 | 内容 |
|---|---|
mem0/ |
核心 Python SDK(PyPI 上的 mem0ai):memory、LLMs、embeddings、vector stores、graphs、rerankers |
mem0-ts/ |
TypeScript SDK(npm 上的 mem0ai):托管客户端 + OSS 记忆 |
cli/python/ |
Python CLI(PyPI 上的 mem0-cli),基于 Typer,入口命令 mem0 |
cli/node/ |
Node CLI(npm 上的 @mem0/cli),基于 Commander,入口命令 mem0 |
integrations/ |
Agent 与编辑器集成,每个集成为独立自包含目录 |
server/ |
自托管 Mem0 的 FastAPI REST 服务器(Docker:FastAPI + pgvector + Neo4j) |
skills/ |
Claude Code skill 定义 |
docs/ |
文档站(Mintlify) |
tests/ |
Python SDK 测试(pytest) |
examples/ |
示例应用、Chrome 扩展、多 Agent 模式、notebook |
scripts/ |
仓库级工具脚本,如 check-llms-txt-coverage.py |
evaluation/ |
子模块,固定指向 mem0ai/memory-benchmarks |
目录之间的依赖关系用下面这棵结构树表达(继承自 AGENTS.md 原文):
mem0 (Python SDK) mem0-ts (TypeScript SDK)
├── mem0/memory/ ├── src/client/ MemoryClient (hosted)
├── mem0/llms/ └── src/oss/ Memory (self-hosted)
├── mem0/embeddings/ ├── src/llms/
├── mem0/vector_stores/ ├── src/embeddings/
├── mem0/graphs/ ├── src/vector_stores/
└── mem0/reranker/ └── src/graphs/
cli/python/ ──▶ mem0ai (optional, OSS mode)
cli/node/ ──▶ mem0ai (npm)
integrations/vercel-ai-sdk/ ──▶ ai, @ai-sdk/*
integrations/openclaw/ ──▶ mem0ai (npm)
从源码结构看,这条依赖链与仓库实际布局吻合:mem0/ 下确实存在 memory/、llms/、embeddings/、vector_stores/、reranker/ 等子包(其中 graph 能力在 mem0/AGENTS.md 中描述为 MemoryConfig 的 graph 配置段,作为向量记忆之上的可选关系感知检索层);mem0-ts/src/ 下则分 client/(托管)与 oss/(自托管)两大块,oss/ 内再按 llms/、embeddings/、vector_stores/、graphs/ 组织。
Setup:开发环境搭建
AGENTS.md 给出的标准初始化命令:
hatch shell dev_py_3_11 # Python:创建含全部依赖的环境
pre-commit install # 提交时自动跑 ruff + isort
cd <ts-package> && pnpm install # 进入任意 TypeScript 包后安装
环境要求:Python 3.9+(CLI 需 3.10+)、Node 18+(推荐 20 或 22)、pnpm 10+、hatch、server/ 需 Docker。
结合仓库实际文件可以对这套要求做三点补充:
- hatch 环境矩阵。pyproject.toml 中定义了
dev_py_3_10、dev_py_3_11、dev_py_3_12三个 hatch 环境,各自激活test、vector-stores、llms、extras四个 feature 组;Makefile 提供make test-py-3.10 / 3.11 / 3.12来固定 Python 版本跑测试,make install_all则一次性装齐大部分可选依赖。hatch内的脚本别名format、lint、test也定义在 pyproject.toml 的[tool.hatch.envs.default.scripts]中。 - pre-commit。.pre-commit-config.yaml 在提交时运行 ruff 与 isort,对应根文档“不要跳过 pre-commit hooks”的红线。
- TypeScript 侧。进入任意 TS 包(
mem0-ts/、cli/node/、integrations/*/)执行pnpm install;mem0-ts/的完整命令集(pnpm run build走 tsup 双输出 CJS+ESM、pnpm run test走 jest、pnpm run typecheck走tsc --noEmit)见 mem0-ts/AGENTS.md。
Conventions everywhere:全局编码规范
各包共性约定(继承自 AGENTS.md):
- 命名:Python 源文件
snake_case.py,测试test_<module>.py;TypeScript 源文件snake_case.ts,测试<module>.test.ts;配置与 manifest 文件用kebab-case; - Python:所有数据模型与配置类使用 Pydantic v2;每个 provider 继承对应目录
base.py中的抽象类,配置集中在configs.py; - TypeScript:strict 模式,tsup 构建,ES module import;
- Commit:遵循 Conventional Commits(
feat:、fix:、docs:、refactor:、test:); - 版本号:在
pyproject.toml或package.json中 bump;发布按 tag 前缀触发,细节见 .github/AGENTS.md。
这些约定在仓库内均有实证:mem0/ 各 provider 类别(llms/、embeddings/、vector_stores/、reranker/)统一采用 base.py + <provider>.py + configs.py + __init__.py 注册的四件套结构;tests/AGENTS.md 则规定 provider 测试镜像源码树(tests/<category>/<provider_name>/)、mock provider SDK 而非被测代码本身。
Python SDK 包(mem0/)要点
mem0/AGENTS.md 给出了核心包的完整命令集:
hatch shell dev_py_3_11 # 或 dev_py_3_9 / dev_py_3_10 / dev_py_3_12
pre-commit install
make lint # ruff check
make format # ruff format
make sort # isort mem0/
make test # pytest tests/
make test-py-3.9 # 固定 Python 版本(3.9 ~ 3.12)
make install_all # 可选依赖,跑完整测试前执行
make build # hatch build
注意其明确声明“使用 hatch 管理环境与依赖,不要用 pip 或 conda”。该包的 provider 规模如下表(继承自 mem0/AGENTS.md):
| 类别 | 数量 | 示例 |
|---|---|---|
| LLMs | 24 | OpenAI、Anthropic、AWS Bedrock、Azure OpenAI、Gemini、Groq、Ollama、Together、DeepSeek、vLLM、LiteLLM、LM Studio、xAI |
| Vector stores | 30 | Qdrant、Pinecone、Chroma、Weaviate、Milvus、MongoDB、Redis、Elasticsearch、pgvector、Supabase、Faiss、S3 Vectors |
| Embeddings | 15 | OpenAI、Azure OpenAI、Gemini、HuggingFace、FastEmbed、Together、AWS Bedrock、Ollama、Vertex AI |
| Graph stores | 4 | Neo4j、Memgraph、Kuzu、Apache AGE |
| Rerankers | 5 | Cohere、HuggingFace、LLM-based、Sentence Transformer、Zero Entropy |
其公开 API 面为 Memory(自托管同步)、AsyncMemory(自托管异步)、MemoryClient(托管平台同步)、AsyncMemoryClient(托管平台异步),统一方法面包括 add、search、get、get_all、update、delete、delete_all、history——文档同时强调:改动任一签名必须在同一 PR 中更新 docs/。新增 provider 的八步流程(建 <category>/<provider>.py → 继承 base.py 抽象基类 → 补 configs.py → 注册 __init__.py → 加测试 → 依赖进 optional 组 → 严格对齐同类现有 provider 的签名与错误处理 → 补 docs/integrations/ 指南)也完整定义在该文档中。
TypeScript SDK 包(mem0-ts/)要点
mem0-ts/AGENTS.md 的关键事实:Node 20 与 22 是 CI 实测版本;tsup 产出 CJS + ESM 双格式;formatter 只有 Prettier(无 linter);测试是 jest(cli/node/ 与 integrations/openclaw/ 则用 vitest);源文件命名 snake_case.ts、测试 <module>.test.ts。每次改动后必须跑 pnpm run typecheck。公开导出为 MemoryClient(import { MemoryClient } from 'mem0ai')、Memory 与各 provider(import { Memory } from 'mem0ai/oss'),方法面镜像 Python SDK(add、search、get、getAll、update、delete、deleteAll、history)。发布流程:先 bump package.json 版本,tag 前缀 ts-v* 触发 npm 的 OIDC 发布。
自托管服务器(server/)要点
server/AGENTS.md 规定 server/ 只有 Docker 路径,没有本地非 Docker 方案:
make build # docker build -t mem0-api-server .
make run_local # docker run -p 8000:8000,带 .env
docker-compose up # 开发栈:FastAPI + PostgreSQL/pgvector + Neo4j
| 服务 | 端口 |
|---|---|
| mem0 API | 8888 |
| PostgreSQL (pgvector) | 8432 |
| Neo4j HTTP | 8474 |
| Neo4j Bolt | 8687 |
该服务器的 dev Dockerfile 同时挂载 server/ 与 mem0/,因此对 SDK 的改动无需重建镜像即可热生效;且由于 server 直接 import 仓库内的 Python SDK,SDK 的规范同样适用于你触碰的 SDK 代码。
测试约定(tests/)
tests/AGENTS.md 是 Python SDK 测试套件(mem0/ 的 pytest 套件)的规则来源:
make install_all # 部分测试需要可选依赖
make test # pytest tests/
make test-py-3.9 # 固定 Python 版本(3.9 ~ 3.12)
pytest tests/llms/test_openai.py::test_generate_response # 跑单个测试
核心约定:测试文件命名 test_<module>.py;provider 测试镜像源码树(tests/<category>/<provider_name>/);用 pytest-mock 做 mock、pytest-asyncio 覆盖异步面;ruff 行宽 120 与 mem0/ 保持一致。两条测试质量红线值得注意:mock provider SDK,永远不要 mock 被测代码——“一个让实现反向断言自己的测试比没有测试更糟”;bug fix 必须先写一个没有修复就会失败的回归测试,先看着它失败。其他包的测试各自就近存放:mem0-ts/(jest)、cli/python/tests/(pytest)、cli/node/(vitest)以及 integrations/ 下各目录。
变更交付清单:What to ship with a change
AGENTS.md 明确这部分是“指南而非硬性规则”——琐碎修复要求更少,面向用户的功能要求更多:
| 变更类型 | 预期交付 |
|---|---|
| Bug 修复 | 一个没有该修复就会失败的回归测试(先写)、修复本身、相关测试套件通过、该包的 linter 已运行 |
| 新功能 | 遵循既有模式的实现、测试覆盖、公开 API 的 docs/ 更新、行为面向用户时附示例、新 .mdx 页面的 llms.txt 条目 |
| 新 provider | 见 mem0/AGENTS.md 的 "Adding a provider" 小节 |
| 新集成 | 见 integrations/AGENTS.md 的 "Adding an integration" 小节 |
| 重构 | 变更行为的测试、既有测试保持绿色、纯内部改动无需更新文档 |
该文档还留下一句值得单列的工程原则:在根因处修 bug,而不是在症状处。如果某道守卫逻辑属于共享函数,就放进共享函数,而不是在每个调用点各写一份。
Benchmarking:评测子模块
基准测试(LOCOMO、LongMemEval、BEAM)不在本仓库内维护,而在独立的 mem0ai/memory-benchmarks 仓库;本仓库的 evaluation/ 路径是指向该仓库 main 分支的 git 子模块,这一事实在 .gitmodules 中有登记:
[submodule "evaluation"]
path = evaluation
url = https://github.com/mem0ai/memory-benchmarks
branch = main
初始化方式:
git submodule update --init evaluation
贡献流程:从 issue 到 PR 的七步
AGENTS.md 的 Contributing 小节给出的完整流程(完整指南见 CONTRIBUTING.md,行为准则见 CODE_OF_CONDUCT.md):
- 先开 issue 并等待维护者打上
accepted标签。每个 PR 必须用Closes #<number>链接它;未链接 accepted issue 的 PR 会被 PR Gate 自动关闭,有重开路径。纯文档类变更豁免。 - Fork 后从
main拉分支(feature/...、fix/...)。 - 做出改动:代码、测试、文档、示例。
- 对你触碰的每一个包运行 lint 与测试。
- 用 Conventional Commits 提交。
- 向
main开 PR 并填写 PR 模板——不要改写模板内容,GitHub 会预填。 - 签署 CLA。
双门机制决定 PR 的生死
两个 workflow 作用于每个来自 fork 的 PR,判断对象不同、互不覆盖,因此两个门都必须通过:
PR Gate 判断“变更”。对应 .github/workflows/pr-gate.yml,它关闭所有未链接 accepted 标签 issue 的 PR。文档强调:关闭是一个排队决定而非终审——当维护者补上标签时,PR 会自行重新打开。Draft、纯文档变更、推送到本仓库(而非 fork)的分支均豁免。
vouch check 判断“账户”。对应 .github/workflows/vouch-check-pr.yml,它读取 .github/VOUCHED.td,对任意一个人有三种状态:
| 列表状态 | 含义 | 对 PR 的效果 |
|---|---|---|
-handle |
维护者在 CoC 流程中执行了 !denounce |
即使有 accepted issue 也关闭 |
| 什么也没有 | 所有未曾在此仓库贡献过的人 | 无效果,仅留下一条“未被拦截”的新手评论 |
handle |
维护者执行了 !vouch |
无效果,且评论不再出现 |
原文特别澄清:被 vouch 不赋予任何权限——它只是一个“我们见过这个人”的标记,作用是静音新手评论,而不是跳过 accepted-issue 规则;不在列表里也不损失任何东西。对代替他人开 PR 的 Agent,实际后果浓缩为一条规则:在开 PR 之前确保所链接 issue 已打上 accepted 标签,否则预期 PR 被关闭、之后再重开;不要绕过任何一道门,不要手动重开被门控的 PR,也不要在 PR 被关闭后把同一变更换个 PR 重新提交。
CLA 不可省略
未签署 Contributor License Agreement 的贡献者,其 PR 不接受、不评审、不合并。 文档强调这不是合并时才走的形式:未签署 CLA 的 PR 根本不进入评审队列——维护者不读 diff、不留反馈、不讨论方案;它会一直搁置到 CLA 签署为止,过期则被关闭。CLAassistant 机器人会在你的第一个 PR 上留下带链接的评论,签署不到一分钟、每个 GitHub 账户只需一次、覆盖之后所有贡献;签署前 license/cla check 保持红色。若你是代替他人开 PR 的 Agent,必须告知对方需要本人签署——没有人能代签,在此之前 PR 寸步难行。
哪些行为会导致 PR 被关闭
除 CLA 与 accepted-issue 门控外,CODE_OF_CONDUCT.md 的 Contribution Conduct 小节是这个仓库 anti-slop(反灌水)策略的可执行形态,AGENTS.md 将其完整列出:
- 披露 AI 使用情况。PR 模板询问的是代码如何写的;用模型起草 PR 描述没问题。披露永远不会被当作攻击你的把柄,它只是告诉评审者该往哪里看;沉默之后再来一条你答不上来的 review 评论,才是真正让所有人损失一个下午的事。
- 不要提交你跑过的东西。bug report 意味着你复现过它;PR 意味着你跑过测试。
- 不要伪造证据。编造的 traceback、未测量的 benchmark、让实现反向断言自己的测试、描述与 diff 实际改动不一致的描述。
- 变更体量要与你的参与度匹配。以你能讨论它们的速率开变更。
- 不要催促合并。合理等待后一次礼貌跟进是可以的。
- 你必须能解释 diff 中的每一行及其与代码库其余部分的交互方式,而无需求助 AI 工具——这是唯一一条不可弯曲的规则。
Reference:参考资料索引
| 主题 | 文件 |
|---|---|
| 贡献指南 | CONTRIBUTING.md |
| 行为准则 | CODE_OF_CONDUCT.md |
| 安全报告 | SECURITY.md |
| 开发环境搭建 | docs/contributing/development.mdx |
| 文档贡献 | docs/contributing/documentation.mdx |
| PR 模板 | .github/PULL_REQUEST_TEMPLATE.md |
| Issue 表单 | .github/ISSUE_TEMPLATE/ |
| 信任列表(vouch) | .github/VOUCHED.td |
| CI/CD、门控与规则集 | .github/AGENTS.md |
小结
AGENTS.md 的本质是一份“仓库操作系统”说明书:它用 Where-to-look 矩阵消除多语言 monorepo 中“配置漂移”带来的试错成本,用 Do NOT 清单圈出工具链与依赖管理的硬边界,用逐包 AGENTS.md(mem0/AGENTS.md、mem0-ts/AGENTS.md、server/AGENTS.md、tests/AGENTS.md 等)承载各包的命令集、命名约定与 provider 模式,再用 PR Gate + vouch check 双门与不可协商的 CLA 保证贡献队列的质量。对在这个仓库中工作的任何人——包括 AI 编码助手——正确的操作顺序始终是:先读最近邻的 AGENTS.md,选对该包的工具链,改动后跑对应包的 lint 与测试,最后带着 accepted issue 与已签 CLA 提交 PR。
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