ARTICLE · 1082701
AI 时代,回到软件工程本身
今天和 Claude Opus 5.5 聊了会,从软件工程的一些老问题,聊到 AI 时代工程师到底该做什么。聊着聊着,慢慢收敛成了这篇文章里的六个步骤。这些想法其实都不新,但放在今天,我觉得它们变得格外重要。
回头想想,技术的发展好像一直在做一件事:把底层一层层盖住,让人不用再直接面对那些很难懂的细节。最早大家写机器码,后来有了汇编,再后来是高级语言、操作系统、云平台。现在大多数工程师已经不太需要关心寄存器怎么分配、指令怎么编码了。
AI 大概是这条路上新的一层,只不过这一次,很多人直接面对的代码正在变少。写代码变得越来越容易,单纯产出代码的稀缺性在下降,工程判断的价值则相对上升。
那工程师还剩下什么呢?我自己的感受是,要回到软件工程最开始关心的那些事:想清楚要做什么,为什么这么做,边界在哪,做错了怎么办。这些东西不在代码里,所以也不太会被哪一层工具替代掉。
当然,底层总还是需要有人去深耕的,做基础设施的应该都有体会。只是对大多数人来说,重心可能会慢慢从“怎么写”,挪到“该不该写、写什么”上。
下面是我整理的六个步骤,算是给自己的一份备忘:
定义问题 → 摸清约束 → 权衡方案 → 划清边界 → 判断可逆性 → 落地对齐
一、定义问题
我们接到的需求,很多时候是以方案的样子出现的:“把网络换成 RDMA”“上一个虚拟化方案”“把这个模块重写一遍”。听起来像问题,其实已经默认了原因和解法。如果原因判断错了,方案做得再好,也解决不了真正的问题。
我比较喜欢的一个说法是:问题就是期望和现状之间的差距。定义问题的时候,可以依次问自己几个问题:
- 差距:
现在是什么样,希望是什么样,能不能量化? - 原因:
对方说的是症状、方案,还是问题本身?多问几个“为什么”。 - 相关方:
谁受影响,谁提的需求,谁来买单?大家对“解决了”的理解一样吗? - 代价:
不解决会怎样?为什么是现在? - 边界:
这次不解决什么? - 标准:
做到什么程度算解决,怎么验证?
最后,试着把问题写成一句话:
谁,在什么情况下,因为什么原因,遇到了什么差距,不解决会付出什么代价,解决到什么程度算成功。
如果这句话写不出来,大概说明还没到动手设计的时候。很多时候,问题一旦定义清楚,会发现最好的选择是不做,或者换一个问题来解。
在 AI 时代,这一步可能比以往都重要。AI 会放大规格说明中的歧义和错误:描述有偏差,它就可能更快、更大量地把错误的东西做出来。对 AI 来说,问题定义本身就是规格说明。
二、摸清约束
架构设计很少是在找最优解,更多是在约束里找一个可行的、尽量好的解。约束大致可以分成几类:
- 业务:
目标是什么,什么时候要上线 - 资源:
人力、预算、硬件 - 技术:
现有系统、版本、兼容性要求 - 组织:
谁来维护,团队能不能驾驭 - 合规:
安全和监管方面的要求
梳理的时候,可以区分一下硬约束和软约束。硬约束会直接淘汰一些方案,软约束则往往可以谈。很多看起来没解的局面,把软约束谈出一点空间,就松动了。
一个技术上很漂亮、但团队驾驭不了的方案,放在现实约束下,其实并不是好方案。
AI 能给出技术上可行的方案,但它并不了解你的预算、团队和历史包袱,除非你告诉它。约束的梳理,还是得靠了解现场的人。
三、权衡方案
遇到重要的决策,尽量比较两到三个方案,并且把“不做”或者“最简单的做法”也放进去。
比较的维度最好从目标和约束里来,比如性能、隔离性、维护成本、兼容性、风险,而不是泛泛地列优缺点。比完之后,试着用一句话说出核心的取舍:
选择 A,意味着放弃 B。
能说清楚为什么不选另外几个,才算真的想明白了选中的那个。如果从头到尾只有一个方案,那更像是一种默认,而不是决策。
现在 AI 可以在几分钟内给出好几个候选方案,权衡的成本低了很多。但哪个方案最适合眼下的约束,选错了又由谁来负责,这些还是需要人来判断。
四、划清边界
系统变乱,很多时候是因为边界不清楚:好几个组件都觉得自己说了算,状态冲突的时候又没有规则来裁决。有些看起来是实现上的 bug,追到根上,其实是边界的问题。
划清边界,大概要回答这几件事:
- 状态归属:
每一份关键状态归谁管,谁说了算? - 接口约定:
组件之间怎么交互,约定是什么? - 故障范围:
某个组件出了问题,会影响到哪里? - 责任划分:
哪些归我们,哪些归上下游、厂商或者使用方?
边界不只是技术问题,也是责任问题。“出了问题谁负责”这句话,在工程讨论里经常被当成推诿,但换个角度看,对方其实是在要一个边界。如果一个方案能讲清楚负责到哪一层、出了问题怎么定位、怎么回滚、怎么交给别人,它就更容易推得动。
除了边界本身,也值得把“不做什么”写下来。非目标写清楚了,方案才不容易越做越大。
AI 写的代码有一个比较常见的特点:在缺少统一上下文和约束时,局部看都合理,整体看却不太统一。每次任务都能给出一个看起来正确的实现,但它们未必遵循同一套边界和设计思路。代码越来越多由 AI 生成,守住边界这件事,也就越来越需要人的判断。
五、判断可逆性
决策大致可以分成两类:回不了头的“单向门”,和随时能退回来的“双向门”。每做一个关键决定,可以先问一句:如果错了,撤回来要付出多大代价?
- 可逆的决定:
可以快一点,边做边调。 - 不可逆的决定:
值得慢一点,先小范围验证,多听听意见,分步推进。
更有意思的是,很多单向门其实可以被改造成双向门:功能开关、灰度发布、加一层抽象、留好回滚路径。拿不准的时候,可以优先选可逆的做法。比如一个功能不确定该不该放进系统核心,可以先放在外围,成熟了再收进来。进去容易,出来难,这两个方向的成本差别往往很大。
AI 让重写代码变便宜了,一部分以前的单向门变成了双向门。但数据模型、对外接口、存储格式这些真正的单向门,并没有因此变得更容易回头。能分清哪些是真正回不了头的,反而成了一种更稀缺的判断力。
六、落地对齐
前面五步想清楚之后,其实就已经有了一页设计文档的骨架:
- 背景与问题:
用那句问题陈述来写 - 目标与非目标:
解决什么,不解决什么 - 约束:
哪些是硬的,哪些可以谈 - 方案对比:
一张对比表,加一句核心取舍 - 选定方案与边界:
架构图、状态归属、责任划分 - 风险与回滚:
哪些是单向门,出了问题怎么退 - 验收标准:
怎么算成功,怎么验证
对于比较关键的决定,还可以单独记一条架构决策记录(ADR),写清楚背景、有哪些选项、最后怎么选、会带来什么影响。它的价值常常要一年后才显现出来,当有人问“当初为什么这么做”的时候,答案就在那里。
文档写完,只是开始。推动对齐的时候,可以先私下和关键的人聊一聊,并且用对方关心的方式来讲:跟管理者多聊成本、风险和责任,跟使用方多聊收益和影响,跟研发多聊实现和接口。到了评审会上,只需要处理剩下的分歧,而不用从头说服所有人。
AI 时代,写下来这件事好像变得更有价值了。设计文档和决策记录不只是写给以后的同事看,也是给 AI 的上下文。一个说不清楚的设计,人和机器都很难接着往下做对。
写在最后
这六步也不用每次都走一遍。小事在脑子里过一下就行,大事再认真写一页纸。我自己也还在练,希望慢慢能变成一种习惯:遇到需求时,先问问“为什么”和“要不要”,再去想“怎么做”。
做了这么多年基础设施,越来越觉得,技术每往前走一步,往往也在把人的关注点往更高一层推,同时带来新的复杂性。以前从汇编走到高级语言,大家开始关心架构;现在 AI 接过了一部分代码,我们也许正好可以把注意力放回问题本身。
我也不能确定,未来还会不会有我们今天所说的软件工程师。也许这些工作会被 AI 慢慢吸收,软件工程像汇编一样退到更底层;也许它会变成一种还没有名字的新协作方式。
但至少在今天,面对一个需求,先问清楚为什么、边界和代价,仍然是值得做的事。至于这是不是软件工程的未来,可能要交给未来回答。