Appearance
古法编程宣言
古法编程(Ancient Coding)是指在 AI 泛滥的时代,坚持人定义架构、AI 填充逻辑的工程范式。判断标准只有一条:你能不依赖 AI 解释你写出来的每一行代码吗?可以——古法。不能——vibe coding。
为什么需要古法编程
AI 写代码已经不是新鲜事。问题出在另一个地方:越来越多的开发者开始用"感觉"堆砌代码。
Vibe coding 的典型路径:把需求丢给 AI → 得到一段能运行的代码 → 上线 → 出问题 → 继续丢给 AI 修 → 循环。架构没人设计,测试没人定义,每一行代码都是 AI 的决策,开发者只是在转发指令。
这不是工程,这是赌博。
古法编程不是怀旧,不是反对 AI。它的主张只有一条:工程纪律不能省,AI 只是执行工具。
三大戒律
一、架构先行,代码在后
没有任何一行代码可以在没有明确设计的情况下产生。
在让 AI 动手之前,人必须先回答清楚:
- 这个模块的职责边界是什么?
- 它对外暴露哪些接口?
- 它依赖哪些外部输入,产生哪些副作用?
这些问题写不清楚,AI 写出来的代码就是一个黑盒。能跑,但没人能维护。
二、契约驱动,拒绝模糊
所有接口先定义类型,所有功能先定义测试用例,AI 才准动笔。
typescript
// 先有契约
interface ParseResult {
frontmatter: Record<string, string>;
body: string;
}
// 先有测试用例
// 输入:带 --- 分隔符的 Markdown 字符串
// 输出:分离的 frontmatter 和 body
// 边界:无 frontmatter 时 body 为原文,frontmatter 为空对象
// AI 然后才填充实现
function parseFrontmatter(content: string): ParseResult { ... }契约是人和 AI 之间的协议。没有契约,AI 写的东西满足的是它自己的假设,不是你的需求。
三、透明可控,拒绝黑盒
每一段 AI 生成的代码,你必须能独立解释它在做什么,以及为什么这样做。
不是逐行注释,而是你自己能说清楚逻辑。如果有一段代码你看不懂,就是还没到 merge 的时候。
这条戒律的反面是:不停地 prompt 试错,直到测试通过,然后不知道为什么通过了。古法编程不接受这种状态。
Vibe Coding vs. 古法编程
| 环节 | Vibe Coding | 古法编程 |
|---|---|---|
| 需求拆解 | AI 猜 | 人先写清楚 |
| 架构决策 | AI 生成,照单全收 | 人决定,AI 实施 |
| 接口定义 | 写完代码再看有什么 | 先定类型再写实现 |
| 测试 | AI 写或跳过 | 人定标准,AI 填充 |
| 代码生成 | AI 写 | AI 写,人能解释每一行 |
| Debug | 不断 prompt 试错 | 人能独立定位根源 |
| 上线标准 | 能跑就行 | 每条逻辑路径都能讲清楚 |
古法编程的三个阶段
P1 — 预设(Presupposition)
AI 动手前,人必须完成:
- 写清楚这个模块的意图(一段话,不是一句话)
- 定义所有对外接口的类型签名
- 写出至少一个核心测试用例(输入→输出)
P2 — 受控实现(Controlled Implementation)
- 任务拆解到最小可验证的函数粒度
- 每次只让 AI 实现一个明确的契约
- 不接受 AI 引入未经声明的依赖
P3 — 验证(Verification)
- 测试通过不是终点,你能解释为什么测试通过才是终点
- 每个边界情况都有对应测试,不靠"感觉没问题"
FAQ
Q: 古法编程是不是很慢?
P1 的前置工作会花时间,但它把返工的成本前移了。Vibe Coding 快在开始,慢在维护和 debug。古法编程慢在开始,但后期可以稳定迭代。
Q: 和 TDD 有什么区别?
古法编程包含 TDD 的精神(测试先行),但范围更广:架构决策、接口契约、可解释性要求都在内。TDD 是古法编程的一个子集。
Q: AI 能力越来越强,以后古法编程还有必要吗?
AI 的执行能力再强,架构决策的责任仍然在人。一个不知道自己系统怎么运作的开发者,在 AI 面前永远处于被动。古法编程解决的是"谁在决策",而不是"谁在写代码"。