乐于分享
好东西不私藏

AI 时代的软件工程方法论

AI 时代的软件工程方法论

很多团队都已经把 AI 引入了研发流程。

有人用它写函数,有人用它补测试,有人让它生成 SQL、排查日志、写接口文档。刚开始时,大家普遍都会有一种兴奋感:代码出得更快了,很多原本嫌麻烦的小事,现在一句话就能做完。

但热闹过后,问题也会很快出现。

同样一个需求,AI 今天写得像样,明天就开始越层;上一次它遵守了项目规范,下一次又自作主张改了目录结构;简单任务看起来很高效,复杂任务一多,返工、回滚、补测试、人工兜底反而变成了新的隐性成本。团队最后得到的,不是一个稳定的工程助手,而是一个时好时坏、产量很高、但协作成本也很高的“临时工”。

这时候我们才会意识到,问题往往不在模型本身,而在工程体系本身。

如果团队只是“把 AI 接进来”,却没有给它明确的边界、可靠的能力来源和可执行的外部工具,那么 AI 最多只能算一个会说很多、能写不少、但不真正对结果负责的生成器。真正能把 AI 用深、用稳、用出复利的团队,依赖的从来不是几条神奇 prompt,而是一套围绕软件工程重建过的协作系统。

这篇文章想讨论的,就是这套系统。

我会把它概括为一条核心判断:

AI 辅助软件工程的重点,不是“让 AI 会写代码”,而是“让 AI 在同一套工程约束下,稳定地参与设计、实现、验证和交付”。

围绕这个目标,我把实践中逐渐稳定下来的方法总结为六个关键词:规范SkillMCPDDD测试治理。它们不是彼此独立的工具箱,而是一套前后衔接的协作机制。

在这个过程中,工程负责人关注的重点也会发生变化。AI 时代真正重要的,不再是试图逐行盯住所有代码细节,而是像架构师或 CTO 一样,把更多精力放在需求澄清、架构边界、测试闭环、运行环境和反馈机制上,用软件工程的方法持续压缩不确定性。

一、为什么很多团队用了 AI,效率却没有持续提升

如果只看局部任务,AI 的确能带来非常明显的提速。

  • 写样板代码更快
  • 生成测试用例更快
  • 理解陌生模块更快
  • 完成文档和脚本更快

但软件工程不是若干个局部任务的简单相加。真正决定团队产能的,从来不是“生成速度”,而是“从需求到上线这条链路上,总体返工率是否下降,整体吞吐是否提升”。

很多团队之所以在第一波红利之后进入停滞,往往是因为遇到了下面四类问题。

1. AI 产出很快,但不稳定

它可以在一分钟内生成大量代码,但这些代码是否符合项目架构、是否遵守边界、是否贴合已有约定,常常是不确定的。于是团队必须投入额外时间去审查、修补和重写。

2. AI 能解决单点问题,但难以走完整链路

写一段函数、补一个测试、生成一个接口没问题,但一旦任务跨越多个系统,例如“操作页面验证功能,再查数据库确认结果,再回写测试报告”,单靠编辑器里的生成能力就不够了。

3. AI 提升了个人效率,却没有沉淀为团队能力

一个熟悉项目的人,可能靠经验和 prompt 把 AI 用得很好;换一个人、换一个模块、换一种任务,效果就会大幅波动。能力停留在“高手经验”层面,而没有变成可复制的团队资产。

4. 团队还在用“盯代码”的方式管理 AI,而不是用架构和测试管理不确定性

这可能是最容易被忽视、但也最关键的一点。

在传统团队里,一个架构师或 CTO 也不可能逐行掌控整个系统的所有代码细节。真正能把控全局的,从来不是“记住了每一行实现”,而是是否掌握了系统的边界、约束、验收标准、测试闭环、发布机制和回退手段。

AI 时代也是一样。我们不该把目标设定为“AI 绝不能写出有 bug 的代码”,因为人写的代码同样会有 bug。更关键的问题是:这个系统有没有能力尽快暴露问题、准确定义问题、并把问题收敛掉。

从软件工程视角看,真正的 bug 不是“实现细节看起来不够优雅”,而是结果不满足需求、不符合约束、不通过关键场景验证。很多争论停留在代码风格和实现细枝末节上,但对交付影响更大的,往往是需求偏差、边界越界、场景缺失和验证不足。

所以,AI 辅助软件工程真正要追求的,不是消灭一切不确定性,而是把原本模糊的需求、分散的约束、隐性的环境依赖和不完整的反馈,逐步转化成更确定的规范、更确定的架构、更确定的测试和更确定的执行闭环。

所以,AI 真正带来的不是一个简单的工具升级,而是一个新的工程命题:

如何把 AI 从“偶尔帮忙的生成器”,升级为“可以被规范、被编排、被验证、被复用的工程协作者”。

二、从工具思维到系统思维:AI 辅助工程化的三个支柱

如果要让 AI 稳定参与研发流程,我越来越倾向于用“三个支柱”来理解这件事。

  • 规范约束:定义 AI 的行为边界
  • 能力扩展:把复杂经验沉淀成可触发的 Skill
  • 工具集成:让 AI 能够真正触达代码之外的世界

这三者分别对应三个问题。

  • 它应该遵守什么规则
  • 它在复杂任务上凭什么做得稳定
  • 它除了生成文本和代码之外,是否真的具备执行力

很多团队的问题,恰恰就在于这三者只做了其中一项。

只做规范,没有能力和工具,AI 会变得“听话但不够能干”。

只做 Skill,没有规范,AI 会在局部任务上表现精彩,但整体行为仍然不可控。

只接工具,没有规范和 Skill,AI 虽然拥有执行权限,却很容易把流程跑偏,甚至把错误放大。

真正可持续的状态,是三者形成闭环:

  • 规范像宪法,始终生效
  • Skill像技能书,按需加载
  • MCP像双手,让 AI 能够执行动作

从这个角度看,AI 辅助软件工程并不是“把一个大模型接进 IDE”,而是“为 AI 建一套可长期演进的工程协作环境”。

三、第一根支柱:规范,不是文档,而是 AI 的行为边界

很多团队写规范,是给人看的。

但在 AI 时代,规范还有一个更关键的角色:它必须变成 AI 可以持续读取、持续执行、持续遵守的边界条件。

这是一个很重要的认知变化。过去我们说“团队有共识”,很多时候靠的是口头传递、代码评审和老成员带新人;现在如果希望 AI 参与交付,这些隐性共识必须被显式化。

规范真正需要解决的,通常不是“所有事情都写清楚”,而是优先写清楚那些最容易做错、做错代价又最高的部分。

例如:

  • 分层边界是什么
  • 目录结构如何组织
  • API 返回格式如何统一
  • 错误处理与日志规范如何约定
  • 哪些变更必须补测试
  • 哪些核心规则不能被自动重写

为了让规范既稳定又可演进,我更推荐把它拆成三个层级。

1. 全局宪章:定义长期稳定的底层约束

这一层变化最少,通常包括架构原则、代码风格、日志规范、错误处理策略、分层依赖方向等。它决定的是项目的“基本法”。

2. 领域规范:定义当前业务的真实约束

例如 API 契约、数据模型、业务规则、命名约定。这一层会随着业务演进逐步调整,但在任一时刻都应该代表“当前真相”。

3. 变更提案:承接正在发生的新增和调整

新功能、重构、优化、兼容性修改,都应该通过增量提案进入系统。这样 AI 在执行时知道什么是既有事实,什么是待落地变更,而不是把一切都混在一起。

这三层的核心意义在于:让 AI 在面对复杂项目时,不是每次都从零猜测上下文,而是沿着已有约束去理解和执行。

所以,规范不是“写完就放在那里的文档”,而是 AI 协作系统中的第一层基础设施。

四、第二根支柱:Skill,不是提示词模板,而是团队经验的模块化沉淀

规范解决的是边界问题,但它解决不了所有流程问题。

在真实研发过程中,有很多任务不是一句规则能讲清楚的。它们往往跨多个步骤、包含隐含判断、依赖经验顺序,甚至还要结合某些工具使用方式。比如:

  • 如何把需求拆成可实现的 change proposal
  • 如何生成高质量 E2E 用例
  • 如何排查一个线上故障并缩小范围
  • 如何按团队标准完成一次代码审查

这类任务最适合沉淀成 Skill。

我更愿意把 Skill 理解为“工程化的任务说明书”,而不是普通意义上的 prompt。一个好的 Skill,不只是告诉 AI 要做什么,而是把完成该任务所需的流程、判断、参考资料、工具调用方式和异常处理,打包成一个可重复触发的能力模块。

这件事对团队的价值非常大,因为它把原本依赖个人经验的能力,转化成了可复制的组织资产。

Skill 大体可以分成三类。

1. 知识型 Skill

负责提供某个领域的关键背景,例如架构模式、代码规范、排查经验、业务知识。这类 Skill 的作用是减少 AI 在陌生领域里的“胡乱发挥”。

2. 流程型 Skill

负责编排一个完整任务的步骤,例如需求录入、方案设计、测试验收、问题排查、发布文档生成。这类 Skill 最能体现“经验的结构化沉淀”。

3. 工具型 Skill

负责封装具体工具的调用方式,例如如何通过浏览器自动化做验收、如何访问数据库做数据校验、如何生成日报或同步规范。它本质上是让工具变得更容易、安全、稳定地被 AI 使用。

Skill 设计时有一个非常关键的原则:不要试图做一个“万能 Skill”,而要优先沉淀那些高频、复杂、容易出错的任务。

因为真正值得沉淀的,不是所有任务,而是“重复出现且需要判断”的任务。对于低频又简单的事情,直接做反而更划算;但对于高频又复杂的事情,越早 Skill 化,团队越快获得复利。

五、第三根支柱:MCP,让 AI 从“会说”走向“会做”

很多人第一次真正感受到 AI 协作的边界,往往发生在这一刻:

AI 已经把代码写出来了,也解释得头头是道,但你还是得自己打开页面点一遍、自己查数据库、自己看日志、自己确认结果,然后再回来告诉它哪里错了。

这说明它会“生成”,但还不会“闭环”。

MCP 的价值,就在于把这种断裂补上。

当 AI 能够借助 MCP 访问浏览器、数据库、文档系统、流程系统和其他外部工具时,它的角色就会从“代码编辑器里的建议器”,变成“具备一定执行能力的协作者”。

比如一个完整的功能验收流程,完全可以从过去的人工串行,变成一条自动闭环链路:

  1. AI 通过浏览器自动化操作页面
  2. AI 识别界面反馈是否符合预期
  3. AI 访问数据库验证数据是否正确写入
  4. AI 汇总结果并输出验收结论
  5. 若失败,AI 进一步缩小故障范围并协助修复

一旦打通这条链路,AI 的价值就不再只是“帮你写”,而开始变成“帮你验证、帮你排查、帮你完成更多原本需要人工串起来的流程”。

当然,MCP 不是接得越多越好。

它会直接扩大 AI 的执行半径,也会带来权限、安全、回退策略和审计要求。所以更合理的做法不是“全面接入”,而是“围绕具体 Skill 按需接入”,并在 Skill 中明确:

  • 什么时候调用工具
  • 调用失败后如何回退
  • 哪些环境允许调用
  • 哪些动作需要审计

也就是说,MCP 不是一个单独成立的能力层,而是要服务于规范和 Skill,成为整个 AI 工程体系里的执行引擎。

六、为什么 DDD、TDD 和 E2E 在 AI 时代反而更重要

有些人会觉得,AI 时代是不是可以弱化一些传统的软件工程方法,因为模型已经能“自动补全很多东西”了。

我的感受恰恰相反。

越是引入 AI,越需要那些能显著降低歧义、提高可验证性的工程方法。因为 AI 的长处是快,短板是偶尔会在看起来很合理的方向上一路跑偏。越能提供清晰结构和清晰反馈的工程方法,越能把 AI 的速度转化为真正有价值的产能。

1. DDD 的意义:让 AI 知道代码应该放在哪里

DDD 不只是“建模方法”,它对 AI 更直接的价值在于明确分层边界。

  • 接口层做输入输出映射
  • 应用层负责流程编排
  • 领域层承载核心业务规则
  • 基础设施层处理 ORM、缓存、外部系统接入

这套结构对人类开发者有帮助,对 AI 更有帮助。因为 AI 一旦理解了职责边界,很多常见错误就会明显减少,例如在 handler 里堆业务逻辑、在领域层直接依赖外部实现、在应用层写难以测试的细节代码。

某种意义上,DDD 提供的是一种“可生成的秩序”。

2. TDD 的意义:先固定预期,再让 AI 生成实现

AI 特别适合根据明确预期去补实现,也特别容易在预期模糊时输出“看起来像正确答案”的代码。

这就是为什么 TDD 与 AI 的结合非常自然。

当我们先写失败测试,先把输入、输出和关键行为定义清楚,再让 AI 生成最小可行实现,整个过程会稳定很多。因为这时候 AI 面对的不是开放性问题,而是受约束的问题。

这里还有一个经常被忽略、但我认为更重要的点:即使你怀疑 AI 写出来的某些单元测试存在“伪正确”,TDD 依然有很高的工程价值。因为我关注的重点不只是这些测试是不是完美正确,而是它们是否在持续逼迫代码走向更好的结构。

一个能够被稳定单元测试的函数,通常意味着它的输入输出更明确、依赖更可控、职责更单一、耦合更低。换句话说,单元测试不只是验证代码,它也在反向约束代码设计。只要系统里的核心函数能够被独立测试,这个系统的结构通常就不会太差;反过来,如果大量逻辑根本无法被拆开测试,往往说明真正的问题已经不是测试写得少,而是代码结构本身出了问题。

换句话说,TDD 给 AI 的不是负担,而是护栏。

3. E2E 的意义:给复杂业务场景一个真实闭环

单元测试能保证局部逻辑,集成测试能保证模块协作,但很多业务问题最终还是要回到“用户场景是否真正成立”。

而 AI 一旦具备浏览器和外部系统访问能力,E2E 就不再只是 CI 里的最后一道防线,也可以成为 AI 驱动验证和自我修复的重要依据。

从这个角度看,测试体系在 AI 时代不是被削弱了,而是被重新放大了价值:

  • 它让 AI 改得更大胆
  • 它让 AI 验得更及时
  • 它让 AI 的重构成本更低
  • 它让团队更敢把复杂任务交给 AI 参与

七、AI 辅助编码的效率,最终取决于工程环境是否可运行、可理解、可验证

很多人谈 AI 辅助编码效率,容易把注意力集中在模型能力和提示词技巧上。但在真实项目里,AI 的编码效率从来不是单变量问题,它更像下面这几个因素共同作用的结果:

AI 辅助编码效率 ≈ 模型能力 × 软件工程能力 × 架构能力 × 基础设施建设能力

如果后面三项明显薄弱,模型再强,最终表现也会很糟糕。因为 AI 写代码只是链路中的一个环节,而不是整个交付闭环。

真正容易把 AI 效率拉垮的,通常是下面几种情况。

1. 程序在开发环境下根本启动不起来,AI 就无法自启动、自验收

如果一个项目连本地开发环境都难以稳定启动,AI 就很难完成真正有效的闭环工作。它可以写代码,但没法自己运行、自己观察结果、自己验证改动是否生效,于是整个过程仍然高度依赖人工反复接力。

这种情况下,看似是 AI 能力问题,本质上其实是工程可运行性问题。

2. 程序启动依赖过多外部服务,场景缺失会让 AI 无法完成验证

很多系统即使本地能启动,也仍然强依赖外部服务、测试数据、权限配置、消息链路或历史状态。一旦这些依赖没有本地替代方案、Mock 机制或最小可运行场景,AI 看到的就只是一个残缺系统。

它也许能改动局部代码,但无法真正还原业务场景,自然也就无法完成高质量验收。

3. 代码结构混乱到人都读不懂,AI 只会把混乱进一步放大

如果代码结构本身职责不清、分层混乱、命名失真、目录无序,那么人类开发者读起来已经很吃力,AI 只会更难建立稳定理解。它可能通过局部模式匹配勉强完成修改,但很难形成真正可靠的全局判断。

换句话说,AI 并不会自动修复一个高度混乱的系统,很多时候它只会在混乱中继续生成更多混乱。

4. 运行基础环境拿不全,AI 就只能在残缺上下文中工作

AI 要想真正参与交付,不只是要看到代码,还要尽可能拿到运行所需的关键上下文,例如:

  • 环境变量和配置说明
  • 启动方式与依赖关系
  • 日志、监控和报错信息
  • 测试数据、数据库结构和外部接口约束

如果这些上下文长期散落在人的记忆、临时文档或口头经验里,AI 的工作就会天然建立在信息缺失之上。信息越残缺,它越容易在错误前提下给出“看起来有道理”的答案。

所以,AI 提效从来不只是“开发提效”,而应该是覆盖软件工程全链路的整体提效:从需求澄清、架构设计、环境准备、编码实现、测试验证,到上线验收、问题排查和能力沉淀,整个链路越可运行、越可理解、越可验证,AI 的价值才越容易真正释放出来。

八、AI 工程化最容易忽视的一点:基础设施要边开发边建设

很多团队在落地 AI 时会陷入一个两难。

一种做法是想先把规则、Skill、工具、测试、规范体系全部准备好,再开始真正使用 AI。结果往往是准备周期太长,建设动作脱离真实业务,最后做出来一套“看起来完整、实际上没人用”的平台。

另一种做法是完全不建设,只靠大家各自摸索 prompt 和习惯。这样短期看很灵活,长期却会让能力碎片化,难以传承,也难以放大。

更可行的路径,是边开发边建设。

也就是说,不把 AI 工程化当成一个必须先完成的大项目,而是当成一套随着交付逐步补齐的研发基础设施。每当团队在真实项目里遇到一个反复出现的问题,就顺手把它沉淀下来:

  • 如果它是长期稳定的约束,就补进规范
  • 如果它是高频复杂流程,就沉淀成 Skill
  • 如果它需要访问外部世界,就考虑接入 MCP
  • 如果它总是难以验证,就补测试和 Mock 基础设施

这样做的好处有两个。

第一,它始终围绕真实痛点建设,不容易过度工程化。

第二,它会天然形成复利。因为每一次沉淀,都会让后续类似问题的处理成本更低,让 AI 的协作稳定性更高。

这也是我越来越认同的一条实践原则:

最好的 AI 工程体系,不是预先设计得最完整的那一套,而是在持续交付中最能自我增长的那一套。

九、如果从零开始,团队应该怎么落地

说了这么多,如果把问题收缩成一句话,其实就是:

一支普通工程团队,怎样才能从“会用 AI”走到“能把 AI 用成稳定生产力”。

我的建议不是全面铺开,而是从最小闭环开始。

第一步:先建立一份真正会被执行的治理规范

不要一开始写很厚的文档。先把最关键的几条规则写清楚,例如:

  • 项目的分层原则
  • 目录与职责边界
  • API 与错误处理约定
  • 新增代码的测试要求

它们的目标不是“完整”,而是“能马上约束 AI 的日常输出”。

第二步:选一个高频复杂任务做第一个 Skill

比如需求录入、E2E 用例生成、故障排查、代码审查。标准很简单:这个任务最好高频、复杂、容易出错,而且团队已经积累了一些稳定经验。

第一版 Skill 不需要完美,只要能把核心流程跑顺就够了。

第三步:为这个 Skill 配一个最必要的外部工具

如果是功能验收,就接浏览器自动化。

如果是数据验证,就接数据库能力。

如果是文档查询,就接文档系统。

不要同时铺太多工具,而是让第一个 Skill 真正形成“能做完一件事”的闭环。

第四步:先把开发环境做成 AI 也能真正跑起来的环境

这一点往往比很多人想象得更重要。一个对人都不够友好的开发环境,通常也不可能对 AI 友好。

至少要尽量做到下面几件事:

  • 项目有稳定、明确的启动方式
  • 关键依赖服务有本地替代方案、测试环境或 Mock 方案
  • 必要的环境变量、配置和初始化步骤是可见的
  • 日志、错误信息和验证结果能够被及时获取

只有当环境本身可运行、可观察、可复现,AI 才有可能从“会生成代码”走向“能闭环完成任务”。

第五步:补测试基础设施,让 AI 可以安全迭代

一旦你希望 AI 能更频繁地改代码,就必须给它更稳定的反馈系统。单元测试、集成测试、E2E、Mock、覆盖率校验,这些都不是额外负担,而是 AI 协作的放大器。

第六步:把每一次有效实践继续沉淀

当团队开始在多个任务上稳定使用 AI,就可以逐步扩展:

  • 增加更多规范
  • 拆分更多 Skill
  • 扩展更多 MCP 集成
  • 让规范、技能和工具形成更完整的协作网络

到这时,AI 才会真正从“个体效率工具”演进为“团队生产力基础设施”。

十、结语:AI 的上限,取决于团队是否愿意重建自己的工程秩序

AI 当然会继续变强,模型能力也一定会继续提升。

但在工程实践里,真正决定使用上限的,往往不是模型参数,而是团队是否愿意把自己的规范、经验、流程和工具重新组织起来,让它们变成 AI 可以理解、可以执行、可以复用的协作系统。

人写的代码会有 bug,AI 写的代码当然也会有 bug。真正不成熟的,不是 bug 本身的存在,而是团队没有能力把 bug 快速暴露、快速定义、快速修正。软件工程的价值,正是在不确定的需求、不完整的上下文和复杂的实现之间,持续制造确定性。

所以,AI 辅助软件工程最值得做的事情,不是追逐下一条更强的 prompt,而是认真回答下面几个问题:

  • 我们希望 AI 长期遵守哪些规则
  • 我们有哪些经验值得沉淀成 Skill
  • 我们愿意让 AI 接触哪些外部工具
  • 我们有没有足够的测试与治理,让 AI 可以安全地更深入参与交付

当这些问题被认真对待之后,AI 才不再只是一个“帮忙写代码的工具”,而会逐渐变成一个真正融入团队协作体系的工程角色。

这时,你会发现,所谓 AI 时代的软件工程,核心变化并不是“多了一个代码生成器”,而是“团队终于开始用新的方式,重新建设自己的软件工程”。


附:一句话版方法论

如果需要把这篇文章压缩成一句话,我会这样说:

用规范定义边界,用 Skill 沉淀经验,用 MCP 赋予执行力,再用架构、测试、环境和持续治理把不确定不断收敛为确定性,最终把 AI 变成一个稳定可协作的工程伙伴。

后记:关于这套方法论的实践课程

围绕这套方法论的落地实践,我也已经在持续写专栏,把规范设计、Skill 沉淀、MCP 接入、AI 友好环境建设、DDD/TDD/E2E 落地等内容进一步拆成更具体的实践课程与案例,持续对外推广和分享。