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)
相关推荐
JXJD20046 分钟前
【无标题】
人工智能·ai·自动化
LONGZETECH21 分钟前
低空经济背景下:五组核心数据拆解无人机职业教育的机遇与实训破局
大数据·人工智能·系统架构·无人机
aichitang202424 分钟前
希尔伯特空间中的正交性
人工智能·学习·机器学习·ai·泛函分析
aiqianji26 分钟前
功能全面的教AI短篇小说写作的软件都有哪些?
人工智能·python
格林威39 分钟前
C# 相机Burst模式图像采集:使用相机内存配合OpenCvSharp和Halcon实现短时间的高速采集的方法
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·工业相机
轮到我狗叫了44 分钟前
Slurm如何使用
人工智能·python·深度学习·机器学习
AI创界者1 小时前
【开源硬核】comfyUI MiniMax H3 融合模型本地部署一键整合包!单卡撬动 2K 影音全模态输出,附避坑指南
人工智能·aigc
2601_963749101 小时前
越华环保集团|河湖工况下数字化污水治理云边协同采集架构实现
人工智能·架构
闪学it1 小时前
小滴课堂-AI大模型小龙虾-OpenClaw-0基础从入门到实战
人工智能
代码方舟1 小时前
零信任架构实战:基于天远手机携号转网V即时版构建自动化营销风控网关
人工智能·智能手机·架构·自动化