首页
/ Docling AGENTS.md 深度解读:为 AI 编程代理构建可执行的仓库协作契约

Docling AGENTS.md 深度解读:为 AI 编程代理构建可执行的仓库协作契约

2026-09-06 12:51:38作者:虞亚竹Luna

本文以仓库根目录的 AGENTS.md 为主体,系统拆解 Docling 项目如何为 AI 编程代理(如 Claude Code、Codex 等)定义一套可直接执行的协作契约:从项目概览与目录结构、双轨 Skills 机制,到与 Makefile 一一对应的关键命令、七条代码规范,再到“变更—测试—收尾校验”的完整工作流。读完本文,你将掌握在 Docling 仓库中安全发起修改的完整方法论——包括如何用 make setup / make check / make validate 对齐 CI 校验,如何用 DOCLING_GEN_TEST_DATA=1 安全重生成参考数据,以及为何 Docling 把一份面向代理的“使用技能”直接打包进 Python wheel 中。

1. AGENTS.md 的定位:单一事实来源的代理指南

AGENTS.md 开篇即声明其用途:“This file provides guidance to AI coding agents when working with code in this repository.”。它不是一份给人读的教程,而是一份写给 AI 代理的仓库操作手册:告诉代理这个项目是什么、代码在哪里、哪些命令可以跑、必须遵守哪些代码规范、以及任务完成前必须通过哪些校验。

值得注意的是,仓库中的 CLAUDE.md 全文仅有一条实质内容——@AGENTS.md 导入指令。也就是说,Claude Code 等支持该导入语法的代理运行时打开 CLAUDE.md 时,会被重定向到 AGENTS.md。这种“薄壳 + 单一事实来源”的组织方式避免了两份指南在长期维护中产生分叉,是代理化仓库工程(agent-native repo engineering)中一种值得借鉴的模式。

2. 项目概览与目录结构

AGENTS.md 给出的官方概览是:Docling 是一个 Python SDK 与 CLI,负责把 PDF、Office 文件、HTML、Markdown、音频、图片、XML 等多种格式统一转换为 DoclingDocument 表示,供下游 AI 工作流消费。

其描述的项目结构如下:

docling/                 # 主 Python 包
docling/.agents/skills/  # 随包分发的“使用技能”(见下文 Skills 一节)
packages/docling/        # 完整 docling 元包
packages/docling-slim/  # slim 包的说明
tests/                   # pytest 测试套件与测试数据
docs/                    # MkDocs 文档与示例
scripts/                 # 项目维护脚本

从源码结构看,docling/ 主包内部按职责分层,且这一分层并非随意而为——仓库根目录的 tach.toml 用 Tach 工具把模块显式划分为六个层级:entrypoints(如 docling.document_converterdocling.document_extractordocling.cli)、clients(如 docling.service_client)、pipelinemodelscorefoundation,并为每个模块声明了允许的 depends_on 白名单。make check 中的 tach check 会把任何跨层依赖越界当作错误拦截。因此 AGENTS.md 中“Keep edits scoped and consistent with the surrounding module”这条规范,实际上有 tach.toml 的自动化约束作为后盾。

此外,pyproject.toml 表明该仓库构建发布的是 docling-slim 包(当前版本 2.124.0,requires-python = '>=3.10,<4.0'),并通过 extras 机制按需加载格式解析器与 OCR 引擎等重依赖;CLI 入口 doclingdocling-tools 分别由 docling.cli.main:appdocling.cli.tools:app 提供。理解了这些背景,再读 AGENTS.md 中“依赖变更用 uv add”“公共 API 必须保持类型标注且兼容 Python 3.10+”等要求就不会觉得突兀。

3. 双轨 Skills 机制:开发技能 vs 使用技能

AGENTS.md 中“Skills”一节区分了两种性质完全不同的技能目录,这是该文件最有特色的部分:

3.1 开发技能(.agents/skills/,仓库根目录)

面向在 Docling 仓库上做开发的贡献者/代理,位于仓库根目录 .agents/skills/,不随包分发。当前包含:

  • dignified-python:一套有主见的生产级 Python 规范技能,自动检测 Python 3.10–3.13 版本差异,覆盖类型注解、LBYL 异常处理、pathlib 优先、CLI 模式等——这与下文“Code standards”中“偏好 pathlib.Path”“避免 hasattr 探测”等条目形成呼应。
  • building-pydantic-ai-agents:Pydantic AI 代理构建技能,覆盖工具、结构化输出、流式、多代理模式与测试。

3.2 使用技能(docling/.agents/skills/docling/,随包分发)

面向使用 Docling 转换文档的下游代理,直接放在包内 docling/.agents/skills/docling/SKILL.md。其 front matter 声明了 MIT 许可、Requires Python 3.10+ 兼容性,以及允许的工具白名单(Bash(docling:*)Bash(uvx:*)Bash(python3:*) 等)。SKILL.md 本体是一个“路由器”:它给出最短可运行的 CLI 命令(docling report.pdf --to md --output /tmp/)和一张“按需选路”表,把 CLI、Python SDK、DocumentExtractor、RAG 分块、Service Client、docling-slim 精简安装六条路径分别指向 references/ 下的按需加载文件(cli.md、python-sdk.md、extraction.md、rag.md、service-client.md、slim-packaging.md),使代理只读取当前任务所需的内容。

AGENTS.md 对维护者提出了明确的同步义务:“Keep them in sync with the CLI, the SDK (PipelineOptions), the Service Client, and the docling-slim extras when user-facing behavior changes.” 也就是说,只要用户可见行为变了,这份随包分发的技能文档就必须跟着改——它和 wheel 一起发布,属于发布物的一部分。下游如何发现它,可参考 docs/usage/agent_skills.md:用 uvx library-skills 扫描项目已安装的依赖并在 .agents/skills/docling(或 Claude Code 的 .claude/skills/docling)建立符号链接,升级 Docling 时技能内容自动更新;不支持 .agents/ 约定的运行时则可用 importlib.util.find_spec('docling') 定位技能目录手动注册。

4. 关键命令:与 Makefile 逐一对应

AGENTS.md 给出的四条关键命令:

make setup          # install CI-style dev environment
make test           # run pytest
make check          # run read-only local checks
make validate       # run mutating hooks on the current changeset

结合 Makefile 的真实实现,可以精确还原每条命令背后做了什么:

  • make setup 等价于 uv sync --frozen --group dev --all-extras --no-group docs --no-group examples:以锁定文件(uv.lock)为基准安装开发环境,装齐全部 extras(覆盖各格式解析器与 OCR 引擎依赖),但排除 docs/examples 依赖组。所谓 “CI-style” 即指与持续集成使用的依赖集合完全一致,避免“本地能跑、CI 挂掉”的依赖漂移。
  • make testuv run pytest -v tests,运行 tests/ 下的完整测试套件。该套件同时包含行为测试(如 tests/test_e2e_conversion.py)与大量 groundtruth 参考数据(tests/data/*/groundtruth/),这正是下一节中“参考数据再生成”规范存在的原因。
  • make check 展开为 check-all,是一串只读校验:ruff format --checkruff check(格式与 lint)、ty check(类型检查)、tach check(模块分层约束,配合 scripts/check_tach_module_coverage.py 确保覆盖率)、scripts/check_max_lines.py(文件行数上限)、dprint check(非 Python 资源格式化)、uv lock --locked(锁文件一致性)。任何一条失败都会在 CI 前暴露。
  • make validate 则与 check 互补:它先用 git diff --name-only --diff-filter=ACMR、暂存区差异与 git ls-files --others 汇总当前变更文件集,再对这批文件执行 uv run prek run --files(prek 是 git hooks 管理器的 uv 发行版,即运行仓库预提交的钩子)。注意 Makefile 注释中刻意区分了两个词:check 是 read-only,validate修改文件(mutating hooks)。AGENTS.md 特意把这两条命令的语义差异写进代理指南,正是为了防止代理在“验证”环节意外改写工作区而不自知。

5. 代码规范:七条规则的源码级依据

AGENTS.md 的“Code standards”一节共七条,每一条都能在仓库中找到对应的工程依据:

  1. 公共 API 保持类型标注,兼容 Python 3.10+。 依据是 pyproject.tomlrequires-python = '>=3.10,<4.0' 与 3.10–3.14 的 classifiers,且 make check 中的 ty check 会对未标注的公共接口亮红灯。
  2. 依赖变更使用 uv add 或项目内的依赖组织方式。 本仓库采用 uv 管理依赖与 uv.lock 锁定文件,check-all 末尾的 uv lock --locked 要求锁文件与声明严格一致;直接手改 pyproject.toml 而不更新锁文件会导致校验失败。
  3. 为行为变更添加聚焦的测试;只有转换输出被有意改变时才重生成参考数据。 tests/ 下按格式(tests/data/pdf/tests/data/docx/tests/data/xlsx/ 等)维护了大量 groundtruth 文件,配套测试如 tests/test_backend_pdfium.pytests/test_backend_msword.py。参考数据的再生成方式见第 6 节。
  4. 结构化模型优先于松散字典。 凡跨模块边界、参与序列化、或代表稳定契约的数据,应使用 Pydantic 模型或 dataclass。从源码结构看,docling/datamodel/ 整个子包(document.pypipeline_options.pybackend_options.pyspatial.py 等)正是这一规范的落地范本——DoclingDocumentPipelineOptions 等核心契约全部是 Pydantic 模型,CLI、SDK、Service Client 共享同一套 schema。
  5. 路径处理优先 pathlib.Path,新代码避免 os.path 这与开发技能 dignified-python 的 “pathlib vs os.path” 主题一致,属于仓库级统一风格。
  6. 避免 hasattr(...) 与宽泛的 getattr(...) 探测。 理由写明:这类模式通常掩盖接口不确定性;确需兼容文档化的第三方 API 时,应窄化作用域并加注释说明。这条规则对代理尤其重要——代理生成的代码最爱用 getattr(x, y, default) 做防御性编程,而该仓库将其视为异味。
  7. 禁止琐碎或自验证的测试。 测试应验证有意义的应用行为、回归或集成边界,而不是复述对成熟库功能的假设、或仅为验证代理自己刚写的代码而存在;能不用 mock 就不要 mock,除非 mock 是验证真实契约或失败模式的最清晰方式。

6. 变更流程:四步工作流与参考数据再生成

AGENTS.md 的“When making changes”给出四步:

  1. 编辑保持限定范围,并与所在模块的既有风格一致(受 tach check 分层约束与 ruff 风格检查双重约束);
  2. 用户可见行为变化时,同步更新文档与示例(docs/docs/examples/,以及第 3 节提到的随包使用技能);
  3. 对触及的行为运行针对性测试(而非每次全量);
  4. 若参考输出变化,使用 DOCLING_GEN_TEST_DATA=1 uv run pytest 重生成,并仔细审查生成的数据。

关于第 4 步,仓库中有完整的实现链条可查:环境变量由 tests/test_data_gen_flag.py 读取(os.getenv("DOCLING_GEN_TEST_DATA", 0),经 Pydantic 的 TypeAdapter(bool) 解析),各格式测试据此决定是“对比 groundtruth”还是“重写 groundtruth”;CONTRIBUTING.md 第 79 行附近也记载了同样的再生成命令。其安全语义是:普通测试运行永远只做断言对比,只有在显式打开该环境变量时才允许覆盖参考数据——这防止了代理或开发者在无意中以“新输出”污染基线。

7. 收尾校验:validate 循环与 read-only 复核

AGENTS.md 最后一节“Before finishing”定义了任务完成的硬标准:

  • 先跑 make validate 如果 hooks 修改了文件,必须复查这些改动并重跑 make validate,直到干净通过为止——这是一个明确的收敛循环而非单次检查。
  • 同时运行受影响文件的测试。 与“变更四步”第 3 条呼应,收尾时不能只过静态检查。
  • 需要纯只读验证时改用 make check 再次强调二者语义差异:check 绝不改写工作区,适合代理在提交前做无损复核。

综合来看,AGENTS.md 为代理设定的完成判据是“静态钩子收敛 + 针对性行为测试通过”的双条件,并且明确告知代理两套校验命令各自的副作用边界(mutating vs read-only),这是该文件与一般模板化 agent 指南相比最务实的地方。

8. 小结

AGENTS.md 虽然篇幅不长,但它把 Docling 仓库的工程约束压缩成了一份代理可直接执行的契约:项目概览锚定上下文,目录结构配合 tach.toml 的分层约束划定修改边界,双轨 Skills 机制区分了“贡献 Docling”与“使用 Docling”两种代理场景,四条 make 命令给出了与 CI 对齐的验证路径,七条代码规范均有 Makefile 检查项或 datamodel 实现作为落点,而“DOCLING_GEN_TEST_DATA=1 再生成 + make validate 收敛循环”则把参考数据维护和钩子副作用这两个最容易出错的环节写成了明确规程。对于希望在大型 Python 仓库中稳定接入 AI 编程代理的团队,这份文件的结构——单一事实来源、命令语义显式区分副作用、规范条目与自动检查一一对应——本身就是可复用的模板。

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