首页
/ Mem0 多语言 Monorepo 协作工程指南:AGENTS.md 体系、逐包工具链与贡献双门机制

Mem0 多语言 Monorepo 协作工程指南:AGENTS.md 体系、逐包工具链与贡献双门机制

2026-09-03 15:22:36作者:胡唯隽

本文以 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 module import 语法;
  • 不要搞混 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.tomldependencies 仅包含 qdrant-clientpydanticopenaihttpxposthogpytzsqlalchemyprotobuf 八个包,而向量库、LLM 等全部依赖都位于 vector-storesllmsextras[project.optional-dependencies] 组中;ruff 行宽 120 的配置则写在 pyproject.toml[tool.ruff] 段(line-length = 120),isort 采用 profile = "black" 且 first-party 为 mem0mem0_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 中描述为 MemoryConfiggraph 配置段,作为向量记忆之上的可选关系感知检索层);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

结合仓库实际文件可以对这套要求做三点补充:

  1. hatch 环境矩阵pyproject.toml 中定义了 dev_py_3_10dev_py_3_11dev_py_3_12 三个 hatch 环境,各自激活 testvector-storesllmsextras 四个 feature 组;Makefile 提供 make test-py-3.10 / 3.11 / 3.12 来固定 Python 版本跑测试,make install_all 则一次性装齐大部分可选依赖。hatch 内的脚本别名 formatlinttest 也定义在 pyproject.toml[tool.hatch.envs.default.scripts] 中。
  2. pre-commit.pre-commit-config.yaml 在提交时运行 ruff 与 isort,对应根文档“不要跳过 pre-commit hooks”的红线。
  3. TypeScript 侧。进入任意 TS 包(mem0-ts/cli/node/integrations/*/)执行 pnpm installmem0-ts/ 的完整命令集(pnpm run build 走 tsup 双输出 CJS+ESM、pnpm run test 走 jest、pnpm run typechecktsc --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.tomlpackage.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(托管平台异步),统一方法面包括 addsearchgetget_allupdatedeletedelete_allhistory——文档同时强调:改动任一签名必须在同一 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。公开导出为 MemoryClientimport { MemoryClient } from 'mem0ai')、Memory 与各 provider(import { Memory } from 'mem0ai/oss'),方法面镜像 Python SDK(addsearchgetgetAllupdatedeletedeleteAllhistory)。发布流程:先 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):

  1. 先开 issue 并等待维护者打上 accepted 标签。每个 PR 必须用 Closes #<number> 链接它;未链接 accepted issue 的 PR 会被 PR Gate 自动关闭,有重开路径。纯文档类变更豁免。
  2. Fork 后从 main 拉分支(feature/...fix/...)。
  3. 做出改动:代码、测试、文档、示例。
  4. 对你触碰的每一个包运行 lint 与测试。
  5. 用 Conventional Commits 提交。
  6. main 开 PR 并填写 PR 模板——不要改写模板内容,GitHub 会预填。
  7. 签署 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.mdmem0/AGENTS.mdmem0-ts/AGENTS.mdserver/AGENTS.mdtests/AGENTS.md 等)承载各包的命令集、命名约定与 provider 模式,再用 PR Gate + vouch check 双门与不可协商的 CLA 保证贡献队列的质量。对在这个仓库中工作的任何人——包括 AI 编码助手——正确的操作顺序始终是:先读最近邻的 AGENTS.md,选对该包的工具链,改动后跑对应包的 lint 与测试,最后带着 accepted issue 与已签 CLA 提交 PR。

登录后查看全文
热门项目推荐
相关项目推荐