深入解读 Storybook 仓库的 update-pr-description Agent Skill:让 PR 标题与描述始终与真实改动一致
本篇技术文章基于 Storybook 开源仓库中的 .agents/skills/update-pr-description/SKILL.md,完整讲解这个"PR 描述一致性更新"Agent Skill 的触发条件、六步工作流、证据收集命令、分歧判定标准,以及它与 Storybook PR 模板(.github/PULL_REQUEST_TEMPLATE.md)、pr、open-pr 等配套 Skill 的协作关系。读完后,你将掌握一套可复制的"PR 元信息与 diff 对账"方法论,并理解 AI Agent 在 GitHub 工作流中如何安全、迭代地修改 PR 标题和描述。
什么是 update-pr-description Skill
update-pr-description 是 Storybook 仓库为编码 Agent(Claude Code / Codex 等)定义的一个 Agent Skill,文件位于 .agents/skills/update-pr-description/SKILL.md。它解决的问题非常具体:PR 的标题和描述往往是提交时写下的"当时快照",随着迭代推进,分支上的实际改动会与文字描述逐渐脱节——scope 写错了、漏掉了重大改动、声称的修复范围已经过时。这个 Skill 就是让 Agent 负责"对账":把 PR 标题/描述与真实实现逐条比对,发现有意义的分歧后,逐条征求用户同意再修改。
Skill 文件使用标准的 YAML frontmatter 声明元信息:
---
name: update-pr-description
description: Evaluate a PR's title and description against its actual implementation, then iteratively suggest and apply updates. Use when the user asks to check, fix, or update a PR title or description.
---
其中 description 既是功能说明,也是触发条件——当用户要求"检查、修正或更新 PR 标题/描述"时,Agent 应加载并执行这个 Skill。整个 .agents/skills/ 目录下还有十余个同类 Skill(如 pr、open-pr、canary、github-qa-labels、minor-release 等),它们共同构成了 Storybook 仓库面向 Agent 的研发协作规范层;update-pr-description 是其中专门负责"PR 元信息质量"的一环。
完整工作流:六步流程逐条拆解
Skill 定义了一个清晰的六步工作流。下面逐步说明每一步的目标、命令与约束。
第 1 步:解析目标 PR(Resolve the PR)
优先使用用户提供的 PR 编号或 URL;如果用户没有提供,则用 gh pr view 查找当前分支对应的 PR:
gh pr view
这一步的价值在于:多数情况下开发者正处在 PR 对应的分支上,Agent 可以直接定位目标,无需用户再报一次编号。
第 2 步:收集三类证据(Gather evidence)
判定"描述是否失实"必须依赖客观证据,Skill 明确指定了三条命令:
| 命令 | 获取的证据 |
|---|---|
gh pr view <pr> --json title,body |
PR 当前标题与完整描述(即"声称内容") |
gh pr view <pr> --json commits |
全部 commit messages(改动意图的中间记录) |
gh pr diff <pr> |
相对 base 分支的完整 diff(真实实现) |
这三者构成一个递进的证据链:commit messages 描述"作者当时想做什么",diff 则回答"代码实际做了什么"。当两者与 PR 描述出现矛盾时,以 diff 为准。
第 3 步:评估分歧(Evaluate divergence)
这是整个 Skill 的核心判断环节。将"声称的标题/描述"与"commits 和 diff 实际做的事"逐条比对,但只标记有意义的分歧(meaningful divergence),Skill 给出的判据包括四类:
- wrong scope:声明的改动范围与 diff 不符(例如描述说只改了 A 模块,diff 里却动了 B、C 模块);
- missing major changes:描述漏掉了重大改动;
- stale claims:曾经正确但已过时的陈述(例如"此 PR 依赖另一分支"但该依赖已被 rebase 掉);
- inaccurate summary:总体总结与实际行为不符。
同时 Skill 明确要求忽略措辞层面的琐碎差异(trivial wording)。这一条非常关键:它防止 Agent 沦为"文字润色器",把精力耗在与技术事实无关的措辞打磨上。
第 4 步:报告(Report)
把比对结果告诉用户:标题和/或描述是否存在有意义的分歧。Skill 特别规定——如果没有分歧,到此为止(If not, stop here)。这与后文 Notes 中"不要重写一份本来就准确的描述"形成呼应:本 Skill 是"纠错"工具,不是"润色"工具,零改动也是正常的、甚至常见的结果。
第 5 步:迭代式建议(Suggest iteratively)
确认存在分歧后,Agent 不能直接动手,而是进入逐条协商模式:
- 提出具体的更新后标题/描述(Propose concrete updated title/description);
- **一次只问一个变更(Ask the user one change at a time)**是否应用;
- 接受用户的编辑意见(accept edits),继续打磨(refine)。
这种"一次一个变更"的交互约束,保证了用户在 Agent 批量改动描述前,对每一处修改都有明确的知情权与否决权——这是把破坏性操作(改写 PR 公共信息)转化为可审计、可回退过程的关键设计。
第 6 步:应用更新(Apply)
双方达成一致后,Agent 代表用户执行:
gh pr edit <pr> --title "..." --body "..."
gh pr edit 是 GitHub CLI 原生命令,支持只更新标题、只更新正文或同时更新,Agent 在此处一次性把协商好的最终版本写入 PR。
与 Storybook PR 模板的强约束:Notes 四条例
Skill 的 Notes 部分是它的"合规细则",每一条都与 Storybook 仓库的 PR 基础设施直接对应,值得结合 PR 模板 逐条展开。
1. 匹配仓库现有的 PR 模板/风格
Match the repository's existing PR template/style if the body uses one.
Storybook 的 PR 正文并非自由文本,而是基于 .github/PULL_REQUEST_TEMPLATE.md 生成的结构化文档,包含以下固定骨架:
Closes #—— 关联 issue(多 issue 时用closes #1000, closes #1001拆分书写);## What I did—— 一句话说明 PR 做了什么;## Checklist for Contributors—— 贡献者自查清单,细分 Testing(自动化测试覆盖类型:stories / unit / integration / end-to-end 复选框 + 强制的 Manual testing 小节,写明给另一位维护者可复制粘贴的验证步骤)和 Documentation(文档是否更新、若涉及废弃/移除功能是否同步MIGRATION.md);## Checklist for Maintainers—— 维护者清单(CI label、QA 声明、类型 label 单选);### 🦋 Canary release—— canary 发布区段。
Agent 更新描述时必须尊重这套结构,不能把它"压平"成一段话。
2. 不要重写已经准确的描述
Don't rewrite a description that's already accurate.
这是对"过度主动"的明确禁止。结合第 4 步的"无分歧即停止",Skill 整体立场是:准确性是目标,风格改写不是。
3. 适时更新复选框状态
Update the state of checkboxes where appropriate.
模板中大量使用 - [ ] 复选框(如四类自动化测试覆盖、文档更新项)。当 diff 证据表明某些项实际已勾选成立(例如 PR 确实新增了 unit test),Agent 应把 - [ ] 更新为 - [x],使清单真实反映改动状态——这正是"描述与实现对账"在模板粒度上的落地。
4. 填写小节时移除占位符/提示,但绝不删除 canary release 区段
Remove section placeholders/reminders when filling out a section. Do not remove the canary release section.
这里对应模板里两类不同的"注释":
- HTML 注释形式的引导语(如
<!-- Briefly describe what your PR does -->、Manual testing 小节下那段给写作者的示例提示)——这些是给人类填写者看的占位说明,Agent 在真正填好对应内容后应当移除; <!-- CANARY_RELEASE_SECTION -->标记——这是机器识别的锚点,不是给人类看的。模板中 canary 区段前后各有一对<!-- CANARY_RELEASE_SECTION -->注释,仓库内的自动化流程(canary 发布相关的 workflow 与评论机器人)依赖这对标记来定位和更新区段内容。误删它们会直接破坏发布流水线对 PR 正文的解析,因此 Skill 单独立条禁止删除。
这一条是典型的"面向 Agent 的防御性规范":它把仓库自动化流程的隐含依赖(HTML 注释锚点)显式写进 Skill,防止 Agent 以"清理无用注释"为由误伤。
生态位:update-pr-description 与 pr / open-pr Skill 的分工
从 .agents/skills 目录 的整体结构看,Storybook 把 PR 生命周期拆成了若干职责单一的 Skill,update-pr-description 处在"PR 创建之后"的质量维护位置:
prSkill(.agents/skills/pr/SKILL.md):定义 PR 的创建规范——标题格式[Area]: [Description](Area 首字母大写、无空格、可用连字符,示例如CSFFactories: Fix type export)、三类必选 label(类型 label 九选一:bug/maintenance/dependencies/build/cleanup/documentation/feature request/BREAKING CHANGE/other;CI label 四选一:ci:normal/ci:merged/ci:daily/ci:docs;QA label 二选一:qa:needed/qa:skip),以及"正文必须逐字复制模板、保留全部 HTML 注释"的硬性要求。它同时规定 PR 一律以 draft 模式创建。open-prSkill(.agents/skills/open-pr/SKILL.md):把上述规范变成可执行流程——先git fetch origin并运行bash .agents/skills/open-pr/scripts/detect-base-branch.sh检测 base 分支(支持叠层 PR,按 tracked upstream → reflog → 最近 origin 祖先的顺序判定,平局时 feature 分支优先于主干、next优先于main),再用gh pr create --draft ...建 PR,最后询问是否需要触发 canary。update-pr-descriptionSkill:在 PR 存活期内持续对账。当分支经历 rebase、追加 commit、scope 变化后,由它保证标题(例如[Area]: ...的 Area 是否仍正确)、描述(What I did、Testing/Documentation 复选框、Manual testing 步骤)与最终 diff 保持一致。
三者的关系可以概括为:pr/open-pr 保证"生而正确",update-pr-description 保证"始终正确"。而且由于 update-pr-description 的评估基准之一就是 pr Skill 定义的标题格式与模板结构,三者共享同一套规范来源(PR 模板 + label 体系),不会出现各改各的。
工程视角小结:这个 Skill 体现的 Agent 协作设计原则
从这份约 30 行的 Skill 文档中,可以提炼出几条可迁移到任何仓库的 Agent 工作流设计经验:
- 证据先行:任何判断都绑定到具体命令输出(
gh pr view --json、gh pr diff),而不是依赖 Agent 对分支的"印象"; - 判定边界显式化:用"只标记 meaningful divergence,忽略 trivial wording"把模糊的"描述好不好"问题收敛为四类可枚举的失实模式;
- 破坏性操作渐进化:报告 → 逐条建议 → 用户逐条确认 → 才执行
gh pr edit,把对公共信息的写操作降为可审计、可拒绝的小步骤; - 与仓库自动化基础设施对齐:明确保护
<!-- CANARY_RELEASE_SECTION -->这类机器锚点,说明 Agent 规范必须与 CI/发布流水线的解析约定同步维护; - 克制即质量:两次强调"准确的描述不要重写",避免 Agent 的主动性变成 PR 历史的噪声来源。
对读者而言,即使不复用 Storybook 的具体命令,这套"证据收集 → 有意义分歧判定 → 迭代协商 → 受控应用"的模式,也完全可以照搬到你自己仓库的 PR 治理流程中;若你的项目同样采用结构化 PR 模板和 CI/QA label 体系,这份 Skill 更是可以直接参考的实现范本。
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 StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
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