大家好,我是Zack。
先说个场景:你让 AI 写了个脚本,它说写好了,你一跑,成了。行,收工,关窗口。
三天后你要改需求,打开那脚本,从头到尾看不懂。哪段在干嘛、为什么这么写、有没有坑,一概不知道。你面临两个选择:花半小时自己啃,或者整段删了让 AI 重写。
问题不是脚本坏了,是你压根不知道它给你的是什么。
我昨天拿一个真实的图片整理脚本做了实验:让 AI 写完之后,多花一分钟让它用大白话讲一遍。结果它自己交代了 5 个问题——全是「跑通」根本看不出来的那种。
先说实验怎么做的
我给 AI 的任务很简单:写个 shell 脚本,把照片文件夹里的 jpg 和 jpeg 按扩展名分到两个子文件夹,统一小写,递归处理子目录。
40 秒写完。我一跑,exit 0,输出「移动 5 个文件」,文件各就各位。看起来完美,对吧?
如果到此为止,这 5 个问题就跟着脚本一起进我的工具箱了。
让它讲一遍,它自己招了
我追加了一句话,就一句:
读一下 sort_photos.sh,用大白话一段一段讲它每部分在干嘛。
讲完之后,检查一遍:有没有你没讲到的、或者你自己看着心里发虚的段落?
有没有你自己也说不清为什么这么写的行?
它老老实实讲了 40 多秒,每段都对应上了。然后画风变了,它开始交代问题,一共 5 个:
第一个:第 31 行那个 *) continue ;; 基本是死代码。前面 find 已经把扩展名过滤死了,走到这里的必然是 jpg 或 jpeg,这个兜底分支永远走不到。不是错,但它是摆设,读者会误以为它在干活。
第二个:扩展名提取那两行在「文件没扩展名」时会出怪结果。这次没事,是因为 find 恰好过滤掉了。但哪天有人把 find 条件改宽松,这里就是雷。它原话是「这是我最发虚的一行」。
第三个,也是我用真实文件验证到的:如果目标文件夹已经有同名文件,脚本会「跳过」它,但这个跳过只在屏幕上一闪而过。我实测:往原目录放一个同名文件再跑一次,stdout 只有一句「完成:移动 0 个文件,跳过 1 个重名文件」,细节全甩在 stderr 里。那个文件就永远躺在原地,脚本再也不会碰它,也不会提醒你。你要是以为「跑完了就是都整理完了」,这文件就丢了。
第四个:mv 没加 -n 参数。检查和移动之间有个理论上的空档,单机无所谓,严格说「不会覆盖」这个保证不是百分百。
第五个:有行注释写得不准确,把一个「性能优化」说成了「正确性必需」。
我补一句实话:第三个坑我在自己的 Mac 上只验证到「跳过滞留」这一层。它还提到 macOS 大小写不敏感、Linux 服务器上 a.jpg 和 a.JPG 会互相顶替——这个我在 Mac 上复现不了,文件系统压根不允许两个只差大小写的文件共存。这条我记下了,等哪天上服务器跑再验。
一分钟换来了什么
算笔账:写脚本 40 秒,讲一遍加自查 48 秒,多花 48 秒。
换来的是:5 个问题全部摆在台面上。死代码我可以顺手删掉;mv -n 我 10 秒补上;注释改一句就好;最值钱的是那个「跳过滞留」——不改的话,哪天有文件没被整理,我会以为出了灵异事件,顺着查半天,最后发现是脚本「正确地」跳过了它。
不问这一句,这 5 件事我一件都不知道。脚本照样跑,照样 exit 0,照样「移动 N 个文件」报喜。
顺便说个意外收获:它讲完之后,我再去改代码,基本不用重新读——因为它讲的时候我已经把每段的意图听了一遍。省的是后面「重新熟悉」的那半小时。
提示词模板,直接抄
AI 写完任何东西,追加这三句:
用大白话一段一段讲你刚写的每部分在干嘛。
讲完之后检查:有没有你没讲到的、或者讲不顺的段落?
有没有你自己也说不清为什么这么写的行?
三个要点,别省:
一,让它「讲」,不是让它「检查」。直接说「检查有没有 bug」,它大概率回你一句「我检查过了,没问题」。但让它逐段讲,讲到哪段卡壳,那段就是问题所在——讲不出来就是没懂,装不了。
二,「心里发虚」「说不清为什么」这两个词留着。这是在给它递台阶,允许它说不知道。你要是问「有什么问题吗」,它倾向于给你个体面的「没有」。
三,它交代的问题要分拣。有的是真 bug 立刻改,有的是理论边界记着就行,还有的是它自己编戏。分拣的办法就是像上面那样拿真实数据验证一下,一分钟的事。
如果它讲得含糊,追问两句
多数时候它交代得挺干脆,但偶尔也会绕。给你两个追命句,我常用:
它说「这段是为了保证正确性」——追:「换个写法行不行?为什么非得这么写?」说不出一二三的,就是抄来的惯用法,不是理解。这种段落出问题最难查,因为它不知道自己在干嘛。
它说「这段没什么特别的」——追:「那删掉会怎样?」要么它给你说清后果,要么它承认没想过。我这次实验里那个死代码分支,就是靠这个思路问出来的:删掉也不影响,留着只会让人以为它在过滤什么东西。
追问到第三轮还讲不顺的段落,直接让它重写那一段,写完再讲。别攒着,含糊的段落攒多了,这份代码就又回到「不敢改」的状态了。
通用原则一条
「跑通」和「能用」是两码事。跑通只证明这次输入没炸,「能用」要求你知道它的边界在哪、什么时候会炸。
让 AI 讲一遍它写的东西,等于让它把自己的理解摊开给你看。讲得顺的段落你放心,讲不顺的段落就是雷区——这招不止管代码,管用它写的配置、正则、SQL,一样好使。
你有没有遇到过「代码能跑但你不敢改」的东西?评论区聊聊,你是自己啃的还是删了重写的。