1. 从“氛围编程”到工程纪律:为什么我们需要重新审视 AI 协作方式
“氛围编程”这个词最近在开发者圈子里流传得很快,它描述的是一种相当普遍的工作状态:打开 AI 编程助手,用自然语言描述一个模糊的需求,看着代码一行行自动生成,感觉效率飞起,然后不断追加新的需求,让 AI 继续补全。整个过程行云流水,充满“氛围感”,但几轮对话之后,项目里开始出现重复的工具函数、互相矛盾的接口定义、无法运行的测试用例,以及没人能说清楚逻辑的“黑盒模块”。这就是所谓的“代码雪崩”——不是一次性的崩溃,而是持续累积的熵增,最终让整个项目变得不可维护。
我过去大半年时间一直在跟踪和实践 AI 辅助编程的工作流,踩过的坑可以说相当密集。最开始我也沉迷于那种“一句话生成一个模块”的快感,直到有一次在一个中型项目里,AI 生成的代码在第三天开始出现前后端字段对不上的问题,排查了两个小时才发现是两次对话中 AI 对同一个数据结构的理解发生了漂移。那次之后我开始认真思考:AI 编程助手的能力毋庸置疑,但如果没有一套工程纪律来约束协作过程,它带来的技术债务可能比手工编码还要隐蔽和危险。
这篇文章要拆解的核心,就是如何用Superpowers 技能框架、TDD 契约驱动和AI 工程纪律闭环这三样东西,把 AI 辅助编程从“氛围驱动”拉回到“工程驱动”的轨道上。Superpowers 技能框架解决的是“AI 应该具备哪些可复用的能力单元”的问题;TDD 契约驱动解决的是“如何让 AI 在明确的边界内工作”的问题;工程纪律闭环解决的是“如何持续验证和修正 AI 的输出”的问题。三者叠加,形成一套可落地、可复现的协作方法论。
这套方法适合谁?如果你已经在日常开发中使用 AI 编程助手,但经常遇到生成代码质量不稳定、上下文丢失、重构困难等问题,那这篇文章就是写给你的。如果你刚开始接触 AI 辅助编程,这套框架同样适用,因为它本质上是在教你如何像一个技术负责人那样去管理一个“能力很强但需要明确指令”的协作者。下面我会从整体设计思路开始,逐步拆解每个环节的实现细节和实操要点。
2. Superpowers 技能框架的整体设计与拆解思路
2.1 什么是 Superpowers 技能框架,它解决什么问题
Superpowers 技能框架的核心思想,是把 AI 编程助手的能力从“通用对话”转化为“可组合的技能单元”。你可以把它理解为一套给 AI 准备的“工具箱”,每个工具(技能)都有明确的输入、输出和适用场景,而不是让 AI 每次都从零开始理解你的意图。
我最初接触这个概念时,觉得它有点像给 AI 写“岗位说明书”。传统方式下,你对 AI 说“帮我写一个用户登录功能”,AI 会根据自己的训练数据和对这句话的理解,生成一套它认为合理的代码。但问题在于,它认为合理的方案可能和你的项目架构、命名规范、错误处理策略完全不一致。Superpowers 技能框架的做法是,提前定义好“登录功能”这个技能应该包含哪些要素:输入参数是什么、输出格式是什么、依赖哪些基础设施、遵循什么编码规范、需要覆盖哪些边界情况。AI 在这个框架下工作,就像一个有经验的开发者拿到了详细的技术方案,而不是凭感觉发挥。
这个框架解决的核心问题是一致性和可复用性。在没有框架的情况下,每次让 AI 生成代码都是一次“重新协商”,协商结果取决于你这次描述得是否清楚、AI 这次理解得是否准确。有了框架之后,技能本身成为可积累的资产,你可以在不同项目、不同会话中复用同一套技能定义,AI 的输出质量会随着技能定义的完善而持续提升。
2.2 技能单元的粒度划分与组织方式
技能单元的粒度划分是这套框架落地时最关键的决策。粒度太粗,技能定义会变得臃肿,AI 难以准确执行;粒度太细,技能数量爆炸,管理和组合的成本会急剧上升。我实践下来的经验是,以“一个完整的业务动作”作为技能单元的边界比较合适。
举个例子,“用户注册”可以是一个技能单元,它包含表单验证、密码加密、数据库写入、邮件通知等子步骤,但这些子步骤在业务上是紧密关联的,拆开反而会增加组合复杂度。而“发送邮件”本身也可以是一个独立的技能单元,因为它会被多个业务动作复用。判断标准很简单:如果一个动作在多个场景下被重复使用,它就值得成为一个独立技能;如果一个动作只在特定业务场景下出现,它就应该被包含在更大的技能单元里。
在组织方式上,我建议采用三层结构:基础技能层、业务技能层和编排层。基础技能层包含与具体业务无关的通用能力,比如“生成符合项目规范的 CRUD 接口”“编写单元测试”“进行代码格式化”等。业务技能层包含特定领域的业务动作,比如“处理订单退款”“生成月度报表”等。编排层则负责把多个技能组合成一个完整的工作流,比如“用户下单”可能涉及“验证库存”“创建订单”“扣减库存”“发送通知”等多个技能的编排。
这种分层的好处是,基础技能层可以跨项目复用,业务技能层可以在同一项目的不同模块间复用,编排层则根据具体需求灵活调整。我在一个电商类项目中应用这套结构时,基础技能层积累了大约二十个通用技能,业务技能层有八个核心业务技能,编排层根据不同的用户故事组合出十几种工作流,整体开发效率比之前提升了大约三倍,而且代码一致性明显改善。
2.3 技能定义的结构化描述方法
技能定义的质量直接决定了 AI 输出的质量。我试过好几种描述方式,最后稳定下来的结构包含六个部分:技能名称与描述、输入契约、输出契约、依赖声明、执行步骤、验证条件。
技能名称要简洁明确,描述要说明这个技能解决什么问题、适用于什么场景。输入契约定义这个技能需要哪些参数,每个参数的类型、格式、是否必填、默认值是什么。输出契约定义技能执行后会返回什么,包括返回值的类型、格式、可能的错误码。依赖声明列出这个技能依赖哪些外部资源,比如数据库表、第三方接口、配置文件等。执行步骤是技能的核心,描述具体的操作流程,可以包含伪代码或自然语言描述。验证条件定义如何判断技能执行成功,包括单元测试要求、集成测试要求、手动验证要点等。
注意:输入契约和输出契约必须尽可能精确。我踩过的一个坑是,早期定义技能时只写了“输入:用户信息”,结果 AI 每次生成的用户信息结构都不一样,有的包含手机号,有的不包含,导致下游技能频繁出错。后来我把输入契约改成明确的字段列表和类型定义,问题就消失了。
这种结构化描述方法的好处是,它强迫你在让 AI 写代码之前,先自己想清楚这个技能到底要做什么、边界在哪里。很多时候,AI 生成代码出问题,根源不在于 AI 能力不够,而在于需求本身就没有想清楚。技能定义的过程,实际上是一次需求梳理和设计评审。
2.4 技能框架与 AI 助手的协作模式
技能框架和 AI 助手的协作模式,我总结为“技能调用 + 上下文注入 + 结果验证”三步循环。技能调用是指你通过特定的提示词格式,告诉 AI 现在要执行哪个技能,并传入必要的参数。上下文注入是指在调用技能时,把相关的项目背景、编码规范、已有代码结构等信息一并提供给 AI,让它在一个完整的上下文中工作。结果验证是指 AI 输出代码后,通过自动化测试和人工审查来确认输出是否符合预期。
这里有个关键细节:上下文注入的内容需要精心筛选。我最初的做法是把整个项目结构都塞给 AI,结果发现效果反而不好,因为信息过载会让 AI 抓不住重点。后来我改成只注入与当前技能直接相关的上下文,比如相关的数据模型定义、接口规范、工具函数等,AI 的输出质量明显提升。这就像给一个新加入项目的开发者做 onboarding,你不需要把整个代码库都讲一遍,只需要告诉他当前任务相关的背景就够了。
协作模式中还有一个容易被忽视的环节:技能执行的日志记录。每次调用技能时,记录下调用的时间、传入的参数、AI 的输出、验证结果等信息。这些日志在排查问题时非常有用,也能帮助你持续优化技能定义。我在一个项目中积累了大约两百条技能执行日志,通过分析这些日志,发现了好几个技能定义中的模糊之处,逐一修正后,AI 输出的首次通过率从大约六成提升到了八成以上。
3. TDD 契约驱动:让 AI 在明确的边界内工作
3.1 契约驱动的核心逻辑与 TDD 的结合点
TDD 契约驱动的核心逻辑是:先定义契约,再让 AI 实现,最后用测试验证。这里的契约包含两层含义:一是接口契约,即函数签名、输入输出格式、错误码定义;二是行为契约,即这个函数在不同输入下的预期行为。TDD 的作用是把这两层契约用可执行的测试用例固定下来,让 AI 有一个明确的“靶子”可以瞄准。
传统 TDD 的流程是“红-绿-重构”:先写一个失败的测试,然后写代码让测试通过,最后重构优化。在 AI 辅助编程的场景下,这个流程需要做一个关键调整:测试用例由人来写,实现代码由 AI 来写。人负责定义“什么是对的”,AI 负责“把对的做出来”。这个分工非常重要,因为如果让 AI 同时写测试和实现,它可能会写出“互相配合”的测试和代码,测试通过了但实际逻辑是错的。
我刚开始尝试这个模式时,觉得写测试用例很麻烦,心想“让 AI 一起写了不就行了”。结果有一次,AI 写了一个测试用例,断言某个函数在输入为空时返回空数组,然后实现代码也确实返回了空数组,测试通过。但实际业务要求是输入为空时应该抛出异常。这个 bug 直到集成测试阶段才被发现,返工成本很高。从那以后,我坚持测试用例必须由人来定义,AI 只负责实现。
3.2 如何编写 AI 可理解的契约描述
编写 AI 可理解的契约描述,关键在于精确性和完整性。精确性是指每个术语都有明确的定义,不能有歧义;完整性是指所有可能的输入情况和预期行为都被覆盖到。我通常会用“给定-当-那么”的格式来描述契约:给定某个前置条件,当执行某个操作时,那么应该产生某个结果。
举个例子,假设我们要实现一个“计算订单折扣”的函数。契约描述可能是这样的:给定一个订单,包含商品列表和用户等级;当用户等级为普通用户时,那么折扣率为零;当用户等级为白银用户且订单金额大于一百时,那么折扣率为百分之五;当用户等级为黄金用户时,那么折扣率为百分之十,且订单金额大于两百时额外再减十。这种描述方式把所有的条件和对应的行为都列清楚了,AI 实现时就不容易遗漏分支。
除了行为契约,接口契约也需要精确描述。函数名、参数名、参数类型、返回值类型、可能抛出的异常,这些都要明确。我习惯用 TypeScript 的类型定义或者 Python 的类型注解来写接口契约,因为这些类型系统本身就有很强的表达能力,AI 也容易理解。比如function calculateDiscount(order: Order, userLevel: UserLevel): DiscountResult这样的签名,比自然语言描述“输入订单和用户等级,返回折扣结果”要精确得多。
提示:契约描述中要特别注意边界条件的定义。比如空数组、零值、负数、超长字符串、并发调用等情况,这些是 AI 最容易忽略的地方。我通常会在契约中专门列一个“边界条件”小节,把所有能想到的边界情况都写清楚。
3.3 测试用例作为 AI 实现的“靶子”
测试用例在 TDD 契约驱动中扮演的是“靶子”的角色。AI 的任务是写出能让所有测试用例通过的代码,测试用例越全面,AI 的实现就越接近正确。这里有个实操技巧:测试用例的命名要清晰表达意图。比如test_calculate_discount_returns_zero_for_normal_user这样的命名,比test_calculate_discount_1要好得多,因为 AI 能从命名中理解这个测试的意图,从而更好地实现对应的逻辑。
测试用例的组织也有讲究。我通常会把测试用例分成三组:正常路径测试、边界条件测试和异常路径测试。正常路径测试覆盖典型的输入和预期输出;边界条件测试覆盖空值、零值、最大值、最小值等情况;异常路径测试覆盖非法输入、资源不足、超时等情况。这三组测试用例加起来,基本上能把一个函数的契约描述完整。
在实际操作中,我会先把测试用例写好并运行,确认它们全部失败(红),然后把测试用例和契约描述一起交给 AI,让它实现代码。AI 实现完成后,我再运行测试,如果全部通过(绿),就进入重构阶段;如果有失败,就把失败信息反馈给 AI,让它修正。这个循环通常需要两到三轮,AI 就能给出一个符合契约的实现。
3.4 契约变更时的处理策略
契约变更在项目迭代中是不可避免的。当需求变化时,契约也需要相应调整。这时候的处理策略很关键,因为如果处理不当,很容易导致 AI 生成的代码和已有代码不一致。
我的做法是先改测试,再改实现。具体来说,当契约需要变更时,先修改测试用例,让它们反映新的契约,然后运行测试确认它们失败,再把新的测试用例和变更说明交给 AI,让它修改实现代码。这样做的好处是,变更的影响范围被测试用例清晰地界定出来了,AI 只需要关注如何让新测试通过,而不需要理解整个项目的上下文。
还有一个细节:契约变更时,要同步更新技能定义中的输入输出契约。我在一个项目中遇到过这样的情况:接口契约变了,但技能定义没有更新,结果 AI 按照旧的技能定义生成代码,和新的测试用例对不上,排查了半天才发现是技能定义过期了。从那以后,我把“契约变更时同步更新技能定义”写进了团队的检查清单。
4. AI 工程纪律闭环:从生成到验证的完整流程
4.1 闭环的四个环节:定义、生成、验证、反馈
AI 工程纪律闭环包含四个环节:定义、生成、验证、反馈。定义环节确定要做什么,包括技能定义和契约描述;生成环节让 AI 产出代码;验证环节通过自动化测试和人工审查确认代码质量;反馈环节把验证结果反馈给 AI 或反馈给技能定义,用于持续改进。
这四个环节形成一个循环,每循环一次,技能定义就更完善一些,AI 的输出质量就更高一些。我实践下来的感受是,前几轮循环会比较慢,因为要花时间写技能定义和测试用例,但一旦技能库积累起来,后续的开发速度会越来越快。这有点像投资,前期投入建设基础设施,后期享受复利。
闭环的关键在于反馈的及时性和准确性。如果验证环节发现问题但不反馈,或者反馈的信息不准确,闭环就断了。我见过一些团队,AI 生成的代码有问题,开发者直接手动改了,但没有把问题反馈到技能定义或测试用例中,结果下次 AI 生成代码时又犯同样的错误。这种“手动修补”的做法短期看省事,长期看是在积累技术债务。
4.2 自动化验证管道的搭建
自动化验证管道是闭环的基础设施。我通常会在项目中配置三层验证:静态检查、单元测试和集成测试。静态检查包括代码格式化、类型检查、lint 规则等,这些检查速度快,能在几秒内给出反馈。单元测试验证单个函数或模块的行为,通常在几十秒内完成。集成测试验证多个模块的协作,可能需要几分钟。
在 AI 辅助编程的场景下,静态检查尤其重要,因为 AI 生成的代码有时会有格式不一致、类型不匹配、未使用的变量等问题。我习惯在 AI 生成代码后立即运行静态检查,如果有问题就反馈给 AI 让它修正,而不是等到单元测试阶段才发现。这样能节省不少时间。
单元测试的自动化运行也很关键。我通常会用 watch 模式,让测试在文件变化时自动运行。AI 生成代码后,测试自动运行,结果立即反馈。如果测试失败,我会把失败信息复制给 AI,让它修正。这个循环越快,开发效率越高。集成测试则通常在提交代码前运行,确保整体功能正常。
注意:自动化验证管道本身也需要维护。我遇到过测试用例本身有 bug 的情况,导致 AI 被误导,生成了错误的实现。所以定期审查测试用例的质量也很重要,确保测试用例本身是正确的。
4.3 人工审查的介入时机与检查要点
虽然自动化验证能覆盖大部分问题,但人工审查仍然不可替代。人工审查的介入时机通常是在自动化验证通过之后、代码合并之前。检查要点包括:业务逻辑是否正确、边界条件是否覆盖、代码可读性是否达标、是否有安全隐患。
业务逻辑的正确性,自动化测试只能验证“代码是否符合测试用例的预期”,但测试用例本身是否覆盖了所有业务场景,需要人来判断。我通常会对照需求文档,逐条检查测试用例是否覆盖了所有需求点。边界条件的覆盖也是人工审查的重点,因为 AI 有时会忽略一些不常见的边界情况。
代码可读性方面,AI 生成的代码有时会过于冗长或过于简洁,需要人工调整。我一般会检查变量命名是否清晰、函数职责是否单一、注释是否恰当。安全隐患方面,要特别注意输入验证、权限检查、敏感数据处理等环节,这些是 AI 容易忽略的地方。
4.4 反馈循环的优化与技能库的迭代
反馈循环的优化是持续改进的关键。我通常会把验证环节发现的问题分类:技能定义问题、契约描述问题、AI 理解问题、测试用例问题。不同类型的问题有不同的处理方式。技能定义问题需要修改技能定义;契约描述问题需要补充或修正契约;AI 理解问题可能需要调整提示词或提供更多上下文;测试用例问题需要修正测试用例。
技能库的迭代是一个渐进的过程。我习惯每周花半小时回顾本周的技能执行日志,看看哪些技能经常出问题,哪些技能定义需要优化。这个习惯坚持了几个月后,技能库的质量明显提升,AI 输出的首次通过率从最初的不到五成提升到了八成以上。
还有一个技巧:把常见的修正操作固化成新的技能。比如,如果发现 AI 经常忘记处理空值,可以创建一个“空值处理检查”技能,在每次生成代码后自动运行。这样就把一次性的修正变成了可复用的能力。
5. 实操过程与核心环节实现
5.1 环境准备与工具链配置
在开始实操之前,需要准备好基础环境。我推荐的工具链包括:一个支持技能定义管理的 AI 编程助手、一个测试框架、一个静态检查工具、一个版本控制系统。具体选型可以根据项目技术栈来定,关键是这些工具要能顺畅地集成到工作流中。
以我最近的一个项目为例,技术栈是 TypeScript + Node.js,测试框架用的是 Vitest,静态检查用的是 ESLint + Prettier,AI 助手用的是支持自定义提示词模板的工具。我在项目根目录下创建了一个skills目录,用来存放技能定义文件;一个contracts目录,用来存放契约描述文件;测试用例则按照常规方式放在tests目录下。
配置过程中有几个细节需要注意。第一,技能定义文件的格式要统一,我通常用 Markdown 或 YAML,因为这两种格式既方便人阅读,也方便 AI 解析。第二,契约描述文件要和代码文件放在相近的位置,方便对照查看。第三,测试用例的命名要遵循统一的规范,方便 AI 理解测试意图。
5.2 从零定义一个技能:以“用户注册”为例
下面以“用户注册”技能为例,完整走一遍技能定义的过程。首先定义技能名称和描述:技能名称为user-registration,描述为“处理新用户注册,包括表单验证、密码加密、数据库写入和欢迎邮件发送”。
输入契约包括:邮箱(字符串,必填,符合邮箱格式)、密码(字符串,必填,长度八到三十二位,包含字母和数字)、昵称(字符串,可选,长度二到二十位)。输出契约包括:成功时返回用户 ID 和注册时间;失败时返回错误码和错误信息,错误码包括EMAIL_EXISTS、INVALID_EMAIL、WEAK_PASSWORD等。
依赖声明包括:用户数据库表、密码加密工具、邮件发送服务。执行步骤为:验证邮箱格式和密码强度;检查邮箱是否已存在;加密密码;写入数据库;发送欢迎邮件;返回结果。验证条件包括:单元测试覆盖所有错误码;集成测试验证数据库写入和邮件发送;手动验证注册流程的端到端体验。
定义完成后,我会把这份技能定义和相关的契约描述、测试用例一起交给 AI,让它生成实现代码。AI 生成的代码通常会包含一些需要调整的细节,比如错误处理的方式、日志记录的格式等,我会根据项目规范进行修正,并把修正后的版本作为该技能的参考实现保存下来。
5.3 契约描述与测试用例的编写实操
契约描述和测试用例的编写是实操中最耗时的环节,但也是最值得投入的环节。我通常先写契约描述,再根据契约描述写测试用例。契约描述用自然语言和类型定义混合的方式,测试用例用测试框架的语法。
以“计算订单折扣”为例,契约描述如下:函数签名为calculateDiscount(order: Order, userLevel: UserLevel): DiscountResult。Order包含items(商品列表)和totalAmount(总金额)。UserLevel是枚举类型,包含NORMAL、SILVER、GOLD。DiscountResult包含discountRate(折扣率)和finalAmount(最终金额)。
行为契约:普通用户折扣率为零;白银用户订单金额大于一百时折扣率为百分之五,否则为零;黄金用户折扣率为百分之十,订单金额大于两百时额外减十。边界条件:订单金额为零时折扣率为零;订单金额为负数时抛出异常;用户等级为未知值时抛出异常。
对应的测试用例包括:test_normal_user_gets_zero_discount、test_silver_user_with_amount_over_100_gets_5_percent、test_silver_user_with_amount_under_100_gets_zero、test_gold_user_gets_10_percent、test_gold_user_with_amount_over_200_gets_extra_10_off、test_zero_amount_gets_zero_discount、test_negative_amount_throws_error、test_unknown_user_level_throws_error。这些测试用例覆盖了所有正常路径和边界条件。
5.4 AI 生成代码后的验证与修正流程
AI 生成代码后,验证流程分为三步:静态检查、单元测试、人工审查。静态检查通常几秒内完成,如果有格式或类型问题,直接反馈给 AI 修正。单元测试运行后,如果有失败,把失败信息反馈给 AI,让它修正。人工审查则关注业务逻辑、边界条件和代码可读性。
我遇到过一个典型案例:AI 生成的折扣计算函数,在黄金用户订单金额刚好等于两百时,没有触发额外减十的优惠。测试用例中有一个test_gold_user_with_amount_exactly_200_gets_extra_10_off,运行后失败了。我把失败信息反馈给 AI,AI 检查后发现是条件判断用了大于而不是大于等于,修正后测试通过。这个案例说明,边界条件的测试用例非常重要,能捕捉到 AI 容易忽略的细节。
修正流程中还有一个技巧:把修正后的代码作为参考实现保存下来。下次遇到类似技能时,可以把参考实现一并提供给 AI,让它参考已有的实现风格和错误处理方式。这样能提高 AI 输出的一致性。
6. 常见问题与排查技巧实录
6.1 技能定义模糊导致的输出漂移
技能定义模糊是最常见的问题之一。表现是 AI 每次生成的代码结构不一致,有时包含某个功能,有时不包含。排查方法是检查技能定义中的输入输出契约是否精确,执行步骤是否明确。如果发现模糊之处,补充具体的字段定义、类型约束和边界条件。
我遇到过一个案例:技能定义中写“输入用户信息”,但没有明确包含哪些字段。结果 AI 第一次生成了包含邮箱和密码的代码,第二次只生成了邮箱,第三次又加上了手机号。后来我把输入契约改成明确的字段列表,问题就解决了。这个经验告诉我,技能定义中的每个术语都要有明确的定义,不能有歧义。
6.2 测试用例覆盖不足引发的漏测
测试用例覆盖不足是另一个常见问题。表现是 AI 生成的代码通过了所有测试,但实际运行时出现 bug。排查方法是审查测试用例是否覆盖了所有正常路径、边界条件和异常路径。我通常会用“等价类划分”和“边界值分析”的方法来检查测试用例的覆盖情况。
有一次,AI 生成的密码验证函数通过了所有测试,但实际使用时发现,密码中包含特殊字符时会报错。检查测试用例后发现,所有测试用例的密码都只包含字母和数字,没有覆盖特殊字符的情况。补充了相关测试用例后,AI 修正了实现。这个经验说明,测试用例的覆盖范围要尽可能广,不能只覆盖典型情况。
6.3 AI 理解偏差的识别与纠正
AI 理解偏差的表现是,AI 生成的代码逻辑和你的预期不一致,但测试用例却通过了。这通常是因为测试用例没有准确表达你的意图,或者 AI 对某个术语的理解和你不一致。排查方法是仔细阅读 AI 生成的代码,对照契约描述逐条检查。
我遇到过一个案例:契约描述中写“订单金额大于一百时折扣率为百分之五”,AI 理解成“订单金额大于等于一百时折扣率为百分之五”。测试用例中刚好有一个金额等于一百的测试,预期是零折扣,但 AI 的实现返回了百分之五,测试失败了。这个案例说明,契约描述中的“大于”和“大于等于”要明确区分,不能含糊。
6.4 常见问题速查表
| 问题类型 | 典型表现 | 排查方法 | 解决策略 |
|---|---|---|---|
| 技能定义模糊 | AI 输出结构不一致 | 检查输入输出契约是否精确 | 补充字段定义和类型约束 |
| 测试覆盖不足 | 测试通过但运行时报错 | 检查边界条件和异常路径 | 补充等价类和边界值测试 |
| AI 理解偏差 | 逻辑与预期不符但测试通过 | 对照契约逐条检查代码 | 明确术语定义,消除歧义 |
| 上下文过载 | AI 抓不住重点 | 检查注入的上下文是否过多 | 只注入与当前技能相关的上下文 |
| 技能定义过期 | AI 按旧定义生成代码 | 检查技能定义是否与最新契约一致 | 契约变更时同步更新技能定义 |
提示:这张速查表建议放在项目文档中,遇到问题时先对照排查,能节省不少时间。我通常会把每次遇到的问题和解决方法补充到表中,形成团队的知识积累。
6.5 独家避坑技巧与经验总结
第一个技巧:技能定义要版本化。技能定义会随着项目迭代不断修改,如果不做版本管理,很容易出现“不知道当前用的是哪个版本”的情况。我通常会把技能定义文件放在版本控制系统中,每次修改都提交一次,并在提交信息中说明修改原因。
第二个技巧:测试用例要先于实现代码存在。这是 TDD 的核心原则,但在 AI 辅助编程的场景下更容易被忽视。我见过一些开发者让 AI 同时生成测试和实现,结果测试和实现“互相配合”,测试通过了但逻辑是错的。坚持测试先行的原则,能有效避免这个问题。
第三个技巧:定期回顾技能执行日志。技能执行日志记录了每次调用的参数、输出和验证结果,是优化技能定义的重要依据。我通常每周花半小时回顾日志,找出频繁出问题的技能,逐一优化。
第四个技巧:保持技能库的精简。技能库不是越大越好,过多的技能会增加管理和组合的复杂度。我通常每季度清理一次技能库,把不再使用的技能归档,把可以合并的技能合并。保持技能库的精简,能让 AI 更容易找到合适的技能来执行。
第五个技巧:人工审查不能省。自动化验证能覆盖大部分问题,但业务逻辑的正确性、边界条件的覆盖、代码的可读性,这些仍然需要人工判断。我通常会在自动化验证通过后,花五到十分钟做一次快速的人工审查,重点检查业务逻辑和边界条件。这个习惯帮我捕捉到了不少自动化测试没有覆盖的问题。
7. 工程纪律闭环的持续运转与个人体会
这套方法落地到现在,我最大的体会是:AI 辅助编程的效率提升,不来自于 AI 本身有多强,而来自于你为 AI 搭建的工作环境有多好。技能框架、契约驱动、工程纪律闭环,这三样东西本质上都是在为 AI 搭建一个“有明确规则、有及时反馈、有持续改进”的工作环境。环境搭好了,AI 的能力才能充分发挥;环境没搭好,AI 越强反而越容易制造混乱。
另一个体会是,这套方法的前期投入确实不小。写技能定义、写契约描述、写测试用例,这些工作在没有 AI 的时代也是要做的,只是那时候可能被“先写代码再说”的习惯掩盖了。现在有了 AI,这些工作的价值被放大了,因为它们直接决定了 AI 输出的质量。我个人的经验是,前期投入大约占项目总时间的百分之二十到三十,但后期开发速度能提升两到三倍,整体算下来是划算的。
还有一个细节值得分享:技能库的积累是一个复利过程。刚开始可能只有几个技能,每个技能都要从头定义。但随着技能库的增长,新技能可以复用已有技能的组件,定义速度会越来越快。我在一个项目中积累了大约五十个技能后,新技能的定义时间从最初的两小时缩短到了二十分钟左右。这种复利效应是这套方法最吸引人的地方。
最后分享一个小技巧:把技能定义当作团队资产来管理。技能定义不仅仅是给 AI 看的,也是团队知识沉淀的载体。一个新成员加入团队,通过阅读技能定义就能快速理解项目的核心业务逻辑和技术规范。我在团队中推行这套方法后,新成员的 onboarding 时间从两周缩短到了三天左右。这个附加价值,是我最初没有预料到的。