优秀的架构与龌龊的代码:一个跨平台团队的 AI 编码实践

分享:

过去小半年,我在一个 Android + iOS 跨平台项目里深度使用 AI 编程。双端逻辑高度对齐,累计代码量数十万行。

说实话,这个过程里踩了不少坑,也摸索出了一些还算靠谱的方法论。

这篇文章不是 AI 工具的使用教程 —— 网上这类内容已经够多了。我想聊的是思维方式的转变:当 AI 成为主要的代码产出者时,工程实践应该做哪些调整?

先说结论:在 AI 时代,架构的重要性远大于代码本身。


一、优秀的架构与龌龊的代码

这个标题看起来矛盾,但它是我们最核心的认知。

传统开发中,我们追求「干净的代码」。变量命名要优雅,函数拆分要合理,注释要恰到好处。一个资深工程师的价值,很大程度上体现在代码的可读性和可维护性上。

但 AI 改变了这个等式。

当 AI 可以在几秒钟内重写一整个函数、甚至一整个模块时,代码的「质量」就不再是最重要的了。真正重要的是什么?是 AI 能不能正确理解「这段代码应该放在哪里」、「它应该跟谁通信」、「它的职责边界在哪」。

说到底,架构决定了 AI 的天花板

举个我们踩过的坑。项目早期有一段时间,模块划分不够清晰,两个业务模块之间有大量隐式依赖。让 AI 在 A 模块加一个功能,它「好心」地直接引用了 B 模块的内部类 —— 编译没报错,功能也跑通了,但这种耦合埋了一堆隐患。后来我们花了差不多一周时间理清模块边界,加上编译级的依赖管控,这类问题才彻底消失。

这就是我说的「优秀的架构与龌龊的代码」—— 我们接受 AI 产出的代码可能不完美,变量名可能不够漂亮,写法可能有点啰嗦。但我们绝不接受架构的混乱

架构一旦乱了,再强的 AI 也只是在错误的位置做「正确」的事。


二、对齐什么,放弃什么

跨平台开发中,「对齐」是永恒的话题。但 AI 时代的对齐策略跟以前不太一样。

有些东西必须严格对齐,有些东西完全可以放手。搞清楚这条线在哪,是高效使用 AI 的关键。

2.1 必须对齐的三个维度

架构对齐

这是最高优先级。

  • API 定义对齐:我们用 OpenAPI YAML 作为 API 的唯一事实来源,通过工具自动生成双端代码。手动写 API 调用代码?直接禁止。
  • 模块分层对齐:项目分为 4 层(App → 业务层 → 基础层 → 三方库),每层的依赖方向严格管控。AI 试图让基础层依赖业务层?编译直接报错。
  • 功能划分对齐:同一个业务功能,在 Android 和 iOS 端必须放在相同的模块路径下。不是「大概差不多」,而是文件名、类名、接口名完全一致

名词对齐

这个容易被忽视,但名词不一致是跨平台项目最隐蔽的技术债。

我们吃过亏。有一次 Android 端一个页面叫 UserProfilePage,iOS 端却叫 ProfilePage,排查一个路由跳转问题的时候,两边的人聊了半天才发现说的根本不是同一个页面。

所以我们做了几件事:

  • 业务名词统一:「角色」「对话」「商品」这些概念,双端必须用同一个英文名。专门搞了一套术语一致性检查工具来强制校验。
  • 技术名词统一:页面名、路由键、接口名,全部通过工具在代码层面检查一致性。
  • 函数和变量命名要准确:AI 时代的代码主要不是给人看的(AI 能秒懂),但命名必须准确 —— 因为 AI 也依赖准确的命名来理解上下文。

流程对齐

最容易被忽视,但影响最大。

  • 需求开发流程:先确定接口 → 再确定页面路由 → 再开发子功能 → 最后集成测试。AI 也必须遵循这个顺序,不能跳步。
  • 编译问题修复流程:修改代码 → 编译 → 分析报错 → 修复 → 再编译,循环直到通过。这个流程已经封装成了自动化 Skill。
  • API 文档更新流程:修改 YAML 定义 → 生成双端代码 → 更新术语表 → 校验一致性。
  • Git 提交流程:AI 禁止自行 commit/push,必须开发者明确说「替我 commit」才行。

2.2 不需要对齐的

功能的实现细节

同一个业务逻辑,Android 用 Coroutines,iOS 用 async/await,完全不需要逐行对齐。我们只关心接口一致、状态一致、行为一致。至于内部怎么写,AI 爱怎么搞就怎么搞。

Bug 修复方式

传统开发中,Bug 修复要 review、讨论方案、评估影响范围。但现在很多时候的做法是:让 AI 改,编译通过,跑一跑没问题,就行了。

代码的「优雅程度」

AI 生成的代码可能有冗余的判空、多余的变量、不够简洁的写法。只要它在正确的位置、做正确的事、编译通过、功能正确,一律接受。

代码的审美不再是瓶颈,架构的正确性才是。


三、让 AI 高效工作的基础设施

光有思路不够。要让 AI 真正高效地干活,需要一套配套的基础设施。

3.1 三层文档体系:AI 的「操作手册」

AI 的工作质量直接取决于它能拿到多少上下文。但全量上下文又会爆 Token。怎么办?

我们的方案是渐进式披露的三层文档体系。

第 1 层 — 项目根目录 AGENTS.md

最精简的项目概览。只包含核心原则、命名规范、依赖规则、和指向下层文档的导航链接。AI 每次对话都会加载这个文件。

第 2 层 — 平台层 AGENTS.md

android/AGENTS.mdios/AGENTS.md,包含平台特定的编译配置、目录结构、技术栈细节。AI 处理特定平台任务时按需加载。

第 3 层 — 模块层 AGENTS.md

每个业务模块都有自己的 AGENTS.md,记录模块的功能说明、核心 API、注意事项。AI 修改具体模块时深入到这一层。

这套体系有几个关键设计:

  • 每个 AGENTS.md 都有对应的 CLAUDE.md 软链接,只维护一份
  • 跨平台共享知识统一在 docs/ 目录,避免重复维护

3.2 术语一致性检查:双端对齐的「守门人」

这可能是我们最有价值的实践之一。

项目维护了三类术语表:页面名词表、组件名词表、接口名词表。每次代码变更后,自动执行一致性检查:

# 从代码自动提取术语
python3 naming_check.py generate

# 校验双端一致性
python3 naming_check.py check

如果 Android 端有一个页面叫 UserProfilePage,iOS 端却叫 ProfilePage,工具会立即报错。这种检查不依赖人工 review,而是在工具层面强制执行。

3.3 编译驱动开发:最务实的质量保障

这是我最想分享的一个观点:在 AI 时代,单元测试的价值大幅下降,编译测试和端到端测试才是王道。

为什么?

AI 不太会犯「函数级」的逻辑错误。它不会把 > 写成 <,不会忘记空值检查,不会搞混参数顺序 —— 这些是单元测试要防止的典型问题。

AI 真正会犯的错误是「架构级」的:在错误的模块引入了不该有的依赖、调用了不存在的 API、类型不匹配。

而这些错误,编译器就能抓住

我们的开发循环:

  1. AI 修改代码
  2. 跑编译脚本(同时编译 Android 和 iOS)
  3. 编译失败?AI 自动分析报错、修复、重新编译
  4. 编译通过?人工跑一遍端到端流程确认

这个循环被封装成了一个自动化 Skill,AI 可以自己跑完整个流程,直到双端都编译通过。

3.4 专用 Skill 工具链

我们把重复出现的 AI 工作流封装成了专用 Skill:

  • build-fixer:自动检测和修复双端编译错误,循环执行直到通过
  • code-align:一端完成修改后,自动将逻辑同步到另一端
  • api-updater:给一个 API 路径,自动更新 YAML 定义并生成双端代码
  • tech-doc-generator:基于 Use Case 驱动的技术设计文档生成

这些 Skill 的价值不在于「自动化」本身,而在于保证了流程的一致性。无论是哪个开发者、哪个 AI 模型,执行同一个 Skill 都会走完全相同的步骤。


四、AI 行为守则

让 AI 高效工作只是一半,另一半是确保它不搞破坏。

我们在 AGENTS.md 里写了一套 AI 行为守则,每次对话自动加载。

4.1 最小变更原则

最重要的一条:AI 只能修改任务直接要求的代码。

我们发现 AI 有很强的「优化欲望」—— 它会顺手重构周围的代码、添加类型注解、调整格式化。这些改动单独看都是「改进」,但在大型项目中,它们会导致巨大的 diff,code review 直接崩溃。

所以明确规定:

  • 不得重写、重新排序或重构不相关的代码
  • 不得修改空白字符
  • 新增函数调用时,参数等于默认值应省略
  • 不确定是否需要额外改动时,必须停下来问人

4.2 禁止 TODO

传统开发中,留 TODO 是合理做法 —— 标记未来要做的事。

但 AI 留 TODO?不行。

因为 AI 留 TODO 意味着它没有完成任务。一个存根实现、一个空代码块、一个「这里以后再补」的注释,就等于交了一份未完成的作业。

我们的要求:每段代码必须完整、具体、可运行。做不到?停下来问,别留占位符。

4.3 注释质量

标准很简单:宁愿不加,也不加废话。

禁止的注释:

  • 重复代码内容的(// 遍历列表
  • 描述函数名、参数名、返回类型的
  • 描述基本逻辑的(// 如果为空则返回

允许的注释:

  • 解释「为什么」而非「是什么」
  • 记录非显而易见的行为或假设
  • 标注平台特定的坑
  • 对外接口可提供简单使用样例

所有注释用中文 —— 团队约定,也避免了 AI 生成大段英文注释。


五、实际效果

说了这么多方法论,聊聊实际效果。

5.1 生产力提升:保守估计 4 倍

这不是为了写文章故意往大了说,是我自己做下来最直接的体感。

以前一个中等复杂度的需求,比如加一个列表页、一个详情页,再把 API 接上,正常做下来怎么也得两三天。现在我的做法一般是:

  1. 先把 API 的 YAML 定义写清楚,差不多半小时。
  2. 跑一遍 api-updater Skill,双端 API 代码几分钟就出来了。
  3. 让 AI 参考现有页面先把骨架搭出来,我再补细节,半小时左右。
  4. 编译一遍,先看有没有明显问题。
  5. 真机把主流程跑一遍,哪儿不对就继续让 AI 修。
  6. 最后过一下术语和命名,没问题就提。

一套走完,通常半天以内能收工,而且 Android 和 iOS 是一起往前走的。

5.2 开发者角色的变化

以前是「写代码的人」,现在更像是「架构师 + 审计员」。

我现在日常更常做的是:

  • 定义架构:决定新功能放在哪个模块、遵循什么接口
  • 审查 AI 产出:主要看架构是否正确,不纠结代码是否优雅
  • 维护文档:AGENTS.md 的质量直接决定 AI 的工作质量
  • 端到端验证:跑通完整流程,确认功能符合预期

其实挺有意思的 —— 这种转变让开发者可以把精力放在真正有创造性的事上:架构设计、产品思考、用户体验。而不是花时间在「把设计稿翻译成代码」这种机械活上。


六、总结

回到开头那句话:在 AI 时代,架构的重要性远大于代码本身。

如果要落到实践,我自己的结论是:

  1. 投资架构:定义清晰的模块边界、依赖规则、命名规范。这是 AI 高效工作的前提。
  2. 投资工具:术语检查、编译脚本、自动化 Skill,让机器来保证一致性。
  3. 投资文档:AGENTS.md 文档体系是 AI 的「培训手册」,文档质量 = AI 产出质量。
  4. 接受不完美的代码,但不接受错误的架构。

不用 AI 辅助开发的团队,会在效率上被逐渐拉开差距 —— 当 2 个人能做原来 8 个人的活时,成本结构就决定了竞争结果。

但 AI 编程不是简单地「让 AI 写代码」。它是一种全新的工程实践,需要在架构、文档、工具链、流程规范上做系统性的投入。

优秀的架构 + AI 的速度 = 真正的生产力革命。