afk 是 away from keyboard 的缩写,意思就是「人离开键盘了」。
这个技能的名字起得很直白。它就是让我离开键盘之后,活还在继续干的那个东西。我把一批 GitHub issue 准备好,一句话扔给它,然后该干嘛干嘛。等我回来,每个 issue 的功能都已经写完、跑过测试、自己截图自证,合进了一条专门等我 review 的分支。
它是我开源技能包 vstack 里的一个技能。上一篇我讲了整套流程,怎么把需求想清楚、怎么拆成一个个开发包。afk-agent 接的是最后那一棒:拆好的活,怎么真正交给 AI 做完。这篇就专门讲它。
先看一个真东西:购物清单 demo
光说不练没意思。我专门建了一个演示仓库 shopping-list-demo,从头到尾就是用 afk-agent 跑出来的。
它是一个单页购物清单 App,能添加要买的东西、勾选已买、删除、筛选、看统计、行内改名字和数量。技术栈很轻,后端 Node 加 Express,数据库用 SQLite,前端一个原生 HTML 页面,没有任何构建步骤。

整个 App 的功能,被拆成了 6 个 issue:添加、勾选已购、删除、输入校验加移动端、筛选统计、行内编辑。每个 issue 都是 afk-agent 独立做完的,一个 issue 对一个 PR,6 个 PR 全部合进同一条批次分支。

这不是我挑出来给你看的成功案例,是这个仓库本来就长这样。你点进去,6 个 issue 全是 CLOSED,6 个 PR 全是 MERGED,每个 PR 和 issue 下面都贴着它当时的执行记录和自测证据。
这些 issue 也不是我手敲的。它们是从一份 PRD 拆出来的,PRD 又是我先跟 AI 把需求聊清楚之后,让它整理成文的。这是上一篇的活,这里只放一眼,让你知道喂给 afk-agent 的「料」长什么样。

它分成两半,一半只看,一半才动手
afk-agent 最让我放心的地方,是它把「看」和「动手」彻底分开了。
第一半是扫描器,只读,绝不碰任何东西。 它做的事就是把仓库里所有 issue 读一遍,挑出那些「准备好交给 agent」的,算清楚它们之间谁依赖谁、该先做哪个,然后给出一份计划。它自己绝不推送代码、绝不评论、绝不改 issue。纯看,纯算,纯给计划。
下面这张就是它算出来的计划:哪几个 issue 能并行、哪个卡在哪个后面、整批大概要跑多久,一目了然。事后回头看,它估的时间还挺准。

第二半才是真正动手的执行 agent,也就是 Claude 或者 Codex 本身。它拿着那份计划,一个一个 issue 往下推:认领、写代码、自测、勾选验收项、开 PR。
这么分有个好处,计划这一步是透明的、可预期的。我能先看到它打算怎么干、按什么顺序干、哪些 issue 因为还没满足条件被挡在外面,然后才让它真的开始动。
一个 issue,从开始到合并的完整一生
这是 afk-agent 的核心。我拿「输入校验与移动端布局」这个 issue(仓库里的 #5)走一遍,它实际就是这么跑的。
开工之前,一个 issue 长这样:上半部分写清楚「要构建什么」,下半部分是一串还没勾选的验收标准,每条前面标着 L1 到 L4 的级别。这就是 afk-agent 的输入,一个定义清楚、能验收的开发包。

第一步,认领。 agent 先给这个 issue 打上 agent-claimed 和 agent-in-progress 标签,发一条认领评论,把这次运行的编号、用的分支、打算怎么验收都写下来。这一步是个锁,告诉别的 agent「这个我接了,你别碰」。因为 afk-agent 可以两个 issue 并行做,这个锁防止撞车。

第二步,TDD 写实现。 这一步没有截图,因为它就是闷头写代码的过程,没有可看的界面。但它写代码的方式有讲究:不是上来就写功能,而是先写一个注定失败的测试。比如 #5 第一个失败的测试是「那个还不存在的校验模块,import 进来就该报错」,然后再写最小的代码让它变绿。一个验收项一个验收项地推,红、绿、红、绿,一直到 17 个测试全过。
边界条件它也不放过。名称 50 个字符要能成、51 个就得拒,数量 1 和 99 要能成、0 和 100 就得拒。这些坎它一个一个写成测试卡死,省得功能「差不多对」就蒙混过去。
第三步,自动验收。 代码写完、测试全绿之后,它还要逐条核对验收标准,每一条都附上对应的证据。这步是重点,下一段单独讲。

第四步,勾选加收尾。 只有验收通过,它才会回到 issue 上,把通过的那几条 - [ ] 勾成 - [x],然后开一个自动合并的 PR 合进批次分支,最后再贴一条完成摘要:PR 去哪了、勾了几条、还剩哪条没勾、测试过没过、花了多久。

这一整趟,#5 花了大概 7 分钟。
每一步都留痕:这些记录是给人看的
你可能注意到了,上面认领、验收、完成这几步,afk-agent 都没有闷声做完,而是在 issue 下面一条一条写评论。
这是我特别看重的一点。这些评论不是给 agent 看的,是给人审计用的。 每一步干了什么、用了哪条分支、哪个测试覆盖了哪条验收、截了什么图、最后为什么勾选或者为什么不勾,全有记录,时间顺序排得明明白白,中文写的,人能读。
我离开键盘的这段时间它干了啥,回来翻一遍评论就全知道了。出了问题,也能顺着这条记录倒查到是哪一步、哪条验收没过。它不是一个「黑箱里吐出一堆代码」的东西,是一个边干边交代、留得下痕迹、回得了头的代码流水线。
最关键的一招:验收证据分四级
我敢放手让它干,靠的就是这一条:每一个验收标准,它都得拿出对应级别的证据来证明做到了,证明不了就算失败。
它把证据分成四级。
L1,代码级。 用 grep 或者 AST 在代码里找到对应的东西。比如「校验模块独立存在」,它就去代码里把那个模块、那几行规则定义抓出来给你看,精确到第几行。
L2,测试级。 跑自动化测试。比如「空名称返回 400」,它指给你看是哪个测试用例覆盖了这条、跑没跑过。
L3,浏览器级。 这条最实在,用无头浏览器真的打开页面、真的操作一遍、截图。比如 #5 要求「375px 手机宽度下单列布局能正常用」,它就把浏览器调到手机尺寸,截下这张图:

这张截图不是贴个本地路径敷衍了事,它是被真正提交进代码分支、再内嵌进验收报告里的。我在 GitHub 上点开就能看到。做不到这一点,这条 L3 就判失败,跟其他失败一样对待。
L4,人工级。 有些东西机器没法判断,比如「真机上单手操作的触控手感顺不顺」。#5 里就有这么一条:创始人得在真手机上走完「添加 → 勾选 → 清除」全流程。这种它绝不自己勾,老老实实留在那里、标明白「这条等人工」,然后告诉我。
所以你看 #5 的完成摘要,它勾了 6 条、留了 1 条没勾——留的那条正是 L4。四级一分,事情就清楚了:能自动证明的,它自动证明;证明不了的,它不装懂,把判断退回给我。
它也会处理「不那么标准」的现实
#5 只是 6 个切片里的一个。其余几个该并行的并行、该排队的排队,afk-agent 一样一条一条推完。
比如筛选这种带交互的功能(#6),它会把切换标签前后的状态都截下来对比:

仓库根目录还能放一个 .afkignore 文件,写法跟 .gitignore 很像。你把某些标签写进去,带这些标签的 issue 就会在最前面被挡掉,计划里看得见,但不会被认领、不会被动。那些其实还得人来处理的活,比如带着 ready-for-human、needs-info 标签的,就别让 agent 瞎接。
一条它永远不会越过的线
这是我觉得这个技能最克制、也最重要的设计。
它绝不把 PR 开到 main,也绝不自动并进 main。
它所有的 PR 都只合进一条临时的「批次分支」。6 个 issue 做完,就是 6 个 PR 攒在这一条分支上。从这条批次分支到 main 的最后一步,永远是我自己来。
换句话说,agent 负责把一堆零散的活,推进成「一坨等我拍板的东西」。但拍板这一下,它不替我做。该它干的全干了,该我管的它一点不抢。
怎么用
如果你也想试,最简单的就是在目标仓库里直接喊它:
/afk-agent它会先扫描、把计划摆给你看,确认之后再执行。
想只看不动,就用 /afk-agent scan,纯产出计划,一行代码都不碰。想盯着某一个 issue,就 /afk-agent plan #5。
它也是个能单独跑的命令行脚本,在仓库根目录:
node ~/.codex/skills/afk-agent/scripts/scan-ready-issues.mjs加 --json 出结构化结果,加 --self-test 自检。这些都是只读的,跑多少遍都不会动你的仓库。
写在最后
我学 AI 编程才半年,不会写代码。但用下来我越来越觉得,AI 干活靠不靠得住,关键不在它多聪明,而在你有没有给它一套「干完得证明给你看、每步还得留下记录」的规矩。
afk-agent 对我来说就是这套规矩本身。需求想不想得清、活拆得对不对、最后这一版要不要、敢不敢上 main,这些判断全在我手里。它只管一件事:把我拆好的活老老实实做完,每一步留好痕,并且证明给我看。
我离开键盘,活还在干。这就够了。
演示仓库:github.com/vshen009/shopping-list-demoafk-agent 是开源技能包 vstack 的一部分:github.com/vshen009/vstack
夜雨聆风