症状:Agent 已经创建 PR,但 Xcode 构建仍无法复现。
最快解法:PR 创建留在 Agent Host,交付证明放到独立 CI 与 Mac 构建层。

这套分层适合需要自动改代码、生成 Pull Request,同时还要完成静态检查、Xcode 构建、签名测试或 Apple 平台回归的团队。只有低风险原型、无签名任务、无敏感凭据的临时任务,才适合暂时共用一台主机。

先把三个状态分开

VS Code 1.138 发布说明显示,该版本发布日期为 2026 年 9 月 16 日,Agent Host 会在独立进程中运行 Agent,并支持从会话创建 Pull Request。GitHub 在 2026 年 9 月 18 日的周更新中进一步说明,创建 PR 时可以检查标题与描述、选择草稿状态,再直接创建 PR 或让 Agent 执行创建动作。

但你的交付流程至少要区分下面三件事:

  1. PR 已创建:代码已经提交到分支,并产生了 Pull Request。
  2. 检查已通过:确定性 CI、静态分析、单元测试或指定的 Xcode 检查已返回可接受状态。
  3. 代码可发布:完成必要审批、签名、归档、设备或模拟器验证,并满足受保护分支规则。

第一种状态只证明 Git 操作完成,不能替代后两种状态。Agent Host 的职责是理解任务、修改工作区、提交变更和发起 PR;CI 的职责是用固定环境重复执行检查;独立云端 Mac 则负责 Apple 平台相关的真实构建与交付证据。

你还需要保存提交 SHA、工作区或分支名称、执行环境、依赖版本、测试日志和构建产物。GitHub Actions 支持将测试结果、二进制文件、日志与崩溃信息作为工作流产物保存;产物上传还可以提供 SHA-256 摘要,便于后续核对文件是否被替换。Workflow artifacts 官方文档

按代码类型选择构建层

先不要按 Agent 会话数量购买 Mac。你应该先判断代码是否真的依赖 Apple 平台,再决定任务放在哪里。

场景 Agent Host GitHub Actions Runner 独立云端 Mac 决策
Web、脚本、跨平台后端 修改代码、提交分支、创建 PR 静态检查、单元测试、容器构建 通常不需要 继续使用通用 Runner
跨平台客户端但不调用 Apple 专属框架 生成代码并运行轻量检查 执行确定性测试和打包 仅在发布前抽样验证 先不新增 Mac
iOS、iPadOS、macOS 项目 修改代码和准备 PR 可负责通用检查 Xcode、模拟器、归档、签名测试 拆出 Mac 构建层
需要证书、Provisioning Profile 或发布权限 不保存高权限凭据 只使用最小权限 使用受控 Mac 和短时凭据 必须隔离
多 Agent 同时提交 PR 管理会话和工作区 承担可并行的确定性检查 进入队列执行 Apple 构建 按峰值扩容,不按会话一比一配置

如果项目只涉及 TypeScript、Java、Python、Go、容器镜像或普通单元测试,并且没有 Xcode、Simulator、系统框架或 Apple 签名依赖,那么新增 Mac 往往不会解决真正瓶颈。此时你可以让 Agent Host 负责修改和创建 PR,再由通用 Runner 执行固定测试。

代码已经由 Agent 提交后,是否还要经过 CI?

需要。PR 创建只说明分支和 Pull Request 已经产生,不能证明测试使用了干净环境,也不能证明 Agent 的本地依赖与团队标准环境一致。CI 至少应重新执行依赖安装、静态检查、单元测试和构建命令,并把日志、提交 SHA 与运行环境绑定起来。

进入 Apple 平台后,拆出独立 Mac

涉及 Xcode、Simulator、系统框架或 Apple 平台依赖时,通用容器不能替代真实 macOS 验证。Apple 官方文档明确说明,Simulator 运行在 Mac 上,而且不能完全复现真实设备的性能和功能;需要确认设备行为时,仍要使用物理设备验证。Apple 的模拟器与实体设备测试说明

iOS PR 创建完成后,Xcode 构建应交给哪一层?

默认放在独立的云端 Mac 或受控 Mac Runner 上,而不是 Agent Host 原机。Agent Host 可以先运行 xcodebuild 做快速反馈,但最终构建应由干净工作区、固定 Xcode 版本、明确缓存策略和独立权限的 Mac 执行。

这样做主要是为了控制三类风险:

  • ✅ 污染风险:Agent 可能修改依赖、生成临时文件或留下未提交状态,导致下一次构建无法解释。
  • ✅ 复现风险:同一台主机上的缓存、模拟器数据、钥匙串和环境变量,会让失败结果只在某次会话中出现。
  • ✅ 占用风险:Xcode 构建、模拟器启动和归档可能持续占用 CPU、磁盘与设备资源,阻塞后续代码生成任务。

GitHub 托管的 macOS Runner 可以直接通过 runs-on 选择 macOS 标签。官方文档列出的标准 arm64 macOS Runner 示例包括 3 个 CPU、7 GB 内存和 14 GB 存储;但 macos-latest 并不一定等于 Apple 刚发布的最新系统版本,因此你必须锁定所需镜像或在流水线中记录实际环境。GitHub Runner 选择文档

如果你需要固定工具链、保存更长的缓存、控制钥匙串或安排专用队列,可以改用自托管 Mac。GitHub 文档说明,当没有匹配标签且处于空闲状态的自托管 Runner 时,任务会保持排队;如果排队超过 24 小时,任务会失败。自托管 Runner 官方说明

用权限边界阻止“自己给自己背书”

Agent 能创建 PR,不代表它可以绕过分支保护、必需检查、人工审批或合并队列。GitHub 的受保护分支规则可以要求 PR 审批、状态检查、CODEOWNER 审批、签名提交、部署成功或合并队列,也可以禁止绕过这些设置。GitHub 受保护分支文档

高风险仓库建议采用以下组合:

  • Agent 使用单独的仓库身份或 GitHub App,只有创建分支和 PR 的权限。
  • CI 使用独立身份发布必需检查,不能由修改代码的同一身份随意写入成功状态。
  • 初始 PR 使用草稿状态,待人工确认变更范围后再标记为可审阅。
  • 签名、发布、生产凭据和合并权限不放入 Agent Host。
  • 关闭任何会绕过分支规则的自动化路径,尤其是涉及高权限令牌的脚本。

Agent Host 与 GitHub Actions Runner 是否适合共用一台 Mac?

技术上可以,治理上不应作为默认方案。低风险原型可以共用,但必须有隔离工作区、不同用户权限、独立缓存目录和明确清理步骤。只要任务涉及签名、发布、生产仓库、无人值守执行或敏感凭据,就应拆分 Agent Host 与 CI Runner。

⚠️ 注意:不要把“检查变绿”写成“代码安全交付”。检查结果必须能追溯到具体提交、具体 Runner、具体 Xcode 环境和具体构建产物。

远程主机与长任务要分开管理

Agent Host 可以运行在本地、Dev Container 或远程主机。官方架构文档说明,远程 Agent Host 可以通过 WebSocket、SSH 或开发隧道连接,客户端断开后,主机上的会话仍可能继续运行;客户端只是查看和控制会话的入口,不是任务状态本身。VS Code Agent Host 架构文档

这不等于构建一定可恢复。你需要分别保存三类对象:

  • 代码工作区:Git 仓库、分支、worktree 和未提交改动。
  • 任务状态:会话 ID、当前步骤、批准记录、失败原因和重试次数。
  • 构建产物:测试日志、.xcresult、归档文件、签名结果和环境清单。

建议按下面 5 步验收远程长任务:

  1. 让 Agent 创建一个独立 worktree,不直接修改主工作区。
  2. 记录提交 SHA、分支、依赖锁文件和工具链版本。
  3. 断开 VS Code 客户端,再从另一台设备重连会话。
  4. 在任务中断后确认能否从明确检查点继续,而不是从头猜测状态。
  5. 将 Xcode 长任务提交到专用 Mac 队列,避免占用 Agent Host。

如果重连后只能看到聊天记录,却找不到当前工作区、构建日志或实际产物,就不能把该任务标记为可恢复。

多 Agent 并行时,先测队列再扩容

多个 Agent 并行提交 PR 后,瓶颈通常会从模型生成转移到依赖安装、测试队列、模拟器启动和 Mac 构建资源。你需要分别记录:

  • 排队等待时间;
  • Runner 实际执行时间;
  • 失败后的重试时间;
  • 人工审批等待时间;
  • 缓存命中或依赖重新安装情况。

如果主要耗时发生在通用测试,先优化 GitHub Actions 的缓存与并行策略;如果主要耗时发生在 Xcode 归档或模拟器任务,再增加独立 Mac 的基础池或峰值池。不要因为有 5 个 Agent 会话,就直接配置 5 台 Mac。

GitHub Actions 日志可以查看每个 Job 的执行结果、运行时间、失败步骤和 Runner 镜像信息;这些数据适合用来区分“队列太长”和“单次构建太慢”。GitHub Actions 日志文档

用三档方案完成最终决策

你可以按下面的停止条件选择方案:

维持现状

满足以下条件时,继续让 Agent Host 与通用 CI 协作:

  • 项目不依赖 Xcode、Simulator 或 Apple 专属框架;
  • 没有签名、发布或生产凭据;
  • CI 能在干净 Runner 中稳定复现;
  • 并发高峰没有明显 Mac 构建排队。

拆分构建层

出现以下任一情况,就把 Xcode 构建迁移到独立云端 Mac:

  • Agent 本机能通过,但干净环境无法复现;
  • 构建需要固定 Xcode 或 macOS 版本;
  • 任务涉及模拟器、归档、签名或设备测试;
  • Agent Host 的依赖缓存和钥匙串影响了结果;
  • 长任务已经阻塞代码生成会话。

增加弹性容量

只有当你已经确认 Mac 队列是主要瓶颈,并且等待时间持续高于实际执行时间时,才增加峰值容量。基础池承接常规 PR 验证,弹性池承接集中提交、发布前回归和临时项目;签名发布仍应保留独立权限和独立审批。

如果你现在把 Agent Host、GitHub Actions Runner 和 Xcode 构建都塞在同一台 Mac 上,真实缺点通常是缓存污染难定位、长任务阻塞会话、权限边界模糊以及高峰期排队互相放大。自购 Mac 适合长期稳定重负载、需要物理设备接口或固定硬件控制的团队;但对需要临时算力、测试环境和弹性并发的团队,使用 kvmsync 的云端 Mac 可以把构建层从 Agent 主机中拆出来,再按基础池与峰值池安排资源。你可以先阅读 kvmsync 的云端 Mac 使用帮助,标记现有 PR 流程属于“维持现状、拆分构建层”还是“增加弹性容量”,再决定是否需要进入 kvmsync 的方案与周期页面。

kvmsync M4 远程节点

让每个 PR 都有一台随时可用的独占 Mac

使用 kvmsync 租用真实 Mac mini 裸金属节点,为构建、测试、签名和发布提供稳定的 macOS 环境。

立即租用 Mac mini M4 对比 M4 套餐