AI时代后端工程(二):AI把代码写得越来越快,我却越来越不敢让它直接开工了

第一课写到最后,我留下了一个问题:

当 Coding(编码)越来越容易以后,程序员真正稀缺的能力,到底还剩什么?

这个问题其实是上一课最重要的延伸。

上一课我们花了很大篇幅讲一件事:

代码能运行,不等于系统是正确的。

一个接口可以返回 200,测试可以全部通过,每一行代码甚至都没有明显错误,但放进真实系统以后,仍然可能因为重复请求、失败、并发、权限、状态不一致而出问题。

最后我们得到一个结论:

代码生成正在变便宜,Engineering Judgment(工程判断)正在变贵。

但如果第二课只停在这里,其实还是没讲明白。

因为"工程判断"这四个字太大了。

它到底是什么?

是会画架构图吗?

是熟悉 Redis、MQ、微服务吗?

是工作年限够长吗?

还是出了几个线上事故以后自然就会了?

我后来发现,都不是。

真正把普通开发者和成熟工程师拉开差距的,往往发生在第一行代码出现之前

而 AI Coding(AI 编程)越强,这件事就越明显。


一、我后来越来越警惕一句话:这个需求很简单

假设今天产品找到你:

订单后台加一个导出功能。

是不是很简单?

如果是以前,你可能需要自己找 Excel 库、写查询、处理 Response(响应)、测试文件下载。

但现在把需求扔给 Cursor 或 Codex:

参考现有订单查询接口,实现订单导出,支持当前筛选条件,生成 Excel,并补测试。

可能几分钟以后:

接口有了。

Service(业务服务层)有了。

SQLAlchemy 查询有了。

Excel 也生成了。

测试还能跑。

你点一下后台按钮。

文件下载成功。

第一反应非常容易是:

做完了。

但现在我问你一个问题:

一次最多允许导出多少条?

500 条?

5000 条?

50 万条?

如果最多 500 条,这个功能可能真的非常简单。

HTTP 请求进来:

查询数据库

生成文件

返回下载

结束。

可如果是 50 万条呢?

事情立刻变了。

你不可能舒服地让一个 HTTP 请求:

查询 50 万行数据

全塞进内存

慢慢生成 Excel

用户浏览器一直等

因为这时候你马上会遇到:

Timeout(超时)。

内存占用。

数据库压力。

网关超时。

用户关闭页面。

任务执行失败。

文件生成到一半服务重启。

于是"订单导出"开始变成:

用户点击导出

创建 Export Task(导出任务)

立即返回 task_id

Worker(后台工作进程)执行

分批查询

生成文件

上传对象存储

更新任务状态

用户下载

注意这里最有意思的地方。

产品需求根本没变。

产品从头到尾只说了一句话:

加一个订单导出。

但是因为"数据量"这个隐藏条件不同,你设计出来的已经是两套完全不同的系统。

这就是我想从第二课开始,让大家建立的第一个习惯:

不要只听需求说了什么,还要主动寻找它没有说什么。

很多真正值钱的工程能力,就藏在这些"没说出来"的地方。


二、AI最擅长的,恰恰是需求已经变清楚之后的那一段

我们把刚才的事情再拆开一点。

假设我已经把所有东西都告诉 AI:

最多导出 50 万条。

必须异步执行。

导出文件放私有 OSS。

下载地址 30 分钟过期。

普通运营人员手机号必须脱敏。

失败允许重试。

重复提交相同任务时不能无限产生新任务。

Worker 必须分批读取数据库。

任务状态需要记录进度。

到了这里,你再让 AI Coding。

你会发现它非常舒服。

因为现在的问题已经很明确了。

它需要做的事情是:

设计数据库 Model(数据模型)。

写 API。

写 Service。

写 Worker。

写 OSS 调用。

补测试。

处理状态更新。

这些事情依然需要技术能力,但它们有一个共同特点:

目标已经相对确定,剩下的是实现。

英文里可以把这一部分理解成:

Implementation(实现)。

而这一层,恰恰是 AI 进步最快的地方。

以前软件开发里有大量时间花在:

我知道要干什么。

但我要一行一行把它写出来。

现在 AI 正在大幅压缩这段距离。

所以 AI Coding 真正首先降低的,其实不是:

"软件工程的价值。"

而是:

Implementation Cost------实现成本

但是另外一种成本并没有同步消失。

甚至正在变得更加重要:

Decision Cost------决策成本

也就是:

到底应该做成什么样?

哪些情况必须考虑?

这个功能的边界在哪里?

同步还是异步?

哪些地方允许失败?

哪些东西绝对不能发生?

我们凭什么认为这个实现正确?

这些问题,才是第二课真正要讨论的东西。


三、为什么两个人用同一个 Codex,最后做出来的东西可以差一个级别?

我们做个非常简单的对比。

还是:

增加订单导出。

开发者 A 拿到需求以后:

直接让 AI 实现。

AI 很快给出:

GET /orders/export

查询订单。

生成 Excel。

返回文件。

A 本地测试一下。

能下载。

完成。

如果数据量很小,这甚至可能没有问题。


开发者 B 拿到需求以后,第一反应却不是写代码。

他先问:

一次最大导出数量是多少?

哪些角色允许导出?

手机号、地址这类敏感信息怎么处理?

导出过程中订单发生变化怎么算?

导出的应该是点击那一刻的数据,还是执行过程中不断变化的数据?

如果任务需要五分钟,用户关闭浏览器以后还继续吗?

任务执行失败怎么办?

用户连续点击三次怎么办?

文件保存多久?

下载链接是不是永久有效?

导出任务会不会把主库打满?

50 万行应该一次读还是分批读?

最终他可能决定:

小数据量同步导出。

大数据量异步。

私有对象存储。

Signed URL(签名链接)限时访问。

批量读取数据库。

敏感字段按角色脱敏。

导出行为写 Audit Log(审计日志)。

重复任务短时间复用。

然后才让 AI Coding。

现在请注意:

A 和 B 使用的是同一个模型。

甚至 Codex 生成代码的水平一模一样。

真正产生差距的不是:

谁 Prompt(提示词)写得更花哨。

而是:

AI 开始生成代码之前,人类到底做了多少正确决策。

这就是 AI Coding 时代一个非常容易被低估的变化。

过去,一个判断能力普通的人和一个判断能力很强的人,代码产出速度可能不会差得特别夸张。

因为大家都得自己敲。

但今天 AI 把执行速度提高以后:

上游决策质量的差距,会被下游生成速度迅速放大。

方向对了:

AI 帮你高速推进。

方向错了:

AI 帮你高速走错。

所以 AI 越强,我反而越来越不喜欢一句话:

先让 AI 写出来再说。

小功能当然可以。

但复杂 Feature(功能)里,这句话可能非常贵。


四、真正的第一个分水岭:你能不能把"人话"翻译成"工程定义"

产品世界和工程世界,其实说的不是同一种语言。

产品可能会说:

"支持任务取消。"

"把消息发出去。"

"删除用户。"

"增加自动重试。"

"做一个订单导出。"

这些句子人类完全能听懂。

问题是:

计算机听不懂"差不多"。

所以工程师必须完成一次转换:

自然语言需求

工程定义

这一层英文里常叫:

Problem Framing(问题定义)。

我觉得这个词特别重要。

因为很多项目真正的问题,并不是:

答案写错了。

而是:

一开始解决的就不是正确的问题。


比如一句非常普通的话:任务取消

需求是:

给 AI Task 增加取消功能。

你很容易告诉 Cursor:

Implement task cancellation.

实现任务取消。

但真正成熟的工程师会先问:

什么叫"取消成功"?

任务还在 Pending(等待中)。

那简单。

直接变成 Cancelled(已取消)。

但如果 Worker 已经开始执行了呢?

如果正在调用 LLM(大语言模型)呢?

如果 LLM 已经返回,正在把结果写入数据库呢?

如果用户点击取消的时候,Worker 刚好执行完成呢?

如果用户连续点击两次取消呢?

如果取消以后服务重启呢?

如果任务已经产生了一部分副作用呢?

取消以后还能 Retry(重试)吗?

到这里你会突然意识到:

真正困难的根本不是:

cancel_task() 怎么写。

而是:

我们的系统到底如何定义"取消"这件事?

定义没有完成之前,开始 Coding,其实就是把产品定义权和架构决策权一起丢给 AI。

AI当然可以给你一个答案。

但那个答案只是:

"通常别人可能会这么做。"

不代表:

"你的系统就应该这么做。"


五、所以我现在特别喜欢拆需求里的"动词"

这是一个非常实用的习惯。

看到需求以后,专门盯着里面的动词。

比如:

保存。

发送。

删除。

取消。

同步。

完成。

成功。

这些词在人类语言里特别自然。

但在工程世界里,经常模糊得可怕。


"保存成功"是什么意思?

已经写入 Redis?

数据库执行了 INSERT?

数据库事务 Commit(提交)成功?

搜索索引也更新了?

对象存储文件也上传完成?

如果数据库成功,但 Elasticsearch 更新失败呢?

到底算成功还是失败?


"发送成功"是什么意思?

消息放进 MQ(消息队列)?

Consumer(消费者)拿到了?

调用第三方 API 返回 200?

还是用户手机真的收到了短信?

完全不是一个层面的"成功"。


"删除用户"是什么意思?

直接从数据库 DELETE?

Soft Delete(软删除)?

只是不能登录?

历史订单保留吗?

聊天记录呢?

发票呢?

日志呢?

对象存储里的文件呢?

法律合规要求的数据呢?

你会发现:

很多需求之所以后面越做越乱,不是代码能力不够。

而是开头那个动词从来没有被真正定义。

所以以后遇到复杂需求,我建议养成一个条件反射:

先不要问"怎么实现",先问"这句话在我们的系统里到底是什么意思"。

这是第一种越来越稀缺的能力:

Define------定义


六、一个需求什么时候才算真正"可以开发"?

这里再教一个非常重要的概念:

Acceptance Criteria------验收条件

简单理解就是:

做到什么程度,我们才承认这个功能完成了?

比如:

"支持订单导出。"

这不是一个好的验收条件。

因为我无法判断什么叫"支持"。

换成:

用户可以基于当前筛选条件创建导出任务。

任务创建后立即返回 task_id。

任务执行期间可以查看状态。

任务完成后提供下载入口。

普通运营人员导出的手机号必须脱敏。

文件下载链接 30 分钟后失效。

失败任务状态必须进入 Failed。

这时候情况完全不同。

因为它已经开始变得:

可验证。

你会发现一个特别漂亮的关系:

需求

Acceptance Criteria(验收条件)

Test(测试)

Verification(验证)

这也是为什么真正好的工程需求,不只是"方便程序员理解"。

它会直接影响:

后面到底该怎么测试。

所以有时候我看一个需求是否成熟,不是看写了多少字。

而是看:

它有没有办法被明确地证明"做到了"。

如果没有,那开发其实还没有真正准备好。


七、第二种越来越值钱的能力:Model------把现实世界变成系统里的模型

需求定义清楚以后,并不会直接来到代码。

中间还有一个非常重要的过程:

Modeling------建模

很多人第一次看到"建模",第一反应是:

数据库建表。

其实数据库只是建模的结果之一。

真正的建模是在回答:

我们的系统认为,这个世界里到底存在哪些东西?

还是订单导出。

Demo 里你可能觉得:

不就是一个接口吗?

但真正把它当成一个长期存在的系统能力以后,你可能会发现:

系统里其实多了一个新的对象:

ExportJob------导出任务

它可能拥有:

job_id

user_id

status

progress

query_condition

file_key

error_message

created_at

finished_at

到这里我们甚至还没有讨论:

FastAPI。

Celery。

Redis。

RabbitMQ。

我们只是在描述:

业务世界本身。

然后继续。

ExportJob 可能有这些状态:

Pending(等待)

Running(执行中)

Succeeded(成功)

也可能:

Running

Failed(失败)

还可能:

Pending

Cancelled(取消)

这时候又会出现一个真正的工程问题:

Running 能不能变成 Cancelled?

别急着回答。

想象 Worker 正在执行:

它已经生成了 90% 的文件。

用户点击取消。

Worker 正好准备上传 OSS。

取消请求和任务完成几乎同时发生。

最后应该是什么状态?

Cancelled?

Succeeded?

谁赢?

这就是一个典型的:

Race Condition(竞态条件)。

但我们这一课暂时不深入并发。

我要你看到的是另一件事情:

状态不是数据库里随便存的一个字符串。

状态其实是在定义:

系统允许发生什么。

哪些路径合法。

哪些路径非法。

这就是 State Machine(状态机)的思想。


八、很多所谓"代码越来越难维护",其实是模型一开始就没想明白

假设你的 Task 最开始只有:

running

success

两个状态。

后来产品说:

增加失败重试。

于是你开始硬塞:

error。

过几天又说:

支持取消。

再塞:

cancel。

后来还需要:

waiting。

retrying。

timeout。

partial_success。

最后代码里到处都是:

if status == ...

elif status == ...

为什么会这样?

不一定是因为程序员不会重构。

很可能是一开始对业务世界的理解太粗糙。

这就是建模的重要性。

好的工程师在写代码之前,会开始问:

系统里有哪些 Entity(实体)?

有哪些 State(状态)?

状态之间有哪些 Transition(迁移)?

哪些事情绝对不能发生?

哪些规则必须永远成立?

最后一个问题,其实就是第一课讲过的:

Invariant------不变量

所以你会发现第一课和第二课已经开始接起来了。

第一课我们知道:

系统必须保护不变量。

第二课进一步追问:

这些不变量从哪里来?

答案之一就是:

来自你对业务世界的正确建模。

所以第二种能力叫:

Model------建模


九、第三种能力才真正来到"工程判断"的核心:Decide------做选择

现在:

需求清楚了。

模型也大致有了。

是不是终于有标准答案了?

还是没有。

因为真正的软件工程从来充满:

Trade-off(权衡)。

还是订单导出。

现在摆在你面前的问题可能有:

同步还是异步?

CSV 还是 Excel?

主库还是只读库?

Offset Pagination(偏移分页)还是 Cursor Pagination(游标分页)?

Redis 要不要参与?

MQ 要不要上?

文件保存一天还是七天?

失败自动 Retry 还是人工重试?

这些问题没有一个简单的:

"最先进答案"。


十、工程师成熟的一个标志,是开始不相信"哪个技术更高级"

刚开始学后端的时候,我们特别容易有一种技术排行榜思维:

微服务 > 单体。

异步 > 同步。

Redis > 数据库查询。

Kafka > 普通消息队列。

分布式 > 单机。

复杂架构 > 简单架构。

工作几年以后慢慢会发现:

事情根本不是这么回事。

真正合理的表达应该是:

在什么条件下,A 比 B 更合适?

比如还是订单导出。

如果这是一个内部后台:

每天 10 个人用。

一次最多导出 300 条。

查询 100ms。

生成 CSV 再花 100ms。

你非要设计:

MQ。

Redis。

Worker Cluster。

Task Scheduler。

状态恢复。

任务清理。

失败补偿。

可能不是"生产级"。

可能叫:

Overengineering------过度设计

一个普通同步接口也许就是最好的选择。


但是如果:

一次 50 万条。

生成需要 5 分钟。

同时几百个导出任务。

必须支持失败恢复。

还要做进度查询。

那你继续坚持同步:

就是在制造问题。

所以真正值钱的,不是:

"我知道异步任务。"

而是:

我知道什么时候应该使用异步任务。

这就是 Knowledge(知识)和 Judgment(判断)的区别。

知道 Redis 怎么用,是知识。

知道现在到底需不需要 Redis,是判断。

知道 Kafka 怎么部署,是知识。

知道这个项目是否值得引入 Kafka,是判断。

知道微服务怎么拆,是知识。

知道现在到底该不该拆,是判断。

AI 可以越来越容易地把"知识"变成代码。

但"判断"仍然需要依赖上下文和约束。

这也是为什么 Context Engineering(上下文工程)会在后面的课程里越来越重要。


十一、我后来才真正理解:架构不是不断加东西,而是不断管理复杂度

刚开始学习架构时,很容易有一种错觉:

图越复杂,架构越高级。

于是一个简单系统也想放进去:

API Gateway。

Redis。

MQ。

Event Bus。

Worker。

Scheduler。

Microservice。

Service Mesh。

看起来很专业。

但后来我越来越喜欢一个词:

Complexity Budget------复杂度预算

可以简单理解成:

系统能够承受的复杂度是有限的。

你每增加一个组件,都不是只增加一个图标。

比如:

"加 Redis。"

听起来只有三个字。

实际上你同时增加了:

部署。

配置。

连接池。

鉴权。

监控。

高可用。

TTL。

缓存一致性。

缓存穿透。

缓存击穿。

数据过期。

故障降级。

Redis 挂了之后怎么办?

这些全都是系统以后必须承担的东西。

所以技术组件从来不是免费的。

一个优秀架构师真正厉害的地方,很多时候不是:

能想到多少组件。

而是:

知道哪些组件不应该出现。

这点在 AI Coding 时代尤其重要。

因为以前过度设计还有一个天然阻力:

你得自己写。

写五层 Factory(工厂)、Strategy(策略)、Adapter(适配器),写着写着可能自己都烦了。

现在 AI 不烦。

你想抽象十层,它真能给你十层。

于是出现一个很有意思的变化:

生成复杂度的成本下降了。

但是:

维护复杂度的成本没有消失。

代码是 AI 写的。

以后出问题还是你查。

新人还是得理解。

测试还是得维护。

依赖还是得升级。

系统还是得部署。

所以 AI 时代我反而认为一个越来越重要的能力叫:

知道什么不要做。

这也是 Decide(决策)的一部分。


十二、第四种能力,是我认为以后越来越值钱的一种能力:Verify------证明它是对的

现在假设前面全做完了。

AI 把代码生成了。

你运行:

测试 37 个。

全部通过。

是不是可以 Merge?

不一定。

因为这里有一个非常危险的问题:

测试是谁写的?

AI。

代码也是谁写的?

AI。

如果 AI 一开始就理解错了怎么办?

比如真实业务规定:

普通运营人员不能导出完整手机号。

但是 AI 理解成:

所有后台用户都可以导出完整手机号。

于是它写出代码:

普通运营可以导。

然后它又写测试:

普通运营导出。

检查 HTTP 200。

检查文件中存在手机号。

测试结果:

PASS。

漂亮。

所有测试绿色。

但是整个实现:

错得非常完整。

这是 AI Coding 时代特别值得警惕的一件事。

因为代码和测试可能来自:

同一个错误假设。

所以以后一定要记住:

Test Pass ≠ Requirement Correct

测试通过,不代表需求正确。


十三、真正可靠的验证,必须有一个"代码之外的锚"

还是刚才的手机号。

如果我们的 Acceptance Criteria(验收条件)已经明确写着:

普通运营人员导出的手机号必须脱敏。

那么这条规则就独立存在于:

AI 生成的代码之外。

于是我们才能真正验证:

普通运营登录

创建导出任务

获取导出文件

解析文件

检查手机号字段

确认完成脱敏

现在这个 Test 才真正有价值。

因为它不是在验证:

"代码是不是按照代码作者的理解运行。"

而是在验证:

系统有没有遵守业务本身的规则。

所以我现在越来越喜欢这样理解测试:

测试不是几个 assert

测试是在回答:

我有什么证据证明系统最重要的规则没有被破坏?

这就是:

Verification(验证)。


十四、到这里,我们终于可以把"工程判断"拆开了

上一课结束的时候,我们说:

工程判断越来越贵。

现在它已经不再是一个模糊词。

至少可以先拆成四层:

Define------定义

到底要解决什么问题?

"成功""取消""发送""删除"分别是什么意思?


Model------建模

这个业务世界里有哪些对象?

有哪些状态?

有哪些关系?

哪些规则必须永远成立?


Decide------决策

同步还是异步?

缓存还是不缓存?

要不要 MQ?

要不要拆服务?

当前约束下,什么方案最合适?


Verify------验证

我们怎么证明系统真的正确?

测试什么?

哪些失败场景必须覆盖?

什么证据足够让它进入 Production(生产环境)?

于是整条链路变成:

Define → Model → Decide → Implement → Verify

定义

建模

决策

实现

验证

注意中间那个词:

Implement------实现

这正是 AI 进步最快的部分。

所以真正发生的不是:

"AI 把程序员消灭了。"

而是:

AI 正在把 Implementation 从 Engineering 中高速压缩。

于是以前被"写代码"遮住的能力开始全部露出来。


十五、为什么我现在越来越不喜欢"让 AI 先写一个看看"?

不是因为不能这么做。

简单需求当然可以。

但复杂需求里真正危险的是:

AI 的实现速度,已经开始超过人的理解速度。

以前:

你想一个方案。

开始写。

写了一下午。

发现方向不对。

可能也就改了三个文件。

现在:

你一句话。

Agent 开工。

十五分钟以后:

改了 26 个文件。

新增两个表。

做了 Migration(数据库迁移)。

加了 Worker。

补了缓存。

测试写了 40 个。

README 都改好了。

看起来效率爆炸。

问题是:

如果最开始那个方案错了呢?

你得到的不是:

一个小错误。

而是一整套非常完整的错误实现。

所以我后来越来越能理解为什么 AI Native Development Loop(AI 原生开发循环)应该是:

Context

Plan

Code

Test

Review

Production

而不是:

Prompt

Code

上一课已经把这条循环作为整套课程的主线之一。

现在第二课我们可以真正理解:

为什么一定要先有 Context(上下文)。

为什么复杂任务应该先 Plan(规划)。

不是流程洁癖。

而是在控制一个新的风险:

AI 可以比你想清楚问题更快地把代码写出来。


十六、这也意味着,未来一个优秀程序员的角色会慢慢发生变化

以前一个程序员大量时间在:

理解需求

设计

写代码

Debug

测试

上线

其中"亲自生产代码"占据非常大的一部分。

未来越来越可能变成:

理解需求

定义问题

建立约束

设计模型

拆任务

做技术决策

AI 高速实现

人验证

AI 修正

Production Check(生产检查)

你会发现人的工作逐渐从:

Code Writer------代码编写者

往:

Engineering Director------工程导演

移动。

我用"导演"这个词,不是说以后工程师只动嘴。

恰恰相反。

你仍然必须懂技术。

甚至很多地方需要懂得更深。

为什么?

因为 AI 写了错误 Transaction Boundary(事务边界),你得看得出来。

出现 N+1 Query(N+1 查询问题),你得看得出来。

锁范围错了,你得看得出来。

Retry(重试)可能制造重复副作用,你得看得出来。

权限漏洞,你得看得出来。

数据库设计不合理,你得看得出来。

所以 AI 时代绝对不是:

技术不重要了。

而更准确的说法应该是:

"记住怎么写"的价值在下降,"理解为什么这样设计"的价值在上升。


十七、以后"只懂业务,不懂技术"同样会非常危险

讲到这里,有人可能会走向另一个极端:

既然 AI 会 Coding,那以后工程师是不是只需要会提需求?

不是。

还是订单导出。

一个不了解数据库的人,可能会认为:

50 万条一次查出来不就行了吗?

一个不了解 HTTP 的人,不知道为什么五分钟的同步请求非常危险。

一个不了解分布式系统的人,不知道为什么 Retry 可能让同一任务执行两次。

不了解数据库事务,就不容易理解为什么"执行到一半失败"需要考虑状态一致性。

不了解安全,就可能觉得 OSS 文件生成一个永久公开 URL 最方便。

不了解并发,就很难发现:

两个看起来都正确的请求,同时执行可能产生错误结果。

所以未来并不是:

懂业务 > 懂技术。

而是:

技术知识的使用方式正在变化。

以前很多时候:

我学 SQLAlchemy,因为我要亲自把 ORM 代码写出来。

以后还会多一层:

我理解 Transaction(事务),因为我要判断 AI 为什么在这里写错了。

我理解索引,因为我要判断这个查询上线以后会不会拖垮数据库。

我理解消息队列,因为我要决定这里到底有没有必要引入异步。

技术仍然是工程判断的底座。

只是它不再只服务于"写"。

它越来越服务于:

判断。


十八、如果把未来后端工程师的能力画成四层,我会这么分

最底下一层:

Level 1:Implementation------实现能力

Python 怎么写。

FastAPI 怎么写。

SQLAlchemy 怎么用。

Redis 怎么接。

Docker 怎么配。

这层依然重要。

但是 AI 正在高速增强它。


第二层:

Level 2:Modeling------建模能力

系统里到底有哪些对象?

状态是什么?

关系是什么?

生命周期是什么?

哪些规则不能被破坏?


第三层:

Level 3:Decision------决策能力

什么方案适合现在?

为什么?

成本是什么?

风险是什么?

什么时候需要升级架构?

什么复杂度根本不值得引入?


第四层:

Level 4:Verification------验证能力

我们怎么证明它是正确的?

正常路径怎么测?

失败路径呢?

边界呢?

权限呢?

并发呢?

上线以后通过什么指标判断系统仍然健康?

最终你会发现:

越往上走,工作的核心越不像:

"我会不会写。"

而越来越像:

我能不能定义正确,并证明正确。


十九、从今天开始,拿到复杂需求先问这六个问题

如果第二课最后只留一个你明天上班就能用的东西,我建议记住下面这套方法。

不要背术语。

真的拿去用。


第一问:我们到底在解决什么问题?

不要重复产品原话。

你必须能用自己的话解释。

如果自己都说不清楚,说明问题还没有定义完成。


第二问:什么才叫成功?

尽量给出可验证的定义。

不要只说:

"支持任务取消。"

而应该继续定义:

哪些状态允许取消?

取消接口返回成功到底代表什么?

重复取消怎么办?

已完成任务怎么办?


第三问:什么事情绝对不能发生?

找 Invariant(不变量)。

不能重复扣款。

不能越权。

不能让库存凭空减少。

不能让任务永久停留在 Running。

不能因为 Retry 重复产生业务副作用。


第四问:这个业务世界应该怎么建模?

有哪些 Entity(实体)?

有哪些 State(状态)?

状态如何迁移?

哪些数据需要长期保存?

谁拥有生命周期?


第五问:当前条件下,最简单的正确方案是什么?

不是最先进。

不是最酷。

不是简历上最好看。

而是:

满足当前约束,同时保留合理演进空间的最简单方案。

这条特别难。

但也特别值钱。


第六问:我怎么证明它真的对?

不要等 AI 写完才想测试。

开始 Coding 之前就应该问:

哪些行为必须被验证?

哪些规则必须被测试保护?

上线以后哪些指标能够证明系统仍然可信?

如果这一问完全答不上来:

代码写得再快,也应该谨慎。


二十、现在再回来回答文章开头的问题

AI Coding 越来越强以后,程序员真正稀缺的能力到底是什么?

不是一个答案。

而是一条能力链:

模糊需求

Define:把问题定义清楚

Model:把现实世界建模

Decide:在约束中做正确选择

Implement:把设计实现出来

Verify:证明实现真的正确

而 AI 当前正在最猛烈地压缩的:

恰恰是中间的 Implementation。

这也是为什么我现在越来越觉得:

以前我们容易把程序员理解成:

把需求翻译成代码的人。

未来这个定义会越来越不准确。

更成熟的描述应该是:

把模糊问题变成一个可执行、可验证、可以在真实系统中长期成立的工程方案的人。

代码依然重要。

只是代码不再是全部。


二十一、这就是 Coding → Engineering 真正发生的地方

所以这节课最重要的,不是记住:

Problem Framing。

Modeling。

Trade-off。

Verification。

这些英文以后自然会熟。

我真正希望你建立的是一种新的开发直觉。

以后再打开 Cursor、Codex。

看到一个复杂需求。

不要第一反应就是:

帮我实现 XXX。

先多想几秒:

这个问题真的定义清楚了吗?

AI 现在有哪些东西只能靠猜?

这里有哪些业务规则它不知道?

哪些架构决策我不应该无意识地交给它?

最简单的正确方案到底是什么?

最后我准备用什么证据证明它真的做对了?

一旦这几个问题开始变成你的习惯,你使用 Coding Agent 的方式会发生非常明显的变化。

你不再只是:

让 AI 帮你写代码。

而是在逐渐学习:

怎样让 AI 进入一个被人类正确理解、正确约束、并且可以验证的工程空间里工作。

这才是我理解的:

AI Native Backend Engineer(AI 原生后端工程师)。

第一课我们得到:

代码生成越来越便宜,工程判断越来越贵。

这一课,我们终于把"工程判断"拆开了:

定义、建模、决策、验证。

课程最初对第二课的定位本来就是完成一次从 Coding → Engineering 的认知切换,而不是马上进入某个具体框架。

而当你真正理解这一点之后,下一个问题就自然出现了:

既然 AI 实现能力已经这么强,为什么网上那些"10 分钟写完整系统"的 Demo 看起来一个比一个惊艳,可真的到了 Production(生产环境),事情却突然完全不一样?

这就是下一课要解决的问题:

为什么 AI 写 Demo 快得吓人,一到 Production 就开始露馅?

下一课我们不再只讨论抽象能力。

我们会拿一个"已经运行成功"的后端功能,一层一层往真实生产环境里推。

你会看到一个很反常识的事实:

很多时候,功能跑通的那一刻,并不是软件工程结束。

恰恰是软件工程真正开始的地方。

相关推荐
冬奇Lab1 小时前
开源项目第199期:OpenWiki — LangChain 出品的代码库自维护文档 CLI,为 Agent 而生
人工智能·开源·资讯
冬奇Lab1 小时前
Code Agent 解剖(12):Harness 设计之二——上下文工程
人工智能·开源·agent
FII工业富联科技服务1 小时前
AI Agent底层逻辑解析:Token、上下文与异构计算的协同架构
人工智能
小弥儿1 小时前
GitHub今日热榜 | 2026-08-26:AI 大脑与知识管理扎堆
人工智能·学习·开源·github
荷蒲1 小时前
【小白量化Qbuddy】利用AI学习中文Python
人工智能·python·学习
继续商行2 小时前
数据库变更协作:研发与 DBA 如何约定 DDL 边界
人工智能
IT_陈寒2 小时前
Vue的响应式更新有时候真的不听话
前端·人工智能·后端
柳絮飞祭奠2 小时前
Dify Windows Docker Desktop 部署文档
人工智能·深度学习·语言模型·数据分析·transformer·边缘计算·集成学习
DeepLink_20252 小时前
Triton第四课:基于对称内存融合 AllGather 与 MatMul,提速1.56倍
人工智能·芯片·技术科普