先说结论
我不把 Vibe Coding 理解成“描述一句话,然后接受一整个项目”。对我来说,它更像一种高频反馈的协作方式:让 AI 帮忙探索、生成和解释,但每一小步都要有明确的输入、可观察的输出和人工确认。
如果需求本身没有边界,AI 只会更快地把模糊变成大量代码。
第一步:把需求改写成可验证的切片
例如,“给订单增加取消功能”太宽泛。我会先把它改写成一个小切片:
- 只有
Pending和Paid状态的订单允许取消; - 已发货订单返回业务错误;
- 取消操作记录操作者和时间;
- 重复取消不会产生第二条状态记录;
- endpoint 返回稳定的 HTTP 状态和错误结构。
然后把不确定的问题列出来,而不是直接让 AI 猜:
- 操作者身份来自当前用户还是后台参数?
- 状态记录是否需要事务?
- 是否需要发送库存或支付系统事件?
- 旧订单数据是否存在未知状态?
这些问题决定实现边界,也决定测试应该覆盖什么。
第二步:让 AI 先阅读,再动手
我会先让 AI 只做仓库分析,不要求它改代码。一个适合第一轮的任务是:
请先阅读订单实体、状态枚举、现有 endpoint 和测试。
不要修改文件。请列出:
1. 目前的状态流转;
2. 取消操作可能影响的表和服务;
3. 现有测试的缺口;
4. 你认为必须向我确认的问题。
请引用文件路径和关键方法名,不要臆造不存在的代码。
这一步的目标是建立共同上下文。AI 如果在阅读阶段就把不存在的服务或属性写出来,后面生成的代码也不值得直接接受。
第三步:一次只实现一个边界
确认设计后,我会让它先完成领域规则和单元测试,再处理 API 层,最后才接数据库和集成测试。每一步都尽量保持一个小 diff。
状态转换可以先写成显式方法:
public Result Cancel(Guid actorId, DateTimeOffset now)
{
if (Status is not (OrderStatus.Pending or OrderStatus.Paid))
{
return OrderErrors.CannotCancel;
}
Status = OrderStatus.Cancelled;
Events.Add(OrderEvent.Cancelled(Id, actorId, now));
return Result.Success();
}
这段代码是否正确,不能靠“看起来合理”判断。至少要有:允许取消、已发货拒绝、重复取消拒绝、事件记录完整四类测试。
第四步:用测试和工具反馈驱动下一轮
每次生成后,我会立即运行最小验证集:
dotnet format --verify-no-changes
dotnet test --filter FullyQualifiedName~Order
dotnet build --no-restore
上面命令中的空格、项目路径和筛选器要根据实际仓库调整。重点是让失败尽早出现,而不是积累到最后一起处理。
当测试失败时,我会把完整错误和相关文件范围交给 AI,而不是只说“修一下”:
下面是刚才测试的完整失败信息。
请只修改订单取消相关代码,不要改测试断言来绕过问题。
先解释失败原因,再给出最小补丁,并说明为什么不会影响其他状态流转。
“不要改测试来绕过问题”是一个很重要的约束。测试是当前行为契约的一部分,除非需求已经改变,否则应该优先修复实现。
第五步:人工检查 AI 不容易主动发现的风险
自动测试通过以后,我还会单独检查:
- 是否把权限判断放在了可信边界之外;
- 是否记录了不必要的个人信息或敏感日志;
- 是否存在重复提交和并发更新问题;
- 数据库迁移是否可回滚;
- 错误响应是否泄露内部异常;
- 新依赖的许可证和供应链风险;
- 是否为了一个小功能引入了过度抽象。
AI 可以帮我列清单,但不能替我决定业务风险是否可以接受。
一个可复用的提交前清单
| 检查项 | 结果 |
|---|---|
| 需求是否拆成可验证行为 | 已确认 |
| 正常路径和失败路径是否都有测试 | 已确认 |
| 格式化、构建和测试是否通过 | 按项目执行 |
| 数据库和外部服务边界是否明确 | 待集成环境确认 |
| 日志、权限和敏感信息是否复核 | 人工检查 |
| AI 生成内容是否全部经过人工修改或确认 | 已确认 |
总结
Vibe Coding 的核心不是少写代码,而是缩短“想法—实现—反馈”的循环。一个可靠的循环应该包含:
- 小而明确的任务;
- 对现有代码的真实阅读;
- 限制范围的生成;
- 自动化测试和工具反馈;
- 对安全、数据和业务语义的人工复核。
如果一个 AI 工具让代码生成变快,却让审查变得更困难,那只是把成本推迟了。好的协作应该让每一次修改都更容易解释、更容易验证,也更容易在以后被另一个人接手。
说些什么吧!