← 返回资讯
陈默
AI 行业分析师
已审核

用自然语言写代码,复杂不会消失只会转移

说起来你可能不信——我最近被一篇48年前的老文章打脸了。打得还挺响。

用自然语言写代码,复杂不会消失只会转移

用自然语言写代码,复杂不会消失只会转移


说起来你可能不信——我最近被一篇48年前的老文章打脸了。打得还挺响。

1978年,Dijkstra写了篇东西,标题就特别冲:《论“自然语言编程”的愚蠢》。当时我觉得,这老头儿也太极端了吧。现在我带团队用AI编程工具一年多了,从全组抵触到全员切Cursor,再到从Vibe Coding的狂热回归Planned模式……走完这一圈,我才发现。

老爷子说对了一半——而且是更要命的那一半。


先说说我们这一年的过山车。

去年我推全员Cursor的时候,团队经历了一个教科书式的闭环。

甜蜜期。 Vibe Coding真爽。动动嘴,Demo几分钟就能跑起来,快得像开了挂。前端同学慌得一批,因为后端的随便描述一下就能生成一个能用的界面。我们开始接受“不用想太清楚就能开始”的节奏。舒服。

然后翻车了。

真的翻了。

AI开始习惯性漏需求。代码架构松散得像沙堆,风一吹就散。上下文一长,它就开始“降智”。最要命的——我现在想起来还后怕——AI的服从性变成了毒药。它会顺着你模糊甚至错误的描述,在死胡同里一路狂奔,还跑得特别快。

说个具体的。上周清理旧代码发现的。

有一次我让AI定义users表,email字段加unique约束。代码能跑,测试能过,一切看起来岁月静好。后来偶然发现——是偶然,不是特地排查——它在回调函数里偷偷手动创建了一个idx_email索引。

问题在哪?unique约束本身就会自动生成索引。这个手动创建的索引完全是重复的。浪费性能,浪费存储。代码不报错,项目正常运行,但这个冗余就在那静静地躺了几个月。

要纠正这个问题,我得写一段比代码还长的prompt:“请使用Drizzle ORM定义users表,email字段添加unique约束,但禁止在回调函数中手动创建idx_email索引,因为unique约束会自动生成索引,重复索引会造成性能浪费与存储冗余。”

你品品。

这已经不是“描述需求”了。这是在用自然语言写代码。而且写得比代码还啰嗦。

还有一个更隐蔽的坑。

我在项目文档里明确写了:本地开发用dotenv加载环境变量,生产环境通过docker-compose注入变量,不需要dotenv。结果AI直接把dotenv装到了dependencies里。

应该是devDependencies。

代码不报错。项目能启动。但生产环境打包体积增大,不符合企业级工程规范。这种问题,你不review根本发现不了——等发现了,可能已经跑了几个月了。

这两个案例有一个共同点:代码不会报错,但都是明显的问题。不是隐藏的bug,是明晃晃的设计缺陷。

问题到底在哪?


这时候,Dijkstra 48年前写的那段话突然蹦进我脑子里。

他说什么来着?

形式化文本的美德在于,其操作只需满足少数简单规则;它们是排除各种胡说八道的极其有效的工具——而当我们使用自然语言时,胡说八道几乎不可避免。

绝了。

他还说了句更刺耳的:所谓自然语言的“自然性”,归根结底,不过是我们能轻松地说出那些荒谬性并不显而易见的话。

翻译成大白话:你用自然语言描述需求的时候,很容易觉得自己说清楚了,其实满篇都是你没意识到的模糊和矛盾。

这事儿我太有发言权了。用了这一年AI,我最大的感受就是——当你追求100% Vibe Coding准确落地时,你必须用“模糊”的语言去约束一个“极其确定”的结果。当你的约束严谨到足以让AI不犯错时,你的prompt其实已经变成了一套极其臃肿、低效的“新编程语言”。

复杂度没有消失。

它只是转移了。

Vibe Coding最大的幻觉是什么?降低开发难度等于消除系统复杂度。

真相扎心:AI把开发成本转移成了维护成本。项目从0到1极快,新手也能生成可用代码。从1到100呢?维护地狱。没人能读懂、修复、扩展AI生成的混乱代码。

短期利好:MVP验证、原型demo、一次性脚本——项目扔了也不可惜。

长期灾难:企业级系统80%的成本在维护与迭代。


回归期。

我们现在的开发流程变成了这样:描述意图 → 自动转化为Spec → AI分析排除矛盾 → 人类审查关键算法 → 设计测试套件 → 分拆执行。

你看这个流程的每一步,本质上都是在把自然语言的“毛坯”,精加工成形式化的“构件”。

我们又回到了Planned模式。

不是AI不行。是我们用AI的方式需要重新设计。


扯个题外话。

Karpathy——就是那个从去年12月起几乎没再亲手敲过代码的大神——最近在演讲里讲了个故事,我觉得特别说明问题。

他自己vibe code了一个叫MenuGen的app,功能是拍一张餐厅菜单,然后生成每道菜的图片。他花了些功夫把整个流程跑通,觉得这app挺有用。后来有人告诉他:你只要把照片丢给Gemini,加一句提示词,模型直接在原图上渲染出菜品图。

整个app根本不需要存在。

他的反思是:我们不能只把AI当成“加速器”。如果你只是用AI把旧流程加速10倍,那你做出来的东西可能会在下一个模型版本发布时,被一行提示词替代。

这话扎心。但确实是这么回事。

说回Dijkstra。


他到底对在哪?

他对在指出了自然语言的“毒性”——那种让你觉得自己说清楚了、其实满篇模糊的舒适感。这种毒性在Vibe Coding里被放大了十倍。48年前他写这篇文章的时候,可能都没想到会这么应验。

但他也错了一点:他低估了形式化符号和自然语言可以共存的可能性。

我们现在做的,不是用自然语言替代形式化符号,而是用自然语言作为入口,然后快速收敛到形式化的约束上。Spec是形式化的,测试套件是形式化的,架构约束是形式化的。自然语言只是那层皮。

这大概是Dijkstra没预见到的——不是“要不要形式化”的问题,而是“在哪一层形式化”的问题。这个问题我们还在摸索。说实话,我也不知道答案。


最后说一个我自己的判断。

AI对偶然复杂性——语法、实现、调试、样板代码、API对接——不止是银弹,简直是核弹。这些东西过去占开发者70-80%的时间,正在被快速自动化。真他妈好。

但对本质复杂性——需求判断、架构选择、业务权衡、系统边界的划定——AI连一颗子弹都不是。

Brooks在《人月神话》里画了一条线:偶然复杂性在这边,本质复杂性在那边。那是1975年,快50年前了。AI没有擦掉这条线,反而让它变得比任何时候都清晰。清晰得刺眼。

构建变得几乎免费了。

“决定构建什么”成了唯一的战场。

而这个战场,需要的恰恰是Dijkstra说的那种能力:用精确的形式化思维,排除胡说八道。

不是用自然语言。

是用脑子。

274
6872 阅读
2 评论
分享
链接已复制
编辑说明

本文由 MakeSense 编辑团队撰写并审核。文中引用的数据和观点均经过交叉验证,如有疏漏欢迎在评论区指正。最后更新:2026年06月27日 12:13

陈默

AI 行业分析师

前某大厂 AI 实验室研究员,关注大模型技术演进和商业化落地。写过 200+ 篇行业分析,擅长从产品视角拆解技术趋势。

读者评论 2

老李 1周前
有个小问题想请教,文中提到的那个方案在大规模场景下性能怎么样?
回复 点赞 (5)
运营小陈 1周前
转发到团队群了,大家都觉得有参考价值。
回复 点赞 (4)