三次演进换的都是同一件事:把人搬运的颗粒度,从字符放大到任务。 补全时代搬的是几个字符,对话时代搬的是一段代码,委派时代搬的是一个任务。 颗粒度一变,「人管什么」就跟着变——从管打字,变成管验收。
这是全书的第一篇,先把位置摆清楚。前面 49 门课讲的多半是「某个东西怎么工作」—— SQL 怎么执行、TCP 怎么握手、FFmpeg 怎么解码。 这一门讲的是「你怎么用它」,而且用的东西本身还在变。 教材第 1 章四节,从历史讲到哲学: 三次演进、为什么它是交付工具、心智模型怎么转、规则为什么比聪明重要。 这四节合起来回答一个问题:凭什么说它不一样。 沙箱里没有装 Codex, 所以这一章几乎没有「跑命令」的内容—— 但它有一个自己能做的实验:把一个真任务,用三种颗粒度各做一遍,量轮数。 配套:22 课 Harness 技术架构原理。 那一门讲这套东西内部怎么转,读完再回来读这一章,会顺很多。
一、第一次演进:补全一个 token
最早的那一代,干的事只有一件:猜你下一个要敲什么。你在编辑器里敲了 for (int i = 0; i,
它把 < n; i++) 灰字摆在你后面,按 Tab 收下,不按就继续敲。
它的视野就是光标前后那几十行,而且它不执行、不验证、不记得上一次。
你让它写一个函数,它写完就完了——
这个函数在别处有没有同名、调用它的地方会不会挂,它完全不知道,也不负责。
这一代的价值是真的:样板代码、重复的 getter、见过一万遍的正则,敲三个字符就能出来。
但它解决的是「打字太慢」,不是「活儿太多」。
这两件事经常被混为一谈——打字快十倍,不等于交付快十倍。
二、第二次演进:选一段再对话
第二代把「上下文」这件事交给了人:你选中一段代码,在旁边说一句话,它改这一段。
选中范围就是它的世界观——你选了三行,它只知道三行。
这一代最大的进步是「能理解意图」:你说「这段改成提前返回」,它知道要把嵌套的 if 拆平;
你说「这个循环太慢」,它知道要换个写法。补全做不到这个——补全只能接续,不能改写。
但它把搬运的活儿留给了人。
它给你一段新代码,你得自己复制、自己贴回去、自己对齐缩进、自己去别的地方看看有没有跟着改。
一段代码改六个文件,就是六次复制粘贴——机器没累,人累了。
还有一个隐性的坑: 它改的是你贴过去的那一段文本,不是你仓库里的那个文件。
所以你贴回去的时候,如果原文件在你选中之后被别人改过,你就把它覆盖了。
这一代工具没有「文件」这个概念,只有「文本」。
三、第三次演进:把任务交出去
第三代换了个单位:不是「一段代码」,是「一个任务」。你给的不是代码片段,
是一句需求加上一个仓库;它自己去读文件、自己改、自己跑测试、自己把结果拿回来。
这一代跟前面两代的分水岭是「它有了手」。
补全只有嘴(给你文字),对话也只有嘴(给你代码),
委派这一代有手——它能读文件、能写文件、能跑命令、能看命令的输出。
手一有,「验证」这件事就不需要人代劳了。
但手一有,风险也就来了。
它能在你仓库里删文件、能 git push、能连数据库。
前两代顶多给你一段错代码,这一代能给你一个错状态。
所以第三代工具的全部设计重心,最后都落在「护栏」上——这也是本书后半本的主题。
顺带说一句名字的事。
「智能体」这个词被用得很泛,做客服的、做流程自动化的都叫智能体。
这一课里说的智能体,特指「能在一个代码仓库里自主完成一次改动的程序」——
它有三个硬条件:能读、能改、能验证。
四、三次演进换的到底是什么
| 代际 | 单位 | 它的视野 | 人管什么 |
|---|---|---|---|
| 补全 | 一个 token | 光标前后几十行 | 管逻辑、管结构 |
| 对话 | 一段选中 | 你选中的那段 | 管搬运、管一致性 |
| 委派 | 一个任务 | 整个仓库 | 管验收、管边界 |
注意最后一列的变化:人管的东西在往后退,但没有退到零。 补全时代人管逻辑(因为机器只管接续);对话时代人管搬运(因为机器不知道文件在哪); 委派时代人管验收(因为机器会自己说「我做好了」)。 「人管验收」这件事是退不掉的。 因为验收的定义是「符合我的意图」,而意图在你脑子里—— 机器再强,也没法替你确认它做的是不是你想要的。 这不是能力问题,是位置问题。 所以这一课真正要练的,不是「怎么让它更聪明」,是「怎么把意图写清楚、怎么验证它做到了」。 后面每一章,说到底都在练这两件事。
五、动手 Demo:同一个改名任务,三种模式各要几轮
「三次演进」这种说法最容易变成空话。所以这个 Demo 不举例子,直接造一个真项目: 一个函数,六个调用方,然后要求「把函数改名」——改动点分散在七个文件里。 三种模式各做一遍:补全式(只改光标所在的那个文件)、对话式(一次一个文件)、 委派式(一次全改)。量三个数:人的轮数、改动的文件数、验收结果。 为什么要挑「改名」? 因为它是重构里最典型的一种:单点改动、多点牵连。 这种活儿最能看出颗粒度的差别——补全的视野根本够不着别处。
# fmt.py:一个函数
def ts(sec):
return "%.2fs" % sec
# m1.py ~ m6.py:六个调用方,都是这一句
from fmt import ts
def run():
return ts(1.25)
# check.py:逐个导入并调用,任何一处断链就退出码 1
for i in range(1, 7):
try:
importlib.import_module("m%d" % i).run()
ok += 1
except Exception as e:
print("m%d 失败 %s" % (i, msg))
fail += 1
实跑输出:
--------------------------------------------------------------------
同一个改名任务,三种模式各要几轮
--------------------------------------------------------------------
① 先造一个真项目:一个函数,六个调用方
--------------------------------------------------------------------
fmt.py 一个函数,m1~m6 六个调用方,check.py 挨个跑一遍。
现在跑:通过 6 / 失败 0
! 六个调用方都正常,这是起点。
② 任务:把 ts 改名成 fmt_ts(六个调用方都得跟着改)
--------------------------------------------------------------------
改名是重构里最烦的一种——改动点分散在七个文件里,漏一个就断链。
③ 模式 A:补全式——光标在哪儿就改哪儿
--------------------------------------------------------------------
只改了 fmt.py,跑 check.py:
m1 失败 ImportError: cannot import name 'ts' from 'fmt'
m2 失败 ImportError: cannot import name 'ts' from 'fmt'
m3 失败 ImportError: cannot import name 'ts' from 'fmt'
m4 失败 ImportError: cannot import name 'ts' from 'fmt'
…
通过 0 / 失败 6
六个调用方全断——因为补全的视野就是光标附近那几行,它不知道还有六个文件在 import 这个名字。
人的补救办法是:自己 grep 一遍、自己逐个改、自己再跑一遍。
这一步的轮数算在人头上,不叫「机器没做到」。
④ 模式 B:对话式——一次贴一个文件
--------------------------------------------------------------------
一轮改一个文件,六轮改完六个调用方,第七轮验:通过 6 / 失败 0
结果是对的,但每一轮都要人复制、粘贴、切回编辑器——机器没省下这件事,只是把打字换成了点击。
⑤ 模式 C:委派式——一次把任务交出去
--------------------------------------------------------------------
一次改完七个文件,一轮验收:通过 6 / 失败 0
⑥ 三种模式摆在一起
--------------------------------------------------------------------
| 模式 | 人的轮数 | 改动文件 | 验收结果 |
|---|---:|---:|---:|
| A 补全 | 7(自己补六处) | 1 | 失败 6 |
| B 对话 | 7(六贴一验) | 7 | 通过 6 |
| C 委派 | 2(一交一验) | 7 | 通过 6 |
轮数是这么算的:A 与 B 每改一个文件都算一轮(人必须介入一次),C 把六处改动折进同一轮。
注意 C 的「2」不是「不用人」——人要写任务、要看 diff、要跑验收。省掉的是逐处搬运,不是审阅。
! 三次演进换的其实是同一件事:把「人搬运的颗粒度」从字符放大到任务。
模式 A 的结果最关键:只改了定义,六个调用方全断。
这不是「模型笨」——
补全的视野就是光标附近那几行,它没有任何办法知道还有六个文件在 import 这个名字。
人的补救办法是:自己 grep 一遍、自己逐个改、自己再跑一遍。
这三步是「补全模式」的隐性成本——它不写在工具的说明书里,但每次重构都得付。
模式 B 是对的,但轮数是 7。
一轮改一个文件,六轮改完,第七轮验。
每一轮都要人复制、粘贴、切回编辑器——机器没省下这件事,只是把「打字」换成了「点击」。
模式 C 是 2 轮:一交一验。
但别把这个 2 读成「不用人」——人要写任务、要看 diff、要跑验收。
省掉的是「逐处搬运」,不是「审阅」。
这两个数(7 和 2)的差距,就是三次演进真正卖掉的东西。
30 秒实验
- 把你手上的一个真实改动拆开数一数:它动了几个文件、几处地方? 如果超过三处,那就是「委派式」的活儿——用对话式做,你会把时间全花在复制粘贴上。
- 试着只用补全做一次跨文件改动,看看你能坚持多久。 大多数人做到第三处就开始用 grep 了——那一刻你就知道「视野」这件事有多要紧。
- 找一段你写过的代码,问自己:如果交给一个只能看这一个文件的人改,他能改对吗? 答「不能」的地方,就是需要「整个仓库视野」的地方。
常见误区
- 「补全不就是小一号的智能体吗?」 不是。 补全没有「文件」概念,也没有「验证」能力——它连自己写的东西能不能跑都不知道。 这三样缺一样,就还是前两代。
- 「模型变强了,就不需要人验收了。」 验收不是能力问题,是位置问题。 「符合我的意图」这件事,只有你能判断。 模型再强,也只能保证「代码能跑」,保证不了「这就是我要的」。
- 「三次演进是替代关系,新的把旧的淘汰了。」 不是。 今天你打字时仍然在用补全,改一个小地方时仍然在用对话。 三者是叠加的,按「改动的影响面」选。 影响面小就用小的,别拿大炮打蚊子。
自测三问(点开对答案)
1. 补全、对话、委派三代,最本质的差别是什么? —— **有没有「手」。** 前两代只会产出文字,第三代能读文件、能改文件、能跑命令看结果。 **手一有,「验证」就不用等人了**——但风险也跟着来了。 2. 为什么说「人管验收」这件事退不掉? —— **因为验收的标准是「符合我的意图」,而意图在人的脑子里。** **工具能保证代码能跑,保证不了这就是你要的。** 这跟模型多强没关系。 3. 一个改动动了七个文件,你该用哪种模式?为什么? —— 委派式。 **跨文件改动的成本全在「一致性」上**—— **补全和对话都要人逐处搬运,漏一处就断链;委派能让它一次看全,人只审一遍 diff。**下一篇 1.2 往下问一层:既然它换的是「交付」,那「交付」到底比「给代码」多了什么? 答案是四样证据——变更、验证、留痕、可回滚。
- ☐ (本篇完,下一篇 1.2 为什么 Codex 是软件工程交付工具)