src/ 让我们设想这样一种场景:需要从散落在各处的目录中找出已废弃的 API 调用。如果将 12 个 AI 代理同时分配到 12 个目录中,人们往往觉得会冒出 12 个 issue。但在 GitHub 的 agentic 工作流(gh-aw)中,无论调动多少代理,最终只会打开一个 issue。这并非得益于复杂的冲突解决技术,而在于其设计初衷——从一开始就未授予代理修改代码库的权限(即“写权限”)。
代理持有的 GitHub 令牌完全不具备写权限。即便指示代理“将此代码推送到代码库”,请求也会在令牌层面被拒绝,因此在物理层面无法执行写入操作。代理唯一能做的输出,是留下诸如“请将此内容创建为 issue”的请求数据。本文将探讨多个代理并行分析时,为何不会出现代码库冲突或重复工作的运行机制。
并行性在于“读”,“写”位于闸门之后

GitHub 于 2026 年 6 月 11 日将 agentic 工作流转为公开预览版。该功能通过 GitHub Actions 运行编码代理,以处理 issue 分类、每周摘要等重复性任务。该系统的核心安全设计之一,是仅向代理提供只读令牌,并限制其访问 secret 值的能力 1。
这意味着,并行处理仅存在于“读取和分析代码库”阶段。多个代理可以同时打开不同文件以掌握其内容,但没有任何代理能将结果直接写入代码库。实际的写入操作由具备独立写权限的单独任务(job)负责。这种隔离结构从根源上阻断了并行执行可能引发的冲突和重复。
Safe Outputs:代理提出建议,系统负责执行
GitHub 官方文档中称为“Safe Outputs”的机制负责管理分离式的写入流程。代理在不具备写权限的情况下,仅生成结构化数据(即请求事项),而具有读取权限的独立任务则负责实际调用 API 2。例如,当代理留下“请创建这样一个标题的 issue”的请求后,具有 issues: write 权限的另一个系统会处理该请求 2。
这里存在一个默认值,它是防止重复的关键。若无特殊设置,create-issue 功能会自动启用,且其上限(max)固定为“1”2。标签和标题前缀也与 workflow ID 关联,从而处于管控之下 2。即使 12 个代理同时请求“创建 issue”,作为闸门的系统也会对其进行确认,并仅执行一次。
每个请求都拥有唯一 ID(so_...)。若任务间需要顺序关系,则通过 depends-on 引用前一任务的 ID 来构建等待队列。只有当前任务完成后,后续任务才会执行;若依赖关系出现异常(fail-closed),为安全起见,执行会停止 2。PR 合并也遵循此规则:代理本身不具备直接合并权限,而是由系统验证策略后,仅处理获批准的请求 23。

从实际代码看并行与串行的边界

Start Debugging 公开的 api-sweep 示例代码很好地展示了这一流程。该示例在 src/ 下的每个目录中分配一个代理,以查找废弃的 API 调用(HttpClientFactory.Legacy)3。
// .github/extensions/api-sweep/extension.mjs (Start Debugging 예제 기반)
const dirs = await ctx.step("dirs-v1", async () =>
(await readdir("src", { withFileTypes: true }))
.filter((d) => d.isDirectory())
.map((d) => `src/${d.name}`),
);
// ctx.parallel(): 디렉터리 수만큼 에이전트를 동시 실행 (읽기/분석)
const results = await ctx.parallel(dirs.map((dir) => () =>
ctx.agent(
`List every call to ${api} under ${dir} and the replacement it needs. ` +
`Return an empty list if there are none.`,
{ label: `sweep:${dir}`, schema: HITS },
),
));
// 결과를 합치는 단계는 순차적으로 진행됨
return { hits: results.filter(Boolean).flatMap((r) => r.hits) };在使用 ctx.parallel() 函数的阶段之前,均为并行执行。每个代理仅将发现的结果以 JSON 格式返回。在所有返回的数据汇聚后,最终阶段根据 safe-outputs 设置(max: 1)最终创建唯一的单个 issue 3。即使 12 个代理各自带来了发现内容,在最终关卡处也会收敛为一个。
三种运营方式与共同的安全边界

多代理的使用方式大致分为三类,它们在是否具备写权限方面有所不同 3。
/fleet(即时执行):在 Copilot CLI 会话中,当用户发出提示词时,子代理会立即分担任务。这种方式适合人在旁观察并把控方向时使用,可利用会话赋予的权限执行保存操作 3。- 动态工作流(脚本):通过 JavaScript 代码预先定义拆分计划。该方法适用于需要重复执行或设置预算上限的任务,是否可保存取决于会话权限和代码配置 3。
- gh-aw(无人化自动化):由事件或计划触发,在无人查看时运行。在此环境下,代理任务必须严格为只读模式,所有写操作都必须通过 Safe Outputs 闸门 3。
像 Carvana 和 Marks & Spencer 这样的企业将 gh-aw 用于复杂的系统变更和维护,归根结底也是得益于这些内置控制机制所建立的信任 1。Carvana 指出,之所以能够将涉及同时修改多个代码库的变更委托给代理,原因在于其“灵活性和内置控制”;而 Marks & Spencer 则通过可复用的工作流目录,将以往在 issue 分类和依赖项维护中流失的开发时间重新找回。
结语
多个 AI 代理处理同一代码库时之所以不会发生冲突,并非因为它们通过智能手段相互竞争。因为在 gh-aw 架构中,代理持有的是只读令牌,因此在物理层面无法向代码库写入任何内容 31。相反,生成的请求会在设有 max 上限和标签规则的独立闸门处进行验证,即使收到多个建议,最终也只会落实一次 2。并行性得以安全维持,并非依靠复杂的合并技术,而是因为从源头上就将写操作推到了单一闸门之后。
参考资料
- Getting Started with GitHub Agentic Workflows · kdnuggets.com↩
- Safe Outputs | GitHub Agentic Workflows · github.github.com↩
- Copilot Dynamic Workflows vs /fleet vs GitHub Agentic Workflows: Which Multi-Agent Option to Reach For - Start Debugging · startdebugging.net↩




