先把现象讲清楚
过去几个月,越来越多一线工程师公开承认,自己手写代码明显变少了。Andrej Karpathy 在 2026 年 1 月被广泛转述为“mostly programming in English”;Steve Yegge 在 2025 年 3 月和 6 月的两篇长文里,已经把软件工程师的新工作描述成“少直接编码,多管理和监督 agent”;OpenClaw 作者 Peter Steinberger 到 2025 年底更进一步,甚至明确写到自己很多代码已经“不怎么看了”,关注点转到了结构、组件和整体设计上。
如果只看表面,很容易把这件事理解成一句很刺激的话:程序员以后不写代码了。这个说法当然抓人,但它只抓到了变化的壳,没有抓到变化的骨架。
真正发生的事,是软件工程里最稀缺的部分在迁移。以前最贵的是“把想法稳定翻译成代码”,现在这部分成本正在快速下降;而问题定义、边界控制、结果验证、风险审计和长期维护,依然没有一起变便宜。
这不是“AI 替代写代码”,而是“代码本身没那么稀缺了”
Simon Willison 讲得很准:代码正在变便宜,但好代码没有一起变便宜。今天你让 agent 生成几百行、几千行初稿,已经越来越像一件廉价的事;真正还昂贵的,是那些以前被手写代码速度遮住的部分。
比如这段代码是不是在解决对的问题,边界条件有没有兜住,错误路径是不是能解释,未来两周改需求时会不会直接散架,出现事故后能不能快速定位和回滚。AI 可以显著降低“敲进去”的成本,却不会顺手替你把这些成本一起抹掉。
所以如果还把软件工程的核心理解成“谁更快把功能写出来”,判断已经落后一层了。更贴近现实的说法是:实现正在自动化,责任正在上移。
为什么是这些人先敢放手
Karpathy、Yegge、Peter Steinberger 这类人,真正领先的地方未必是更会写 prompt,也未必是更敢赌模型。他们敢把越来越多实现工作交给 agent,通常是因为下面几件事抓得更牢。
第一,他们脑子里本来就有很强的系统模型。agent 吐出一堆代码后,他们未必逐行欣赏,但很快能判断这次修改有没有碰坏模块边界、状态流向和依赖结构。
第二,他们默认把 AI 产物当成高产但不稳定的初级合作者,而不是把它当成可以无条件信任的高级工程师。Peter Steinberger 在 2025 年底的公开文章里写得非常直接:他的产出速度越来越像“受推理时间和硬思考时间限制”,而不是受打字速度限制。这里最重要的不是“他不读代码”这句表态本身,而是他已经把关注点切到了系统设计、依赖选择和整体结构。
第三,他们通常已经接受一个事实:AI 给出 70 分初稿,很多时候就足够进入工程流程了。剩下的 30 分,靠验证、回归和关键点审查来收口,而不是继续沉迷于让模型一次性长出 100 分答案。
这也是为什么外界最容易学错姿势。很多人只看见“他们手写得更少”,没看见他们对系统质量的掌控其实更强了。
真正迁移的,是软件工程的主战场
我越来越倾向于把这轮变化概括成一句话:软件工程的中心,正在从“写”迁移到“定义、约束、验证、审计和演化”。
以前我们对工程师的想象,往往是他坐在编辑器前,把一个想法一点点雕成程序。现在越来越多现实工作会变成另一种样子:人先定义任务边界和验收标准,agent 负责生成、重构、补测试和跑流程,机器负责先过滤掉低层错误,人最后对关键风险负责。
这个分工变化看起来像只是工作流升级,其实是价值链重排。因为一旦代码生成足够便宜,团队就不该再把最贵的人力放在“亲手敲每一行”这件事上,而会更多放在下面这些问题上。
- 需求是不是写成了可执行、可判断、可拒绝的规格。
- 工具和依赖是不是被限定在安全边界里。
- 自动化验证是不是足够覆盖关键路径。
- 变更出了问题时能不能快速追到责任点。
- 这次改动会不会给下个月的维护埋一颗雷。
未来优秀工程师当然还会写代码,但更关键的工作已经不只是写代码。
“100% AI 来写”如果要成立,必须先改写成工程目标
很多人现在会说,终局肯定是 100% AI 写代码。我理解这句话背后的方向感,但如果要把它变成团队能执行的目标,最好重写一下。
更稳、更专业的版本应该是:100% 的实现工作都可以委托给 AI,但 100% 的结果都必须可验证、可回滚、可审计。
这两句话差别很大。前一句像口号,后一句才像工程。
因为“AI 生成了多少代码”并不是质量指标。真正重要的是,每一次改动能不能拿到足够清晰的完成证据。OpenAI 现在官方文档里一再强调 eval-driven development、持续评测、trace grading,本质上也是在回答这个问题:面对一个概率系统,不能靠“感觉它大概对了”来运营生产软件。
如果把这件事再压缩一下,成熟团队最后会越来越像在跑这样一个闭环:
SpecAgentVerifyGateDeployObserveLearn
人最重要的角色,不再是每一步都亲手完成,而是保证这个闭环不会断。
把 Spec -> Agent -> Verify -> Gate -> Deploy -> Observe -> Learn 拆开看
如果只把这七个词并排写出来,它更像一句口号;可一旦放进真实团队,它其实对应的是七种不同职责、七类不同产物,以及七个最容易失控的地方。
先看一个总览图:
flowchart LR
S["Spec<br/>目标、输入、边界、验收"] --> A["Agent<br/>拆任务、读仓库、生成改动"]
A --> V["Verify<br/>编译、类型、测试、评测"]
V --> G{"Gate<br/>风险级别<br/>是否放行"}
G -->|通过| D["Deploy<br/>Staging、灰度、回滚"]
G -->|退回| S
D --> O["Observe<br/>日志、指标、反馈"]
O --> L["Learn<br/>回归集、规则、ADR"]
L --> S
这个闭环里,最常被低估的是前后两头。很多团队一上来就盯着 Agent,觉得模型够强就能直接起飞;真正把系统拉开差距的,往往反而是 Spec 是否清楚,以及 Observe 和 Learn 是否闭环。
Spec 不是写一段“帮我把这个功能做完”的自然语言愿望,而是把任务写成机器和人都能判断的规格。它至少要回答 5 个问题:目标是什么、输入输出是什么、不能碰什么、验收样例是什么、失败时谁来接手。没有这一步,后面所有 agent 的高产都只是高概率偏航。
Agent 也不只是“让模型开始写代码”。更成熟的做法,是让 agent 先做三件事:读上下文、拆子任务、说明计划。你需要知道它为什么改这些文件、为什么不用另一种实现、哪些部分它其实没有把握。真正好的 agent 轨迹,本身就该是一份可以被审查的工作记录。
Verify 是今天最容易被说轻、却最该被加码的一层。代码已经便宜了,验证没有。这里的任务不是“再看一遍”,而是让机器先把机器能确定的部分都做掉:能不能编译、类型过不过、契约有没有被破坏、关键路径测试是不是还绿。验证越自动化,人越能把注意力留给关键风险。
Gate 是把“可生成的东西”和“可上线的东西”分开的那道门。不是所有通过测试的改动都值得同样对待,也不是所有能跑起来的 agent 输出都值得同样信任。门禁的本质,是根据风险级别决定还需要什么证据、什么审批、什么灰度和什么回滚条件。
Deploy 在 AI 时代反而比以前更需要保守。因为 agent 会放大单次改动的范围,一次提交可能比过去人工一天的修改量还大。Staging、灰度、feature flag 和可回退发布,不再是“成熟团队锦上添花”的东西,而是 agent 真正进入生产前的安全阀。
Observe 负责回答一件很朴素的问题:上线之后,它到底按预期工作了吗。日志、trace、metrics、告警和用户反馈,不只是运维习惯,而是 agent 时代对概率系统做持续校正的基础设施。没有观察层,团队很容易把“没报错”误当成“没问题”。
Learn 则决定团队是不是在重复犯同一种错。一次事故如果只停在复盘会上,它只是情绪;只有当它被沉淀成新的回归测试、新的 lint 规则、新的审批策略、新的 ADR,它才真正变成了工程资产。
每一步到底应该产出什么
把这套闭环落到工程里,每一步最好都对应明确产物,而不是只对应一种模糊活动。
Spec 阶段,最理想的产物不是一段口头需求,而是一组可以复用的约束:
- 任务目标:这次改动究竟要优化什么指标、修什么问题、交付什么能力。
- 输入输出:入口数据、目标接口、预期输出、错误返回分别是什么。
- 禁止事项:不能碰的目录、不能新增的依赖、不能改变的兼容性边界。
- 验收样例:最少要有一个 happy path,一个异常 path,一个拒绝 path。
- 接管规则:agent 遇到哪类情况必须停下来等人确认。
Agent 阶段,团队真正需要的也不只是代码 diff,而是一份可追踪的执行记录:
- 它读了哪些文件、查了哪些上下文。
- 它为什么这样拆任务,而不是一次改完整个模块。
- 它改了哪些文件、没改哪些文件。
- 它跑过什么命令、失败过什么、重试过什么。
- 它自己对哪些部分是高置信,哪些部分只是猜测。
Verify 阶段,理想产物是一组分层证据,而不是一句“看起来没问题”:
- 静态证据:format、lint、type、schema 检查结果。
- 行为证据:unit test、integration test、contract test、smoke test。
- 风险证据:安全扫描、迁移预演、性能基线、权限检查。
- 运行证据:trace、关键日志片段、异常路径覆盖、失败样例。
Gate 阶段,最好把“谁说了算”变成显式规则:
- 哪些改动机器门禁通过即可进入 staging。
- 哪些改动必须有人审关键差异。
- 哪些改动必须业务 owner、安全 owner 或 SRE 额外批准。
- 哪些改动即使通过测试,也必须等灰度窗口而不能立刻全量。
Deploy、Observe、Learn 则是把“上线”从一个瞬间,改造成一段持续动作:
Deploy产出发布记录、灰度策略、feature flag 状态和回滚条件。Observe产出指标看板、异常告警、用户反馈和行为偏差记录。Learn产出新的回归集、规则调整、设计附注和团队约束更新。
一旦每一步都有明确产物,团队就更容易避免一种常见错觉:大家都以为自己做了某一步,但谁也拿不出那一步真正的证据。
决定自治级别的,不是模型强弱,而是风险分级
很多讨论喜欢把问题简化成“这个 agent 够不够强,能不能自己做完”。真实团队更该问的是:这件事值不值得给它这么多自主权。
可以先看一个更现实的分级图:
flowchart TD
T["任务进入"] --> R{"风险分级"}
R --> L["低风险<br/>样板、文档、测试"] --> A["Agent 直做<br/>机器门禁后可合并"]
R --> M["中风险<br/>业务逻辑、重构"] --> B["Agent 实现<br/>人工看关键差异"]
R --> H["高风险<br/>权限、支付、删除、迁移"] --> C["人工先设边界<br/>灰度与回滚必备"]
低风险任务适合让 agent 发挥“高产”的优势,比如脚手架、文档整理、测试初稿、重复样板、已知模式下的改写。这类任务更适合把目标定成“尽快给我一个 70 分起点”,而不是要求 agent 一次性交付完全成熟版本。
中风险任务开始进入业务逻辑、重构和跨文件修改。这里 agent 当然依然很有价值,但默认就不该再走“直接生成直接放行”的路径。更合理的是让它先做实现和初步验证,再把人的注意力集中到边界、抽象层级、异常路径和未来维护成本上。
高风险任务则不该再问“能不能自动完成”,而该先问“如果它错了,代价有多大”。权限、支付、删除、数据迁移、认证、对外副作用这类改动,本来就不是靠代码量决定风险,而是靠后果决定风险。越是这种区域,越需要人工先画边界,再允许 agent 在边界里工作。
这也是为什么“让 AI 写 100% 代码”如果没有风险分级,很容易沦为空话。真正成熟的团队不会争论 agent 能不能做一切,而会先决定哪些事值得让它放手做、哪些事必须带着安全绳做。
一套更现实的最小实践,应该细到什么程度
前面那 7 条最小实践,如果只写成 bullet,团队知道方向,却未必知道怎么落。真正能执行的版本,至少要细到“每一条对应什么动作、什么文件、什么门槛、什么回退”。
先看验证栈的层级关系:
flowchart TD
C["代码变更"] --> S1["静态层<br/>format、lint、type、schema"]
S1 --> S2["行为层<br/>unit、integration、contract"]
S2 --> S3["系统层<br/>smoke、perf、security"]
S3 --> S4["运行层<br/>trace、log、metrics、alerts"]
S4 --> D{"证据足够吗"}
D -->|否| R["退回 Spec 或 Agent"]
D -->|是| G["进入 Gate / Deploy"]
把需求写成机器可判断的验收标准,最细要细到“什么叫完成、什么叫失败、什么叫拒绝”。如果任务描述里只有“把登录体验优化一下”“把这里改顺一些”“让 agent 接管这个流程”,那 agent 得到的不是规格,而是解释权。更可执行的写法是:输入是什么、输出是什么、异常是什么、兼容性边界是什么、不能引入什么依赖、必须保留什么行为。好的验收标准通常不是一段长提示词,而是一组样例和断言。
把团队约束外显成 lint、类型、schema、测试、依赖策略和迁移规则,关键不是规则多,而是规则对机器可见。很多团队把约束藏在资深工程师脑子里,结果就是 agent 每次都在撞隐形墙。真正稳的做法,是把目录约定、命名约定、错误处理约定、接口 schema、数据库迁移规范、依赖白名单都写成检查器能看见的东西。对 agent 来说,显式规则越多,随意发挥的空间越小,返工成本反而越低。
按风险给任务分级,不同级别给不同自治级别,最怕的是“一把尺子量所有改动”。有的团队会犯两个相反错误:要么所有事情都必须人肉盯死,导致 agent 的产出优势完全被吃掉;要么所有事情都默认自动推进,最后把高风险改动混进普通工作流。真正成熟的做法,是为低风险、中风险、高风险分别配好不同证据要求、审批要求和发布要求。
让机器先审低层错误,让人重点审高风险差异,关键在于重新分配 review 预算。现在很多团队嘴上接受 agent,行动上还在按传统 review 惯性走,结果就是试图人工审完所有 diff,最后谁都很累,谁也没真正看到重点。更高效的做法,是让机器先过滤掉风格、类型、基础测试、静态扫描这一层,把人的审查时间集中到权限边界、数据模型、异常路径、并发语义和未来维护成本上。
默认保留 staging、灰度、feature flag 和回滚预案,不把 agent 直接连到不可逆操作上,这条最容易在效率焦虑下被跳过。可一旦 agent 能一口气改更多文件、生成更大 diff,回滚能力就不是锦上添花,而是基本工程礼仪。团队最好提前回答这些问题:这次发布能不能灰度、开关能不能单独关、数据库变更能不能回退、回退后会不会出现数据不一致。没有这些准备,就算 agent 当下看起来很快,团队也会在上线前本能地把速度全部抵消掉。
保留执行 trace 和验证记录,知道它看了什么、改了什么、为什么这样改,是为了让“事后复盘”不再靠猜。未来很重要的一类资产,不只是代码仓库,而是 agent 的执行轨迹。你最好能回答:它当时看了哪些文件、为什么没看另一些文件、哪一步验证失败过、为什么选择了现在这条实现路径。没有 trace,很多生产事故最后都会演化成“感觉它当时可能是这么想的”的集体推理游戏。
把每次事故沉淀成新的回归测试和新的门禁规则,才是真正把 agent 从“会干活的工具”变成“越用越稳的系统”。事故如果只是靠人吸收,下次还会再犯;但如果每次事故之后,你都补一个回归样例、补一条 lint 规则、补一个 schema 断言、补一个审批策略,那系统就真的会随着使用次数变得更可靠。很多 AI 工程团队后劲不足,不是因为模型变差,而是因为他们没有把错误转成资产。
把这些动作合在一起看,你会发现所谓“更现实的最小实践”,其实一点都不小。它更像是在重建一套适合 agent 时代的软件工厂,只是这套工厂的装配线不再以人工敲代码为中心,而是以规格、验证和风险分配为中心。
为什么普通团队暂时还很难复制
很多团队今天试了一轮 coding agent,结论往往会两极分化。有人觉得已经够用了,有人觉得一地鸡毛。这里面当然有模型差异,但更大的分水岭通常不在模型,而在仓库和流程本身是不是机器友好。
第一,很多代码库对 agent 极不友好。目录混乱、命名漂移、历史包袱太重、测试覆盖稀薄、文档长期失真。人类老员工还能靠记忆和上下文补足,agent 一进来就容易东撞西撞。
第二,很多团队还停留在“代码 review 等于人逐行看 diff”的旧习惯里。可一旦 agent 让代码量暴涨,这种审查模式物理上就撑不住。未来更现实的方向,是把人的注意力集中在权限边界、数据模型、错误路径、外部副作用和架构层级这些高风险差异上。
第三,很多组织没有把验证、灰度、回滚、追踪做成默认工程纪律。没有这些底座,AI 写得越多,团队越不敢放权;不敢放权,就会重新掉回“每一行都想靠人兜住”的疲劳工作流里。
所以真正拖慢 agent 落地的,往往不是模型不够聪明,而是工程环境还没准备好接这种委托关系。
一套更现实的最小实践
如果一支团队真想往“AI 写更多代码”这个方向走,我觉得至少该先把下面几件事做稳。
- 把需求写成机器可判断的验收标准,而不是一句模糊愿望。
- 把团队约束外显成 lint、类型、schema、测试、依赖策略和迁移规则。
- 按风险给任务分级,让不同任务拥有不同自治级别,而不是一把尺子量所有改动。
- 让机器先审低层错误,让人重点审高风险差异。
- 默认保留 staging、灰度、feature flag 和回滚预案,不把 agent 直接连到不可逆操作上。
- 保留执行 trace 和验证记录,知道它看了什么、改了什么、为什么这样改。
- 把每次事故都沉淀成新的回归测试和新的门禁规则。
这些动作看起来都不如“AI 一句话改完一个模块”有传播性,但它们才决定团队能不能从 demo 走到长期交付。
未来最值钱的程序员,会更像软件工厂的设计者
这篇文章如果要收成一句判断,我会写成这样:未来最强的程序员,不一定是手写代码最快的人,而是最会设计“AI 生成、机器验证、人类负责”这套系统的人。
Karpathy、Yegge、Peter Steinberger 这些人最值得看的,不在于“他们是不是已经彻底不写代码了”,而在于他们为什么敢把更多实现工作交给 agent。答案并不神秘:因为他们已经把注意力往代码之上的那一层移动了。
代码会越来越多地由 AI 生成,但软件能不能长期活着,仍然取决于人怎么定义问题、怎么约束系统、怎么做验证、怎么处理例外、怎么对关键风险负责。
从这个角度看,所谓“少手写代码”并不是软件工程在变浅,相反,它是在逼工程师进入更高的一层。谁先适应这一层,谁就更接近下一代工程师真正的核心位置。
还没有评论,你可以写下第一条。