ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AI写代码总翻车?字段级Spec让大模型一次生成可用代码

AI写代码总翻车?字段级Spec让大模型一次生成可用代码 我前阵子接了个活儿想让 AI 帮我写一个“客户信息管理模块”。我当时觉得这需求够清楚了吧五个字一句话丢给 AI 就能出代码。结果它给我生成了一堆看起来运行正常、实际上完全没法用的东西电话字段允许输入“abc”邮箱格式全靠自由发挥地址随便填什么都能过删除客户没有任何确认逻辑。那一刻我意识到问题不在 AI 身上在我身上——我给它的“一句话需求”本质上等于没给需求。后来我把那套“客户信息管理系统”的模糊想法花了一个下午拆成了一份字段级 Spec也就是把每个字段叫什么、类型是什么、能填多长、可不可以为空、默认值怎么定、校验规则是什么逐条写清楚再拿这份 Spec 去喂 AI。结果生成的代码几乎一遍跑通连测试用例都自己补得七七八八。这篇文章就是想说清楚一件事AI 写代码的时代吃香的已经不是会写多少行代码的人而是能把需求写得让 AI 不用猜的人。我会讲讲为什么一句话需求指挥不动 AI怎么把模糊想法逐步拆成字段级 Spec再附一份可以直接抄的实战案例和排查清单。适合刚接触 AI 编程、总觉得“AI 写的东西不靠谱”的开发者也适合想在团队里推行 AI 辅助开发的负责人。1. 为什么一句话需求指挥不动 AI 写代码1.1 AI 其实是“概率模仿者”不是“需求翻译官”很多朋友有一个误解觉得 AI 是万能的翻译你给它一句人话它就能理解成计算机程序。实际用过大模型写代码的人应该都有体会它更像一个训练量极大的“模式匹配器”你给它一句话它会根据训练数据里出现频率最高的模式给你接一个“最像那么回事”的答案。我举个例子你就明白了。你去一家餐厅跟服务员说“来个好吃的”服务员大概率给你推荐大众点评排名第一的招牌菜。这不是因为它读懂了你的口味而是因为在它见到的所有点单样本里排名靠前的菜最容易让人满意。你如果补一句“辣的、酸汤肥牛、别放香菜”它端上来的菜就完全不一样了。AI 写代码也是这个道理。你说“帮我写个注册功能”它就用训练语料里出现频率最高的那种注册模块来生成用户名加密码存数据库查重一下返回 success。它不知道你的系统还有手机号注册、邀请码、短信验证、登录风控、第三方绑定因为你没说。不是说 AI 蠢而是它只能用文本模式去“猜”概率最高的上下文。你给的信息越少它就越倾向于生成一个泛化到谁都能用的“平均答案”而这个答案往往不是你的业务要的东西。这里还要多说一句频繁翻车的另一个原因是“代码”本身的复杂性大概率超过一句自然语言能承载的信息量。一句话需求压缩了太多业务上下文而代码要求的是精确、无歧义、可执行。两者之间存在巨大的信息鸿沟AI 再聪明也没法凭空跨越除非你自己去把鸿沟填上。1.2 一句话需求到底丢掉了什么我复盘了自己踩过的坑发现一句话需求至少会丢掉下面这些关键信息字段约束、边界条件、业务规则、异常路径。你一说“注册功能”脑子里可能已经默认了“用户名 3~20 个字符、密码 8 位以上包含字母数字、手机号走短信验证、重复用户名要提示”。但这些默认值AI 完全不知道。它只能按最常见的设计来而最常见的注册功能大多只覆盖用户名和密码。再举一个更典型的例子。“写一个订单系统”这句话能引起的歧义多到离谱订单需不需要拆单支付有几种方式订单状态怎么流转取消订单有没有时限超时未支付要不要自动关闭库存是下单锁还是支付才扣这些规则哪怕漏掉一条AI 生成的代码都算不上“可用”只能算“能跑”。一句话需求还有一个非常隐性的破坏力就是它会让你误以为“需求已经说完了”从而跳过审视需求的环节。等到 AI 生成一堆代码你才发现这里不对那里不对再一条条改成本反而比一开始把规则写清楚更高。传统开发里有个词叫“需求变更成本”AI 编程时代这个成本没有消失只是从“改代码”变成了“改描述”和“重新生成”如果反复重新生成时间一样哗哗地流走。所以我的判断是AI 不是不需要需求分析而是比以前更需要需求分析只不过交付物要从“一份给产品经理看的需求文档”变成“一份给 AI 当施工图的字段级 Spec”。这个转移背后才是真正想清楚业务逻辑的过程。1.3 字段级 Spec 为什么能成为突破口字段级 Spec说白了就是把需求细化到“每个字段怎么定义、每条规则怎么表达”的文档。它像是给 AI 的一张“施工图纸”。你跟装修师傅说“把房子弄好看”师傅只能按他理解的审美发挥你给他一张标好了插座高度、柜子颜色、地板材质的图纸他才能还你一个你想要的屋子。代码也是一样。有人可能会问我直接跟 AI 说清楚不就行了吗为什么非要写下来成 Spec这里面有一个 AI 输出的本质问题上下文越长AI 对每条信息的遵守度反而会下降尤其是纯聊天的长篇对话越到后面越容易遗忘早期约定。你如果口头零零散散告诉 AI 十条规则它生成第三十个字段的时候可能已经忘了第一条。但如果你把规则集中成一份结构化 Spec放进提示词的开头AI 在生成每个字段、每个函数时都能“看到”这份权威定义输出的一致性会显著提高。另外字段级 Spec 也是你和 AI 之间的“唯一事实来源”。遇到 AI 生成得不对你不用翻聊天记录去对质直接把 Spec 里对应字段的条目甩给它说“这里违反了第 3 条”。这比“你上次说的那个再改改”靠谱得多。后面我会专门讲怎么用这套办法跟 AI 来回拉扯效率能翻一倍。2. 把口头想法拆成字段级 Spec 的四步法2.1 第一步拆业务对象让实体浮出水面拿到一个模糊需求第一步不是急着写字段而是先把业务对象拆出来。业务对象就是你系统里要管理的“东西”比如商品、订单、用户、客户、项目、任务。一个对象配一张表一个对象就是一个核心实体。怎么拆我最常用的办法是拉一个“名词清单”。把你刚才那句话里的所有名词都抓出来比如“做一个客户信息管理系统”抓出来的名词就是“客户”和“信息”。再往下细化“客户”可以拆出基础资料、联系方式、交易记录、售后记录等子对象“系统”还要考虑登录账号、角色权限这些外围对象。拆的时候宁多勿少因为这决定了你给 AI 的边界——你不写客户交易记录AI 就默认不生成你后来说“怎么没有下单历史”那只能怪自己没写进去。拆完实体之后还要理一下实体之间的关系。客户和订单是一对多订单和商品是多对多这些关系决定了 AI 该怎么建表、怎么设计外键。有些人可能会说“我直接用 AI 设计表结构就行了”我也试过结果它设计出来的表字段倒是挺全但表之间的关联、索引、唯一约束经常想当然比如同一个手机号允许注册了两次。实体和关系这一步我建议人先想清楚AI 可以辅助但不要完全撒手。你给它一个稳定的骨架它才好填肉。2.2 第二步逐字段落盘写出让 AI 不猜的定义实体确定后就进入最关键的一步把每个实体的属性拆成字段再为每个字段写清楚定义。什么算“定义清楚”我给自己定的标准很简单一个字段要让完全没参与过这个项目的人或者 AI看了就懂、不用猜。我常用的字段定义模板是这样的字段名、中文含义、数据类型、长度、是否必填、默认值、是否唯一、校验规则、业务说明。举个例子“客户手机号”这个字段如果你只写“phone: string”AI 大概率会存成 varchar(255)不校验允许为空。但如果你写成phone: string, 长度 11 位, 必填, 唯一, 符合大陆手机号正则AI 生成的代码就会对应给它加一堆校验、唯一索引和错误提示。差别就是这么大。我是从实际项目里真切感受到的同样的 AI同样的模型Spec 写得越细生成代码的质量差距就越明显。这一步比较耗时但它有个隐藏好处写字段的时候你会被迫思考业务逻辑。比如“客户状态”这个字段写默认值的时候你会想新客户是什么状态禁用客户怎么表示这就是在做需求分析。很多人觉得写字段级 Spec 浪费时间的根本原因是他们把需求分析当成了额外负担。实际上它就是你该做的事只不过以前是拿嘴在会议上说现在是拿键盘落到文档里。2.3 第三步补齐行为规则把“大概”变成“必须”字段定义完了还差行为规则。我管它叫“动词层”因为字段定义管的是“数据长什么样”行为规则管的是“数据怎么被创建、修改、查询、删除”这正是最容易让 AI 自由发挥的地方。行为规则要覆盖四个问题谁能操作这个对象管理员可删除/客服只读。操作流程是什么注册先填手机号再收验证码最后设密码。状态怎么流转订单从待支付变已支付已支付才能发货退款只能发生在已支付之后。异常怎么办库存不足要提示什么话术删除已停用客户是否允许邮箱格式错了返回什么错误码为什么必须写到“什么错误返回什么话术”这种粒度因为 AI 生成的异常处理往往千篇一律只会返回一个“error: invalid input”这在真实场景里根本不够用。你告诉它“手机号格式错误时返回 code 40001提示文案为‘手机号格式不正确请重新填写’”它就能给你完整的响应结构。你连错误码都给了它它就不会自己随便编。我还喜欢在行为规则里加一句硬约束“未在 Spec 中声明的行为一律不要默认实现。”这句话非常重要等于给 AI 的自由发挥关上了门。你看很多 AI 生成的代码给你多加一些自以为是的功能表面上很贴心的样子实际却是画蛇添足。有了这条约束你至少能保证一辈子的“清纯”出来的代码跟你的 Spec 一致你的评审成本就低很多。2.4 第四步用验收清单反向检查 Spec写完 Spec 别急着喂给 AI建议先自己拿它做一轮“验收测试”。我会把 Spec 里的每条字段规则转成一个验收点比如“手机号少于 11 位能不能保存成功”“重复手机号报不报错”然后把验收点列成清单。如果这个清单你自己说不出答案说明 Spec 没写完还得补。这一步还有一个更实用的技巧你先不看代码只看 Spec把这张验收清单丢给 AI让 AI 根据 Spec 写出对应的测试用例。如果 AI 能写出像样的测试用例说明 Spec 的自洽性没问题如果 AI 卡住了或者反复问你“这个字段的规则没提”那就是 Spec 有漏洞。我自己每次的新项目都会走一遍这个闭环需求 → 实体 → 字段 → 行为规则 → 验收清单。走完之后心里特别踏实因为我知道 AI 再怎么生成也就是在替我把“已经想清楚的东西”翻译成代码而不是替我“发明业务逻辑”。这个区别决定了 AI 写代码是效率工具还是麻烦制造机。3. 实战案例一个客户信息管理的字段级 Spec 全流程3.1 一句话需求及其翻车现场为了让你更直观地看到差别我拿最典型的“客户信息管理”来走一遍。先说原始需求很多人会这样提帮我写一个客户信息管理系统能增删改查客户。这个需求够普通吧我把它直接丢给 AI 生成了一份代码结果是客户表里就四个字段姓名、电话、邮箱、地址“电话”字段用的是字符串随便存邮箱格式没校验删除客户直接物理删没有任何二次确认。更夸张的是它连客户唯一标识用的还是自增 id传一次数据换一次环境 id 就乱了。你能说这代码不能跑吗能跑但没有一个字段经得起业务细节的审视。我当时遇到这种情况第一反应是“换一个更强的模型试试”换完发现还是老样子逼得我回头去补 Spec才意识到我的问题从一开始就偏了我把它当成 AI 的问题其实是我需求做得不到位。3.2 我的最终字段级 Spec直接可抄下面这份 Spec 是我后来整理的“客户信息管理”简化版字段粒度到了可以直接丢给 AI 生成后端接口的程度。我强烈建议你照抄结构再替换成自己的业务字段。# 客户信息管理模块字段级 Spec ## 实体customer客户 | 字段名 | 类型 | 长度 | 必填 | 默认值 | 唯一 | 校验规则与业务说明 | |---|---|---|---|---|---|---| | customer_id | bigint | - | 是 | 自增 | 是 | 主键系统生成 | | customer_no | string | 32 | 是 | 自动生成 | 是 | 格式CUS 年月日 4位随机数如 CUS202501160013 | | name | string | 50 | 是 | 无 | 否 | 客户名称首尾空格自动去除不允许为空串 | | phone | string | 11 | 是 | 无 | 是 | 必填正则校验1开头第二位3-9共11位数字 | | email | string | 100 | 否 | 无 | 否 | 如果填写必须符合 email 格式正则 | | address | string | 200 | 否 | 无 | 否 | 详细地址最长200字符 | | status | string | 20 | 是 | enabled | 否 | 枚举enabled启用/ disabled禁用 | | remark | string | 500 | 否 | 无 | 否 | 备注内嵌 500 字符 | | created_at | datetime | - | 是 | 当前时间 | 否 | 创建时间系统自动生成不可修改 | | updated_at | datetime | - | 是 | 当前时间 | 否 | 最后更新时间每次更新自动刷新 | ## 行为规则 1. 新增客户front desk、API 均可新增新增时如果 phone 已存在返回错误码 40001文案该手机号已注册请更换手机号。 2. 查询客户支持按 name 模糊查询、按 customer_no 精确查询列表分页默认每页 20 条最大 100 条。 3. 更新客户仅更新非空字段name、phone 修改时重新做唯一性校验remark 可更新为 null 语义的空字符串。 4. 删除客户不允许物理删除启用逻辑删除添加 deleted 字段默认 false已删除客户在普通列表不展示。 5. 特殊约定所有接口入参和出参均为 JSON时间格式 ISO8601如 2025-01-16T10:30:00Z。 6. 未在本 Spec 中声明的功能一律不要默认实现。你仔细对比一下这份 Spec 和“能增删改查客户”这句话的信息密度差多远。字段多达 10 个光校验规则就有电话正则、邮箱格式、唯一索引、状态枚举、逻辑删除还规定好了错误码。AI 拿到这份图纸根本不需要“猜”因为它已经没有任何发挥空间了。3.3 喂给 AI 的提示词附模板与要点Spec 写好之后怎么喂给 AI 也有讲究。很多人直接把整份文档复制到对话框里说“按这个生成”这样能用但还不够稳。我用的提示词模板长这样你是一名资深后端工程师。请严格按照下面的字段级 Spec 实现客户信息管理模块的 RESTful API。 【硬性要求】 1. 不得新增、删除或修改 Spec 中字段的定义。 2. 所有接口字段名与 Spec 保持一致不准自行改名。 3. 校验规则必须按 Spec 逐条实现缺失校验视为错误。 4. 错误码和提示文案按 Spec 定义不得自定义。 5. 生成代码时请同步生成对应的数据库建表语句。 6. 最后给出所有接口的单元测试代码覆盖 Spec 中每条验收点。 【字段级 Spec】 在这里粘贴上面那份 Spec这里面有几个点值得展开讲。第一我强调“不得新增、删除或修改 Spec 的字段定义”这句话是在给 AI 划边界否则它会很积极地把“deleted_at”这种字段自己加上或者把 customer_no 改成 customerId代码风格完全不可控。第二让它“同步生成建表语句”和“单元测试代码”这等于把 Spec 里的每一条规则都变成可验证的东西你再拿测试结果跟 Spec 对哪里不一致一目了然。第三提示词里不要写“请把代码写得好一点”这种废话AI 对“好”的定义和你不一样“好”是不可度量词在 Spec 里根本不存在。如果你是第一次这么干可以先用一个小模块练手感受一下“约束严格”和“自由发挥”之间的差距真的非常明显。我见过很多同事第一次用这套方法直接愣住“我怎么之前没这么干过。”3.4 AI 生成后的逐项核对方法AI 生成完代码不要直接上线一定要做一次“Spec 核对”。怎么核我把方法归纳成三个动作。第一个动作是“字段对照”。打开数据库表结构跟 Spec 里的字段表逐一比对多一个字段、少一个字段、类型不一致全部打回。这一步用肉眼是体力活但真的很重要因为生成代码经常会出现“email 字段搞成 varchar(255)结果校验正则也写错”这种小事堆起来就是灾难。第二个动作是“用例抽查”。让 AI 生成的单测跑一遍然后手动再补几个边界用例电话填 10 位报不报错电话填 12 位报不报错邮箱填“123”行不行remark 填 501 个字符会不会崩拿这些边界值去戳 API本质就是在给你的 Spec 做压力测试顺手还能验证 Spec 本身的合理性。我曾经在抽查中发现“删除客户后还能按 customer_no 查到它”因为我把逻辑删除字段放在了实体里却忘了在查询规则里声明“默认过滤 deletedtrue”这个坑就是边界测试帮我捞出来的。第三个动作是“差异回写”。核对过程中如果发现 Spec 有漏洞先改 Spec再让 AI 按新 Spec 重跑而不是直接在生成的代码上改。我一直秉持一个原则文档和代码必须一致不一致时以文档为准让代码反过来适配文档。这样你手里的 Spec 永远是最新的长期来看维护成本极低。如果你直接改代码Spec 很快就过时了后续再用 AI 改需求就又回到“AI 猜你想改哪里”的老路。4. 常见翻车现场与排查技巧4.1 三种典型翻车模式与快速诊断跟 AI 配合写代码久了翻车场景来来回回就那么几类我把最常见的三类整理成了速查表方便你定位问题翻车现象大概率原因快速排查方法解决动作AI 生成的字段/表结构跟想象不一样Spec 没有覆盖字段粒度或覆盖了但提示词没强调“不得修改”对照 Spec 逐字段检查建表语句补全字段定义重新生成绝不手改代码校验规则缺失非法数据入库校验规则只写在自然语言里没收敛到字段表打开数据库尝试插入非法值查代码里有无对应正则把校验规则写成 Spec 的字段行让 AI 按行实现代码能跑但多了很多没要求的东西提示词里没有“未声明功能不要实现”对比 Spec 功能列表检查是否有额外路由/表/字段在提示词中追加硬约束把自由发挥项删掉重跑我早期犯的最多的就是第一类总以为自己说得够清楚了其实 AI 眼里的“清楚”跟我脑子里的“清楚”完全是两码事。后来我养成了个习惯写完 Spec 先默读一遍看到底有没有“合理就行”“合适就好”“按常规来”这类词只要看到这种主观模糊词一律改成可度量的描述。好比你把“地址要校验”改成“地址长度 5~200不允许只有空格的纯空白字符串”AI 就不会在“校验地址”四个字上一头雾水。第二类翻车说白了还是因为你偷懒。你说了“email 可选”但你没说“可选的意思是不填也能过填了就必须符合格式”两种话的代码实现完全不同。AI 一看“可选”很容易理解成“不管填没填格式都不校验”于是你的邮箱字段成了什么都能装的大筐。所以要记住凡是“可选”字段必须同时声明“为空时的行为”和“非空时的校验”缺一个AI 就漏一个。4.2 值得长期保持的几条实用习惯除了上面这些排查方法我自己沉淀了几条习惯算是长期跟 AI 配合下来的“肌肉记忆”。第一把 Spec 当成项目的一部分而不是一次性工具。我会在项目文档里建一个docs/specs.md把所有模块的字段级 Spec 都放进去。以后每次让 AI 改需求先更新这条 Spec再把它丢给 AI省得每次都在聊天窗口里翻旧账。有些 IDE 类 AI 工具支持读取项目文档你把 Spec 放进去它会自动参考生成代码的自觉性非常高。第二用优先级标记控制 AI 的实现顺序。Spec 里每一条规则我都习惯加一个优先级标签比如 [P0] 表示不做会出大事[P1] 表示应该做[P2] 表示有更好。AI 生成代码的时候它会先实现 P0再考虑 P1最后才管 P2。这招在长模块开发里特别管用以前我让它“先搭个框架”结果它把所有功能都平铺开来一次性实现没有主次现在有了优先级标签它反而知道什么该放主路径。第三遇到 Spec 歧义回到现实业务里找答案而不是问 AI。有一次我让 AI 生成退款功能它向我确认“退款要不要走原路退回”我说“你按普通方案处理”等代码出来才发现业务方要的是“仅原路退回”。这种问题根源不是技术而是需求本身没定。AI 能帮你处理“怎么做”但“做什么”必须由人来拍板。所以我在很多事情上都特别警惕尽量不让 AI 替我做业务决策我有空就先把业务规则研究透再写进 Spec。业务上拿不准的时候最快的路径是去问真实用户而不是问 AI。4.3 工具链建议用哪个环节承载 Spec 最合适最后一个经常被问的问题字段级 Spec 应该存在哪对话式 AI、IDE 插件、代码仓库文档到底放哪里最合适我的答案是存在代码仓库的文档目录里又或者放在你的知识库里喂 AI 的时候随时能整份复制。对话式 AI 用的是“粘贴式”适合一次性需求把 Spec 贴进去生成完就结束优点是灵活缺点是对话一长AI 容易把早期规则忘掉。IDE 类 AI 工具用的是“参考式”它会自己读取项目里的 Spec 文件生成时自动遵守优点是可以持续生效缺点是如果文件太多太乱它也分不清哪个 Spec 对应哪个模块所以文件命名一定要清晰比如customer_spec.md、order_spec.md这样。很多人纠结“我是不是一定要用最贵的模型”。以我的观察模型的差距远小于 Spec 质量造成的差距。你给开源模型一份无懈可击的字段级 Spec它一样能生成能用的代码你给顶级模型一句模糊需求它再聪明也只能给你一个概率最高的“标准答案”。先把 Spec 写明白再谈模型选型。工具链上我有两条建议一代码生成用带项目上下文感知的工具它能把 Spec 和现有代码结构联系起来二需求澄清阶段用对话式 AI 当陪聊帮我想出我遗漏的问题但最终的字段定义一定要自己读一遍、过一遍脑子再定稿。写在最后的一点点个人体会我踩过很多坑以后最大的体会是AI 写代码这事真正值钱的工作不是“写”而是“描述”。描述得越精确AI 的发挥空间越小代码质量反而越高。现在我基本不在 AI 生成之后再逐行 review 代码了因为我知道只要 Spec 没有漏洞它生成的东西就能放心用。有一个小技巧我几乎每个项目都会用在生成代码之前先把 Spec 当作一条条“验收口令”发给 AI让它按字段逐个念一遍并解释它打算怎么实现。这个过程非常神奇你会在它一句句复述里发现你写的哪些规则不够严谨、哪些字段存在语义歧义。等它把整份 Spec 的意图“反讲”一遍你心里就有底了这份图纸已经严丝合缝。再往后AI 生成的代码是不是一次过已经没那么重要了因为你知道只要按 Spec 来检任何偏差都能在两三句话之内被纠正回来。
返回列表