首页
/ Astro PR 写作规范技能:Changes / Testing / Docs 三段式结构与审阅者友好的 PR 标题

Astro PR 写作规范技能:Changes / Testing / Docs 三段式结构与审阅者友好的 PR 标题

2026-09-05 16:40:43作者:牧宁李

在 Astro monorepo 中向核心仓库提交代码时,一份审阅者(reviewer)能快速理解的 PR 描述与提交流程同等重要。本文基于 Astro 仓库中的仓库级 Agent 技能文档 .agents/skills/astro-pr-writer/SKILL.md,完整拆解该技能定义的 PR 标题规则、三段式正文结构、简洁性标准、Changeset 强制约束与提交前自检清单,并结合仓库中的技能评估配置(evals.jsonvitest.skills.config.ts)说明这套规范如何被自动化验证。读完后你可以为任何 Astro 贡献者 PR 写出符合该仓库惯例、信噪比高的标题与描述正文。

1. 技能定位与触发场景

该技能是一个"仓库级技能"(repository skill),存放在 .agents/skills/astro-pr-writer/ 目录下,以 Markdown 文件加 YAML front matter 的形式定义,其元数据声明了名称(astro-pr-writer)与触发描述:

name: astro-pr-writer
description: Write and update Astro pull requests with reviewer-friendly titles and high-signal bodies. Trigger whenever the user asks to create a PR, open a PR, draft a PR, update PR title/body, or write PR notes/summary/description.

技能文档明确列出了所有应当激活该技能的 PR 写作任务,覆盖"从零起草"与"修订已有 PR"两种场景:

  • 创建/打开一个 pull request;
  • 创建/打开一个 draft pull request;
  • 更新 PR 标题;
  • 更新 PR 正文/描述;
  • 撰写 PR notes / summary。

这类技能文件并非面向最终用户的文档,而是面向 AI Agent 的行为规范:当用户在 Astro 仓库上下文中提出 PR 写作请求时,Agent 按该文档的标题规则、正文模板与自检清单产出内容。仓库中同目录的 evals/evals.json 则为这些规范提供了可执行的验收用例(见第 7 节)。

2. 核心原则:讲清楚"改了什么、怎么改、为什么重要"

文档给出的核心原则(Core Principle)只有一句话:描述变更本身(change)、它的工作原理(how it works)以及它为什么重要(why it matters)

在这条原则下,三段式正文各有严格分工:

  • Changes 解释这个修复/功能做了什么(what the fix/feature does);
  • Testing 列出新增或修改了哪些测试代码(what test code was added or changed);
  • Docs 说明是否需要面向用户的文档变更(whether user-facing docs changes are needed)。

文档还特别强调一条反向约束:不要把 PR 的各小节当作任务日志来写(Do not use PR sections as a task log)。也就是说,正文不是"我今天做了 12 件事"的流水账,而是围绕行为变更组织的信息摘要。

3. PR 标题规则:用自然语言,禁用 conventional commit 前缀

标题必须"面向人、对审阅者友好",具体规则有三条:

  1. 用平实语言描述结果(Describe the outcome in plain language);
  2. 简洁且具体(Keep it concise and specific);
  3. 优先采用审阅队列中一个开发者会自然写出的措辞(Prefer phrasing a person would naturally write in a review queue)。

同时文档明确禁止两类 commit 风格标题:

  • conventional commit 前缀,如 fix:feat:docs:
  • 带 scope 的 commit 式标题,如 fix(cloudflare): ...

这一规则在评估用例中得到了精确验证:evals.json 第 3 条用例给出的输入标题是 fix(examples): sort RSS posts,预期产出是一行纯文本、直接描述"blog RSS 条目按发布日期倒序排列"这一结果的标题,断言明确检查输出不得以 fix:fix(feat:docs: 开头。

4. 正文模板:固定的三段式结构

技能文档给出了正文必须使用的标准模板(原文即如此,可原样复制使用):

## Changes

- <行为变更以及它为什么重要>
- <实现细节及其影响>

## Testing

- <新增/修改的测试及其覆盖点>
- <某条既有断言变更的原因>

## Docs

- <无需更新文档,因为……>

三个小节各有明确的"应包含 / 不应包含"清单,下面逐节展开。

4.1 Changes:聚焦行为、实现方式与影响

该小节聚焦行为(behavior)、实现思路(implementation approach)和影响(impact)。

应包含:

  • 修复后"以前不工作、现在工作"的能力;
  • 修复/功能的工作原理——以审阅者有用的颗粒度说明(reviewer-useful level);
  • 面向用户的可靠性、兼容性或性能方面的行为变化。

不应包含:

  • "added test"、"updated fixture" 之类内容——这些属于 Testing 小节;
  • "added changeset"——这是流程噪音,不是行为变更;
  • 没有行为影响的内部流程说明。

4.2 Testing:只描述测试代码的变化,不报告测试结果

审阅者阅读该小节的目的是了解测试覆盖面的变化,而不是"你跑过测试套件"这一事实。

应包含:

  • 新增的测试文件或测试用例,并简短说明它们覆盖什么;
  • 被更新的既有测试,以及断言为什么改变。

不应包含:

  • "测试通过"之类的陈述——CI 会展示这一点,属于噪音;
  • 你运行了哪些命令;
  • 通过了多少个测试。

4.3 Docs:显式说明文档影响

文档影响必须被明确交代,二选一:

  • 如果不需要文档更新,用一句话说明原因(例如"没有公共 API 或配置变更");
  • 如果需要文档更新,链接对应的 docs PR。

5. 简洁性标准:30 秒读完原则

文档给出了量化目标:默认保持简短,每个小节 1~2 个 bullet 是常态,只有当变更确实复杂时才允许更多。检验标准是"一位扫视 PR 队列的审阅者应在 30 秒内读完典型 patch 的整个正文"。

为了校准"啰嗦"与"恰当"的边界,文档内置了一组对照示例,以一次 Zod 4.4.0 兼容性修复为例:

过于冗长的版本(Too verbose):

  • Moves .optional().prefault({}) outside z.preprocess() for the server config property in both base.ts and relative.ts, matching the integrations fix from #16531. Zod 4.4.0 rejects missing properties wrapped in z.preprocess() before the preprocessor or inner defaults can execute — moving .optional().prefault({}) outside the preprocess call resolves this. Fixes the server property issue reported there by @rururux.
  • Adds invalid_key, invalid_element, and discriminated union options handlers to both Astro and DB error maps for Zod 4.4.0 compatibility. Zod 4.4.0 surfaces record key refinement failures (e.g. env schema variable names) as structured invalid_key issues with nested errors instead of a flat message. The handlers extract the actual refinement message for clear user-facing errors.
  • All changes are backward-compatible with Zod 4.3.x. New error map branches only activate on issue codes that 4.4.0 starts emitting.

更好的版本(Better):

  • Moves .optional().prefault({}) outside z.preprocess() for the server config, matching the integrations fix from #16531. Fixes the issue reported there by @rururux.
  • Adds invalid_key, invalid_element, and discriminated union options handlers to both error maps for Zod 4.4.0 compat.
  • Backward-compatible with Zod 4.3.x.

对比可以看出精简手法:保留"改了什么 + 为什么 + 兼容性结论",删掉 Zod 内部机制的展开解释、重复的文件路径罗列和过程性细节。这与第 2 节"Changes 讲实现方式但控制在 reviewer-useful 颗粒度"的要求一致。

6. Changeset:改包必带的强制配套

技能文档规定:任何修改了 package 的 PR 都必须附带 changeset,仅 examples/* 的变更可以豁免。

写作 PR 正文时的配套要求:

  • 发布前检查 changeset 是否存在;如果 PR 修改了 package 却没有 changeset,先创建再发布,不得在没有 changeset 的情况下提交 PR;
  • 不要在 Changes 小节中写"added changeset"——那是流程噪音。

创建 changeset 的具体操作由配套技能 .agents/skills/changeset/SKILL.md 承接,核心流程是:在仓库根目录运行 pnpm changeset --empty,它会在 .changeset/ 下创建一个随机命名的 .md 文件(含空 front matter),无需自拟文件名,再编辑该文件补充包版本声明与消息。文件格式为:

---
'<package-name>': patch
---

<changeset message>

要点包括:包名必须与对应 package.jsonname 字段完全一致(如 'astro''@astrojs/node');bump 类型只能是 patch / minor / major;一个 changeset 文件可覆盖多个包;针对核心 astro 包的 majorminor bump 会被 CI 拦截,需要维护者审核。changeset 消息本身是公开的 CHANGELOG 条目,要面向 Astro 用户撰写,以现在时动词开头(Adds、Fixes、Refactors、Deprecates 等),patch 级一句话即可,new feature(minor)应给出 API 名称与代码示例,breaking change(major)必须包含迁移指引。

当前仓库中 ​.changeset/ 目录保留了可参考的真实样例,例如 ​.changeset/better-lines-show.md 声明 @astrojs/cloudflare 的 patch bump:"Fixes cold astro dev crashes by adding astro/app/manifest and @astrojs/cloudflare/cache/provider to the optimizeDeps.include list"——这正是"以用户可感知的行为影响开头"的写法。changeset 的仓库级配置见 .changeset/config.json:changelog 由 @changesets/changelog-github 生成(repo 为 withastro/astro),内部依赖默认以 patch 联动更新。根目录 package.json 中的脚本则体现了 changesets 在发布链路中的位置:release 脚本执行 changeset publishversion 脚本执行 changeset version 后同步示例项目版本号。

7. 提交前自检清单

技能文档定义了发布前必须核对的五条 Self-Check:

  1. 标题是审阅者友好风格(不是 commit 风格);
  2. Changes 的 bullet 描述的是行为/实现/影响;
  3. Testing 列出的是新增/修改的测试代码,而不是测试运行结果;
  4. Docs 的决策是显式的;
  5. 凡是修改 package 的 PR,.changeset/ 下都存在 changeset 文件——缺失就先创建再发布。

8. 规范的自动化验证:skills evals 机制

这套 PR 写作规范并不是"写出来就完事"的软文档,仓库为其配备了可执行的验收层:

  • 评估清单存放在 .agents/skills/astro-pr-writer/evals/evals.json,包含 3 条隔离式评估用例。每条用例给定一段"变更上下文"(例如 trailing slash 重定向循环修复、@astrojs/node 新增 gracefulShutdownTimeout 选项、examples 下的 RSS 排序修改),要求模型仅凭上下文产出标题和正文,并用一组断言逐条校验。以第 1 条为例,断言同时验证:标题不带 fix: 前缀且描述"阻止 trailing-slash 重定向循环";正文恰好包含 ## Changes## Testing## Docs 三个二级标题且无多余 H2;Changes 小节不超过两个 bullet、解释路径规范化与重定向循环的影响,但不提及测试文件、命令、通过数或 changeset;Testing 小节点明回归用例却不出现 pnpmpassed18 tests 等运行结果字样;Docs 小节显式说明"公共 API 与配置未变,故无需文档更新"。这些断言与第 4~5 节的规则一一对应。
  • 运行器配置为 vitest.skills.config.ts:以 .agents/evals/**/*.eval.ts 为入口,禁用文件并行、单并发执行。
  • 运行方式由 .agents/evals/README.md 说明:这些是"live-model 测试",与 pnpm test 独立、不接入 CI(每条用例消耗模型 token 且可能非确定性)。根目录 package.json 提供两个脚本——pnpm eval:skills:validate 可在不调用模型的情况下校验全部评估清单,pnpm eval:skills 配合 -t "astro-pr-writer" 过滤运行单个技能。每条用例执行一次"受试模型 + 一次评审模型(judge)"的两段式判定,每次运行都在一个运行后删除的临时工作区中进行,并且 runner 在挂载技能资源时会排除 evals 清单本身,避免预期答案泄露给受试模型。

9. 小结

.agents/skills/astro-pr-writer/SKILL.md 用不到两百行的篇幅定义了一套完整、可验证的 Astro PR 写作契约:标题走自然语言、禁用 conventional commit 前缀;正文固定为 Changes / Testing / Docs 三段并各有"应写 / 不应写"边界;整体以 30 秒可读为简洁性目标;改包必附 changeset 且不得把"加了 changeset"写进正文;发布前过五问自检。配合 evals/evals.json 的断言式评估与仓库内真实的 .changeset/ 样例,这套规范既约束人的写作习惯,也能直接约束 Agent 的输出质量,是观察大型 monorepo 如何将"PR 描述规范"工程化、可测试化的一个具体样本。

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

项目优选

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