1. 从“许愿式”编程说起:一个被热词带偏的真实需求
“GPT-6 与许愿式编程”这个标题第一次看到的时候,我脑子里蹦出来的不是某个具体模型,而是一种很具体的开发体验:你对着一个对话框敲下一段模糊到不能再模糊的需求,然后期待它吐出一整套能跑的代码。这个过程像极了对着流星许愿——愿望说出口的那一刻很爽,但流星并不会因为你许了愿就真的帮你把房贷还了。
所谓“许愿式”编程,我给它下的定义是:开发者把自然语言当作唯一的输入接口,把“描述意图”等同于“完成实现”,把模型的输出当作可直接交付的成品,而跳过了验证、拆解、约束和迭代这四个真正决定代码能不能上线的环节。它和“AI 辅助编程”最大的区别在于,前者是许愿,后者是协作。许愿的人只负责说,协作的人负责说清楚、验明白、改到位。
这个标题之所以能成为热词,本质上不是因为 GPT-6 本身有多神秘,而是因为过去两年里,大量开发者第一次用自然语言写出了能跑的代码,兴奋之余产生了一种错觉:编程这件事的门槛被彻底抹平了。但真正在项目里落地过的人都知道,模型越强,“许愿”的代价反而越高——因为它生成的代码看起来越像对的,你越容易跳过 review,最后在某个边界条件上炸得越惨。
这篇文章想聊的不是“GPT-6 有多强”,而是在模型能力持续进化的前提下,一个从业者应该怎么把“许愿”变成“工程”。我会从许愿式编程的典型翻车场景讲起,拆解提示词到底在补什么信息,再给出一套我自己在用的、可复现的协作流程,最后聊聊哪些活该交给模型、哪些活必须自己扛。适合已经用过 AI 编程工具、但总觉得“生成的东西不太敢直接上”的中级开发者,也适合刚接触这块、想少走弯路的新手。
2. 许愿式编程的四种典型翻车现场
2.1 需求描述里的“默认值陷阱”
最常见的一种翻车,是你在提示词里写“帮我写一个用户登录接口”,然后模型给你返回了一个带 JWT、带密码哈希、带限流的完整实现。看起来很美好,但你仔细一看:它默认用了 bcrypt 的 cost 因子 10,默认 token 有效期 24 小时,默认把用户 ID 直接塞进 payload。这三个默认值,在你的业务里可能全是错的。
问题不在于模型选错了,而在于你根本没告诉它你的约束条件。模型在信息缺失时,会用训练数据里最高频的“合理默认值”来填空。这些默认值在通用场景下没问题,但你的项目从来不是通用场景。cost 因子 10 在高并发登录场景下会让 CPU 打满,24 小时有效期在金融类应用里长得离谱,用户 ID 进 payload 在需要支持多设备踢下线的场景里根本不够用。
我踩过最典型的一次,是让模型写一个分页查询。它默认用了LIMIT offset, size的写法,在数据量小的时候完全没问题,但那张表后来涨到了两千万行,深分页直接把数据库拖垮。模型没有错,它给的是标准写法,错的是我许愿的时候没提数据量级。
2.2 模型“自信地编造”不存在的 API
第二种翻车更隐蔽:模型会非常自信地调用一个根本不存在的函数或参数。比如你让它用某个库的某个方法,它会一本正经地写出client.fetchAsync({ retryPolicy: 'exponential' }),语法完美、命名合理、注释齐全,但这个retryPolicy参数在那个库的当前版本里压根不存在。
这种情况在库版本更新快、或者库本身比较小众的时候尤其常见。模型的知识有截止时间,它见过的可能是某个旧版本,也可能是某个根本不存在的“理想版本”。它不会告诉你“我不确定这个 API 存不存在”,它会直接编一个出来,而且编得比真的还像真的。
我自己的应对方式很简单:任何模型生成的、涉及第三方库调用的代码,第一件事不是跑,是去官方文档里搜那个方法名。搜不到就说明是幻觉,搜到了再看参数签名对不对。这一步花不了两分钟,但能省掉半小时的 debug。
2.3 边界条件被系统性忽略
第三种翻车是边界条件。你让模型写一个“计算两个日期之间工作日天数”的函数,它会给你一个漂亮的实现,但它大概率不会处理:起始日期晚于结束日期怎么办、跨年怎么办、法定节假日怎么算、时区怎么处理。这些边界在提示词里你没提,模型就默认不存在。
这不是模型的缺陷,这是自然语言的固有模糊性。“计算工作日天数”这句话,在人看来是有歧义的,但在模型看来是一个明确的指令,它会按最直接的理解去实现。自然语言天然缺少边界定义,而代码的正确性恰恰建立在边界定义之上。这就是为什么许愿式编程在 demo 阶段很爽,一进生产就露馅。
2.4 生成代码的“局部正确、全局冲突”
最后一种最要命:模型生成的每一段代码单独看都没问题,但拼在一起就冲突。比如你分三次让模型写三个模块,第一次它用了 snake_case 命名,第二次用了 camelCase,第三次又混着来。或者第一次它把配置写死在代码里,第二次它读环境变量,第三次它读配置文件。单看每段都能跑,合起来就是一团乱麻。
根源在于模型没有你项目的全局上下文。它每次生成都是基于你当次给的提示词,它不知道你上一次是怎么写的,也不知道你团队的代码规范。你许的每一个愿都是独立的,但项目是一个整体。
3. 提示词到底在补什么:把“许愿”翻译成“规格”
3.1 提示词的本质是需求规格说明书的压缩版
很多人把提示词当成“跟 AI 说话的方式”,这个理解太浅了。提示词的本质,是把你脑子里那份没写出来的需求规格说明书,用自然语言压缩后喂给模型。你写得越接近规格说明书,模型输出越接近可交付代码。
一份合格的需求规格说明书包含什么?输入输出的类型和范围、边界条件、异常处理策略、性能约束、依赖约束、命名规范、错误码定义。你在提示词里覆盖了其中几项,模型就能少猜几项。你一项都不写,模型就全靠猜,猜中的概率随着项目复杂度指数级下降。
所以“许愿式”编程的问题,不是许愿这个动作本身,而是许愿的内容太贫瘠。你说“帮我写个登录”,这是许愿;你说“写一个登录接口,输入是手机号和密码,密码用 bcrypt cost 12 哈希,返回 JWT,有效期 2 小时,失败返回 401 和统一错误码,需要防暴力破解,同一手机号 5 分钟内失败 5 次锁定 15 分钟”,这是规格。
3.2 结构化提示词的四个必备字段
我自己在用的提示词模板,固定包含四个字段,缺一个我都会觉得这次生成不靠谱:
| 字段 | 作用 | 缺失后果 |
|---|---|---|
| 角色与场景 | 告诉模型这是什么项目、什么技术栈、什么规模 | 模型用通用方案,不贴合你的架构 |
| 输入输出契约 | 明确类型、格式、取值范围 | 模型自由发挥,接口对不上 |
| 约束与边界 | 性能、安全、兼容性、异常处理要求 | 边界条件全被忽略 |
| 验收标准 | 什么样的输出算合格 | 你没法判断生成结果对不对 |
这四个字段不需要写得很长,但必须写。我见过太多人提示词就一句话,然后抱怨模型生成的东西不能用。这就好比你让装修师傅“随便装一下”,然后怪他装出来的风格你不喜欢。
3.3 用“反例”代替“形容词”
还有一个很实用的技巧:少用形容词,多用反例。你说“代码要健壮”,模型不知道什么叫健壮;你说“不要出现未捕获的异常,所有 IO 操作必须有超时和重试”,模型立刻就懂了。
形容词是主观的,反例是客观的。你说“性能要好”,不如说“单次查询不能超过 50ms,不能有 N+1 查询”。你说“代码要清晰”,不如说“函数不超过 30 行,嵌套不超过 3 层,变量名用完整单词不用缩写”。模型对具体数字和具体禁令的响应,远好于对模糊形容词的响应。
3.4 把“许愿”拆成多轮“确认”
最后一个心法:不要指望一次许愿拿到终稿。把一次大许愿拆成多轮小确认,每一轮只解决一个维度的问题。第一轮定接口签名,第二轮定核心逻辑,第三轮补异常处理,第四轮加测试用例。每一轮你都 review,确认没问题再进下一轮。
这样做的好处是,错误在早期就被拦住,不会累积到最后变成一坨没法改的代码。而且每一轮的提示词都很聚焦,模型不容易跑偏。我自己的习惯是,超过 50 行的生成,一定拆成至少三轮。
4. 一套可复现的“反许愿”协作流程
4.1 第一步:先写接口,再写实现
不管模型多强,我都会坚持一个顺序:先让模型生成接口定义,人工确认后再生成实现。接口定义包括函数签名、参数类型、返回值类型、抛出的异常类型。这一步模型几乎不会出错,因为它不需要理解业务逻辑,只需要把契约写清楚。
接口确认之后,实现部分的提示词就可以直接引用这个接口,模型有了明确的锚点,跑偏的概率大幅降低。而且接口一旦定下来,后面就算实现要重写,调用方也不用改,这是工程上的基本纪律。
4.2 第二步:让模型自己写测试,但你来定测试点
模型写测试用例的能力其实很强,但前提是测试点由你来定。你告诉它“测试空输入、测试超长输入、测试并发调用、测试依赖超时”,它就能把这些场景的测试写出来。你不告诉它,它只会写最 happy path 的那一个。
我通常的做法是,先自己列一个测试点清单,然后让模型按清单生成测试代码。生成完我再检查一遍,看有没有漏掉我没想到的边界。这一步经常能发现我自己思维的盲区,算是意外收获。
4.3 第三步:小步运行,每步都验证
生成代码之后,绝对不要一次性跑整个流程。先跑最小可运行单元,确认这一步的输出符合预期,再往下走。比如生成了一个数据处理管道,先单独跑数据读取,确认读进来的格式对;再跑清洗,确认清洗规则对;最后跑输出,确认写出去的格式对。
这样做看起来很慢,但实际上比“一把梭然后 debug 三小时”快得多。而且每一步的验证结果,都可以作为下一步的输入,形成正向反馈。
4.4 第四步:把验证过的代码固化成模板
每次成功协作之后,我都会把这次用到的提示词结构、接口定义方式、测试点清单整理成一个模板。下次遇到类似场景,直接套模板,效率会高很多。模型会进化,但你的工程方法论应该沉淀下来。今天用 GPT-6 许愿,明天可能用更强的模型,但“先接口后实现、先测试点后测试代码、小步验证”这套流程,换什么模型都适用。
5. 哪些活该交给模型,哪些必须自己扛
5.1 适合交给模型的:有明确模式、有大量先例的活
模型最擅长的是有大量先例、模式清晰、边界明确的任务。比如 CRUD 接口、数据格式转换、正则表达式、单元测试骨架、文档注释、常见算法的标准实现。这些活的特征是:正确答案相对唯一,模型见过足够多的例子,生成质量稳定。
我现在的习惯是,这类活直接交给模型,自己只做 review。省下来的时间用在真正需要判断力的地方。比如写一个 JSON 转 CSV 的函数,模型三秒就能给我一个能用的版本,我花三十秒 review 一下边界,比我自己写快得多。
5.2 必须自己扛的:架构决策、安全边界、业务语义
有三类活,我从来不交给模型做最终决定:
架构决策。模块怎么划分、服务怎么拆分、数据怎么流转,这些决策依赖对业务未来演进的判断,模型没有这个上下文。它可以给你几个方案对比,但拍板必须是你。
安全边界。认证、授权、加密、脱敏、审计,这些地方的任何疏漏都是事故。模型可以帮你写实现,但安全策略必须你自己定,而且必须经过独立的安全 review。
业务语义。什么叫“有效订单”、什么叫“活跃用户”、什么叫“逾期”,这些定义是业务方的语言,模型只能按字面理解。你必须把业务语义翻译成精确的判定条件,再交给模型实现。
5.3 一个简单的判断标准
如果一件事的正确答案依赖于“你项目的具体情况”,那它就不该完全交给模型。如果一件事的正确答案是“业界通用做法”,那模型大概率能帮上忙。这个标准不完美,但足够实用。
6. 模型越强,“许愿”的代价反而越高
6.1 生成质量提升带来的“审查惰性”
这是一个反直觉的结论:模型越强,许愿式编程的风险越大。原因是,当模型生成的代码质量很差时,你一眼就能看出问题,自然会去仔细检查;当模型生成的代码质量很高、看起来很像对的时,你的警惕性会下降,review 会变得敷衍,而恰恰是这种“看起来对”的代码,藏着最隐蔽的 bug。
我管这个叫审查惰性。模型输出越流畅、越自信,人越容易跳过验证。这在心理学上很好解释,但在工程上是灾难。所以我的原则是:模型输出质量越高,我 review 得越仔细。因为高质量的假象最容易骗过人。
6.2 能力越强,越容易掩盖需求本身的模糊
第二个反直觉的点:模型能力越强,越能“圆”你模糊的需求。你需求写得含糊,弱模型会直接报错或者生成明显不对的东西,逼你去把需求想清楚;强模型会自己脑补一套逻辑,生成一个看起来完整、实际上和你真实意图有偏差的实现。你如果不仔细看,就以为需求已经满足了。
模型的能力,某种程度上是在替你掩盖需求定义的不完整。这很危险,因为需求的不完整不会消失,它只是被推迟到上线后才暴露。所以模型越强,你越要主动把需求写清楚,不能依赖模型帮你“猜”。
6.3 从“许愿”到“规格驱动”的转变
说到底,GPT-6 也好,后面的模型也好,它们改变的是实现的速度,不改变需求的清晰度决定实现正确性这个基本事实。许愿式编程的问题从来不在模型,在于许愿的人没有把愿望翻译成规格。
我现在的做法是,把每一次和模型的协作,都当成一次“写规格”的练习。提示词写得越像规格说明书,输出越像可交付代码。这个过程反过来也在训练我自己把需求想清楚的能力,算是意外收获。
7. 我踩过的几个具体坑和对应的解法
7.1 坑一:让模型“优化”一段代码,结果逻辑被改
有一次我让模型优化一段查询代码的性能,它确实优化了,但它顺手把一段“如果用户已注销则返回空”的逻辑删掉了,理由是“这段逻辑看起来是冗余的”。它不知道这个逻辑是业务要求的,它只从代码层面判断冗余。
解法:优化类提示词必须明确“只改什么,不改什么”。我现在会说“只优化查询部分,业务逻辑一行都不许动,改完把改动点列出来”。这样模型就不会自作主张。
7.2 坑二:多轮对话里模型“忘记”了前面的约束
多轮对话时,模型对早期轮次的约束记忆会衰减。你在第一轮说“所有金额用分为单位”,到第五轮它可能就用了元。这不是模型故意,是上下文窗口的固有限制。
解法:关键约束在每一轮都重复一遍。或者把约束写成一个固定的“系统提示”部分,每轮都带上。麻烦一点,但能避免很多低级错误。
7.3 坑三:模型生成的代码“能跑但不可维护”
模型生成的代码经常能跑,但命名随意、注释缺失、结构混乱。它能通过测试,但三个月后没人看得懂。
解法:把可维护性要求写进提示词。我现在会明确要求“变量名用完整单词、每个公开函数必须有文档注释、单个函数不超过 30 行、不允许出现魔法数字”。这些要求写进去,模型基本都能遵守。
7.4 坑四:过度依赖模型导致自己能力退化
这是最隐蔽的坑。用久了之后,你会发现自己对某些基础 API 的记忆变模糊了,因为反正可以问模型。短期看效率高了,长期看判断力在下降。
解法:定期做“无模型”练习。我每周会挑一两个小任务,强制自己不用模型完成,保持手感。模型是工具,不是拐杖,这个界限要自己守住。
8. 写在最后的一点个人体会
GPT-6 这个标题之所以能成为热词,我觉得本质上反映的是一种集体焦虑:大家既兴奋于 AI 编程带来的效率提升,又隐隐担心自己会不会被替代。但真正在一线写过代码的人会明白,模型替代的是“敲键盘”这个动作,替代不了“想清楚要敲什么”这个能力。
许愿式编程的诱惑在于,它让你觉得不用想清楚也能出结果。但工程这件事,想不清楚的部分,迟早会以 bug、事故、返工的形式还回来。模型越强,这个还回来的周期可能越长,但不会消失。
我自己现在的状态是,把模型当成一个反应极快、知识面极广、但完全没有我项目上下文的初级工程师。我会给它足够清晰的规格,让它快速产出初稿,然后我用我的上下文去 review、去修正、去补边界。这个协作模式跑下来,效率确实比纯手写高很多,而且质量可控。
至于“许愿”,还是留给流星吧。代码这件事,还是老老实实写规格比较靠谱。