首页
/ LangGraph 单仓开发指南:基于 CLAUDE.md 的库职责划分、依赖图谱与 format/lint/test 标准工作流

LangGraph 单仓开发指南:基于 CLAUDE.md 的库职责划分、依赖图谱与 format/lint/test 标准工作流

2026-09-05 18:27:52作者:庞队千Virginia

本文以 LangGraph 仓库根目录的 CLAUDE.md 为核心,系统讲解该 monorepo 的库划分、库间依赖图谱,以及提交 PR 前必须执行的 make format / make lint / make test 标准流程。读完后你可以独立定位任一子库的代码位置,理解一次修改会影响哪些下游库,并掌握通过 TEST 变量运行指定测试文件、附带 pytest 参数的实操方法。

一、单仓结构:libs/ 下的多库组织

CLAUDE.md 开篇即给出本仓库最重要的约定:

This repository is a monorepo. Each library lives in a subdirectory under libs/.

即:整个仓库是一个单仓(monorepo),每个可独立发布的库都放在 libs/ 的一个子目录中。仓库顶层的 Makefile 正是围绕这一结构编写的——它用 LIBS_DIRS := $(wildcard libs/*) 枚举所有子库目录,然后把 lint、format、lock、test 等动作逐个委派给各库自己的 Makefile:

# 根目录 Makefile 的核心逻辑(节选)
LIBS_DIRS := $(wildcard libs/*)

.PHONY: all
all: lint format lock test

.PHONY: install
install:
	@uv venv
	@for dir in $(LIBS_DIRS); do \
		if [ -f $$dir/pyproject.toml ]; then \
			echo "Installing dependencies for $$dir"; \
			uv pip install -e $$dir; \
		fi; \
	done

也就是说,在仓库根目录执行 make install 会为整个 monorepo 创建一个虚拟环境,并将所有带 pyproject.toml 的子库以 editable(可编辑)模式安装进去;make all 则等价于对所有子库依次执行 lint → format → lock → test 四件套。各子库再通过 [tool.uv.sources] 将同仓内的依赖指向本地路径(editable 安装),实现跨库联调。例如 libs/langgraph/pyproject.toml 中:

[tool.uv.sources]
langgraph-prebuilt = { path = "../prebuilt", editable = true }
langgraph-checkpoint = { path = "../checkpoint", editable = true }
langgraph-checkpoint-sqlite = { path = "../checkpoint-sqlite", editable = true }
langgraph-checkpoint-postgres = { path = "../checkpoint-postgres", editable = true }
langgraph-sdk = { path = "../sdk-py", editable = true }
langgraph-cli = { path = "../cli", editable = true }

二、八个子库的职责划分

CLAUDE.mdlibs/ 下的库给出了官方概览,结合各库 pyproject.toml 中的实际声明(当前仓库快照),可以整理为如下对照表:

库目录 发布包名 当前版本 职责(CLAUDE.md 原文 + 包描述)
libs/checkpoint langgraph-checkpoint 4.2.0 检查点保存器(checkpointer)的基础接口
libs/checkpoint-postgres langgraph-checkpoint-postgres 3.1.2 检查点保存器的 Postgres 实现
libs/checkpoint-sqlite langgraph-checkpoint-sqlite 3.1.1 检查点保存器的 SQLite 实现
libs/cli langgraph-cli LangGraph 官方命令行工具
libs/langgraph langgraph 1.2.11 构建有状态、多参与者(multi-actor)应用的核心框架
libs/prebuilt langgraph-prebuilt 1.1.0 创建与运行 agent、tool 的高层 API
libs/sdk-js —(仅含 README 指引) 与 LangGraph REST API 交互的 JS/TS SDK
libs/sdk-py langgraph-sdk 面向 LangGraph Server API 的 Python SDK

两点值得注意:

  • 所有 Python 库都要求 requires-python = ">=3.10"(见各 pyproject.toml 声明),本地开发环境的 Python 版本需满足该前提。
  • libs/sdk-js/README.md 的内容看,该目录当前已转为指向 langgraphjs 仓库的指引页,在 monorepo 内是相对“独立”的存在,与其余 Python 库没有源码级依赖。

三、依赖图谱:一次修改会波及哪些下游

CLAUDE.md 给出了“每个生产依赖 → 下游库”的依赖图(原文为 ASCII 树形图):

checkpoint
├── checkpoint-postgres
├── checkpoint-sqlite
├── prebuilt
└── langgraph

prebuilt
└── langgraph

sdk-py
├── langgraph
└── cli

sdk-js (standalone)

这份图谱可以直接在各库的 pyproject.toml 中逐条得到印证:

  • langgraph-checkpoint-postgres 声明 langgraph-checkpoint>=4.1.0,<5.0.0libs/checkpoint-postgres/pyproject.toml);langgraph-checkpoint-sqlite 同样声明了对 langgraph-checkpoint 的同版本约束(libs/checkpoint-sqlite/pyproject.toml)。
  • langgraph 声明了 langgraph-checkpoint>=4.1.0,<5.0.0langgraph-prebuilt>=1.1.0,<1.2.0langgraph-sdk>=0.4.2,<0.5.0libs/langgraph/pyproject.toml),因此 checkpoint 的接口变更会传导到 langgraph 核心。
  • langgraph-prebuilt 声明依赖 langgraphlanggraph-checkpointlibs/prebuilt/pyproject.toml),对应图谱中 prebuilt → langgraph 一条边。
  • langgraph-sdk 声明依赖 langgraphlibs/sdk-py/pyproject.toml);而 libs/cli/pyproject.toml 在其 inmem 可选依赖组中引用 langgraph-sdk>=0.1.0,对应图谱中 sdk-py → cli 一条边(该边由 cli 的可选依赖组声明,从源码结构看属于较弱的运行时关联)。

CLAUDE.md 对该图的结论值得记牢:“Changes to a library may impact all of its dependents shown above.”——修改任一库都可能影响图中列出的全部下游库。因此动手前先查这张图,改动底层 checkpoint 接口时尤需检查 checkpoint-postgrescheckpoint-sqliteprebuiltlanggraph 四个方向。

四、PR 前标准流程:make format / make lint / make test

CLAUDE.md 规定:在任一库中修改代码后,提交 PR 前必须在该库自己的目录下依次执行三条命令:

命令 作用(CLAUDE.md 原文) 在 Python 库中的实际实现
make format run code formatters uv run ruff format + uv run ruff check --fix
make lint run the linter uv run ruff check .,并按文件范围补充 ruff format --diffruff check --select Ity check 类型检查
make test execute the test suite 通过 uv run pytest 执行测试套件(各库有差异,见下文)

libs/checkpoint/Makefile 为例,可以看清 formatlint 的具体动作和参数化方式:

# 默认作用于整个库目录
lint format: PYTHON_FILES=.
# 也可只检查相对 main 分支有变更的 .py / .ipynb 文件
lint_diff format_diff: PYTHON_FILES=$(shell git diff --name-only --relative --diff-filter=d main . | grep -E '\.py$$|\.ipynb$$')

lint lint_diff lint_package lint_tests:
	uv run ruff check .
	[ "$(PYTHON_FILES)" = "" ] || uv run ruff format $(PYTHON_FILES) --diff
	[ "$(PYTHON_FILES)" = "" ] || uv run ruff check --select I $(PYTHON_FILES)
	[ "$(PYTHON_FILES)" = "" ] || uv run ty check $(PYTHON_FILES)

format format_diff:
	uv run ruff format $(PYTHON_FILES)
	uv run ruff check --fix $(PYTHON_FILES)

各库的 lint 配置基本一致(ruff 规则集为 EFUPBIPLC0415RUF100,类型检查器为 ty),例如 libs/langgraph/pyproject.toml 中的 [tool.ruff] 段还额外禁用了 typing.TypedDict(要求使用 typing_extensions.TypedDict),并启用了针对 .ipynb 的检查。

make test 在不同库中的实际行为

make test 的语义虽统一,但各库 Makefile 的实现有差异:

  • libs/checkpoint:最简单的形式,uv run pytest $(TEST),其中 TEST 默认值为 .libs/checkpoint/Makefile)。
  • libs/cliTEST 默认值为 "tests/unit_tests",另有独立的 test-integration 目标跑 tests/integration_testslibs/cli/Makefile)。
  • libs/langgraph:最完整的形式,test 目标会自动检测系统是否存在 docker:有则先拉起 Postgres/Redis 容器(tests/compose-postgres.ymltests/compose-redis.yml)和本地 dev server(langgraph dev),再执行 uv run pytest $(TEST),结束后自动停掉服务;无 docker 则以 NO_DOCKER=true 直接跑 pytest(libs/langgraph/Makefile)。此外还提供 test_parallel(pytest-xdist 多进程 + worksteal 调度)、test_watch(pytest-watcher 热重载模式)以及跨四个 checkpoint 相关库并行监视的 test_watch_all

五、TEST 变量:运行指定测试文件与透传 pytest 参数

CLAUDE.md 明确说明可以通过 TEST 变量运行特定测试文件,或追加任意 pytest 参数:

TEST=path/to/test.py make test

Other pytest arguments can also be supplied inside the TEST variable.

结合各库 Makefile 中 uv run pytest $(TEST) 的展开方式,TEST 本质上就是拼在 pytest 后面的完整参数串,因此:

  • 运行单个测试文件:TEST=tests/test_state.py make test
  • 叠加 pytest 参数同样可行,例如 TEST="tests/test_pregel.py -k test_names -x -vv" make test-k 过滤用例名、-x 失败即停、-vv 提高输出详细度);
  • 注意 libs/cli/MakefileTEST 默认带引号(TEST?= "tests/unit_tests"),在不覆盖它时等价于只跑单测目录。

六、仓库级补充工具与约定

除了 CLAUDE.md 的三条主命令外,从仓库配置中还能确认几条对 AI 与人类协作者同样重要的约定:

  1. 统一使用 uv 管理环境与依赖。根 Makefilelock / lock-upgrade 目标会遍历所有子库执行 uv lock(或 uv lock --upgrade),保证各库锁文件与声明一致;libs/langgraph/Makefileinstall 目标使用 uv sync --frozen --all-extras --all-packages --group dev
  2. pytest 全局行为由各库 pyproject.toml 固化,例如 libs/checkpoint/pyproject.tomladdopts = "--strict-markers --strict-config --durations=5 -vv"asyncio_mode = "auto",这意味着 pytest -m 之外的未知标记会直接报错,异步测试无需 @pytest.mark.asyncio 装饰。
  3. docstring 与注释中的行内代码格式约定:CLAUDE.md 结尾明确要求不要使用 Sphinx 风格的双反引号(``code``),一律使用单反引号(`code`)。
  4. 计划级安全分析:CLAUDE.md 中的 <corridor> 区块要求——在生成或修改代码之前,先制定计划并(在 Corridor 的 analyzePlan 工具可用时)调用该工具分析该计划,再依据其给出的安全指导落码。这相当于把“先评审计划、后写代码”固化为了仓库级的协作规范。
  5. 可选的拼写与基准检查libs/langgraph/Makefile 还提供 spell_check(codespell)、coverage(pytest-cov 生成覆盖率报告)、benchmark / profilepython -m bench 与 py-spy 火焰图)等目标,供需要时按需使用。

七、提交前自检清单

把 CLAUDE.md 的约定收敛为可执行的清单:

  1. 确认修改落在哪个库目录(libs/<name>),并对照第三节依赖图谱检查受影响的下游库;
  2. 该库目录下依次执行 make formatmake lintmake test,全部通过后再发起 PR;
  3. 只需回归部分用例时使用 TEST=path/to/test.py make test,或把 pytest 参数一并写进 TEST 变量;
  4. 若改动了 checkpoint 等基础接口,建议顺带执行依赖方(如 libs/checkpoint-postgreslibs/checkpoint-sqlite)的测试以覆盖传导影响;
  5. 新增 docstring/注释时检查行内代码是否使用了单反引号而非 Sphinx 双反引号;
  6. 在生成/修改代码前,按 <corridor> 区块的要求完成计划分析与安全指导的应用。

以上流程与仓库根目录、各子库的 Makefilelibs/langgraph/Makefilelibs/checkpoint/Makefilelibs/cli/Makefile 及各 pyproject.toml 的当前实现一一对应,可直接在当前仓库中复制验证。

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