首页
/ Ghost Monorepo 的 AGENTS.md:AI Agent 协作指南的设计与执行约束

Ghost Monorepo 的 AGENTS.md:AI Agent 协作指南的设计与执行约束

2026-09-06 12:02:34作者:胡唯隽

根目录的 AGENTS.md 是 Ghost monorepo 面向 AI Agent 的执行指南,它定义了仓库内必须遵守的工作流(强制使用 pnpm、pnpm setup / pnpm check)、仓库级 Agent 技能(repository skills)的发现与校验机制,以及按子系统路由的任务指引和高价值警告。读完本文,你将理解这份文档如何与仓库脚本、pnpm 工作区配置、技能符号链接体系配合形成一套可被工具链自动验证的 Agent 协作规范,并掌握在多包、多运行时的大型 Node.js monorepo 中约束 Agent 行为的可复用方法。

文档定位:只放路由、约束与警告

AGENTS.md 开篇即声明自身边界:面向 Agent 的执行指引放在这里,而人类可读的环境搭建、工作流程、架构和实践说明放在 docs/README.md 及其引用的各篇文档、以及各包就近的 README 中。文末还给出了自我约束原则:

Keep shared facts in human documentation. This file should contain only routing, agent execution constraints, and high-value warnings that prevent recurring mistakes.

这条原则在仓库里有对应的机器校验:scripts/check-agent-guidance.js 定义了 MAX_AGENT_GUIDANCE_LINES = 150,会扫描 git ls-files 中所有被追踪的 **/AGENTS.md 文件并检查行数上限。也就是说,“Agent 指南必须短小精悍”不只是一句口号,而是被 pnpm lint:agent-guidance(经由根 package.jsonlint:docs 串联)强制执行的质量门禁。

与之形成对照的是就近覆盖原则:文档要求“在修改某个包或子系统之前,先读最近的 AGENTS.mdCLAUDE.md 和 README,更具体的指引覆盖本文件”。仓库中嵌套 AGENTS.md 的典型例子是 apps/shade/AGENTS.md,它先引导阅读 Shade 的人类文档(README.mdsrc/docs/introduction.mdxsrc/docs/contributing.mdx 等),再给出 Shade 专属的必做工作流(用 shade-component-decision 技能做组件决策、只从层级子路径导入而非根 barrel、使用语义 token 而非原始颜色等)。

另外,根目录的 CLAUDE.md 是指向 AGENTS.md 的符号链接(仓库中可见 CLAUDE.md -> AGENTS.md)。从源码结构看,这是一种“单一事实源 + 多入口别名”的做法:不同 Agent 工具(Claude Code 读 CLAUDE.md,其他 Agent 读 AGENTS.md)读到的是同一份内容,避免双份文档漂移。

阅读顺序:Start with 清单

文档给出了一份固定的阅读顺序,全部指向 docs 目录下的实践文档:

这六份文档覆盖了从克隆仓库到提交 PR 的完整生命周期,AGENTS.md 的作用相当于给 Agent 的“目录页”:先读这些,再进入具体任务。

必做工作流:pnpm、setup 与 check

文档“Required workflow”一节列出了五条硬性规则,每条都能在仓库中找到对应的实现证据。

只用 pnpm,外部依赖版本进 catalog

规则原文:永远使用 pnpm,禁止 npm 或 Yarn;外部依赖的版本号放在 pnpm-workspace.yaml 的 catalogs 中,工作区内部依赖使用 workspace: 版本。

仓库中有两层保障。第一层是拦截:根 package.jsonpreinstall 钩子执行 scripts/enforce-package-manager.js。该脚本通过 npm_config_user_agent 判断调用方是否为 pnpm,若不是则进一步检查是否存在 pnpm_config_* 环境变量作为回退信号(脚本注释说明这是为了应对某些 CI 环境下 user agent 未传递到生命周期脚本的问题),两者都不满足时打印一段包含 corepack enable pnpm 及 yarn 到 pnpm 命令替换对照表的提示并以非零码退出。第二层是配置约束:pnpm-workspace.yaml 设置了 catalogMode: strict,意味着依赖版本应当统一走 catalog;工作区包由 ghost/*apps/*e2ekoenig/*packages/**(排除 packages/_template)、configs/*scripts 等 glob 定义。同一个文件还启用了 strictDepBuilds: trueblockExoticSubdeps: true,并用 allowBuilds 白名单按“包@版本”粒度精确控制哪些依赖允许执行安装期构建脚本(如 sharp@0.35.3better-sqlite3@12.11.1 允许,sqlite3ssh2@sentry/cli 明确为 false),配合 minimumReleaseAge: 4320(3 天,与 Renovate 配置对齐)限制过新版本的引入——从源码结构看,这套配置把“锁版本、防供应链、控构建脚本”三道闸门都固化在了工作区配置层,Agent 无需理解细节也不会误操作。

全新检出先跑 pnpm setup

pnpm setup 的定义在根 package.json

pnpm install && git submodule update --init --recursive && git config --local blame.ignoreRevsFile .git-blame-ignore-revs

它做了三件事:安装依赖、初始化 git submodule(Ghost 的仓库结构中包含子模块)、配置 blame.ignoreRevsFile 指向 .git-blame-ignore-revs(用于在 git blame 中忽略批量格式化等提交)。对 Agent 的意义在于:不先跑 setup 就执行其他命令,可能因缺少子模块内容或依赖而得到误导性报错。

pnpm check 作为默认全量校验

check 脚本的展开是:

pnpm format:check && pnpm lint && pnpm test

其中 format:check 使用 oxfmt --checklint 串联 nx run-many -t lint lint:boundarieslint:packages(内部包检查)与 lint:docs(后者又包含 lint:agent-skillslint:agent-guidancelint:markdownlint:doc-links,即 Agent 相关门禁本身也是 pnpm check 的一部分);test 通过 nx 在全部工作区跑 test target,但显式排除了 @tryghost/e2eghost-admin 两个项目——这正对应文档中“Browser E2E 和 Ember Admin 测试单独运行,遵循测试指南(docs/contributing/testing.md)”的说明:浏览器 E2E 需要完整的 Docker 基础设施与浏览器环境,Ember Admin 测试走独立 runner,两者都不适合混在默认校验里。

提交时加载 commit 技能

规则要求“提交时加载并遵循 .agents/skills/commit/SKILL.md”。该技能规定了提交前检查 git status / git diff / git log -5 --oneline、只 stage 与本次改动相关的文件、以 .github/CONTRIBUTING.md#commit-messages 为提交约定的事实源、区分“需要发布的包”(README 会随包发布,需要 release intent)与纯仓库 Markdown(如 AGENTS.mdCLAUDE.md、changelog 不需要)、提交后确认结果,以及两条红线:用户不要求就不 push,hooks 失败就修复后重新提交、绝不绕过 hooks。

Repository Skills:.agents/skills/ 与符号链接校验

仓库技能集中存放在 .agents/skills/ 下,当前包含约 20 个技能目录,覆盖面包括:

  • 高风险操作类:add-admin-api-endpointcreate-database-migrationadd-private-feature-flagtinybirdtinybird-cli-guidelines
  • 包迁移类:migrate-internal-packageconvert-internal-package-to-typescript
  • UI 组件类:shade-component-decisionshade-new-componentshade-importsshade-tokens-not-hexshade-no-dark-variantsshade-shadcn-installshade-page-templatesshade-dropdown-surface-contractshade-input-surface-recipeshade-use-primitives
  • 通用类:commitformat-number

文档规定的新增技能流程是两步:技能实体放在 .agents/skills/<name>/,同时创建指向 ../../.agents/skills/<name>.claude/skills/<name> 符号链接,再运行 pnpm lint:agent-skills 验证可发现性。当前仓库的 .claude/skills/ 目录下 20 个条目全部是指向 ../../.agents/skills/* 的符号链接,与该约定一致。

这个约定的机器校验实现在 scripts/check-agent-skill-links.js:它遍历 .agents/skills/ 的每个子目录,逐一检查 (1) 存在 SKILL.md 且为普通文件;(2) .claude/skills/<name> 存在且是一个符号链接;(3) 链接目标恰为 ../../.agents/skills/<name>。任何一条不满足都会报错并直接打印修复命令(例如 ln -s ../../.agents/skills/<name> .claude/skills/<name>)。从源码结构看,这套“实体目录 + 符号链接 + 脚本校验”的组合,让同一个技能目录同时被 .agents(通用约定)和 .claude(Claude Code 约定)两套发现机制引用,而校验脚本保证两者不会脱节。

文档还明确了必须“先加载对应技能再动手”的四类场景:新增 Admin API 端点(add-admin-api-endpoint,其目录含 SKILL.mdreference.mdvalidation.mdpermissions.md 四个文件)、新增数据库迁移(create-database-migration,含 rules.mdexamples.md)、新增私有 feature flag(add-private-feature-flag)、新增 Shade 组件或内部包(对应 shade 系列与 migrate 系列技能)。

任务路由与高价值警告

文档“Task routing and important warnings”一节按子系统给出了路由规则和防止反复踩坑的警告,每条都指向具体的参考文档:

Admin UI

apps/admin/README.mdapps/shade/AGENTS.md。新特性用 React 构建,API 层使用 admin-x-framework(对应 apps/admin-x-framework 包),UI 层使用 Shade。关键警告:Admin 与 Core 是独立部署的,因此前端必须 feature-detect 后端能力,并专门测试“旧版本后端”的场景——这条针对的是 monorepo 中前后端版本错位这一典型故障源。

嵌入式 Admin CSS 警告

禁止从嵌入式应用(embedded app)导入 @tryghost/shade/styles.css:Admin 独占唯一的 Tailwind 与 Shade CSS 通道(CSS lane)。从源码结构看,这与 apps/shade/AGENTS.md 中“不要在嵌入的 Admin 应用里导入该样式表或再加一层 ShadeApp 包装”是同一约束的两处表述,目的是避免多份 Tailwind/样式运行时共存导致的样式冲突与体积膨胀。

翻译(i18n)

遵循 docs/practices/internationalization.md:修改 t() 调用后必须运行提取命令(仓库的 packages/i18n 提供 i18next-parser 相关配置与 311 个 locale 文件),并且绝不把一句话拆进多个翻译调用——拆分会破坏翻译上下文的完整性。

Public apps(公开应用)

先读对应应用的 README 与 发布指南apps/ 下的 portal、comments-ui、signup-form、sodo-search、announcement-bar、admin-toolbar 等公开应用的发布节奏与 CSS 通道和 Admin 不同,不能套用 Admin 的流程。

Ghost Core

新增服务前先查 monorepo 结构中的 Ghost Core 部分services 指南。约束包括:新的独立服务使用 TypeScript 编写,CommonJS 只保留在既有的 require() 边界;服务初始化由 Boot 统一负责,禁止在首次请求时懒初始化(从源码结构看,这是为避免请求路径上的首次调用开销和初始化顺序不可控问题)。

ESLint 配置

使用 configs/eslint/README.md 中的共享工厂与依赖规则;手写的 ESLint 配置必须在本地声明它导入的每一个插件。仓库内各包(如 apps/shade/eslint.config.jsapps/admin/eslint.config.js)都遵循这一约定,且 configs/eslint-react 提供 React 侧的共享工厂。

Analytics

pnpm dev:analytics 起步(对应根 package.json 中的脚本,通过 DEV_COMPOSE_FILES='-f compose.dev.analytics.yaml' 叠加 compose.dev.analytics.yaml 启动 Tinybird 等依赖),并遵循 ghost/core/core/server/data/tinybird/ 下的就近 README。

对 Agent 工程实践的三点启示

  1. 文档分层,各负其责。 人类文档(docs/、README)承载共享事实,AGENTS.md 只承载路由、约束、警告,并用 150 行上限(scripts/check-agent-guidance.js)防止 Agent 指南膨胀成第二份重复文档。
  2. 约定必须可被脚本验证。 pnpm 强制(preinstall 钩子)、技能符号链接(lint:agent-skills)、catalog 严格模式(catalogMode: strict)、文档链接(lint:doc-links 使用 remark-validate-links --frail)——每一条规则都有对应的自动检查,pnpm check 一次性跑完,Agent 与人遵守的是同一套门禁。
  3. 高风险操作前置技能清单。 数据库迁移、Admin API 端点、feature flag、Shade 组件这类“做错代价高”的操作,通过强制加载 .agents/skills/ 下带规则与验证清单的技能目录来约束流程,而不是依赖 Agent 的临场判断。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388