
上周三晚上,我让 Claude Code 帮我写一个"读 csv,存进 Postgres"的脚本。
12 秒后它交付了 240 行 TypeScript:三层抽象、独立的 ConfigLoader 类、一个 IngestionPipeline interface、依赖注入、catch 了 8 种异常分类、最底下还顺手附了一份 README 解释怎么扩展到 Parquet。
我盯着屏幕看了 30 秒,把整段删了。
我只是想看下今天那份 1.2MB 的 csv 长啥样。
···
如果你用 AI 写过代码,你有过这种感觉:跑通了,能用,看起来也挺像那么回事——但你心里就是有一个声音说"差点意思"。
差在哪儿一时说不上来。说不上来又不能怪 AI——它字面上做对了你说的所有事。
后来我发现一件事:"差点意思"不是 AI 笨,是它默默替你填了 5 个空,每一个都填错了。
这 5 个空它不会主动问。它假装它知道——然后用一个看着对、其实接不住你想法的版本交差。
下面 5 件,每一件都是开发者用 AI 写代码时,不主动说就会被 AI 默认填错的隐藏前提。说出来这 5 件,AI 写出的代码会从"差点意思"跳到"挺合手"。
···
你说「写一个 X 函数」。
你心里想的其实是「我最终要交付 Y,X 只是 Y 中间的一步」。
这个差别 AI 接不到。它会按字面把 X 做到完美——optimal、generic、coverage 满分——但你 merge 进去会发现 X 跟 Y 哪儿都别扭。signature 不对、return 类型让下游难用、错误处理跟整体风格不一致。
这就像让木匠做一个"门"。 他给你做了一扇完美的门——结实、平整、五金齐全。 但他不知道你这门是要装在会议室还是保险柜还是你家厕所。 出来的门当然差点意思。
修正方法很简单,prompt 头部加一句:
我最终要做的是 Y。这个 X 函数是 Y 里负责 Z 部分的一步,下游 W 会消费它的输出。
加了这一句,AI 会主动避开"X 完美但跟 Y 别扭"的所有路径。signature 会贴合 Y 的需求,return 会让 W 好用,错误处理会跟整体风格对齐。
不是 AI 突然变聪明了。是你终于让它看见了你真正在做的事。
「写个 X」AI 默认会按生产级给你——三层抽象、interface、依赖注入、完整 error handling、每个变量带 type 标注、JSDoc 写齐。
但你可能只是想跑个一次性脚本。或者验证一下思路。或者就是个 demo。
AI 不会问你这是什么档位。它默认 prod。
这就像你问朋友"晚上随便吃点啥"。 他给你订了一份米其林三星套餐。 你想吃的其实是楼下那家黄焖鸡。
我那天的 240 行 csv 脚本就是这么来的——我只想 head 5 行看看,AI 觉得我要做一个生产级 ingestion pipeline。
修正:prompt 直接说档位。
档位 | 给 AI 的话 | AI 该交付的 |
|---|---|---|
一次性脚本 | "一次性脚本,跑完就丢" | 30 行内、能跑、不要 type、不要 error handling |
prototype | "原型,验证想法" | 简单 type、try/catch 包关键路径、可读 > 优雅 |
内部工具 | "内部工具,会有人维护" | 标准 error handling、log 关键节点、不要过度抽象 |
prod | "上 prod" | 完整 type、所有 edge case、依赖注入、文档 |
这一句话决定了 AI 给你的代码是你想要的那个长度,还是你被迫删一半的那个长度。
你让 AI「写一个调用外部 API 的函数」。它给你的版本是这样的:
try { const r = awaitfetch(url); return r.json(); } catch (e) { thrownewError('API failed'); } 漂亮。简洁。没用。
哪个真实的 API 只有"成功"和"失败"两种结果?真实情况是:429 要退避,500 要重试,401 要刷 token,超时要兜底,返回 schema 偏离要降级,上游这次返回 200 但 body 是空的也得处理。
AI 不会主动覆盖这些。它默认 happy path,是因为你也没说边界在哪。
AI 写的 catch 总是只有"throw"。 像把家里所有的烟雾报警器接到一个总开关上: 要么所有报警器一起响,要么所有报警器一起静默。 中间状态?没有。
修正:prompt 里逐个点出来。
这个 API 调用要面对几种失败:限流(429)、偶发 5xx、token 过期(401)、超时、schema 不一致。 我希望的处理:限流退避 + 重试 3 次 / 5xx 重试 1 次 / 401 刷 token 后重试 / 超时降级用 cache / schema 不一致打 warning 但继续。
逐项点。AI 会按你说的处理每一种。
如果你不点,它会自动跳过 90% 的真实场景——给你一个在 demo 数据上完美工作、在 prod 5 分钟内就报警的版本。
AI 默认追求"clean"——单一职责、无重复、最小 surface area、私有变量、全部 const。
但你心里清楚:这段代码下周还要改 3 次,因为业务还没定。
如果你不告诉它"这是会变的",它会把所有东西缝得很紧。表面上 clean,但你周二想加个新规则,发现要动 5 个文件、改 3 个抽象、还得回去问"当时为啥这么抽象"。
AI 的 clean code 是 PhD 论文级别的整洁。 也是 PhD 论文级别的难改。 你想插一句话,得先重新答辩。
修正:
这段代码 [我下周会回来改 / 业务还在变 / 是 PoC 还要 pivot]。 请保留 [显式参数 / 拆分点 / 一些 hook],方便我后面只改一处不动其他。
或者反过来,如果你确定不会再动:
这段代码上线后基本不改了,请按"无 hook 最 clean"的标准写。
工程上的 clean 和抗修改是矛盾的。AI 默认走 clean,你不告诉它"我还要改",它把所有修改入口都缝死了。
AI 拿到一个 prompt 写函数,默认这个函数是 standalone——它不知道你 codebase 里有没有现成的 utility,不知道你的命名风格,不知道你用了哪个 logger,不知道你的 error 类型继承关系。
结果是 AI 给你一个自带轮子的版本:自己定义了一个新的错误类,自己 import 了一个新 logger,自己写了一个新的工具函数——而你 codebase 里全都有现成的。
merge 进去就别扭。要么留下"两套 logger 共存"的债,要么你手动改一遍。
这像你公司新来个实习生。 第一天上班自带了一个键盘、一台显示器、一个鼠标—— 都很好。但公司也有这些。 而且公司那一套,你们已经用三年了。 他不知道。因为没人告诉他。
AI 不会主动 grep 你的 codebase(它真的不会)。所以 prompt 里直接给钩子信息:
codebase 里:
请用现有的,不要新造。
这一段 5 行,让 AI 输出从"插进去要改 30 处"变成"插进去要改 0 处"。
···
把 5 件放在一起看,是同一个反模式:你以为 AI 像同事一样会主动问,但 AI 不会。
同事不知道会先问,AI 不知道会自己脑补。
它是个超会猜的同事,但它从来不验证。你说啥它信啥,你没说的它自己接着填。
「差点意思」就是这 5 个脑补加起来的差。
···
写到这你可能已经发现:这 5 件事——目标 / 档位 / 失败模式 / 可改性 / 外部依赖——其实就是任何工程项目开头那份 spec 的最小集。
你以为你在写 prompt,其实你在写一份 micro-spec。
公司里写 spec 是因为大家心里有数:写不清楚后面就要返工。但跟 AI 对话时,"返工"的成本被压缩到了 12 秒——你按一次回车,它就开始写了。没人等你想清楚。
正因为决策速度被压到极限,前置规范的价值反而变大了。每多写 30 秒 spec,少删 12 秒后的 240 行——这笔账每个开发者 1 秒就能算清。
再往上一层看:这 5 件事不只是单个 prompt 的 spec,它是你跟 AI 长期合作的「项目宪法」——边界在哪、出事算谁的、风格谁说了算、未来怎么演化。看着废话,缺了哪一条都会出事。
「prompt 工程」这个词有点误导。它让人以为写 prompt 是某种修辞技巧——怎么遣词造句让 AI 听话。
不是。写 prompt 不是工程,是写规范。写得好的人不是 prompt 写得花,是 spec 写得清。
···
1. 真实目标说了吗? (我最终要做的是 Y) 2. 质量档位说了吗? (prod / 内部工具 / prototype / 一次性脚本) 3. 失败模式说了吗? (遇到 X 怎么办,遇到 Y 怎么办) 4. 改不改说了吗? (这段下周还要改吗) 5. codebase 钩子说了吗?(已有的 logger / 错误类 / utility) 5 个都说,AI 给你的代码会让你觉得「就是这个」。
5 个都不说,AI 给你的代码会让你觉得「差点意思」。
代码差的那一点,从来不在 AI 那边。在你那一份没写完整的 spec 里。
下次再让 AI 写代码之前,别先按回车。先花 30 秒,把这 5 件事填完。
填了 0 件 —— AI 给你 240 行你删了 240 行。 填了 5 件 —— AI 给你 30 行你保留 30 行。
差的就是这一份 spec 的事。
更深一点说:在 AI 时代,会写 spec 比会写代码更值钱——因为 AI 替你写代码的速度已经很快了,但没人能替你想清楚要做什么。