1. 五种范式到底在解决什么问题
第一次听到“Vibe Coding”这个词是在一个周末的深夜,当时我正对着一个报错堆栈发呆,脑子里想的是“能不能别让我一行行查了,直接告诉我要改哪里”。后来陆续接触到 Plan、Glue、Spec、Smell 这几个词,才发现它们并不是什么玄学概念,而是把“人和 AI 一起写代码”这件事拆成了五种截然不同的协作姿势。有人把它们当成五个工具,其实更准确的理解是:这是五种你和 AI 之间的分工协议。
先说清楚这五种范式各自站在什么位置。Vibe 是“我描述感觉,你来写”,Plan 是“我先想清楚,你按计划执行”,Glue 是“我搭骨架,你填血肉”,Spec 是“我把规格写死,你严格照做”,Smell 是“我闻着不对劲,你来帮我诊断”。它们不是互斥的,一个真实项目里往往五种都会用到,只是不同阶段侧重点不同。
为什么现在要专门聊这个?因为大多数人用 AI 写代码还停留在“打开对话框,粘贴需求,复制结果”的阶段。这种方式在写一个独立函数时没问题,但一旦项目超过几百行、涉及多个文件、需要长期维护,就会立刻崩盘。我见过太多人抱怨“AI 写的代码跑不起来”“改着改着就乱了”,根因不是模型不行,而是协作范式选错了。你让一个擅长即兴发挥的模式去干需要严格约束的活,结果必然失控。
这篇文章面向的是已经用过 AI 编程工具、但总觉得“差那么点意思”的开发者。不管你是写 Python 脚本做数据处理,还是维护一个中型前端项目,或者只是想让 AI 帮你改改配置文件,这五种范式都能直接套用。我会把每种范式的适用场景、具体操作步骤、真实案例和踩坑经验都摊开讲,你可以当成一份“协作姿势选择手册”来用。
提示:下面每种范式我都会给出“什么时候用”“怎么操作”“实测案例”三个部分,你可以按需跳读,但建议至少把 Vibe 和 Spec 这两节看完,因为它们代表了两个极端,理解了这两个,中间三种就很好把握了。
2. Vibe Coding:把感觉说清楚,让 AI 先跑起来
2.1 什么场景下该用 Vibe
Vibe Coding 的核心是低约束、高速度。你不需要提前想清楚所有细节,只需要把“我想要什么感觉”描述出来,AI 会给你一个能跑的初版。它最适合这几种情况:一是你在探索一个不熟悉的领域,比如第一次写某个库的调用代码,自己都不知道 API 长什么样;二是你在做原型验证,只需要快速看到效果,不关心代码质量;三是你在写一次性脚本,用完就扔,不需要维护。
反过来,如果你要写的是核心业务逻辑、需要长期维护的模块、或者涉及数据安全的代码,Vibe 就不合适了。我见过有人用 Vibe 模式让 AI 生成数据库迁移脚本,结果 AI 凭感觉写了个DROP TABLE,幸好是在测试环境。所以用之前先问自己:这段代码如果写错了,后果严重吗?严重就别用 Vibe。
2.2 怎么把“感觉”翻译成 AI 能懂的指令
很多人用 Vibe 效果不好,是因为描述太模糊。你说“帮我写个登录功能”,AI 只能猜。有效的 Vibe 指令要包含三个要素:输入输出示例、技术栈约束、风格偏好。比如:
用 Python 写一个函数,输入是一个包含用户信息的字典列表, 输出是过滤掉年龄小于 18 岁的用户后的列表。 用列表推导式,不要用 for 循环,代码尽量短。这个指令里,“输入输出示例”让 AI 知道数据形状,“技术栈约束”限定了语言和写法,“风格偏好”告诉它你要什么味道。实测下来,加上这三样,AI 一次生成可运行代码的概率能从三成提到七成以上。
还有一个技巧是给 AI 一个“参照物”。比如你说“按照 requests 库的风格来写”,AI 就会模仿那种简洁的链式调用。你说“像 Flask 路由那样组织”,它就知道要用装饰器。这比你说“写好看点”有效得多。
2.3 一个真实案例:用 Vibe 快速搭一个数据清洗脚本
上周我需要处理一批 CSV 文件,里面有日期格式不统一、有空值、有重复行。这种活我完全不想手写,就用 Vibe 模式试了一下。我的指令是:
写一个 Python 脚本,读取当前目录下所有 csv 文件, 把日期列统一成 YYYY-MM-DD 格式,删除全空的行, 去掉完全重复的行,输出到 cleaned 目录。 用 pandas,代码要能直接跑,不要用 argparse。AI 给了我一版代码,我跑了一下,发现日期列的名字它猜的是date,但我的文件里叫日期。我补了一句“日期列名是中文的‘日期’”,它立刻改对了。整个过程不到五分钟,脚本就能用了。这就是 Vibe 的价值:你不需要提前知道 pandas 的to_datetime怎么处理混合格式,AI 会帮你查。
但我也踩过一个坑:AI 生成的代码里用了df.drop_duplicates(),但没有指定subset,结果它把所有列都考虑进去了,而我只想去重“订单号”相同的行。这个错误在 Vibe 模式下很常见,因为 AI 不知道你的业务规则。所以用 Vibe 生成的代码,一定要跑一遍真实数据,检查边界情况。
注意:Vibe 模式生成的代码,建议加一行注释标明“AI 生成,未经过完整测试”,方便后续维护时知道这段代码的来路。
3. Plan 模式:先写“施工图”,再让 AI 砌墙
3.1 Plan 和 Vibe 的本质区别
Vibe 是“边想边做”,Plan 是“想好了再做”。Plan 模式要求你在让 AI 写代码之前,先和它一起把实现方案讨论清楚。这个方案包括:要改哪些文件、每个文件改什么、函数签名是什么、数据结构怎么定义、异常怎么处理。听起来很繁琐,但对于超过 200 行的改动,Plan 模式能帮你省下大量返工时间。
我自己的经验是:如果一个任务需要改三个以上文件,或者涉及两个以上模块的交互,就必须用 Plan。比如“给用户模块加一个手机号登录功能”,这涉及路由、数据库、验证逻辑、错误处理,直接让 AI 写,它很可能只改路由就交差了。但如果你先让它列计划,它会告诉你“需要改 user_routes.py、user_model.py、auth_service.py,并在数据库加一个字段”。
3.2 怎么和 AI 一起做计划
Plan 模式的操作流程分三步。第一步,你把需求描述给 AI,让它输出一个文件级别的改动清单。第二步,你审查这个清单,补充它漏掉的部分,删掉它多做的部分。第三步,你让它按清单逐个文件生成代码,每生成一个你确认一个。
这里有个关键技巧:让 AI 用“伪代码”先写一遍。比如你说“先用注释写出每个函数的逻辑,不要写实现”。这样你能快速看出它的思路对不对,不对就改,比看几百行代码快得多。我通常会让它输出这样的格式:
# 1. 在 user_model.py 中新增 phone 字段 # 2. 在 auth_service.py 中新增 send_sms_code 函数 # - 输入:手机号 # - 输出:验证码 # - 逻辑:生成6位随机数,存入缓存,设置5分钟过期 # 3. 在 user_routes.py 中新增 /login/phone 路由 # - 接收手机号和验证码 # - 调用 auth_service 验证 # - 返回 token这个伪代码清单就是你的“施工图”。确认无误后,再让 AI 逐个实现。实测下来,这种方式生成的代码,一次通过率比直接生成高很多,因为你在计划阶段就排除了逻辑错误。
3.3 Plan 模式中最容易忽略的“接口对齐”
Plan 模式有一个隐藏陷阱:AI 在生成不同文件时,可能会对同一个数据结构有不同的理解。比如它在 model 里把用户 ID 定义成int,但在 route 里当成str用。这种错误在单独看每个文件时很难发现,只有跑起来才会报类型错误。
我的应对方法是:在计划阶段就明确写出关键数据结构的定义。比如:
User 对象: - id: int - phone: str - created_at: datetime然后要求 AI 在每个文件里都引用这个定义。如果项目里有types.py或models.py,就让它从那里导入。这样能避免大部分接口不一致的问题。
还有一个经验:Plan 模式适合有明确验收标准的任务。比如“实现一个排序算法”,你知道排完序就是对的。但如果是“优化页面加载速度”,验收标准模糊,Plan 模式反而会限制 AI 的发挥。这种时候更适合 Vibe 或 Glue。
4. Glue 模式:你搭骨架,AI 填血肉
4.1 Glue 模式的适用边界
Glue 模式是我日常用得最多的一种。它的核心是:你负责架构和关键逻辑,AI 负责填充重复性代码。比如你定义了一个类的所有方法签名,让 AI 写每个方法的具体实现;或者你写好了主流程,让 AI 补全每个步骤的细节。
这种模式特别适合有固定套路的代码。比如 CRUD 接口、数据转换函数、配置文件解析、单元测试。这些代码结构相似,但手写又很费时间。你搭好骨架后,AI 能很快填满,而且质量通常不错,因为套路固定,它不容易出错。
但 Glue 模式不适合需要创造性设计的部分。比如你要设计一个缓存淘汰策略,或者实现一个复杂的业务规则引擎,这些需要你自己想清楚,AI 只能帮你写边角料。我见过有人让 AI 设计整个微服务架构,结果生成了一堆互相矛盾的接口定义,根本跑不起来。
4.2 怎么搭一个“AI 好填”的骨架
骨架的质量直接决定 AI 填充的效果。一个好的骨架应该包含:完整的函数签名、清晰的注释说明、输入输出的类型标注、以及关键步骤的占位注释。比如:
def process_order(order: dict) -> dict: """ 处理订单,计算最终价格。 输入 order 包含: - items: list[dict],每个 dict 有 price 和 quantity - discount_code: str,可选 - user_level: str,'normal' 或 'vip' 输出: - final_price: float - discount_amount: float """ # 1. 计算商品总价 # 2. 根据 discount_code 计算折扣 # 3. 根据 user_level 计算额外折扣 # 4. 返回最终价格和折扣金额 pass这个骨架里,注释已经写清楚了每一步要做什么,AI 只需要把pass替换成实现。实测下来,这种骨架的填充准确率很高,因为 AI 不需要猜你的意图。
4.3 Glue 模式的验收技巧
AI 填完代码后,不要直接跑,先做静态检查。我通常会让 AI 自己检查一遍:“你写的代码里,有没有变量未定义、类型不匹配、边界条件没处理的地方?”它往往能自己发现几个问题。然后我再跑单元测试,重点测边界情况:空输入、超大输入、异常输入。
还有一个技巧是让 AI 写测试。你说“给刚才生成的每个函数写一个 pytest 测试,覆盖正常情况和两种异常情况”。这样你不仅得到了实现,还得到了测试用例。如果测试跑不过,说明实现有问题,你可以把报错信息贴回给 AI,让它修。
提示:Glue 模式下,建议把 AI 生成的代码和你的骨架放在同一个文件里,用注释分隔。这样后续维护时,你能一眼看出哪些是手写的,哪些是 AI 填的。
5. Spec 模式:把规格写死,让 AI 没有发挥空间
5.1 什么时候需要“规格驱动”
Spec 模式是五种范式里约束最强的一种。它的做法是:你先写一份形式化的规格说明,然后让 AI 严格按照规格生成代码。规格里要包含:函数签名、参数类型、返回值类型、异常类型、边界条件、性能要求。AI 不允许“自由发挥”,只能照做。
这种模式适合对正确性要求极高的场景。比如金融计算、数据校验、协议解析、安全相关的代码。这些地方一旦出错,后果很严重,你不能接受 AI“猜”你的意图。Spec 模式通过把规格写死,把 AI 的创造力限制在“翻译”而不是“设计”上。
我自己的经验是:Spec 模式写规格的时间,可能比直接写代码还长。但它是值得的,因为规格本身就是文档,后续维护、测试、交接都用得上。而且规格写好后,你可以让 AI 生成多个语言的实现,或者生成测试用例,复用性很高。
5.2 一份合格的 Spec 长什么样
Spec 不是自然语言描述,而是接近代码的伪形式化语言。它应该包含这几个部分:
函数名:calculate_interest 输入: principal: float, 必须 > 0 rate: float, 必须 >= 0 且 <= 1 years: int, 必须 >= 1 输出: float, 保留两位小数 异常: ValueError: 当 principal <= 0 或 rate 不在 [0,1] 或 years < 1 边界条件: rate = 0 时,返回 0 years = 1 时,按单利计算 算法: 复利公式:principal * (1 + rate) ** years这份规格里,每个参数的类型和约束都写清楚了,异常情况也列出来了。AI 拿到这份规格,只需要把它翻译成代码,几乎没有发挥空间。实测下来,这种方式的生成结果一次通过率接近百分之百,因为所有歧义都在规格阶段消除了。
5.3 Spec 模式的“过度约束”陷阱
Spec 模式最大的风险是规格写得太死,导致代码无法适应变化。比如你把“返回两位小数”写进规格,但后来业务要求返回四位,你就得改规格、重新生成、重新测试。如果这种变化很频繁,Spec 模式反而会拖慢速度。
我的建议是:只把真正稳定的部分写进规格。比如算法逻辑、异常类型、参数约束,这些通常不会变。而输出格式、日志级别、错误信息文案,这些容易变的部分,可以留给 AI 自由发挥,或者用配置项控制。这样既保证了核心逻辑的正确性,又保留了灵活性。
还有一个经验:Spec 模式适合有明确数学定义或协议定义的任务。比如“实现一个 Base64 编码器”,规格就是 RFC 文档,AI 照着写就行。但如果是“实现一个推荐算法”,规格很难写清楚,因为推荐效果的好坏没有绝对标准,这种时候 Spec 模式就不合适。
6. Smell 模式:代码有“味道”时,让 AI 帮你诊断
6.1 什么是代码的“坏味道”
Smell 模式不是用来写新代码的,而是用来诊断和修复已有代码的。它的核心是:你感觉代码“不对劲”,但说不清楚哪里不对,让 AI 帮你找出问题。这种“不对劲”就是代码坏味道,常见的包括:函数太长、重复代码太多、命名混乱、耦合太紧、异常处理缺失、性能瓶颈。
我通常在这几种情况下用 Smell 模式:一是接手别人的代码,看不懂但感觉有问题;二是自己写的代码跑得慢,但不知道慢在哪;三是代码能跑但改起来很痛苦,每次改都要动好几个地方。这些时候,让 AI 帮你“闻一闻”,往往能发现你忽略的问题。
6.2 怎么让 AI 帮你“闻”出问题
Smell 模式的操作很简单:你把代码贴给 AI,然后问“这段代码有什么问题?”但这样问太宽泛,AI 可能只给你一些表面建议。更有效的方式是指定你要闻的方向。比如:
- “这段代码有没有重复的逻辑?”
- “这个函数的圈复杂度是多少?哪里可以拆分?”
- “这段代码有没有潜在的并发问题?”
- “这个循环的时间复杂度是多少?有没有优化空间?”
我试过让 AI 分析一个 300 行的函数,它指出了三个问题:一是中间有一段重复的日期格式化逻辑,可以抽成函数;二是异常处理只捕获了Exception,太宽泛;三是有一个循环里做了数据库查询,会导致 N+1 问题。这三个问题我自己看的时候都没注意到,特别是 N+1,因为代码逻辑是对的,只是性能差。
6.3 Smell 模式的修复策略
AI 诊断出问题后,不要让它直接改。先让它给出修复方案,你确认后再改。因为有些“坏味道”是故意的,比如为了性能牺牲了可读性,或者为了兼容旧接口保留了冗余代码。AI 不知道这些背景,可能会把有用的代码“优化”掉。
我的做法是:让 AI 列出问题清单,每个问题标注严重程度(高/中/低)和修复建议。然后我逐个判断,哪些要修,哪些不改。对于要修的,再让 AI 生成修复后的代码,我对比一下改动范围,确认没有引入新问题。
还有一个技巧:让 AI 写一个“修复前后对比”。比如:
修复前:函数 300 行,圈复杂度 25 修复后:拆成 5 个函数,每个 50 行左右,圈复杂度 8这样你能直观看到修复的效果,也方便向团队解释为什么要做这次重构。
7. 五种范式怎么组合使用
7.1 一个项目的完整范式切换流程
真实项目里,五种范式不是孤立的,而是按阶段切换的。我通常的流程是:项目启动时用 Vibe 快速搭原型,验证想法可行;然后切换到 Plan 模式,设计整体架构和文件结构;接着用 Glue 模式填充各个模块的实现;对于核心算法和关键逻辑,用 Spec 模式严格约束;最后用 Smell 模式做代码审查和优化。
举个例子,我之前做一个数据报表系统。第一周用 Vibe 模式,让 AI 快速生成了一个能跑的原型,虽然代码很乱,但验证了数据源和报表格式没问题。第二周用 Plan 模式,重新设计了模块划分:数据获取、数据清洗、报表生成、导出。第三周用 Glue 模式,把每个模块的骨架搭好,让 AI 填充实现。第四周对报表生成的公式部分,用 Spec 模式写了严格的规格,确保计算准确。最后用 Smell 模式做了一轮审查,发现了几处重复代码和性能问题,修完后上线。
这个流程的关键是:不要试图用一种范式解决所有问题。Vibe 快但不可靠,Spec 可靠但慢,Plan 和 Glue 是中间地带,Smell 是收尾。根据任务的性质和阶段,灵活切换。
7.2 范式选择速查表
为了让你更快做决定,我整理了一个速查表:
| 场景 | 推荐范式 | 理由 |
|---|---|---|
| 探索新领域、写原型 | Vibe | 快速看到效果,不纠结细节 |
| 改多个文件、涉及模块交互 | Plan | 先理清依赖,避免返工 |
| 写 CRUD、数据转换、测试 | Glue | 套路固定,AI 填充效率高 |
| 核心算法、金融计算、协议解析 | Spec | 正确性要求高,不能有歧义 |
| 接手旧代码、性能优化 | Smell | 先诊断问题,再决定怎么改 |
| 一次性脚本、临时工具 | Vibe | 用完就扔,不需要维护 |
| 长期维护的核心模块 | Spec + Glue | 关键逻辑用 Spec,边角料用 Glue |
这张表不是绝对的,但能帮你快速定位。我自己的习惯是:新项目从 Vibe 开始,稳定后转 Plan,实现用 Glue,核心用 Spec,收尾用 Smell。
7.3 组合使用时的注意事项
组合使用最大的坑是范式切换太频繁。比如你刚用 Vibe 生成了一个函数,马上切到 Spec 去改它,结果发现 Spec 的约束和 Vibe 的代码风格冲突,改起来很痛苦。我的建议是:一个模块内尽量用一种范式,模块之间可以不同。比如数据层用 Spec,业务层用 Glue,接口层用 Vibe。这样每个模块内部风格一致,维护起来不混乱。
还有一个经验:范式切换时,让 AI 重新读一遍上下文。比如你从 Plan 切到 Glue,先让 AI 把之前的计划复述一遍,确认它还记得。因为对话太长时,AI 可能会忘记前面的约定。我通常会说“回顾一下我们刚才定的文件结构,然后按那个结构填充 user_service.py”。这样能避免它跑偏。
8. 实测中踩过的坑和总结的经验
8.1 Vibe 模式的“幻觉代码”怎么防
Vibe 模式最大的问题是 AI 会“编造”不存在的 API。比如它可能写df.read_csv_with_encoding(),但 pandas 根本没有这个方法。这种错误在跑的时候才会暴露,浪费调试时间。我的应对方法是:让 AI 在生成代码后,自己检查一遍所有 API 调用是否存在。你说“检查你刚才写的代码,有没有调用不存在的函数或方法,如果有,改成正确的”。实测下来,它能自己发现大部分幻觉。
另一个技巧是:让 AI 标注每个 API 的来源。比如“在代码注释里写明每个函数来自哪个库的哪个版本”。这样你一眼就能看出哪些是它编的。虽然它不一定标得准,但至少能提醒你哪些地方需要验证。
8.2 Plan 模式的“计划膨胀”问题
Plan 模式容易走向另一个极端:AI 会列出一个巨大的计划,包含很多你根本不需要的步骤。比如你让它加一个登录功能,它可能计划“重构整个用户模块、引入 OAuth、加双因素认证”。这时候你需要明确告诉它范围:“只加手机号登录,不要动其他部分,不要引入新依赖”。把边界划清楚,计划才不会膨胀。
我通常会在 Plan 阶段加一句:“只列必须的改动,不要加‘顺便优化’的内容”。这样 AI 会收敛很多。如果它还是列多了,你就手动删掉,然后说“按这个精简后的计划执行”。
8.3 Spec 模式的“规格漂移”怎么避免
Spec 模式写好后,如果需求变了,规格也要改。但很多人改了代码忘了改规格,导致规格和代码不一致,后续维护时被误导。我的做法是:把规格和代码放在同一个文件里,规格用注释形式写在函数上方。这样改代码时自然会看到规格,改完代码顺手改规格。如果规格太长,就放在同目录的.spec.md文件里,并在代码里引用。
还有一个经验:规格里不要写实现细节。比如你写“用快速排序”,但后来发现数据量小,用插入排序更快。规格应该写“排序结果正确,时间复杂度不超过 O(n log n)”,而不是指定算法。这样 AI 有优化空间,你也不会被规格绑死。
8.4 Smell 模式的“过度重构”风险
Smell 模式诊断出问题后,AI 可能会建议大规模重构。但重构是有风险的,特别是没有测试覆盖的代码。我的原则是:没有测试,不重构。如果代码没有测试,先让 AI 写测试,跑通后再重构。这样重构过程中如果引入 bug,测试能立刻发现。
另外,一次只修一个问题。不要一次性接受 AI 的所有建议,那样改动太大,出了问题很难定位。我通常按严重程度排序,先修高严重度的,跑一遍测试,确认没问题再修下一个。这样即使出问题,也能快速回滚。
8.5 五种范式的共同底线
不管用哪种范式,有几条底线是不能破的。第一,AI 生成的代码必须经过你的审查,不能直接上线。第二,关键逻辑必须有测试,不能只靠“看起来对”。第三,不要泄露敏感信息,比如数据库密码、API 密钥,这些不要贴给 AI。第四,保持代码风格一致,AI 生成的代码要符合项目的规范,不能它写它的、你写你的。
我自己的习惯是:每次 AI 生成代码后,先跑一遍 lint,再跑一遍测试,最后人工看一遍关键部分。这三步走完,基本能过滤掉大部分问题。虽然麻烦,但比上线后出故障再修要省事得多。
最后分享一个小心得:把每次和 AI 协作的过程记录下来。比如“这次用 Vibe 生成了数据清洗脚本,踩了日期格式的坑”。积累多了,你就能形成自己的“范式选择直觉”,看到任务就知道该用哪种方式。这比任何教程都管用。