调试时对着一只橡皮鸭把问题讲一遍,很多 bug 会自己露馅——这招老程序员都听过。我后来发现,AI 其实是一只很会追问的橡皮鸭:它不会嫌你啰嗦,还会在你讲不清的地方打断你。前提是:你别一上来就问“怎么修”,先逼自己把问题说清楚。
这篇文章记我怎么把 AI 当橡皮鸭用,而不是当自动答题机。写的都是个人习惯,不保证适合每个人,但对我自己很管用。
为什么一上来就要答案,反而更慢
以前我的坏习惯是:报错一贴,再加一句“帮我修”。AI 很快给一串可能原因和改法,我挑一个试,不行再试下一个。看起来很高效,其实经常在还没定义清楚问题的情况下乱开枪。
典型症状:
修完 A,B 又坏了,才发现根因根本不是 A
AI 给的方案依赖一个我其实没有的前提(比如“你用的是某某版本默认配置”)
我自己事后复盘,发现当时连“期望行为是什么”都没写清楚
橡皮鸭调试的核心不是鸭子,是强制外化:把脑子里模糊的一团,变成一句能被别人听懂的描述。AI 一旦变成答题机,外化就被跳过了。

图:不问答案先说清:答题机路径 vs 橡皮鸭路径(原创示意图)
我现在会先立一条规矩:前两轮对话禁止要修复方案,只允许澄清问题。 听起来矫情,但能挡住“先开枪再瞄准”的冲动。
我怎么开口:先讲场景,再讲现象,最后才猜
对着 AI 当橡皮鸭,我会按固定顺序说,顺序本身就是体检表。
1. 场景(Context)
我在做什么?哪个模块、哪条路径、什么环境?尽量一句话说完,比如:“本地起的订单服务,走创建接口创建草稿订单。”不要一上来贴整段无关日志。
2. 期望(Expect)
我认为“正确”长什么样?能写成可观察的结果最好:“应返回 201,body 里有 orderId。”期望说不清,后面所有“修”都没有验收。
3. 实际(Actual)
真实发生了什么?只贴最小相关的报错或响应,并标明我已经排除过什么(比如“重启过、清过缓存、换过账号仍复现”)。
4. 我的猜测(Hypothesis)
这一步最容易偷懒,也最值钱。我会强迫自己写一句:“我猜是 X,因为 Y;也可能是 Z。”猜错没关系,没猜才有问题——没猜说明我还在等别人替我思考。
说完这四步,我常常还没等 AI 回复,自己就已经发现漏了一步或前提错了。那只“鸭子”的价值,一大半发生在我自己说话的时候。
让 AI 追问,而不是给补丁
如果我讲完四步还是糊,我会明确下达角色指令,大意是:
你现在是橡皮鸭,不要给修复代码。只做三件事:指出我描述里缺的信息、问我最多三个澄清问题、把我的问题用一句话复述给我确认。
这条指令有两个作用。一是挡住它急着写 patch 的惯性;二是逼我听它的复述——复述对不上,说明我自己都没说清。
我遇到过一次:AI 复述成“创建订单偶发 500”,我立刻纠正:“不是偶发,是带了某个优惠券字段就必现。”一纠正,问题从“玄学”变成“具体字段”,后面排查就快了。

图:橡皮鸭四步:场景、期望、实际、猜测(原创示意图)
追问轮次我一般卡在两到三轮。超过三轮还在绕概念,说明我该去看代码或文档,而不是继续聊天。“橡皮鸭”不是无限倾诉对象,它是澄清器。
什么时候才允许问“怎么修”
澄清够了,我会自己设一个放行条件,至少满足两条才要方案:
我能用一句话复述问题,AI 的复述也和我对齐
期望与实际都可观察,且我知道怎么验证修好了
(加分)我已经有一个可证伪的猜测
这时再问,我会改口风:不是“帮我修”,而是“基于上面的问题定义,给出 2 个最可能原因,按可能性排序,每个原因对应一个最小验证步骤;先不要写大段补丁。”
要验证步骤、不要大补丁,是为了防止它一次甩给我重构式修改。橡皮鸭阶段培养的是定位习惯;一旦直接吞补丁,习惯又回去了。
几个我踩过的坑
坑 1:把情绪当问题。
“这段代码好恶心帮我重写”不是问题定义。重写成什么样、保留哪些行为、哪些测试必须绿,说不清就不要开干。
坑 2:日志糊一脸。
贴 200 行日志让 AI“自己看”,等于把外化工作外包回去。我现在最多贴关键 20 行,并标注我认为相关的行号。
坑 3:过早要最优解。
澄清阶段若开始讨论“架构上更优雅的做法”,话题会漂。先让现象对齐,优雅留给下一轮。
坑 4:鸭子变枪手。
有时我嘴上说当橡皮鸭,手却忍不住问“那怎么改”。一旦破戒,后面几轮很容易滑回试错循环。我会把“禁止给补丁”写进对话开头,当作物理隔离。
一套可照抄的开场白
我常直接用下面这段当模板(按需改括号里的内容):
场景:我在(模块/接口)做(动作),环境是(本地/测试)。
期望:(可观察结果)。
实际:(最小报错/响应);(已排除:……)。
猜测:我猜是(X),因为(Y)。
请你当橡皮鸭:复述问题、指出缺口、最多问三个澄清问题;本轮不要给修复代码。
跑完澄清,再单独开一轮“只要验证步骤”。两轮目的不同,混在一块最容易乱。

图:何时放行要方案:复述对齐、可观察、有猜测(原创示意图)
和“结对编程”差在哪
有人会问:这不就是让 AI 结对吗?有重叠,但侧重点不同。结对时常一起写代码;橡皮鸭模式刻意延后写代码,先把问题钉死。对我这种容易“手比脑快”的人,延后写,反而整体更快。
它也不等于“不要用 AI 写代码”。代码还是可以让它写,只是写之前多一道门槛:问题陈述必须能通过复述测试。门槛过了,生成质量通常也更稳,因为上下文不再是一团浆糊。
和“直接贴报错”怎么配合
有人会说:报错本身已经很清楚了,还要四步干什么?我的经验是——报错清楚 ≠ 问题清楚。同一段 NullPointerException,可能是空指针该防,也可能是上游根本不该传来空,还可能是你看错了线程。报错是线索,不是问题定义。
所以我会把报错嵌进“实际”那一步,而不是用报错替换整段陈述。嵌进去之后,再问自己:如果把这行报错遮住,我还能不能讲清期望与场景?讲不清,说明我其实在依赖 AI 替我读栈,而不是在澄清。
还有一种情况:根本没有报错,只有“感觉慢”或“偶发不对”。这时橡皮鸭更有用——因为它会逼你把“慢”定义成可测量的东西:慢在哪个接口、P95 还是平均值、对比基线是什么。说不清测量,后面优化全是感觉。
团队里怎么用这招而不显得矫情
一个人调试时对着鸭子讲话很正常;在群里或对着同事,有人会不好意思“先不谈方案”。我的做法是把澄清写成短消息模板,不喊口号:
「复述一下我的理解:……对吗?」
「我缺这三点信息:……」
「验收标准我写成:……」
这些句子不提橡皮鸭,但完成的是同一件事。和 AI 练习多了,跟人协作时也会更自然地先对齐问题。反过来也一样:你会越来越受不了“直接甩补丁却说不清要修什么”的对话。
收尾:鸭子的价值是逼你开口
橡皮鸭调试从来不是玄学,是把隐性假设逼成显性句子。AI 只是让这只鸭子会追问、会复述、会指出缺口。你若一上来就要答案,它就退化成搜索框加补丁机;你若先逼自己说清楚,它才像一名耐心的同事。
我给自己的一句话是:先让问题变得可被复述,再谈修复。 复述都对不齐的问题,修一万次也只是在碰运气。


2026-10-14鱼鱼