零代码规范开发:2024年极简落地实践指南
AI辅助编程已成为现代开发流程的标配,但提升其输出质量的关键,在于采用“规格驱动开发”(Spec Coding)。然而,传统Spec Coding因与繁琐文档绑定,让许多开发者望而却步。
以GitHub上流行的OpenSpec框架为例,它虽倡导“流式”协作,但实际落地仍要求为每个功能维护包含多个Markdown文件的专属文件夹。这种“文档驱动”的沉重负担,迫使大多数团队退回到最原始的模式:将数百行原始代码直接抛给AI,并期望它能理解整个系统的复杂上下文。
其结果往往是AI产生“幻觉”,输出无法运行或逻辑错误的代码。我们必须打破“Spec Coding等于重型工程”的迷思。本文将阐述一种极简的替代方案——“零文档契约”(Zero-Doc Spec Coding)。它无需引入新工具链或学习复杂的提示词,只要求开发者回归一项核心技能:编写结构化的测试断言。
一、 困境与破局:从“文档驱动”到“极简意图”
1.1 上下文窗口的“信噪比”危机
理解Spec Coding的必要性,始于认清大语言模型(LLM)的根本局限:它是一个“无状态”的函数,输出质量完全由输入质量决定。
将整个项目的源代码直接塞入AI的上下文窗口,会引发一场“信息灾难”。生产级代码库充斥着实现细节:数据库连接池配置、冗长的错误处理、各类工具函数。对于AI理解核心业务意图而言,这些绝大部分都是干扰噪声。
当噪声淹没了关键的业务逻辑信号,AI的注意力会被严重分散。简单类比:向AI投喂原始代码,就像在嘈杂的施工现场试图口头传达一套精密的建筑设计图——沟通效率低下,错误百出。
1.2 极简解法:Zero-Doc(零文档)
传统Spec Coding难以推广,正因为它陷入了误区:要求开发者在代码之外,额外维护一套独立且易腐化的文档体系。像OpenSpec这类方案,虽解决了意图对齐的“从无到有”,却无法逃避“文档腐化”的宿命——文档的编写和维护本身就是沉重负担,且极易过时。
Zero-Doc Spec Coding的核心理念截然不同:我们不维护任何静态的Markdown或注释文档,我们只维护“活的”断言。文档是死的,而单元测试可以伴随系统迭代,是活的。
我们的极简着陆点,是将产品需求(PRD)直接转化为结构化的测试断言:
- 输入:PRD(业务意图)
- 锚点:结构化测试代码(人类绝对审查的领域)
- 产物:实现代码(可随时抛弃的衍生品)
二、 核心方法论:构建“海平面”的高保真契约
传统Spec Coding要求开发者频繁进行“信息压缩”,为AI提供提炼过的说明书。在Zero-Doc范式下,我们将这种“压缩”直接具象化为测试用例的编写。
为此,我们借鉴软件工程中“海平面用例”的概念。
2.1 锚定海平面
将软件开发视为一片海洋:
- 云端:是高层的战略目标(如“提升用户留存率”),对AI编码而言过于抽象。
- 海底:是底层的具体函数实现(如“数据库连接重试逻辑”),对AI理解意图而言过于琐碎且充满噪声。
- 海平面:是用户目标层级(如“用户想要重置密码”)。
Spec Coding强调将意图锚定在“海平面”。在这一层级,我们不讨论虚无的愿景,也不纠缠于具体实现,而是清晰描述用户通过系统希望达成的、具体且可观测的目标。
2.2 结构化降噪:目录即地图,用例即契约
自然语言充满模糊性。为使AI精准理解海平面用例,我们需要一套多层级的结构化降噪方案:
- 宏观结构化(目录层):利用测试文件的物理目录和动名词命名,构建系统的能力地图。
- 微观结构化(代码层):在具体测试文件中,将断言划分为
@MSS(主成功场景)和@Extensions(扩展流程),将非结构化需求转化为格式严整的测试模板。
2.2.1 宏观降噪:构建系统能力地图
在一个真实的生产级项目(如电商或内容平台)中,整个specs测试目录不应按技术组件(Controller、Service)划分,而应严格按“用户目标(用例)”组织。
打开项目的specs目录,你看到的应是清晰的业务动作:
apps/system/specs/
├── ClaimTask.spec.ts # 认领任务
├── ConfigurePaymentTable.spec.tsx # 配置支付表格
├── CreateOrder.spec.tsx # 创建订单
├── DeleteUserAccount.spec.tsx # 注销账户
├── ManageUserData.spec.ts # 管理用户数据
├── ManageSettlements.spec.tsx # 管理结算列表
├── PerformPaymentAction.spec.tsx # 执行支付操作
├── ReviewContentMachine.spec.ts # 内容机器审核
├── SearchTasks.spec.ts # 搜索任务
└── ViewIncomeSummary.spec.tsx # 查看收益概览
... (共数十个独立业务用例)
基于这种平铺的用例文件,我们可以用AI生成一份高信噪比的系统能力地图(索引文件README_SPECS.md)。
生成索引至关重要。真实业务具有层级结构,而平铺的文件系统在用例增多后会难以维护。一份独立的Markdown索引可以管理业务模块与层级,极大降低管理成本。无论上层业务模块如何调整重组,底层平铺的用例文件结构都无需大改,只需更新索引。
当团队新人或AI需要了解“系统能做什么”时,无需翻阅过时的文档,只需查看这份地图:
## 核心业务用例 (System Capabilities)
### 用户入驻与认证 (User Onboarding)
* **[管理用户资料数据 (ManageUserData)](./specs/ManageUserData.spec.ts)**:管理用户资料拉取、回填及多步表单验证。
* **[内容机器审核 (ReviewContentMachine)](./specs/ReviewContentMachine.spec.ts)**:用户提交材料的机器审核流程,支持自动识别与信息比对。
### 财务与结算系统 (Settlement System)
* **[管理结算单列表 (ManageSettlements)](./specs/ManageSettlements.spec.tsx)**:结算列表主页面,整合搜索、批量操作和创建入口。
* **[执行支付操作 (PerformPaymentAction)](./specs/PerformPaymentAction.spec.tsx)**:处理结算单的审批、绑定、付款、删除等业务动作。
这份地图与底层目录共同构成了一份永不腐化、持续生效的PRD。所有命名遵循动名词组,业务意图一目了然。
2.2.2 微观降噪:结构化测试契约
从宏观地图点击进入任一具体用例文件(如“用户注册”),便进入微观契约层。
传统模式下,这是一个高噪声过程:开发者将一个数百行的React组件丢给AI,其中混杂UI样式、副作用管理和DOM事件,AI极易迷失在技术细节中。
Zero-Doc方式则提供极高的信噪比。我们将业务契约直接写入测试断言:
// specs/RegisteringUser.spec.ts
describe('@UseCase RegisteringUser: 用户使用邮箱和密码注册新账户', () => {
// @MSS: Main Success Scenario (主成功流程)
it('@MSS-1: 提交有效信息应成功创建账户并返回成功消息', async () => {
const result = await register('test@example.com', 'StrongPass123!');
expect(result.status).toBe('success');
});
// @Extensions: 异常与分支流程
it('@Ext-2a: 邮箱格式无效应拒绝并报错', async () => {
const result = await register('invalid-email', 'StrongPass123!');
expect(result.error).toBe('InvalidEmail');
});
});
三、 辨析:Zero-Doc 契约 vs 普通单元测试
这种结构化做法常引发质疑:“这不过是要求多写单元测试并集中存放,与普通单测有何区别?”
这是关键问题。表面看都使用了测试框架,但本质不同:Zero-Doc契约是披着测试外衣的“可执行文档”。
核心差异体现在三方面。
首先是视角的本质不同。 普通单测是自下而上的“海底视角”,关注实现细节(如test_validate_email_regex),用于验证“代码写得对不对”。Zero-Doc契约是自上而下的“海平面视角”,它屏蔽底层技术,只关注业务意图(如RegisteringUser),用于验证“系统做的事情对不对”。
其次是信息架构的不同。 普通单测往往平铺直叙,像一堆缺乏业务关联的零件。Zero-Doc契约通过宏观目录索引和微观@MSS标签,将非结构化需求翻译成高信噪比蓝图,它是用测试框架的壳,装了领域驱动设计(DDD)的魂。
最后是生命周期的不同。 普通单测是代码的附庸,底层重构时常随之报废。在Zero-Doc理念下,契约是AI生成代码的输入源(Prompt的具象化)。只要业务需求不变,无论底层代码被AI如何重写,这份契约都坚如磐石。在Zero-Doc世界里,业务代码才是可随时被AI抛弃和重写的衍生品,而测试契约是系统唯一、永不过时的资产。契约一旦确立,AI便能依此生成具体实现。
四、 全场景落地:统一的工作流闭环
此方法最强大之处在于,它不仅是文档,更是可执行的测试,从而形成自动化反馈循环。
4.1 闭环引擎:AI 的自我修正
- Spec -> 测试:AI读取PRD,自动生成包含
@UseCase、@MSS和@Extensions标签的测试用例。 - 测试 -> 实现:AI编写实现代码以通过上述测试。
- 自我修正:若实现代码有误,测试失败(红灯)。AI收到报错信息后,在“测试围栏”内自动调整逻辑,直至测试通过(绿灯)。
4.2 遗留系统治理 (Reverse Engineering)
面对无文档的“遗留”代码,采用增量逆向策略:
- 逆向:让AI扫描老模块源码,反向生成测试断言。
- 固化:将断言保存为测试文件,形成“行为快照”。
- 重构:有了测试作为安全网,可大胆进行重构。
4.3 新需求开发 (New Feature)
面对冗长的PRD文档:
- 转化:将PRD喂给AI,让其自动提取并生成结构化单测断言。
- 审查:开发者作为人工审查环节,确认测试用例是否覆盖所有@MSS和@Extensions。
- 生成:AI自动生成实现代码。
4.4 需求变更 (Legacy Change)
当业务规则变更(如密码长度从8位改为12位):
- 定位:找到对应的测试文件。
- 修改:仅修改测试断言中的期望值。
- 修复:运行测试,AI发现不匹配,自动定位并修复实现代码。这是一次精准的外科手术。
这本质上是用例驱动的Zero-Doc Spec Coding模式。我们用宏观目录划定系统边界,用@UseCase圈定业务场景,用@MSS和@Extensions穷尽业务分支。此闭环彻底取代了传统的文档维护。
回顾过去,为对抗软件熵增,开发者常需小心翼翼设计复杂系统架构(如洋葱架构、六边形架构),试图用层层抽象保护核心业务逻辑。但在AI编程时代,这种沉重的“防御性设计”可能不再是首选。当AI拥有强大的实现能力,我们不再需要过度设计复杂代码架构,只需设计好清晰的目录结构和契约蓝图。只要契约在,系统随时可以推倒重来。
五、 终极图景:迎接“代码虚无主义”
如果明天AI模型进化,上下文窗口无限大,推理能力强到能秒懂10万行代码,我们还需要写Spec吗?
若真到那一天,连程序员都不再需要。但在那天到来之前,我们必须为系统建立坚固的“护栏”。
这并非一场伪装成“AI最佳实践”的TDD复兴运动,而是确立一种全新的人机协作范式。当你准备好让断言完全接管业务逻辑的描述,你也就准备好接受这种“代码虚无主义”——实现代码变得不再重要,重要的是你定义的测试契约。
告别僵死的文档,拥抱鲜活的断言。Zero-Doc Spec Coding以@MSS与@Extensions为契约,确立了AI协作的唯一事实来源。这不仅是开发门槛的降低,更是生产关系的重塑:人类定义意图,AI交付实现。