Code is not cheap

如何用AI写出好的代码

在 AI 时代,烂代码的代价比以往任何时候都更高

  • 如果代码库难以修改,你就无法充分利用 AI 带来的所有优势
  • AI 在良好的代码库上表现非常出色
  • 因此,好的代码库比以往任何时候都更重要,软件基础原则也比以往任何时候都更重要

失败的解决方案

模式一:AI 没有做你想要的事

症状:头脑中有一个好的想法,但 AI 做了完全不同的事情,或者生成了你不想要的东西。

原因 :你和 AI 之间存在沟通障碍 ,缺乏共享的设计概念(Design Concept)。

概念------设计概念(Design Concept)

出自 Frederick Brooks 的《设计的设计》

当多人共同设计某样东西时,会有一个想法在你们之间飘浮------这就是"设计概念"。它是关于你要构建的东西的无形理论,不是可以放在 markdown 文件中的资产。

解决方案:Grilling Me Skill

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 个),直到达到共享理解
  • 将对话转化为产品需求文档或 issue
  • AFK agent(离线代理)随后接手

建议 :在开始使用工具的默认 Plan 模式之前,先达到共享的设计概念会更好。


模式二:AI 太冗长

症状 :与 AI 交流时感觉不在同一个频道上,它用太多话解释它在做什么。

原因 :开发者与 AI 之间存在语言鸿沟,就像开发者与领域专家之间的鸿沟一样。

概念------统一语言(Ubiquitous Language)

出自领域驱动设计(Domain-Driven Design, DDD)

开发者之间的对话、代码中的表达式、与领域专家的对话,都应源自同一个领域模型。统一语言本质上是一个 markdown 文件,列出了你和 AI 共同拥有的术语列表。

解决方案:Ubiquitous Language Skill

工作流程:

  1. 扫描代码库,识别术语
  2. 创建 markdown 文件,包含术语的表格
  3. 将这个文件传递给 AI
  4. 在与 AI 协作时始终保持打开参考

效果:

  • 改善规划质量
  • 让 AI 以更简洁的方式思考
  • 实现更符合计划精神的代码

模式三:AI 构建了正确的东西但不工作

症状:AI 理解了需求并构建了正确的东西,但代码不工作。

解决:建立反馈循环

  • 使用静态类型(TypeScript 强烈推荐)
  • 让 LLM 访问浏览器以便探索
  • 自动化测试

模式四:LLM 过度超前(Outrunning Your Headlights)

症状 :AI 一次做太多事情,产生大量代码后才发现类型错误或测试失败。

概念------超越你的车灯(Outrunning Your Headlights)

出自《实用程序员》

反馈的速度就是你的速度极限。你应该边做边测试,采取小而谨慎的步骤。AI 默认情况下非常不擅长这一点。

解决方案:测试驱动开发(TDD)

TDD 强制 LLM 采取小步骤:

  1. 先创建测试
  2. 让测试通过
  3. 重构代码以改善设计

为什么测试很难

编写测试需要做出许多相互依赖的决策:

  • 要测试多大的单元?
  • 要 mock 什么?
  • 首先要测试什么行为?

关键 :好的代码库 = 易于测试的代码库


模式五:代码能工作但大脑跟不上

症状:反馈循环运行良好,代码产出比以往任何时候都多,但大脑疲惫不堪。

原因:代码库让 AI 和你都需要在脑中同时处理太多信息。

解决方案:设计接口,委托实现

将深模块视为**灰盒**:

  • 设计好接口
  • 不需要深入审查实现细节
  • 用测试从外部验证

注意:对于金融等关键模块不能这样做,但对于应用中许多其他模块可以。

效果 :节省脑力,专注于战略层面的设计。


软件基础原则

1. 软件熵(Software Entropy)

出自《实用程序员》

熵是事物趋向灾难和崩溃的倾向。每次你修改代码库时,如果只考虑那个变更而不考虑整个系统的设计,你的代码库会变得越来越糟糕。

教训:spec-to-code 的做法只会让代码越来越差。

2. 深度模块化(Deep Modules)

出自 John Ousterhout 的《软件设计的哲学》

类型 特点 示例
深度模块 大量功能隐藏在简单接口后面 ✅ 隐藏复杂性,按需查看内部
浅层模块 功能不多,接口却很复杂 ❌ AI 需要在大量小模块间导航,难以理解

架构改造技能:Improved Codebase Architecture

将浅层模块代码库改造为深层模块:

  1. 探索代码库
  2. 寻找相关的代码
  3. 将它们包装在一个深模块中
  4. 在接口处进行测试

3. 统一语言(Ubiquitous Language)

核心原则:

  • 代码、对话、文档使用相同的术语
  • 确保术语与实际含义一致
  • 术语需要成为 ubiquitous language 的一部分

4. 投资系统设计

来自 Kent Beck

每天都要投资于系统的设计。

spec-to-code 的问题:不是在投资系统设计,而是在撤资。


架构视图对比

浅层模块架构

复制代码
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│ 模块 │ │ 模块 │ │ 模块 │ │ 模块 │ │ 模块 │
└──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘
   │       │       │       │       │
   ▼       ▼       ▼       ▼       ▼
(大量小 blob,AI 需要逐一导航)

深层模块架构

复制代码
        ┌─────────────────────────────┐
        │         接口层              │
        │  ┌─────────┐  ┌─────────┐  │
        │  │ 接口 A  │  │ 接口 B  │  │
        │  └────┬────┘  └────┬────┘  │
        └───────┼───────────┼───────┘
                ▼           ▼
        ┌─────────────┐ ┌─────────────┐
        │  深模块实现  │ │  深模块实现  │
        │  (可委托)  │ │  (可委托)  │
        └─────────────┘ └─────────────┘

AI 协作中的角色分工

角色 职责
AI 地面战术级程序员,执行具体的代码变更
人类 战略级思考者,负责设计、架构、决策

AI 是一个出色的战术级程序员,但需要人类在上面进行战略层面的思考。这正是软件基础技能的价值所在。


参考文献: github.com/mattpocock/skills

相关书籍

书名 作者 核心概念
《软件设计的哲学》 John Ousterhout 深度模块、代码复杂性
《实用程序员》 David Thomas, Andrew Hunt 软件熵、TDD
《设计的设计》 Frederick Brooks 设计概念
《领域驱动设计》 Eric Evans 统一语言(Ubiquitous Language)
相关推荐
JWASX3 分钟前
【agent 开发】Agent 智能体
大数据·人工智能·python
智购科技无人售货机工厂店7 分钟前
玻璃瓶饮料破损率突然上升,排查发现是取货口缓冲垫老化了~YH
java·开发语言·人工智能·python·eclipse
骇客野人11 分钟前
业务系统接入AI方案及全流程实施过程
人工智能
一木 之林14 分钟前
Dify学习笔记 00 · 总览:56集四模块学习地图(从低代码平台到检索底座)
人工智能·计算机视觉·langchain
镜象科技16 分钟前
中小学AI心理健康解决方案服务商怎么选?2026年选型参考
android·java·人工智能
枫叶丹417 分钟前
语音 AI 怎样边听边答:实时对话系统的工作原理
开发语言·人工智能·chatgpt·开源·php·agent·codex
楚楚25122 分钟前
播客单声道怎么变立体声:先明确需求再选择处理方案
人工智能
田里的水稻26 分钟前
IL_部署推理---工具和语言
人工智能·神经网络·机器学习
俊男无期26 分钟前
【AI 和未来】工作(1)
人工智能
IT大白鼠27 分钟前
彭大帅的AI运维助手实战案例 5 · 新接手的服务器,先让 AI 摸底
运维·服务器·人工智能