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)
相关推荐
ting94520001 小时前
GRPO 算法全解析:从原理到实战
人工智能·架构
一朵缥缈的向日葵.1 小时前
[特殊字符] Mojo 语言:为 AI 硬件而生的“Python 升级版” —— 完整指南
人工智能·python·mojo
JAVA面经实录9171 小时前
Spring AI 高频开发万能 Prompt 合集 + 生产级工具类
java·人工智能·spring·prompt
Jmayday1 小时前
NLP第一章:自然语言处理入门
人工智能·自然语言处理
HuDie3401 小时前
prompt构建
大数据·人工智能·prompt
小罗和阿泽1 小时前
简单认识一下大模型!
人工智能·语言模型
TTGGGFF1 小时前
深度学习如何重塑三维重建:从任务定义到工程落地全流程解析
人工智能·深度学习
财经资讯数据_灵砚智能1 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(日间)2026年4月29日
大数据·人工智能·python·信息可视化·自然语言处理
天天讯通1 小时前
OKCC 海外落地最简配置:助力海外业务高效运营
人工智能