用 Agentic Workflows 将代码变更自动转换为审核过的文档 PR。是对程序员直接有效的工作流优化,大幅提升文档维护效率。
这是任何产品团队都不愿意回答的一个问题。坦诚的回答通常是某种"还没完成"的变体。某位编写者正盯着一个关闭的 pull request,试图反向工程出究竟改了什么。该 pull request 的作者已经移至下一个任务。到文档真正发布时,功能往往已经发货,有时还不止一次。
这曾经是我们 Aspire 团队的日常(我们是一个 10 人的小团队,为分布式应用构建开发者工具)。几个月前,我们试图想清楚如何在已经信任的自动化流程中安全地引入 AI。那时我们发现了 GitHub Agentic Workflows。我开始在 microsoft/aspire 中尝试各种原型。
以下是数字说话的成果,直接从 GitHub 中拉出来:对于 Aspire 13.3 和 13.4,82 个功能文档 pull request 在产品 pull request 合并后中位数 44.8 小时内合并,每一个都由发货功能的工程师审查。没有增加人力。没有流程重新培训。只是改变了"谁来写这个"的问法。
我们的产品代码位于 microsoft/aspire,文档站位于 microsoft/aspire.dev——不同的仓库、部署目标和审查链。大多数团队相当快地搞定了同仓库自动化;跨仓库自动化才是真正的挑战。宽泛的仓库级令牌早该进博物馆了,任何负责任的安全态势(包括我们的)都会相应地限制这类令牌。这是好事。但如果编写文档的地方和编写代码的地方不同,这也会成为真正的瓶颈。
多年来的默认工作流是这样的:
工程师在 microsoft/aspire 中发货功能。
文档编写者几周后才注意到。
文档编写者打开 pull request,读取 diff,然后 ping 工程师澄清改了什么。
工程师已经在下一个功能上,模糊地记得一些,用半不全的信息回复。
文档草稿发货,有时对着已经发布的版本。
这就是反向工程税。我们需要的自动化必须跨越仓库,但不能给 agent 一个到处写的令牌。GitHub Agentic Workflows 证明是答案。
GitHub Agentic Workflows 是 GitHub Next 团队的一个项目。我一直用这样的方式向别人描述它:"GitHub Actions,但工作项处理器是一个模型,并配有通过安全审查的护栏"。这是简化描述,但接近事实。
你以单个 markdown 文件(.github/workflows/my-thing.md)形式编写工作流。YAML 风格的前置元数据在上面,下面是英文自然语言提示。
你运行 GitHub Agentic Workflows compile,它生成一个相邻的 .lock.yml(一个普通的 GitHub Actions 工作流),你随之提交。
运行时,工作流用受限工具集对你的提示运行一个 agent。
至关重要的是,agent 不直接向 GitHub 写入。它发出意图(一个 JSON blob,描述它想创建的 pull request、issue 和注释),然后一个独立的、范围狭窄的 job(安全输出处理器)根据每个工作流的 GitHub app 将这个意图物化。
最后这一点是关键解锁。agent 获得读权限和一个提示。写入通过一个小的、可验证的、有明确允许列表的流程。安全审查点头同意。我们发货。
我喜欢用来构建的工具本身就是用你用来构建的相同工具构建的这种情况。GitHub Agentic Workflows 文档用 Astro 和 Starlight 构建。aspire.dev 也是——Astro 配 Starlight,通过更广的 Starlight 插件生态点缀(astro-mermaid、starlight-llms-txt、starlight-sidebar-topics、starlight-image-zoom、华丽的 @catppuccin/starlight 主题等。特别感谢 Chris Swithinbank 和 Starlight 维护者,整个生态感觉是由真正关心的人设计的)。
这里面有真实的亲缘感。我们用来自动化文档的工具和我们自动化输入的文档站共享同一基础。这很方便,因为下一节中的 Mermaid 序列图在两个世界中呈现方式完全相同。
这是我们落地的流程。主人公是一个叫 pr-docs-check.md 的工作流,位于 microsoft/aspire 中。
运行在 pull_request: closed 触发,针对 main 或 release/*,并由 merged == true 守门。从这里,工作流首先用纯 bash 运行一个确定性的目标分支解析器,然后才唤醒 agent:
Pull request 里程碑标题(例如 13.4 → aspire.dev 上的 release/13.4)。
关联 issue 的里程碑标题(从正文中解析 Fixes/Closes/Resolves #N,取出每个 issue,取第一个非空里程碑)。
Pull request 基础分支,如果它匹配 release/X.Y[.Z]。
这是枢纽。产品仓库中的里程碑干净地映射到文档仓库中的发布分支。当 agent 最后运行时,它确切知道文档应该落在哪里,无需任何关于目标分支的创意写作或猜测。
Agent 读取 diff,扫描关联 issue,然后判断:这个需要文档吗?如果是,它在已检出的 microsoft/aspire.dev 工作区中起草实际内容,遵循我们现有的文档编写者 skill(语气、MDX 约定、Starlight 组件)。然后它发出 create_pull_request 安全输出并交接。
安全输出处理器接手:
标签:docs-from-code
draft: true(我们从不自动合并)
基础分支:agent 提供的,限制为 main 或 release/*
目标仓库:microsoft/aspire.dev
审查者:从源 pull request 的审查中识别的 SME——也就是说,产品团队信任来批准功能的人,现在被要求批准该功能的文档。
一个伴随 job 在源 pull request 上发回标记注释,带有文档 pull request 链接,并在重新运行时最小化任何旧的 pr-docs-check 注释。刚点击 Merge 的工程师会在几分钟内收到通知:"这是文档草稿。看一眼?"
整个安全故事归结为一小段无聊的前置元数据:
tools:
github:
toolsets: [repos, issues, pull_requests]
min-integrity: approved # only run pinned, integrity-checked actions
allowed-repos:
- microsoft/*
github-app:
app-id: ${{ secrets.ASPIRE_BOT_APP_ID }}
private-key: ${{ secrets.ASPIRE_BOT_PRIVATE_KEY }}
owner: "microsoft"
repositories: ["aspire.dev", "aspire"]
safe-outputs:
create-pull-request:
title-prefix: "[docs] "
labels: [docs-from-code]
draft: true # human-in-the-loop, always
base-branch: main
allowed-base-branches: [main, release/*]
target-repo: "microsoft/aspire.dev"
protected-files: blocked # AGENTS.md, manifests, security config: hands off
fallback-as-issue: true
这就是用纯文本表述的约定。Agent 获得一个 GitHub App 令牌,其安装范围恰好是两个仓库——产品仓库和文档仓库——组织中的其他任何东西都不可到达。它只能让 pull request 落在 main 或 release/* 上。AGENTS.md 和依赖清单按策略禁区。如果 pull request 创建失败(网络抖动、冲突、任何东西),框架回退到提交 issue,所以没有东西会被静默丢弃。
这是安全审查实际喜欢的部分。agent 的推理是模糊的。行动表面不是。
这是来自一个 30 天滚动窗口的统计数据(2026 年 5 月 3 日 – 6 月 2 日),跨越 Aspire 13.3 发布的后端和 13.4 的助跑:
注:数字在撰写时捕获;工作流持续运行,所以总数只会增加。
其中一些数字值得再看一眼:
396 次运行 → 82 个 pull request 不是缺陷。工作流在每个合并的 pull request 上运行;大多数是内部重构、测试修复或没有用户可见表面的依赖碰撞。agent 说"不需要文档"超过 300 次是一个特性。
100% 合并率说明 agent 的文档选择是对的。我们在 v1 假阳性阶段后发货的更紧凑提示正在发挥作用。
✅ 里程碑 → 发布分支映射。这是我们做的最高杠杆选择。工程师已经在 pull request 和 issue 上设置里程碑;我们免费获得了准确的目标分支路由。
✅ 仅草稿、SME 作为审查者。agent 从不合并。发货功能的工程师是确认文档是否正确的人。我们已经停止了在文档层反向工程功能。工程师只是在他们已经所在的地方告诉文档草稿要说什么。
✅ 每个工作流限制的 GitHub app。每个工作流都获得其自己的 app 令牌,具有明确的仓库和权限范围。安全审查批准。我们也批准了;第一次我们需要轮转密钥时。
✅ protected-files: blocked。agent 不能触碰 AGENTS.md、包清单或仓库安全配置。句号。
首次没起作用的:
❌ Agent 的"这值得有文档吗?"守门在第一版太慷慨了。它为真正是内部的改动起草 pull request,比如一个 CI 调整或日志重构。结果:69 个 pull request 中有 9 个关闭(约 13%),所以我们收紧了提示的用户面改动定义,添加了明确的反面例子(CI、内部助手、仅测试)。现在,比率趋向下降。
❌ 跨仓库 pull request 创建需要一个从文档中不显而易见的镜像检出模式。agent 在一个仓库中工作;安全输出需要找到目标仓库来推送分支。我们通过两次检出 microsoft/aspire.dev 来解决——一次作为当前工作区,一次在 _repos/aspire.dev 下——所以安全输出处理器可以确定性地重新发现它。
❌ 大 diff 会爆掉提示预算。我们在前置代理步骤 bash 中预提取 pull request 元数据(关联 issue、里程碑、基础分支),所以 agent 获得一个小的、结构化的摘要而不是巨大的有效负载。这是 GitHub Agentic Workflows 的设计内模式,而且它起作用。
我们做的改动转变了我们的思维。功能直到文档完成才算完成。文档不再像一根绳子上的锡罐一样尾随其后。工程师的审查是守门;机器人做打字工作。
关键是,这不会取代文档编写者;它减轻了他们的负担。我们的编写者曾经把大部分时间花在反向工程功能上。现在他们花时间在只有人类能做好的事情上:叙述页面、示例程序、概念演练、文档中不从 diff 中脱落的那些部分。机器人处理那些从不令任何人愉快的机械"添加了这个新选项;这是参考页面更新"工作。
巨大感谢 GitHub Next 团队的 GitHub Agentic Workflows(以及让安全输出原语成为设计的一流部分),感谢 Chris Swithinbank 和 Starlight 维护者提供的我们自动化输入的文档平台。还要真诚感谢安全团队,他们的护栏迫使我们从第一次起就以正确的方式设计这个。好自动化的无聊秘密是强大的安全约束使系统更值得信任,也更正确。
如果你在一个仓库中构建产品,在另一个中发货文档——特别是如果你必须在任何非平凡的安全边界内做这件事——GitHub Agentic Workflows 值得认真看一下。从一个工作流开始,比如 pr-docs-check,然后看看你的中位文档发货时间发生了什么。
pr-docs-check 是我写这篇文章的那个,但它不是单独运行。如果你想了解其他的,源码是公开的:
milestone-changelog.md:每两小时运行一次,在活跃里程碑中拉起新合并的 pull request,维护一个 13.x-Change-log wiki 页面(新功能、改进、显著错误修复),附带一个伴随编辑反馈 issue。346 次运行。
release-update-support-mdx.md:在 Aspire 稳定发布时,在 aspire.dev 上起草一个 [support] pull request,更新支持政策页面(推升新版本,降级前一个版本,刷新"最后更新"徽章)。
update-integration-data.md:位于文档仓库;每天运行 pnpm update:all,刷新 NuGet 元数据 + GitHub 统计 + 示例数据,打开一个 chore: Update integration data PR,带有过时运行的超级和关闭逻辑。27 次运行,八个合并的 pull request。
repo-pulse.md:一个滚动三天的仓库仪表板固定到单个 issue 并原地更新:最近合并、等待审查的 pull request、新 issue、讨论活动。一个 issue,总是新鲜的。
祝自动化愉快,朋友们!🤖🚀
GitHub Agentic Workflows
微软 aspire.dev 建设者级高级软件工程师
微软研究院主要研究软件设计工程师。MakeCode、GenAIScript 等的创建者。
其他相关文章:
Tame Dependabot: Group your updates, slow the cadence, keep security fast
The harness is all you need (mostly)
GitHub Copilot app for Beginners: Getting started