LangGraph Monorepo 工程指南:AGENTS.md 协作规范、核心库职责与 make 命令体系深度解析
本文以 LangGraph 仓库根目录的 AGENTS.md 为主线,完整解读这份面向开发者与 AI 编码代理的仓库协作规范:monorepo 目录组织、8 个核心库的职责边界、反向依赖影响图,以及提交 PR 前必须执行的 make format / make lint / make test 工作流。读完后,你可以直接在正确的库目录中定位代码、用 TEST 变量精准运行指定测试文件,并根据依赖图评估一次改动可能波及的下游库。
AGENTS.md 是什么:给“写代码的 Agent”的操作手册
LangGraph 是一个构建有状态、多角色(stateful, multi-actor)应用的框架,仓库本身采用 monorepo 组织——每个库(library)都位于 libs/ 下的一个独立子目录中。AGENTS.md 正是为这一结构编写的操作手册:
- 它规定了修改任何库代码后、创建 Pull Request 前必须执行的验证命令;
- 它给出了仓库内各库的高层职责划分和依赖关系图,用于在做破坏性改动前评估影响面;
- 它包含条件性安全分析指引(Corridor 工具)和文档字符串的格式约定。
仓库根目录同时存在一份内容基本一致的 CLAUDE.md,供 Claude 系编码工具读取;两者差异很小(例如 Corridor 一节中 analyzePlan 工具的触发时机措辞略有不同)。可以把 AGENTS.md 理解为“无论人或 AI 代理,动代码前都应遵守的最小工程契约”。
Monorepo 布局:8 个核心库的职责划分
AGENTS.md 对仓库中的 Python 与 JavaScript/TypeScript 库给出了如下高层概览:
| 库目录 | 职责 |
|---|---|
| libs/checkpoint | LangGraph Checkpointer 的基础接口(状态持久化抽象层) |
| libs/checkpoint-postgres | Checkpoint Saver 的 Postgres 实现 |
| libs/checkpoint-sqlite | Checkpoint Saver 的 SQLite 实现 |
| libs/cli | LangGraph 官方命令行工具 |
| libs/langgraph | 核心框架:构建有状态、多角色 Agent |
| libs/prebuilt | 创建与运行 Agent 和工具的高层 API |
| libs/sdk-js | 与 LangGraph REST API 交互的 JS/TS SDK |
| libs/sdk-py | LangGraph Server API 的 Python SDK |
从各库 pyproject.toml 的实际声明可以进一步印证这种分层关系(以当前仓库版本为准):
- libs/langgraph/pyproject.toml 中
langgraph(当前版本 1.2.11)的生产依赖包含langgraph-checkpoint>=4.1.0,<5.0.0、langgraph-sdk>=0.4.2,<0.5.0、langgraph-prebuilt>=1.1.0,<1.2.0,即核心框架向下依赖 checkpoint 基础库、SDK 和 prebuilt; - libs/checkpoint-postgres/pyproject.toml 中
langgraph-checkpoint-postgres(3.1.2)声明依赖langgraph-checkpoint>=4.1.0,<5.0.0、orjson、psycopg、psycopg-pool,且通过[tool.uv.sources](同文件 L51-L53)将langgraph-checkpoint指向本地相对路径../checkpoint的 editable 安装——这是 monorepo 内跨库联调的典型做法; - libs/prebuilt/pyproject.toml 中
langgraph-prebuilt(1.1.0)生产依赖为langgraph-checkpoint与langchain-core。
此外,libs/ 下还存在 libs/checkpoint-conformance:一套针对 checkpointer 实现的一致性(conformance)测试套件。它不属于 AGENTS.md 列出的核心库清单,但会被 checkpoint 家族库以测试依赖的方式引入(例如 checkpoint-postgres 的 test 依赖组中声明了 langgraph-checkpoint-conformance 并以 editable 方式指向本地 ../checkpoint-conformance),用于保证 Postgres、SQLite 等实现满足同一份接口规范。
依赖关系图:改动前先看谁会受影响
AGENTS.md 的核心资产是一张反向依赖图(dependency map)。该图依据各库 pyproject.toml(或 package.json)中声明的生产依赖整理,列出每个库的下游依赖方——即图中每个分组的根节点是“被依赖的上游库”,其下分支是“直接依赖它的下游库”:
checkpoint
├── checkpoint-postgres
├── checkpoint-sqlite
├── prebuilt
└── langgraph
prebuilt
└── langgraph
sdk-py
├── langgraph
└── cli
sdk-js (standalone)
读图要点与仓库验证:
- checkpoint 是整座仓库的地基。checkpoint-postgres、checkpoint-sqlite、prebuilt、langgraph 四个库都直接依赖它。抽查源码可以印证:checkpoint-postgres 声明
langgraph-checkpoint>=4.1.0,<5.0.0(libs/checkpoint-postgres/pyproject.toml),langgraph 声明langgraph-checkpoint>=4.1.0,<5.0.0(libs/langgraph/pyproject.toml)。因此修改libs/checkpoint的公共接口(如 libs/checkpoint/langgraph/checkpoint/base 中的抽象类)时,必须同时回归四个下游库的测试。 - prebuilt → langgraph 表示 langgraph 核心包在运行时依赖
langgraph-prebuilt(见 libs/langgraph/pyproject.toml 中的langgraph-prebuilt>=1.1.0,<1.2.0)。prebuilt 的公开行为变化会直接传导到核心框架。 - sdk-py → langgraph、cli 表示 Python SDK(
langgraph-sdk)是核心框架与 CLI 的公共依赖;langgraph 一侧已在 libs/langgraph/pyproject.toml 中得到验证。SDK 的 API 变更(如流式传输协议、SSE 解码行为)需要同时关注 CLI 侧。 - sdk-js 是独立的(standalone),不与 Python 侧的库形成生产依赖,JS/TS SDK 的改动影响面相对隔离。
AGENTS.md 对此给出的行动准则很直接:“Changes to a library may impact all of its dependents shown above”——对某个库的修改可能影响图中列出的所有下游依赖方。做接口级变更前,应先沿这张图圈出需要跑测试的目录。
提交 PR 前的标准工作流:make format / make lint / make test
AGENTS.md 规定:修改任意库的代码后,在创建 PR 前要在该库自己的目录中运行以下三条命令:
make format # 运行代码格式化器
make lint # 运行 linter
make test # 执行测试套件
这三个目标在各库 Makefile 中的实际实现高度统一,以 libs/langgraph/Makefile 为例可以看清每一步到底做了什么:
make format 与 make lint 的源码级行为
format目标执行uv run ruff format $(PYTHON_FILES)与uv run ruff check --fix $(PYTHON_FILES),即用 ruff 完成格式化加可自动修复项的修正;lint目标执行uv run ruff check .、uv run ruff format --diff(只检查不落地)、uv run ruff check --select I(import 排序检查)以及uv run ty check langgraph(类型检查);- 通过
PYTHON_FILES变量控制作用域:lint/format作用于整个目录(.),而lint_package/lint_tests可以只检查langgraph或tests子目录;lint_diff则只对git diff中与main分支相比变更过的.py/.ipynb文件生效,适合增量审查。
libs/checkpoint/Makefile 与 libs/prebuilt/Makefile 采用同一套模式(ruff + ty),只是类型检查的目标包名不同。依赖全部通过 uv 管理(各库 pyproject.toml 的 [dependency-groups] 中 lint 组声明了 ruff、ty 等工具),因此命令不需要预装全局工具链。
make test 的内部机制:自动探测 Docker 服务
make test 并不是简单的 pytest .。以核心库为例,libs/langgraph/Makefile 的 test 目标逻辑是:
- 用
command -v docker探测本机是否安装 Docker(NO_DOCKER变量); - 有 Docker 时:先
make start-services启动 Postgres 与 Redis(compose 文件为 libs/langgraph/tests/compose-postgres.yml 与 libs/langgraph/tests/compose-redis.yml),再make start-dev-server以 libs/langgraph/tests/example_app/langgraph.json 为配置启动langgraph dev开发服务器,然后执行uv run pytest $(TEST),结束后自动停掉服务并透传测试退出码; - 无 Docker 时:退化为
NO_DOCKER=true uv run pytest $(TEST),只运行不依赖外部服务的用例。
libs/prebuilt/Makefile 则固定要求先 make start-services 再测试(因为它的测试普遍涉及 Postgres),并额外提供 test-fast 目标(LANGGRAPH_TEST_FAST=1),只用内存版 checkpointer 跑快速测试。而 libs/checkpoint/Makefile 的测试最轻量:uv run pytest $(TEST),无外部服务依赖——这与它作为纯接口/内存实现库的定位一致。
Makefile 还提供了 test_watch(基于 ptw 的 watch 模式)、coverage(pytest --cov)、type(单独跑 ty)、spell_check/spell_fix(codespell)等辅助目标,开发者可以在对应库目录用 make help 查看完整清单。
用 TEST 变量运行指定测试
AGENTS.md 给出的一条高频操作是:通过 TEST 变量运行特定测试文件,或向 pytest 追加参数:
TEST=path/to/test.py make test
对照 Makefile 源码(如 libs/langgraph/Makefile 中的 TEST ?= .),可以明确两点机制:
TEST ?= .表示该变量默认为当前目录(.),即不传参时pytest .跑整个库的测试;TEST的值会被原样拼接进uv run pytest $(TEST)命令行;- 因此
TEST内可以携带任何 pytest 合法参数,例如追加选项、选择器或标记过滤。这也解释了为什么文档强调“Other pytest arguments can also be supplied inside theTESTvariable”。
一个典型场景:修改了 libs/checkpoint-sqlite/langgraph/checkpoint/sqlite 的增量通道逻辑后,在 libs/checkpoint-sqlite 目录运行 TEST=tests/test_get_delta_channel_history.py make test,即可只回归对应的历史取数用例。
根目录 Makefile:对全部库的一键批处理
除了“进入单个库目录操作”,仓库根目录的 Makefile 提供了跨库批处理能力。它用 LIBS_DIRS := $(wildcard libs/*) 枚举 libs/ 下所有子目录,然后逐个进入执行:
all: lint format lock test # 默认目标:全仓库 lint + format + lock + test
make install:创建 uv 虚拟环境后,对每个含pyproject.toml的库执行uv pip install -e <dir>,一次性以 editable 方式安装所有 Python 库(sdk-js 无 pyproject.toml 会被自动跳过);make lint/make format/make test:遍历每个含Makefile的库目录执行对应目标;make lock/make lock-upgrade:在各库内执行uv lock(或--upgrade),维护各库独立的uv.lock。
从源码结构看,这套批处理与 AGENTS.md 的“在该库目录运行命令”并不矛盾:单库命令用于日常开发与 PR 前验证,根目录命令更适合全量回归与依赖锁定检查。
两个容易忽略的附加规范
Corridor 安全分析(条件性要求)
AGENTS.md 用 <corridor> 标签包裹了一段条件性指令:当 Corridor 的 analyzePlan 工具可用时,应在生成或修改代码之前先制定计划并调用该工具做安全分析,再按其给出的安全指引写代码。这是一段典型的“写给工具看”的指令块——没有该工具时自动不生效,人类开发者可忽略。
Docstring 格式约定
文档最后一条规则禁止使用 Sphinx 风格的双反引号(``code``)行内代码写法,要求 docstring 和注释中一律使用单反引号( code )。这条约定保证文档字符串在各种渲染器下的一致性,是在本仓库写注释时需要记住的一个小细节。
开发者自检清单
综合 AGENTS.md 的规范与仓库中 Makefile、pyproject.toml 的实际实现,改动代码后的检查清单可以收敛为:
- 定位改动所在库目录(
libs/<library>),确认其职责边界(见本文库职责表); - 对照依赖图圈出下游依赖方,评估接口变更的影响面;
- 在该库目录依次执行
make format、make lint、make test(注意 langgraph/prebuilt 库的测试会自动拉起 Docker 服务,无 Docker 环境会自动降级或按各库 Makefile 的行为执行); - 需要缩小测试范围时,用
TEST=<path或pytest参数> make test; - 写注释与 docstring 时使用单反引号行内代码,避免 Sphinx 双反引号写法;
- 若工作流中接入了 Corridor 的
analyzePlan工具,先过安全分析再动手改代码。
这套“目录即边界、Makefile 即流程、依赖图即影响面”的约定,本质上把 monorepo 的协作复杂度收敛成了三张表:库职责表、依赖图、Makefile 目标表——无论人类开发者还是自动化编码代理,都可以据此独立、完整地定位并验证自己的改动。
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