在代理工作时就开始审阅
10:40,你在计费服务上启动了一个托管运行:"编写文档,说明如何在本地搭建和运行这个服务。"11:02,一个 pull request 到了,里面有一份新的 docs/setup.md。写得还行。第 12 行让新入职的同事运行 go build ./...,而这条命令会漏掉服务需要的 build tag,所以他们的第一次构建会以一种文档里完全没解释的方式失败。另外,大约在第六分钟的某个时候,代理认定 README 里的 Docker 章节已经过时,把它重写了。没有人让它这么做。
这些问题在审阅时都不难修。审阅补不回来的,是中间那二十分钟。代理很早就做了这些选择,没有人帮它把关,之后的所有工作都建在这些选择之上。于是修正就变成了第二次运行:从零开始,把同样的文件再读一遍,再开第二个 pull request。
在此之前,Archyl 的托管代理运行就是这样工作的。运行页面有事件流和引导输入框,只要你一直开着那个标签页,就能在笔记本上或手机上跟着看工具调用。但代理打算做什么、到目前为止写了什么,你只能从工具调用的 payload 里拼凑,或者等到 pull request 才知道。对夜间的依赖审计来说,这没问题。对一个你反正要审阅的改动来说,这等于把审阅放在了代价最高的时刻。
现在,运行有了审阅闭环。变化如下:
| 闭环中的环节 | 以前 | 现在 |
|---|---|---|
| 代理打算做什么 | 从它的工具调用里推断 | 一份在任何改动发生前你都能修改的计划 |
| 它不该独自做的决定 | 它自己拍板 | 它会提问,并附上建议的回答 |
| 它写了什么 | 最后的 pull request | 变更,边写边按文件呈现 |
| 针对某一行的反馈 | 运行结束后的 PR 评论 | 代理在下一步就会读到的评论 |
| 运行结束后的反馈 | 从零开始的新运行,外加一个新 PR | 继续,在同一个分支和同一个 PR 上 |
本文接下来会用新的方式把同一个任务再跑一遍,按你实际经历的顺序来讲。任务只是示例;下面引用的每条消息,都是代理真实收到的格式。
先有计划
在碰任何文件之前,代理会被要求调用 propose_plan,给出一句话摘要和几个具体步骤。提示词要求 3 到 8 步,工具会拒绝超过 12 步的计划,这样计划一眼就能看完。运行页面顶部的 计划 面板会把它变成检查清单。代理工作时会把每一步标记为 进行中、已完成 或 已跳过,有时附上简短说明,面板则显示当前所在的步骤和进度(2/4)。
默认情况下,计划只是分享出来,代理会马上开工。在代理配置文件的 协作 下开启 先审阅计划,它就会改为等你。面板会切换到审阅模式,你可以在这里重命名步骤、补充细节,以及添加、删除步骤或调整顺序。
针对这份搭建文档,代理提出了五个步骤。第四步是"更新 README 的 Docker 章节",也就是那次没人要求的重写。你把它删掉,给第 2 步补充一个细节,原本显示 批准计划 的按钮就变成了 批准编辑后的计划。代理收到的是这样的内容:
The plan was approved with edits. Follow this plan:
1. Read the Makefile, docker-compose.yml and the config loader
2. Write prerequisites and environment variables — take values from .env.example, never from a real .env
3. Document the build, test and run commands
4. Link docs/setup.md from the README
Call update_plan when each step starts and when it is done or skipped.
你编辑后的版本,就是代理遵循的计划,也是检查清单跟踪的计划。如果计划不是稍有偏差而是方向错了,就改用 要求修改 发送反馈。代理会修改计划并提出新的修订版,之前的修订版保留在事件流里,你可以看到自己的反馈改变了什么。

在计划获得批准之前,代理不能写文件,不能通过 Archyl 的工具修改架构模型,也不能通过连接器向仓库推送。这不是提示词里的一句话,代理没法说服自己绕过去。这些调用会被直接拒绝,代理会读到:
changes are refused until your plan is approved: call propose_plan and wait for the review
如果一小时内没有人审阅计划,运行就会失败,而且不会做出任何改动。一个要求审阅的配置文件,不会因为没人出现就跳过审阅。
需要人来决定时,就提问
有些决定不该由代理独自做出:含糊的需求、没有明显优解的权衡、具有破坏性的操作。针对这些情况,它有 ask_human。它的指令要求它绝不询问自己能查到的东西,而且每次运行最多只能问 5 个问题,所以它没法一个问题接一个问题地把工作推回给你。
做到第 2 步一半时,代理在配置里发现了一个 STAGING_DATABASE_URL。把它写进文档会有帮助,只是 staging 需要 VPN 权限,而新同事入职第一周拿不到这个权限。仓库里没有任何地方写明这一点,所以它提问了。
问题会显示在事件流上方。如果代理给出了选项,会附带 建议的回答("不要写 staging"、"写上,并加一条关于 VPN 权限的说明"),另外还有一个输入框供你自己作答(按 Cmd/Ctrl + Enter 发送)。任何能编辑该项目的人都可以回答,事件流会记录是谁回答的。代理读到 The human answered: Leave staging out,然后继续工作。
一小时内无人回答的问题,不会让运行失败。代理会按自己的判断继续,并在成果里说明它做了什么假设。这和计划正好相反,区别在于利害不同:未经审阅的计划意味着什么都没有达成一致,而一个没人回答的问题,只是多了一个代理在整个运行过程中本来就一直在做的那类决定。
等待的代价
代理在等待计划审阅或回答时,运行会显示 等待你处理,运行列表会把它归入 需要你处理。事件流上方的横幅会说明它在等什么,是 等待你审阅计划 还是 代理有一个问题,并带你直接过去。
等待时间不计入运行的时间上限。截止时间会按等待时长顺延,所以一个上限 30 分钟、等了你 20 分钟的运行,仍然有 30 分钟的工作时间。不过它会继续占用并发名额。处于 等待批准 的运行还没有开始,所以什么都不占用;而正在等你的运行正处在对话中途,工作区开着,你的回复一到就能接着干。
边写边看的 diff
运行页面现在有两个视图:活动,也就是事件流;以及 变更。变更 会在代理写文件的同时列出每个文件,显示状态(新增、已修改 或 已拦截),以及每个文件和整个运行新增、删除的行数。选中一个文件,就能看到每一次写入改了什么(第 2 次编辑,共 3 次),而不只是最终状态。
Guard 也会出现在这里。它对每一次文件写入做合规检查,并且现在运行在 worker 内部。被它拒绝的写入会显示为 已拦截:diff 会展示代理试图写入的内容以及它违反的规则,尽管这些内容从未真正写进文件。只被它标记警告的写入会照常生效,并在文件上显示警告。以前你要在工具结果里才能找到的一次拒绝,现在变成了一份可以阅读的 diff。
有两个限制:较长的 diff 会在 600 行处截断,超过 128 KB 的文件只列出,不显示 diff。
在第 12 行留一条评论
回到 go build ./...。你不必等 pull request。在 变更 中点击行号,写下评论,然后点 发送给代理(Cmd/Ctrl + Enter)。代理会在下一步把它作为一条 code review 评论收到,其中包含文件、行号以及该行的内容:
[Review comment from a human operator on docs/setup.md, line 12 of the file as you wrote it]
> go build ./...
Use the make target instead, it sets the build tags.
Address the comment in that file, then carry on with your plan.
它修好这一行,然后回到自己的步骤。在代码行下方,评论在代理取走之前显示 已排队,之后显示 已送达。评论也会出现在 活动 中,列表里的每个文件都会显示自己有多少条评论。修复到来时,会作为这个文件的下一次编辑出现,所以你留下评论的那个 diff,也就是你检查修复的地方。

新增的行、未改动的行和删除的行都可以评论。对删除行的评论,会以针对 "the lines you removed" 的评论送达代理,你可以用它让代理把某个检查加回来。代理工作中或等你处理时都能接收评论,正在等待的代理会在恢复时读到它们。运行结束时仍为 已排队 的评论会显示 未送达。被 Guard 拦截的写入不能评论。
引导输入框依然在,用来在不取消运行的情况下,用自由文本调整代理的方向("跳过迁移,专注于 handler")。行评论是同一套机制,只是钉在了某一行上。它帮你省掉的是开场白:"在 docs/setup.md 里你写 go build 的那个地方",这句话已经在消息里了。
那个没东西可审阅的运行
在开发 变更 的时候,我让一个运行给我们的某个 Git 仓库补充文档,结果眼看着视图一直是空的。没有文件,没有 diff,没有可以评论的东西。
那个项目没有关联代码仓库,所以 Archyl 什么都没有克隆。但这个运行挂了一个 GitHub 连接器,代理用手边的工具做了合理的事:它用连接器的 push_files 工具,把文件直接写到了 GitHub 上。没有任何东西经过工作区。于是也没有任何东西经过 Guard,变更 里什么都没出现,我正在做的审阅闭环也就没有东西可审。
现在,两种情况下代理都会在工作区里工作:
- 项目关联了代码仓库。 和以前一样,Archyl 在运行开始时克隆它。
- 没有关联代码仓库,但挂了 GitHub 连接器。 代理在碰任何文件之前,会用连接器的凭据调用
open_repository,自己克隆任务所涉及的仓库。这只适用于 GitHub 托管的 MCP 服务器(api.githubcopilot.com),而且令牌需要有该仓库的访问权限。
工作区一旦打开,会写入仓库的连接器工具(push_files、create_or_update_file、delete_file、create_pull_request)都会被拒绝,代理会读到:
a repository workspace is open: change files with write_file and edit_file instead. Archyl commits your changes and opens the pull request when the run ends.
正是这条规则,让每一处改动都经过 Guard、出现在 变更 里,并汇入同一个 pull request。
运行结束时
Archyl 会把工作区的改动提交到 archyl/agent-<run id>(取运行 ID 的前八个字符),并以克隆时所基于的分支为目标开一个 pull request。链接位于 变更 顶部(打开拉取请求)以及结果中。运行以什么方式结束,决定了发布什么:
| 运行如何结束 | Archyl 发布的内容 |
|---|---|
| 成功 | 一个 pull request |
| 失败,或因时间或成本上限而停止 | 一个 草稿 pull request,说明运行为什么停止 |
| 已取消 | 无 |
在 GitLab 上,草稿是一个 Draft: merge request。在 Bitbucket 上,只推送分支,不创建 pull request。没有改动任何文件的运行不会发布任何东西。
你的评论变成下一次运行
运行停了,审阅不会停。pull request 已经打开,你正在 变更 里读最终的 diff。对已结束运行的评论没有代理可以送达,于是它会变成留给下一次运行的备注:留待继续执行 会把它保存在你的浏览器里。文件上方的横条会统计数量(3 条评论留待继续执行),并提供 带上这些评论继续。
每个已结束的运行,无论结果如何,都提供两个按钮。再次执行 会用相同的任务和配置文件打开启动对话框,从头开始一次新的运行:当第一次尝试走向了一个你不想在其上继续构建的方向时,这是正确的选择。继续 会启动一次新的运行,接手本次运行的工作;如果你留了留待继续的评论,它们会预先填入指令,每行一条:
- docs/setup.md:28 — Say that make seed needs the database container running.
- docs/setup.md:44 — Add how to run the tests for a single package.
- README.md:18 (removed line) — Keep the troubleshooting note for port 5432, setup.md doesn't have it.
你可以随意编辑。配置文件默认沿用这次运行的,你也可以选择连接器。

同一个分支,同一个 pull request
继续运行不只是一次提示词更长的新运行。它从上一次运行发布的分支开始,在该分支上提交,并把改动添加到同一个 pull request,而不是另开一个。如果上一次运行是通过 GitHub 连接器打开仓库的,继续运行会在代理启动前,在那个分支上重新打开它。
代理也会被告知自己是在什么基础上继续的。上一个任务、那次运行做了什么(它的成果摘要,或者它为什么停止),以及它的工作放在哪里,全都放在提示词的开头(其中的 ID、URL 和摘要是示例):
# Continuing a previous run
This run continues the work of run `4f1c2a9e-7b3d-4e0a-9c6f-2d8b1a5e3c70`. Build on what it did rather than starting over.
## What it was asked
Document how to set up and run the service locally.
## What it did
Added docs/setup.md with prerequisites, environment variables and the make targets, and linked it from the README. Left the staging database out, as answered.
Its changes are on the branch `archyl/agent-4f1c2a9e`, which your workspace starts from. Your changes are added to its pull request: https://github.com/acme/billing/pull/212. If the workspace could not start from that branch, the run feed says so and your changes go to a new pull request.
The task below is what the person wants now, often review comments on that work: address each of them.
审阅者看到的是一个 pull request 逐步成长,而不是一串 pull request。GitHub 的 Copilot cloud agent 处理后续工作的方式也一样:你在 pull request 的评论里 @copilot,默认情况下它会把提交推送到这个 pull request 的分支上(GitHub Docs)。一项工作对应一个 pull request,这才是正确的形态,继续运行也遵循这一点。
边界情况下会发生什么:
- 分支已经不在了,比如已经合并并删除。继续运行会从默认分支开始,并开一个新的 pull request,事件流里会出现一行琥珀色的提示:"无法检出上一次执行的分支 archyl/agent-4f1c2a9e。此执行将从默认分支开始,并创建新的拉取请求。"
- pull request 是草稿。 它会保持草稿状态。工作完成后,请把它标记为可供审阅。
- 只限代理分支。 Archyl 只在它的代理创建的分支上继续,也就是
archyl/下的分支,绝不会提交到人创建的分支上。
两次运行会互相链接:新运行显示 源自执行,上一次运行显示 后续执行。仍在进行中的运行无法继续,请改为评论它的代码行。
继续运行还会保留架构上下文。它的工作会话是针对上一个任务加上后续要求开启的,而不只是后续要求本身,所以它能找到与被继续的运行相同的架构元素和记忆。这比听起来更重要。"说明 make seed 需要数据库 container 处于运行状态"这句话里根本没有提到任何服务,只凭这一行开启的会话,几乎没有什么可以匹配。
它做不到的事
worker 没有 shell。 它能读取、写入、编辑、列出和搜索文件,但不能构建项目,也不能运行测试。在这个例子里,它能读 Makefile,却不能运行 make build 来确认文档写得对不对。干净的 diff 不等于构建通过,这件事仍然由 CI 来做。
行评论是指引,不是关卡。 没有"已解决"状态,也没有任何机制检查代理是否处理了某条评论。你在 diff 里看到它的下一次编辑,由你来判断。
留待继续的备注只存在于一个浏览器里。 在你继续运行之前,你的队友看不到你留待继续的评论。发给正在工作的代理的评论则不同:它们在事件流里,所有人都能看到。
计划审阅的前提是有人在。 这是按配置文件设置的选项,默认关闭,该配置文件上的每次运行都会遵守它,定时运行也不例外。一个在开启审阅的配置文件上、凌晨 3 点启动的运行,会等待一小时,然后在没有任何改动的情况下失败。问题同样会等待一小时,之后由代理独自决定。
通过连接器克隆只支持 GitHub。 open_repository 适用于 GitHub 托管的 MCP 服务器。其他托管平台,请把仓库关联到项目。
从哪里开始
挑一个你反正要审阅的小任务,在开启了 先审阅计划 的配置文件上运行它。把运行页面开着。批准之前先修改计划,哪怕你做的只是删掉那个你本来不会要求的步骤。在 变更 里,评论你本来会在 pull request 里指出的第一行,看着它从 已排队 变成 已送达。运行结束后,把剩下的留作留待继续的评论,然后点 继续。
在你的定时任务所用的配置文件上,除非有人醒着来审阅,否则保持计划审阅关闭。
计划、提问、实时 diff、行评论和继续运行都是 Archyl 托管代理运行的一部分。上面提到的每项设置和界面文字,都可以在托管代理运行文档里找到。相关阅读:托管代理现在受 Harness 约束,介绍了这一切所依托的 Guard 和工作会话;以及托管代理运行的发布。