现在到处都在说 AI 加快了开发速度,我自己也确实省下了不少时间。以前要写一下午的代码,现在半个小时就能出来。但最近我遇到一个相反的情况:越是时间紧、改动麻烦的活,我越觉得它慢。
最近一次上线前修 Bug,时间很紧,改动又麻烦,我照例把这个任务交给了 AI。它跑了四十多分钟,还没有结束。
这段时间我只能盯着它的输出。我想打断它,问一句方向对不对,又不敢,怕一打断,它攒下来的上下文就散了,等于白改。最耗时的是它压缩上下文:上下文太长,它需要先压缩一次才能继续,每次大约五分钟。这五分钟里它没有任何输出,我站起来在电脑桌前来回走,手上却没有一件能做的事,只能等它压缩完。
等它终于把活交出来,已经过了一个多小时,改出来的结果我仍然不满意,又要再来一轮。
坐在这段空白里,我最在意的不是它改得对不对,而是我又冒出了新想法,却一个也试不了。它们全堵在嗓子眼里,要等 AI 做完当前的修改才轮得到我说。
这篇文章就来聊这个现象:一个确实让代码写得更快的工具,为什么会让我觉得慢,以及我做了哪些改进措施。
我关注的不再是写代码的速度
一开始我以为是自己感觉出了问题。后来发现,问题不在感觉,而在于我关注的东西已经变了。
AI 写代码比我快,这件事没有争议。以前这些活都是我自己写,写一段、测一段、再写下一段,速度是我首先要解决的问题。现在它写代码已经很快,这一段不再构成瓶颈,再拿它跟人比写代码的速度,已经没有意义了。现在真正要比的,是它写代码的速度能不能跟上我思考的速度。
这种情况在任务很复杂,需要我在中间做判断时,特别明显。我冒出一个念头只要一秒,AI 把这个念头做出来至少十分钟。我心里已经往前走了好几步,它还在做第一步。
"AI 让我感觉慢"就是从这里来的。说它快,指的是吞吐,也就是单位时间里能产出多少代码和改动,这一点没有争议;说它慢,指的是我收到反馈的时间,也就是从我想清楚一件事,到它实现后给我反馈之间的时间。以前这些活我自己做,思考是连续的,想一段、写一段、再想下一段,中间没有断层;现在中间插进来一大段我看不清它在做什么、又不敢走开的空档,吞吐上去了,我拿到反馈的时间反而更长了。
为什么等待会打乱思考
我一度以为,等 AI 干活和等编译差不多,顶多几十秒,喝口水就过去了。
但 AI 不是编译。一个改动动辄十几分钟、几十分钟,而且它不像编译那样有一个明确的结束信号。也就是说,你在等的不是一个结果,而是一个不知道什么时候才结束的过程。
等待的代价不只是耗掉的那段时间。人能做事的最小单位,不是一分钟,也不是一小时,而是一段不被打断的连续时间。这段时间被切开,手上的这件小事就做不成,只能留到下一次。AI 干活的时候,这段时间并不真正属于我:它随时可能需要我介入,确认一个方向,选一个分支,或者判断一段它拿不准的代码。这一介入,就把我手上的连续时间打断了,于是我手上有事,也不敢真正开始。
心流的意思就是,念头一个接一个地冒出来,你顺着往下做,中间没有断层。AI 的工作方式恰恰相反,它在每个念头和你之间,塞进了一段你插不上手、又不敢走开的等待。
等一两次还好,等成了常态,思考的节奏就变了。你不再顺着一个念头往下跑,因为你知道跑到一半就要停下来等它。慢慢地,你连顺着想下去的习惯都不敢留,学会的是把每个念头压成一句需求扔过去,然后等。念头还是那些念头,只是都变成了排队等它处理的任务。
空等本身还会加重这种感觉。人在等待的时候很难安静下来,越无聊越容易冒出新的想法,想法一多,它就显得更慢;等得越久越烦躁,烦躁又让这段时间显得更长。
两种等待
等 AI 这件事,我试过两种用法,都不舒服。
第一种是把它当成外包。我把活丢过去,它闷头跑,一个多小时不回话,这段时间我插不上手,只能干等。
第二种是把它当成一个随时能改的助手。我一直在和它对话,不断给指令、不断调整方向。这种用法里我一直在说话,它一直在回话,节奏看上去在我这边。实际上被绑住的是我,一刻也走不开,人比它还累。
这两种用法看起来相反,问题却出在同一件事上:这段协作的节奏不在我手里。
我期望的是,我出一个念头,它很快跟上一个结果,快到我不需要为了它去调整自己的节奏。
现实里的节奏掌握在模型执行那一侧。它跑完一个完整的周期,十几分钟甚至一个小时,才轮到我发一次言。在这个周期里,我只能旁观。更糟的是,它为了保住自己的上下文要压缩一次,这个过程里我连它此刻在做什么都看不清。明明是我在用 AI,最后却变成我在迁就它的记忆节奏,不敢打断它,怕它忘,它压缩的时候我陪着一起等。
也就是说,我的思考速度被硬生生拽到了它的执行速度上。前面说的那种慢,就是从这儿来的。
图:三条时间线,差别不在 AI 快不快,在 AI 有没有按我的时间块交接
我做了哪些改进措施
想明白这件事之后,我改了用法。这里的解法不是让它每走一步都停下来等我确认,那样等于把一次长等待拆成几十次短等待,问题并没有解决。我真正改的是三件事。
首先是计划先于代码,而且计划要随时可改。改计划比改代码快得多,计划是我能即时编辑的东西,代码不是。所以我把等待的焦点从代码挪到计划上。只要计划是我先定的,它在执行里偏了,我也能在代价还小的时候叫停,不必等它跑完一整段才返工。这套办法并不是为 AI 想出来的。我在几年前写 trampoline 时总结过同一件事:先计划、再执行、必记录,只是那时候计划、执行、记录的都是我自己(《Trampoline在生活中的一些思考》)。
其次是让它按计划自己跑,不用每走一步都等我点头,但它必须持续更新进度。不打断它,它自己的上下文才不会散;进度看得见,我才敢走开去做别的事。进度一旦是连续的,这件事就随时可以停,停了也能从当前进度接着跑,我不再被它锁在电脑前面。
最后是能并行就并行,但要控制并行的数量。单条链路的等待逃不掉,那就把几条改动同时铺开。但不能假设自己能同时盯好几路。我一开始也以为并行就是解放,多开几个任务,我这边看看进度就行。真试过才发现,人脑是单线程的,每切一路都要把注意力从一个上下文里硬拽出来一次,切多了疲惫感上来,错误也跟着来。并行能提速的前提,是我一次只盯得住一路。
这三条我已经做成了能反复使用的机制,都收在 gg-daily-workbench 这个仓库里。落到具体工具上,配合关系看下面这张图就够了,这里只讲思路。计划先行的活交给 plan-development-task,执行交给 execute-plan,跨功能跨仓库的大活让 orchestrate-feature-delivery 一步一步拆开,拿不准的部分先派 conduct-spike 去探路。
名字不重要,真正要做的,是把长执行换成随时能停、随时能接着跑的小块,并且让每一块的进度都看得见。做到这一点,等待就不再是一整段插不上手的空档,而是一小段一小段、由我决定什么时候接手的间隔。
图:先定计划,让它按计划自己跑,进度持续更新,随时能停、也能从当前进度接着跑;并行可以铺开,但一次只盯得住一路,最后我才验收
绕不开的一件事:还得负责
我原本以为,改成这样我就不用再守着它了,实际用下来并非如此。
执行可以交出去,计划可以攥在手里,进度也看得见,但有件事绕不开:最后要替这些代码负责的人是我。只要责任在我,它每出一版,我都得回去看,回去验,回去判断对不对、改不改。这本身就是一次上下文切换,就是一段新的等待。前面说它半个小时就能把代码写完,我却要花一天做测试和 review,花的就是这个时间。它写得再快也省不掉这一段,因为省下来的那些,最后还是得由我来验。
也就是说,我改的这些做法让等待变得可停、可续、变短了,但等待并没有消失。它只是从空等一整段,变成一段我可以随时走开的等待。心流依然很难圆满,因为心流要的是完全不中断的连续,而负责这两个字,天然要求你不断回到它那里去确认。我也试过干脆不看了,但把一版没验过的代码推上线,我还是做不到。
想通这一点,我也就明白自己折腾这些机制是为了什么。我做的这些事没能让我回到过去那种纯粹的心流,但它让我在等不起这个现实里,从被 AI 锁死,变成随时能接管,随时能切换到其他上下文。这已经比干等强太多,但它不是终点。
所以这个慢,光靠改用法治不掉。真正的终点不在我这边的用法上,而在责任结构上。我之所以必须一次次回去验收,是因为最后要为这些代码负责的人是我。human in the loop 和 human on the loop 该怎么搭,人为什么要走出回路,我在另一篇《我们说的"提升AI能力",到底在提升什么》里已经讲过。这里只补那篇没有点破的一层:人该从每次亲自把关的回路里退出来,改成去设计那个能自动把关的回路。
真正把一个人钉在 in the loop 里的不是习惯,是责任:只要你还为 AI 的每一行代码负责,你就必须一次次回到环里验收。
这件事换成管理上的说法,会更容易理解:我把 AI 当员工用,员工没法随时找我确认,我也不敢把活交出去就完全不管。两头都难受,不是因为谁不努力,而是确认和不放心的成本都落在我一个人身上。管理上早就给过答案:定目标、定标准、定检查点,而不是每一步都请示,也不是撒手不管。
理想的状态是人只对产品负责,只负责让 AI 表现更好,把代码的责任交给验证体系。这个验证体系不是没人管,而是把反馈器从我换成工具和另一个 AI。工具守硬边界,构建、测试、依赖检查这些没得商量的事交给它;AI 做软判断,代码写得对不对、影响面有多大交给它;我退到最上层,只定标准、处理边界情况,再让这套东西本身越用越好。
到那一天,责任从代码上挪走,那个把我拉回 AI 节奏的环才会松开。我不再要求它做到实时响应,那对长任务本来就不可能;我要求的是它的交接对得上我的时间:我离开多久,它就自己跑多久,等我回来,它正好把一段结果交到我手上。到那时候,慢的体感才有真正消失的可能。
现在回头看开头那次 Bug,我等了一个多小时,不是因为 AI 不够快,而是因为我把它的代码当成了我的责任。那么这个责任,我们到底什么时候才肯交出去?
图:只要责任还在代码上,我就得一次次回到环里验收;责任挪到产品和让 AI 变好上,环才松得开