Be Intentional About How AI Changes Your Codebase

⭐⭐⭐⭐ (4星) | 2026-03-20 | AI 代码设计 最佳实践

概述

关于 AI 辅助编程时代代码设计最佳实践的深度思考,探讨语义函数、实用函数和模型设计的核心原则。

核心理念: 代码应该自我文档化——如何拆分逻辑函数和塑造传递的数据决定了代码库长期维护的质量。

语义函数 (Semantic Functions)

语义函数是代码库的构建块。一个好的语义函数应该尽可能最小化,以优先保证正确性。

特征

  • 接受完成目标所需的所有输入
  • 直接返回所有必要的输出
  • 可以包装其他语义函数来描述期望的流程
  • 副作用通常是不受欢迎的
  • 应该易于单元测试

示例

  • quadratic_formula() - 简单明确
  • retry_with_exponential_backoff_and_run_y_in_between() - 复杂但自描述
原则: 语义函数不需要注释——代码本身应该是其行为的自描述定义。

实用函数 (Pragmatic Functions)

实用函数作为一系列语义函数和独特逻辑的封装层。它们是代码库中的复杂流程。

使用场景

  • 复杂业务逻辑的编排
  • 跨多个语义函数的流程
  • 不太可能在多处重用

示例

  • provision_new_workspace_for_github_repo(repo, user)
  • handle_user_signup_webhook()

文档原则

  • 避免重复函数名称的说明
  • 记录意外情况,如"余额少于10时会提前失败"
  • 把文档评论当作参考,要事实核查

模型设计 (Models)

数据的形状应该使错误状态变得不可能。

核心原则

  • 精确命名: 模型名称应足够精确,以至于看任何字段都知道它是否属于该模型
  • 组合而非合并: 两个经常一起需要但独立的概念应该组合而非融合
  • 品牌类型: 使用品牌类型(brand types)区分形状相同但含义不同的值

品牌类型示例

// 而非 bare UUID
DocumentId(UUID)
MessageId(UUID)

// 模型组合
UserAndWorkspace {
    user: User,
    workspace: Workspace
}

好的命名示例

  • UnverifiedEmail - 明确状态
  • PendingInvite - 明确生命周期
  • BillingAddress - 明确用途

代码腐化模式

函数腐化

常见问题:语义函数变成实用函数后,其他依赖它的代码开始做意想不到的事情。
  • 通过命名用途而非行为来明确创建函数
  • 函数名应表明行为不严格定义
  • 使调试回归更容易

模型腐化

常见问题:"就加一个可选字段"导致模型变成松散的数据袋。
  • 每个可选字段都是代码需要回答的问题
  • 松散类型字段是传入看似正确但实际错误数据的邀请
  • 当模型名称不再描述数据时,是时候拆分了

AI 时代的特别考量

  • AI 更容易阅读良好结构化的代码
  • 语义函数帮助 AI 理解代码意图
  • 清晰的模型边界减少 AI 产生幻觉
  • 自描述代码减少 AI 添加不必要的注释

参考资源