我第一次在这类工具上正经写项目代码的时候,还是一个非常标准的“聊天式”用法:丢一句需求进去,等它吐出一段代码,贴进编辑器,报错了再丢回去让它改。听起来没什么毛病,对吧?但事实是我连着加了七天班,改了一个几乎是从零写的“模拟需求”,被各种诡异的重复逻辑和“上一个错误消失、新错误出现”搞得精神衰弱。最后我把整个对话删除,用十分钟写了一整段结构化的需求描述,一次性丢进去,它给我的第一版代码,我几乎没改就能跑。从那天起,我的AI编程习惯彻底变了:少对话,一次把需求说清楚。这篇文章就围绕这个结论,把我踩过的坑、匹配的原理、实操模板和排查经验聊透。
如果你也正在用AI写代码、写脚本、搭小工具,或者只是想让AI帮你处理点重复劳动,这篇文章值得你花十分钟看完。它能让你少走我走过的弯路——那种浪费三小时、最终发现是需求描述方式出了问题,而不是AI本身不够聪明的弯路。
1. 内容整体设计与思路拆解
1.1 为什么“多轮对话”会越聊越乱
先说一个直观感受。你和一个很聪明但记忆力极差的同事对接需求,你们来回对话十几次之后,他大概率会忘记你第3轮说的那个关键细节,而牢牢记住你第11轮随口提到的一个小例子。现在的AI对话工具,在上下文处理上就有这种“貌似记得,实则模糊”的特性。多轮对话里,模型不是把每句话都同等权重地记住,它需要把较早的信息压缩、取舍,而在压缩的过程中,原始需求的优先级和边界就丢了。
我把这种现象称为“多轮对话的信息熵增”。一开始你的需求是一个清晰的点,但每多一轮对话,模型就会对你的需求增加一层“它自己的理解”。这些理解有对有错,但问题是后续对话会把错误理解当成既定事实继续延展。一轮两轮看不出问题,七八轮之后,代码里全是基于错误前提的生长物,那场景简直是在给一株长歪的树不停施肥,越修越歪。
我自己经历过一个最典型的案例。有个小工具,需求很简单,就是批量把一种文档格式转成另一种。我第一次丢给AI时,说的是“你写个脚本,把这堆文件转换一下”。它生成了一版,能跑,但只处理了单层目录。我说“能不能支持子目录”,它加了递归;我说“转换以后文件名保持原来的”,它加了个参数;我说“有些文件格式不规范,转换失败要跳过”,它加了try-catch;我感觉差不多了,它又突然在日志里多打了一堆内容。看起来每一步都对,结果我拿真实数据一跑,发现它把不支持直接转换的文件自动“静默跳过”了——这完全不是我想要的,我希望它至少能输出一个失败清单。整个对话已经拉长到十几轮,最后为了加一个失败清单,我甚至不知道应该在哪个轮次的基础上让它改,改完这里坏那里。
那次之后我做了一个实验:同样的需求,我把所有约束条件、边界行为、输入输出格式一次性写清楚,让它基于完整需求生成。第一版代码,就直接把“转换失败要记录在error.log里并继续,而不是静默跳过”给实现了。差别就在这里:多轮对话里,一个个补充的需求是碎片化的,模型更倾向于“补充局部逻辑”而不是“重新理解全局”。
1.2 少对话的本质:让AI基于“完整上下文”干活
少对话的本质,不是节省那几轮聊天时间,而是把你脑子里的完整设计一次性“倒”给AI,让它在统一的约束下做决策。这就像你找外包团队做东西,如果只告诉他们“做个小程序”,他们大概率会给你一个套壳模板;如果你给了需求文档、验收标准、技术选型和边界约束,他们交付的东西才可能接近你的预期。
AI编程工具没有“常识性追问”的能力,它默认你在给它全部信息。所以,信息给得越全,它的默认行为就越接近你的意图。在我后来的实践里,“一次性说清需求”被拆成两个层面:
- 一次性:一个需求无论多复杂,都要在第一条消息里尽量完整地呈现,至少要让AI能够理解问题的全貌。
- 说清:不是“说得多”,而是“说得结构化”。把背景、目标、输入输出、约束、边界、验收标准这六类信息分清楚,模型才能建立一个稳定的语义框架。
这两个词合在一起,核心价值就是:让AI在第一次交互时就获得足以做出正确取舍的完整上下文,而不是靠一堆零碎的修正去拼凑它的理解。
有人会担心:“需求那么复杂,一条消息怎么可能写完?”我的经验是,写300字-500字的结构化描述,比来回聊20轮省时间得多。而且这个描述一旦写好,可以反复用于不同版本的AI工具,成为一个可复用的模板资产。这一点,对经常和AI协作的开发者来说,越早意识到越受益。
1.3 我选择“少对话”的三点核心考量
我之所以把“少对话”从习惯上升为原则,不只是因为前面那次受伤的实战,更是基于三个我很看重的实际考量。
第一,稳定性和一致性。多轮对话里,模型会在不同轮次之间产生“偏好漂移”。第一轮你给了它函数式风格的代码,第三轮它自作主张改成了面向对象封装;你第五轮让它改一个逻辑,它顺手把另一个模块的命名风格也换了。这种事我遇到太多次了。一次性说清需求,配合明确的技术风格约定,代码的一致性才有保障。
第二,成本与效率。每一轮对话,AI都需要把前面的全部对话重新处理一遍。这意味着你的历史对话越长,单次请求的延迟越高,费用也越高(如果你是API调用方式,这个成本是实打实的Token开销)。把需求一次说清,一次生成,哪怕第一次生成的代码需要小修,整体成本也远低于十轮短对话的累积。
第三,人的认知负担。你可能没意识到,在多轮对话里真正累的不是AI,是你自己。你需要反复阅读AI的输出,确认它有没有记住之前的约束,需要把新需求和旧上下文合并思考,这非常消耗注意力。把需求一次性结构化写出来,你只需要做一遍“需求澄清”,之后就是检查、测试、微调,认知负担小得多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心机制解析:为什么“说清”能触发更高质量的代码生成
2.1 从注意力机制看需求描述的“上下文污染”
很多开发者不理解,为什么需求描述模糊时,AI写出来的代码会“结构飘忽”。这要从大模型底层的注意力机制说起。模型生成每一个Token时,会重新回顾整个输入序列,但不同位置的Token获得的“注意力权重”是不一样的。
一般来说,靠前的主导性指令(比如“写一个批量转换工具”)会获得比较高的注意力权重,而靠后的、具体的、补充性的信息(比如“失败时输出清单不要静默跳过”)如果表述不清晰,就容易被模型在生成时忽略。这就像你在一张纸上写了一大段话,用红笔圈了后半段的关键需求,但整张纸的前半部分已经写满了无关信息,红笔圈再亮,也容易被视觉淹没。
多轮对话让情况更糟。随着对话长度增加,早期轮次里的原始需求被逐轮稀释,后期轮次里的“额外要求”不断叠加,模型在生成代码时必须同时“注意力”到几十个约束上,而这个能力是有限的。结果就是两头不讨好:原始需求被弱化,后期需求被误读。
我做过一个对比实验。同一段需求,A组用两句话概括,B组用结构化的八要素描述,让同一套模型生成工具脚本。A组的输出功能上能跑,但边界处理非常草率;B组的输出明确包含了我要求的所有边界处理,且代码注释的结构几乎与我提供的要素一一对应。这个实验重复了三次,结论稳定:当需求描述本身结构清晰时,模型生成代码的结构也清晰地倾向于对齐你的结构。
2.2 “初次印象”对大模型输出的决定性影响
很多人低估了“第一轮对话”在这个协作模式里的分量。我观察到的现象是:AI对第一轮你给出的信息,遵循度最高;后续轮次里你提出的修正,遵循度逐轮递减。这与模型的训练方式有关——模型被训练为基于指令和上下文生成最合理的延续,而“最初的指令”就是这个上下文的锚点。
所以,如果你第一轮给的需求模糊,只给了“做个代码生成器”,AI会以“做个代码生成器”为锚点展开。之后你补充的“要支持多种语言模板”“要能自定义变量”“要兼容命令行调用”,都会被模型尝试性地整合进一个已经成型的框架里。你会得到一个试图同时满足所有要求、但每个要求都只做了一半的半吊子产物。
反过来,第一轮你就把六要素全部给齐,AI会以完整的需求文档为锚点,生成时自始至终都在这个框架里做取舍。代码的结构从一开始就是为完整需求设计的,而不是后来打补丁。这就是我反复强调“一次性说清需求”的机制性理由。
2.3 代码质量、返工率与需求描述方式的关系曲线
我用几个月的时间跟踪过一个关系:需求描述的完整度和代码返工率之间,存在明显的反比关系。这里不是拍脑袋,是我自己项目里的统计经验。
我把自己写的各种小工具、脚本、自动化流程分成两类:一类是“想起来就聊两句”写出来的,一类是“写结构化需求描述”后生成的。前者的平均返工次数在4-6次左右,而且往往是全局性返工;后者的平均返工次数1-2次,且返工范围基本集中在局部细节调整。
这条经验曲线让我很笃定:所谓的“AI写代码很垃圾”,很多时候不是模型能力问题,而是需求描述方式问题。你给它的信息越模糊,它的发挥空间越大,而大模型的“发挥”恰恰是最不可控的东西。你给它的信息越精确,它的发挥被约束在合理范围内,输出的质量就越稳定。
从工程管理的角度理解,AI编程工具和别的代码生成器有一个本质区别:它是概率模型,不是确定性程序。给它同样的输入,两次输出可能有微小差异,但如果给它极其严格的约束条件(输入格式、输出格式、风格要求、边界行为),它两次输出的一致性会显著提高。高约束意味着高确定性,高确定性意味着高产出的稳定性。
3. 实操要点:如何做到“一次性说清需求”
3.1 我的“结构化需求六要素”模板
模型听得懂人话,但它更喜欢结构化表达。我现在写需求描述,基本上固定用下面六块信息,每块一个区块,清清爽爽。你也可以直接复制这个模板去用。
- 1. 背景与目标(一两句话):这个工具/代码要解决什么问题?为谁服务?
- 2. 输入与输出(具体):输入是什么格式的文件/参数/接口数据?输出是什么格式?
- 3. 功能清单(列表):需要实现哪些核心功能?按优先级排列。
- 4. 边界与禁止(列表):明确不做什么、不需要支持什么、禁止怎么做。
- 5. 技术选型与风格(一小段):语言、框架、代码风格(函数式/OOP)、命名习惯、是否需要注释。
- 6. 验收标准与参考示例(可量化):怎么算完成?传什么样例、期望什么输出?
我给一个简化的实例。假设我想写一个模拟项目里的图片批量压缩工具,旧写法是:“帮我写个图片压缩脚本,批量压缩文件夹里的图片”。AI大概率给你一个能跑但完全不考虑失败场景、不保留EXIF、输出路径混乱的脚本。
新写法是:
背景:我有一个文件夹,里面有上千张图片需要压缩以减小存储占用。目标是写一个Python命令行脚本,能够递归处理多级目录下所有jpg/png/webp格式的图片。
输入:源目录路径(命令行参数);文件夹内的图片文件。输出:压缩后的图片写入指定输出目录,目录结构保持与源目录一致。
功能清单:1. 递归扫描所有支持的格式;2. 统一压缩到指定质量级别;3. 压缩后尺寸超过3000px的自动等比缩至3000px以内;4. 输出一个summary.json记录每个文件的处理状态;5. 支持--dry-run参数预览将处理哪些文件而不实际压缩。
边界与禁止:不处理gif格式;不覆盖源文件;不修改原文件的修改时间;如果压缩后的文件比原文件大,则跳过该文件并记录状态为skipped。
技术选型:使用Pillow库;脚本风格采用函数式写法,入口为main();文件名命名采用snake_case;关键步骤添加中文注释。
验收标准:在包含子目录的测试文件夹运行,所有文件按目录结构输出到目标目录;summary.json中每个源文件都有对应的处理结果记录;带--dry-run运行时不应产生任何输出文件。
这样一段话,实际写下来大概两三百字,但它把AI可能瞎猜的所有方向全部锁死了。这份描述我发给任何一代AI模型,它都不会跑偏太多。这就是“一次性说清需求”的实操价值。
3.2 把“不做什么”写进去,价值比你想的大
我发现很多人在写需求时喜欢强调“要什么”,但很少写“不要什么”。这是一个很大的误区。AI模型的默认行为是“尽可能多做事”和“尽可能合理推测”,而这两个“尽可能”恰恰会生成很多你不需要的东西。
举个小例子。有一次我需要一个把Markdown里某个标签替换成另一个标签的小脚本。我的需求只写了“把【注意】替换成【提示】”。AI生成的代码非常认真——它自作主张地把所有格式变体也处理了,还顺带帮你把其他标签也统一了格式。看起来是贴心的行为,但实际上破坏了我的原数据。后来我在需求里直接加了边界:“不要修改任何其他标签,不要自动格式化文本,只精确替换指定字符串”,这样的问题几乎不再出现。
写“不做什么”不仅仅是为了约束AI,更是一个帮你理清需求边界的过程。很多开发者跟我聊的时候,讲到需求的中段才突然意识到:“等等,这个场景我们好像不需要支持。”这种后知后觉,如果在描述需求时就提前完成,后面的返工概率会大幅下降。
一个快速上手的“需求描述清单”
如果你不打算记我那六要素,也可以记住一个更精简的版本,每次丢给AI前自查一下:
- 有没有说明背景和目的?(AI能理解“为什么做”,就不会在思路上跑偏)
- 有没有说明输入输出格式?(格式不清是返工最大的源头)
- 有没有说明不能做什么?(不加边界,AI就会替你加戏)
- 有没有给出验收标准?(没有标准,AI就不知道“完成”的定义)
- 有没有指定技术栈和风格?(不指定,AI会按它的口味来,你未必喜欢)
这五条是我复盘了不下二十次项目之后提炼出来的。每次生成之前,对着这个清单过一遍,基本能保证需求质量在及格线以上。
3.3 需求描述里的“废话”和“关键信息”怎么区分
有人听说“描述越详细越好”,就开始事无巨细地写小作文。但这里也有一个度的问题。我的经验是:与决策相关的信息才值得写,和决策无关的修饰词尽量删掉。
什么是与决策相关的信息?比如“这个脚本是给非技术人员用的”,这决定了你要求它提供命令行交互还是图形界面;“这个数据量可能每年增长到百万级”,这决定了你要不要要求AI做分批处理而不是一次性加载;“这个项目后续可能扩展为服务端调用”,这决定了你把逻辑写成独立的可调用模块。这些都是影响AI做出正确架构决策的关键信息。
什么是废话?对AI输出结果没有实质影响的信息,比如情绪化描述“这个需求很紧急”,或者完全无关的背景故事“我和我朋友在咖啡厅聊到这个想法”。这些内容不会让代码变得更好,反而会稀释核心指令的注意力权重、增加Token成本。
我给自己的判断标准很简单:这句话如果去掉,AI生成代码的行为会不会发生变化? 如果不会,就是废话;如果会,就是关键信息。按这个标准去筛选内容,你写的需求描述就不会冗长,而是精确。
3.4 用示例代替抽象描述,一个具体的例子胜过十句话
我发现有一个特别好用但很多人不注意的技巧:在需求描述里塞一个小例子。AI模型在理解虚构的、抽象的需求时很容易产生歧义,但如果给它一个具体的输入和输出示例,它的理解准确率会大幅提升。
比如你想写一个“把CSV数据里时间字段的格式从12小时制转成24小时制”的脚本。你用纯文字描述,AI能写,但你绝对要小心它把“01/02/2025 03:45 PM”这类格式解读成哪种写法。如果你在需求里直接给例子:
- 输入示例:
2025-01-02 03:45 PM - 期望输出:
2025-01-02 15:45
它就会照着这个格式去处理,不会再问你要不要处理夏令时之类的问题。这种“给例子”的方式,本质上是在给模型一个可对齐的靶子,它生成的代码会自动以这个例子为基准。我在写所有涉及字符串处理、文件解析、数据转换的任务时,都会带上两个以上的输入输出示例:一个是常规情况,一个是边界情况。成本和纯文字描述差不多,但效果天差地别。
一个完整的需求描述案例(可直接抄作业)
我用一个我最近模拟的真实场景来演示完整过程。需求是做一个“批量重命名工具”,但不是一个简单工具,而是要有几个明确的行为。
写好的完整描述:
背景:整理一个模拟项目X的素材库,需要把散落在多个子目录中的图片文件按“日期_序号.jpg”的规则重命名,同时保持原目录结构不变。
输入:命令行传入的根目录路径。输出:重命名后的文件自动写回原目录,不做任何移动。
功能清单:1. 递归扫描目录下所有jpg/png/webp文件;2. 读取图片EXIF中的拍摄日期,如果取不到则使用文件修改日期;3. 按日期分组,组内按拍摄时间排序后冠以序号;4. 如果目标文件名已存在,自动追加下划线继续递增;5. 生成一个rename_log.csv记录原始文件名和目标文件名的对应关系。
边界与禁止:不重命名非图片文件;不重命名名称已符合规则的图片(幂等);不对图片内容做任何修改;不输出任何交互式提示。
技术选型:Python + Pillow + exifread库;函数式风格,不要面向对象,不引入数据库;入口为main()函数。
验收标准:对一个包含两层子目录、共60个图片文件的测试目录运行,所有文件被正确重命名;带已有符合规则文件的目录再次运行不产生新操作;rename_log.csv包含全部记录。
这份需求我实际测试过给几个不同模型,它们第一版代码基本都能通过验收标准。重点在于,它是完整的,不是完美的——你不需要文笔好,只需要覆盖所有决策点。
4. 实操过程与核心环节实现
4.1 从“聊天驱动”到“文档驱动”,一次工作流的转变
我从“聊天式”切换到“文档式”之后,整个AI编程工作流发生了本质变化。过去我的流程是:有一个模糊想法 → 打开对话工具 → 边聊边想 → 得到一堆代码 → 反复修补。现在我的流程是:
- 先在备忘录里把需求按六要素写下
- 整理成一段结构化的文字(大约300-500字)
- 一次性发给AI,要求它生成完整代码
- 拿到代码后先跑边界测试,再做局部微调
这个转变最大的好处是:我的需求描述可以复用和演进。新的需求来了,我把旧文档改改,适配新场景,几分钟就能发出去。我甚至为常见的任务类型建立了一个需求描述库,比如“写一个爬虫”、“写一个数据处理脚本”、“写一个自动化测试工具”,每种类型都有默认的模板。用的时候只需要替换具体业务参数,两分钟就能生成一条高质量的AI指令。
这个工作流也让我意识到,AI编程真正考验的不是“会不会写Prompt”,而是“能不能把事情想清楚”。当你被迫把需求写清楚的时候,你其实是在替自己做一次需求分析。AI只是把你的分析结果翻译成代码,但分析过程的质量,始终在你自己手上。
4.2 一次性生成代码之后,我做的第一轮“边界测试”
需求写清楚了,AI给出了第一版代码,并不代表可以闭眼用。我会对生成的代码做一个非常快速的“边界测试”,专门验证我在需求里写的那些边界约束是否真的被执行了。
比如说,我在需求里写了“不覆盖源文件”,我第一件事就是备份一份测试数据,故意构造一个输出目录和源文件冲突的场景,看它会不会真的跳过。我在需求里写了“失败时记录日志继续处理”,我会故意放几个损坏的文件进去,看它是否真的优雅跳过而不是中断执行。
这个边界测试的习惯,是我从踩坑里积累出来的。因为AI生成的代码往往是过拟合于你的描述的,你在描述里写了什么它做得很好,你没写到的它就发挥想象力。边界测试相当于一次验收,把描述和现实的差距找出来。好消息是,因为需求写清楚了,这种差距通常很小,修起来也快——改一两行代码就行,不需要全局重写。
4.3 实测记录:同一个需求,两种描述方式的效果对比
我特意做过一个并排对比实验来验证这套方法的效果。同一个需求,我分别用“聊天式”和“文档式”各生成一次,把结果放在一起比较。
聊天式是这样的:
我:写个脚本,把Excel里的数据整理一下
AI:好的,你能告诉我具体要整理哪些内容吗?
我:就是把A列和B列合并,然后按C列排序,重复行删掉
AI:好的,我需要确认一下,合并后是用逗号分隔吗?
我:对,用逗号分隔
AI:好的,我来写这个脚本……
整个过程来回5轮以上,AI每次都要确认一个细节。最终生成的代码,其实和连写带改5轮来比,花费的总时间差不多,但体验上非常琐碎。文档式的写法是:
写一个Python脚本,读取指定Excel文件。将A列和B列的内容用逗号合并写入新列D;以C列为主关键字升序排序;删除所有列完全相同的重复行;输出为新xlsx文件,不修改原文件。使用pandas库。入口为main()函数。
一条消息,直接生成。因为输入输出格式明确、排序规则明确、删除规则明确,它列的选项全部被锁死,第一版代码就能直接用。我特意数了一下,聊天式从开始到结束花了大约15分钟,产出是4轮对话;文档式从打开编辑器到写完描述花不到5分钟,产出是1轮。
这个对比实验做了三次,每次结论都一样。一个人可能在聊天式里感受到“AI好聪明,竟然会反问”,但站在工程效率的角度,“从来不反问、直接给你正确的东西”的文档式,才是真正对结果负责的方式。
4.4 代码层面的“验收标准”如何设计
验收标准这个要素,很多人在需求描述里容易忽略,但其实它是控制代码质量的关键。如果验收标准写得具体,AI生成的代码就会自带“测试导向”——它会在实现时主动对标你的验收要求。
我来举一个设计验收标准的实际方法。要设计出好的验收标准,不要用模糊词,尽量用可观察、可量化的描述。比如:
-
模糊写法:代码应该能处理错误情况。
-
可验收写法:当输入文件不存在时,程序打印清晰的错误信息并以非零退出码结束,不抛出堆栈跟踪。
-
模糊写法:性能不错就行。
-
可验收写法:处理1000行CSV数据的耗时不超过2秒,内存占用不超过200MB。
-
模糊写法:输出格式要正确。
-
可验收写法:输出的JSON文件必须包含data和meta两个顶层键,data为对象数组,meta中包含数据生成时间。
这些可验收标准在描述里出现,AI生成的代码就会显著地更注意这些边界。因为模型在训练时见过大量“测试导向开发”的语义,当你把验收标准前置,它就会像被要求写单元测试一样,给代码加上防御性逻辑。
我自己现在写需求时,最后一条永远是验收标准,且至少包含两个具体例子:一个是黄金路径(一切正常时的输出),一个是失败路径(出错时的行为)。这两条定下来,代码的质量底线就有了。
5. 常见问题与排查技巧实录
5.1 实操中踩过的高频问题盘点
写需求描述这件事,我一开始也做不好。前几次“一次性描述”翻过车,后来复盘发现主要是几种典型问题。
第一种是描述过细导致模型被细节淹没。有一次我写了一个特别长的需求,把所有可能的字段、格式、异常情况都堆在一起,结果模型生成代码时过于关注字面上的字段映射,反而忽略了核心业务逻辑。后来我把不重要的字段描述删掉,只在验收标准里保留关键字段,模型立刻抓到了重点。
第二种是重要信息放在了不起眼的位置。比如我习惯把“禁止覆盖源文件”放在描述最后一句,结果模型生成代码时偶尔还是会出现覆盖源文件的危险行为。现在我把所有“禁止类”的约束单独做成一块区域,放在功能清单后面,用加粗文字标记,模型遵循的概率显著上升。
第三种是一次描述塞了太多独立模块。如果需求本身包含五六个互不相关的功能,即使描述再清晰,模型也很难一次性处理好。我的策略是拆分成两轮独立请求:第一轮请它生成主框架代码,第二轮请它在框架上补充扩展功能。拆分后整体成功率大大提升。
5.2 排查“代码不按需求写”时的三条路线
当你发现AI生成代码没按需求来,先别急着重写或重开对话,按下面三条路线排查,多数问题都能定位。
第一条:回去检查需求描述里是否有自相矛盾的地方。这是非常常见的问题。比如你写了“递归处理所有文件”,又写了“只处理根目录下文件”,模型会尝试兼顾这两个矛盾的条件,结果生成一个极为别扭的逻辑。AI不像人,它会尽量“都满足”,而不是提醒你矛盾。所以写完后通读一遍,重点检查功能和边界之间是否有逻辑冲突。
第二条:确认验收标准的例子是否和功能清单一致。有时候功能清单里写着“支持批量上传”,验收标准里却只给了单文件上传的例子,模型就会以验收标准的例子为准,把功能做窄。所以验收标准的例子一定要覆盖功能清单里的核心场景。这里的教训,就是“例子比描述更有指导性”。
第三条:检查是否有信息缺失但你没意识到。AI不会主动告诉你“你少描述了某个决策点”,它只会默默替你做一个默认决定。比如你没说输出文件的命名方式,它会按自己的喜好来;你没说日志格式,它会按它见过的通用格式来。这些默认决定汇合起来,就可能表现为“代码看起来不对”。
5.3 修正AI生成代码时的“最小化修改原则”
就算需求描述写得很完美,AI生成的代码也几乎不可能是完美的。但这里有一条值得刻意练习的原则:尽量做最低限度的修改,而不是重写。
原因很简单:AI生成代码的整体框架是基于你的需求描述做的最优解,你局部修改几个点和全局推翻重来,后者的不确定性更大——你重写时如果描述不完整,又会回到多轮对话的老路上去。
我在拿到第一版代码后,习惯先跑一遍边界测试,把问题归类。如果问题是某个分支逻辑不对,我就在那个函数里修;如果问题是某个参数没传对,我就改调用处。整体的架构、命名、注释风格,保留AI的原始输出。这样做的结果是,代码里AI生成的部分和人工修补的部分能非常自然地融合,而你省的精力,可以用来做更重要的业务思考。
有一个例外:如果AI生成的代码在核心架构上就不符合你的预期(比如你想用递归它用了循环、你想用异步它用了同步),那么别犹豫,直接重开一次请求,但这次要在需求描述里把架构偏好写得更加明确。架构级别的偏差,修修补补是补不回来的,重写成本反而更低。
尾声
说实话,我不是一开始就相信“少对话、一次说清”这套思路的。我最初也是一个很喜欢和AI来回唠嗑的人,享受那种“你一句我一句”的感觉。直到我把大量时间花在修补AI因需求碎片化而产生的次品代码上,我才意识到:我的时间应该花在把需求想清楚上,而不是给AI解释需求上。
这两者看着很像,其实差别巨大。前者是主动设计,后者是被动修补。我现在写任何AI编程需求,都强迫自己先在备忘录里把需求描述写完整,再打开对话窗口。这个习惯帮我省下了大量返工时间,也让每一次AI协作变得可预期、可复用、可沉淀。
如果你刚开始使用AI编程工具,或者你正在被多轮对话的高返工率折磨,不妨试一试这个思路:下次你打开对话窗口前,花十分钟把你脑子里的需求结构化地写下来,说清背景、输入输出、边界约束和验收标准,然后一次性发给它,看它给你什么样的结果。我在实际操作中的体会是,当你愿意把需求想得足够清楚,AI能给你的东西,远比随意聊天时给得多。
