---
url: /blog/h076qqxw/index.md
---
# AI 代码越改越烂的真相：软件基础原理的重要性

## 核心论点

> **软件基础原理（Software Fundamentals）从未像现在这样重要。**

演讲者认为，许多人担心在 AI 时代自己的技能变得毫无价值，但事实恰恰相反：代码从来都不便宜，**烂代码现在是史上最昂贵的**。因为：

* 一个难以修改的代码库让你无法充分利用 AI 的能力
* AI 在好的代码库上表现极好，在烂代码库上表现极差
* 越是依赖 AI 编程，越需要扎实的基础能力来把控方向

***

## 一、Spec to Code 运动的困境

### 1.1 什么是 Spec to Code

所谓 **Spec to Code（规格到代码）运动**，主张：

1. 编写应用规格说明（specification）
2. 用 AI 将规格转换为代码
3. 如果应用出问题，回去改规格
4. 重新运行编译器，得到更多代码

### 1.2 实践中的问题

演讲者亲自尝试后发现：

```
运行 → 获得代码 → 运行 → 代码变差 → 运行 → 代码更差 → 运行 → 一团糟
```

这正是软件熵（Software Entropy）的体现——每次改动只关注局部，整体设计不断恶化，最终产出垃圾代码。

### 1.3 错误假设

Spec to Code 运动基于一个错误观念：**Code is cheap（代码是廉价的）**

演讲者明确反对这一观点：

| 观点 | 真相 |
|------|------|
| 代码是廉价的 | 代码从来都不廉价 |
| 烂代码可以随便重写 | 烂代码是史上**最昂贵的** |
| 不需要看代码 | 不看代码只会越来越烂 |

***

## 二、AI 编程的六大失败模式与解决方案

### 失败模式一：AI 没有按照你的想法工作

**现象**：你脑子里有明确的想法，但 AI 的输出完全跑偏。

**根本原因**：你与 AI 之间存在**沟通障碍**，缺乏共享的设计概念。

#### 设计概念（Design Concept）

引用 Frederick Brooks 的《设计的设计》：

> 当多人共同设计某样东西时，脑海中会有一个**短暂的、飘忽不定的想法**——这就是"设计概念"。
>
> 它不是资产，不能写在 Markdown 文件里，而是关于"你在构建什么"的隐形理论。

你和 AI 之间**没有共享的设计概念**，所以它不理解你真正想要什么。

#### 解决方案：Interview Me 技能

演讲者开发了一个技能，要求 AI 不断向你提问，直到达到共享理解：

```markdown
Interview me relentlessly about every aspect of this plan until we reach a shared understanding. 
Walk down each branch of the design tree, resolving dependencies between decisions one by one.
```

**工作原理**：

* AI 会问 40、60 甚至 100 个问题
* 将 AI 变成"对手"，不断向你确认想法
* 最终可生成产品需求文档或直接转化为 issue
* 比工具自带的 Plan Mode 更好用——后者太急于创建资产和开始工作

📦 **GitHub 仓库**：MikeOpenHWGroup/skills（13000+ stars）

***

### 失败模式二：AI 输出过于冗长

**现象**：与 AI 沟通时感觉"鸡同鸭讲"，它用太多文字解释自己正在做的事，用的不是你熟悉的语言。

**根本原因**：缺乏**共享语言**（Shared Language）。

#### 解决方案：领域驱动设计（DDD）与通用语言（Ubiquitous Language）

引用《领域驱动设计》（Domain-Driven Design）：

> 开发者之间的对话、代码中的表达式、与领域专家的沟通，都源自同一个**领域模型**。

**通用语言**本质上是一个 Markdown 文件，包含你和 AI 共同使用的术语表：

```markdown
| 术语 | 定义 | 示例 |
|------|------|------|
| Order | 客户提交的交易请求 | - |
| LineItem | 订单中的单个商品 | - |
| CheckoutSession | 完成购买的上下文 | - |
```

#### 演讲者开发的技能

扫描代码库 → 提取术语 → 生成通用语言 Markdown 文件 → 传递给 AI

**效果**：

* AI 的思考过程更简洁，不再啰嗦
* 实现结果与计划高度一致
* 改善规划质量

***

### 失败模式三：代码能运行但不符合预期

**现象**：AI 构建了正确的东西，但代码根本不工作。

**解决方案：建立反馈循环（Feedback Loops）**

| 反馈机制 | 说明 |
|----------|------|
| 静态类型 | 使用 TypeScript（非 TS 项目简直是疯了） |
| 浏览器访问 | 给 LLM 访问浏览器的能力，让它能探索页面 |
| 自动化测试 | 必须有，覆盖核心功能 |

***

### 失败模式四：AI 一次性生成太多代码

**现象**：AI 一次性产出大量代码，然后才想起来要类型检查或写测试。

**根本原因**：AI 默认**超出 headlights（车灯照不到的范围）**。

#### 引用《 pragmatric programmer》

> **反馈的速率就是你的速度上限（The rate of feedback is your speed limit）**

翻译成人话：开得太快，前面黑漆漆的根本看不见路。

#### 解决方案：TDD（测试驱动开发）

**TDD 强制 AI 采取小步前进**：

```
1. 先写测试
2. 让测试通过
3. 重构改进设计
```

**问题**：测试本身就很难

| 测试决策 | 内容 |
|----------|------|
| 测试单元多大？ | 太大 → 测试不稳定；太小 → 依赖复杂 |
| 什么要 Mock？ | Mock 哪些依赖 |
| 测试什么行为？ | 需要明确边界 |

演讲者的发现：**好的代码库 = 容易测试的代码库**。反过来也成立——测试做得好，反馈循环才好，AI 才能产出更好的代码。

***

### 失败模式五：代码库难以理解

**现象**：AI 尝试探索代码库，但最后还是不理解它在做什么。

**根本原因**：代码库中存在大量**浅层模块（Shallow Modules）**。

#### John Osterhout 的模块设计原则

| 模块类型 | 特征 | 代码库中的样子 |
|----------|------|----------------|
| **深度模块（Deep Module）** | 大量功能隐藏在简单接口后面 | 边界清晰，内部复杂 |
| **浅层模块（Shallow Module）** | 功能不多，接口却复杂 | 一堆小 blob，AI 很难导航 |

**浅层模块的问题**：

* 一堆零散的小代码块
* AI 要在它们之间穿梭导航
* 经常找不到正确的模块
* 无法理解依赖关系

#### 解决方案：创建深度模块

```
┌─────────────────────────────────┐
│  Interface Layer（接口层）       │  ← 设计重点，控制边界
├─────────────────────────────────┤
│                                 │
│  Deep Module（深度模块）         │  ← AI 可以处理内部实现
│  - 复杂逻辑                      │
│  - 隐藏在简单接口后              │
│                                 │
└─────────────────────────────────┘
```

**演讲者的技能**：improve-codebase-architecture

* 探索代码库
* 寻找相关的代码
* 打包成深度模块
* 边界简单 → 易于测试
* 奖励 TDD

***

### 失败模式六：大脑跟不上代码产出速度

**现象**：能用 AI 产出比以往更多的代码，但大脑精疲力竭，根本跟不上。

**根本原因**：烂代码库让 AI 和人类都需要在脑中同时维护大量信息。

#### 解决方案：设计接口，委托实现

将深度模块视为**灰盒（Gray Box）**：

* **设计接口**：仔细思考，确保接口设计良好
* **委托实现**：AI 负责内部实现细节
* **从外部测试**：不深入审查每个实现，只验证接口行为

```
┌─────────────────────────────────┐
│  你：设计接口 + 思考模块职责      │
│  AI：处理模块内部实现            │
│  测试：从外部验证                │
└─────────────────────────────────┘
```

**适用场景**：

* ✅ 非关键模块——不必深究实现
* ❌ 金融、安全等关键模块——必须仔细审查

这样做的代价：

> 你作为人类在规划时必须**始终考虑模块结构**，理解模块的边界和职责。这必须成为你通用语言的一部分。

***

## 三、核心设计原则：每天投资系统设计

引用 Kent Beck：

> **每天为系统的设计投资（Invest in the design of the system every day）**

| 做法 | 结果 |
|------|------|
| Spec to Code | **撤资**（Divest）——忽视设计，只关注规格 |
| 本演讲建议 | **投资**——每次 PR 都考虑接口和模块的变化 |

***

## 四、AI 编程的正确姿势：战略 vs 战术

```
         ┌──────────────────────────────────────┐
         │           你（战略层）                  │
         │  - 架构设计                           │
         │  - 接口设计                           │
         │  - 需求理解                           │
         │  - 代码审查                           │
         └──────────────┬───────────────────────┘
                        │  指挥
                        ▼
         ┌──────────────────────────────────────┐
         │         AI（战术层）                   │
         │  - 具体编码实现                       │
         │  -  Sergeant on the ground           │
         │  - 底层执行                          │
         └──────────────────────────────────────┘
```

**AI 是一个优秀的"地面 tactical 程序员"**——但它需要有人在战略层面思考。那个人就是**你**。

***

## 五、关键书籍推荐

| 书名 | 作者 | 核心概念 |
|------|------|----------|
| **The Philosophy of Software Design** | John Osterhout | 好/坏代码的定义、深度模块 |
| **The Pragmatic Programmer** | Dave Thomas & Andy Hunt | 软件熵、反馈速率即速度上限 |
| **The Design of Design** | Frederick Brooks | 设计概念 |
| **Domain-Driven Design** | Eric Evans | 通用语言（Ubiquitous Language） |

***

## 六、演讲者提供的资源

* **技能仓库**：GitHub [MikeOpenHWGroup/skills](https://github.com/MikeOpenHWGroup/skills)
* **网站**：[aiheroro.dev](https://aiheroro.dev)
* **社交媒体**：YouTube、Twitter

***

## 七、核心要点总结

1. **代码从来都不廉价**——烂代码是史上最昂贵的
2. **Spec to Code 不work**——忽视代码质量只会越来越糟
3. **与 AI 达成共享理解**——通过反复提问建立设计概念
4. **建立共享语言**——通用语言让沟通更高效
5. **反馈循环是关键**——静态类型、测试、浏览器访问
6. **TDD 强制小步前进**——防止"超出车灯范围"
7. **深度模块优于浅层模块**——让 AI 和人类都更容易理解
8. **设计接口，委托实现**——解放大脑
9. **每天投资系统设计**——在每个 PR 中思考架构
10. **你是战略层**——AI 负责战术执行
