调试的真正目的不是"让 Bug 消失"——而是找到 Bug 的原因。原因找到了,修复方案通常就是一行代码的事。
在 Vibe Coding 中,你的调试角色变了:你不是自己去修复,而是帮 AI 提供足够的信息让它修复。
可以把调试想象成看医生:
一个好的患者描述是:"我吃完饭后右上腹疼痛,持续了 2 小时。"不好的描述是:"我应该是胃病,帮我开点胃药。"——后者可能误导诊断方向。同样,告诉 AI "我觉得是数据库的问题"可能误导它,不如说"页面加载变慢了,Network 显示某个 API 请求耗时 6 秒"。
第一步:隔离变量
当程序出问题时,首先问自己(或问 AI):"最近一次修改是什么?"
90% 的 Bug 是由最近一次修改引入的。如果你在添加了歌词功能后才发现录制功能坏了,问题大概率在歌词功能的代码里,而不是录制功能本身。
操作方法:
如果项目使用 Git,运行
git diff查看最近一次修改的内容。把这些改动复制给 AI。
如果没有 Git,直接告诉 AI:
"在我添加了歌词功能之后,录制视频的功能就不能用了。请重点检查我添加的歌词相关代码。"
关于 git diff 的小技巧:
git diff 会显示所有未提交的修改。如果你最近提交了,用 git diff HEAD~1 HEAD 查看上一次提交的改动。
把 diff 输出复制给 AI 时,只要说:
"这是最近一次的 git diff 内容,请检查这些修改是否可能引入了一个 Bug。[粘贴 diff]"
AI 会逐行分析你(或 AI 自己)最近的修改,找到可能的问题点。
第二步:阅读错误堆栈
错误堆栈(Error Stack)是最直接的线索——它告诉你"在哪里"出了"什么"问题。
示例堆栈:
TypeError: Cannot read properties of null (reading 'frequencyBinCount')
at drawSpectrum (app.js:45:12)
at animate (app.js:60:5)
即使不懂编程,你也能从堆栈中提取关键信息:
app.js:45:12 —— 在 app.js 的第 45 行第 12 列drawSpectrum —— 出错的函数名Cannot read properties of null —— 尝试访问 null 的属性把这些信息完整复制给 AI。不需要你自己理解"为什么会 null"——那是 AI 的工作。
堆栈中怎么识别最重要的信息:
错误堆栈可能很长(尤其是 React 或 Next.js 的错误),但大多数行指向框架内部代码,只有几行指向你的代码。
找出包含你项目文件名的行(如 app.js、component.tsx、route.ts)——那些是你的代码。其他行(如 node_modules/、react-dom/)是框架内部代码,通常可以忽略。
告诉 AI:"错误堆栈中只有包含 app.js 的行是我自己的代码,其他都是 node_modules 的。"
第三步:二分法定位
如果你做了一堆修改,搞不清楚是哪一处引入了问题——使用二分法:
Git 的 bisect 命令就是为这个场景设计的。让 AI 帮你操作:
"Git 二分法定位 Bug:自从我开始添加可视化效果以来,录制功能就坏了。我最近有 8 次提交。请帮我用 git bisect 找到引入 Bug 的那次提交。"
AI 会指导你执行 git bisect,你只需要重复"好的,这次没问题/这次有问题",AI 会继续推进。
为什么二分法有效: 如果有 N 次提交,二分法只需要约 log₂(N) 次检查。10 次提交 → 最多检查 4 次。50 次提交 → 最多检查 6 次。比逐次检查快得多。
第四步:向 AI 描述问题
这是最关键的一步。一个好的问题描述包含四个要素:
| 要素 | 例子 |
|---|---|
| 你做了什么 | "我点击了'播放'按钮,选择了一个 MP3 文件" |
| 你期望什么 | "可视化效果应该随着音乐跳动" |
| 实际发生了什么 | "画布是空白的,没有显示任何图形" |
| 环境信息 | "Chrome 120, Windows 11, 文件是 44.1kHz 的 MP3" |
不需要包含"我试了什么但没成功"——AI 不需要知道你的失败尝试,它只需要原始现象和环境。
好的例子:
"在 Chrome 120 上,选择 MP3 文件后点击播放,音频能正常播放,但画布是空白的。控制台没有报错。这个文件是 44.1kHz 的立体声 MP3,文件大小约 8MB。"
需要改进的例子:
"可视化不工作。我试着重装应用、清理缓存、换了个浏览器,都不行。"
第二个例子的问题在于:它包含了 AI 不需要的无效尝试信息,但缺少了 AI 需要的精确现象信息。
问题描述的"Checklist":
□ 我做了什么操作?(点击了什么按钮、打开了什么页面)
□ 我期望发生什么?
□ 实际发生了什么?(控制台报错、页面空白、无响应……)
□ 有什么错误信息?(控制台输出、Network 面板的状态码)
□ 环境是什么?(浏览器版本、操作系统)
□ 这个问题是一直存在还是最近才出现的?
AI 有强大的模式识别能力——你描述的问题场景它可能在训练数据中见过几百万次。但 AI 看不到你的屏幕,它只能根据你提供的信息判断。
所以,你的输出质量直接决定 AI 的修复质量。
一个实用技巧:把调试当作"给同事描述问题"——想象你走到一个资深工程师的工位前,你会怎么描述这个 Bug?
你肯定不会只说"程序坏了"就走开。你会说:"我点了这个按钮,但它没反应,控制台显示了这个错误。" 同样,对 AI 也是这样。
给 AI"喂"信息的策略:
有时候 AI 给出的第一个修复方案不工作。这时候不要放弃,试试下面的步骤:
关于"换方案"的一个例子:
你:这个修复不 work,错误仍然存在。
AI:我换一种方案。不再用 window.resize 事件监听,改用 ResizeObserver。
□ 错误堆栈完整复制了吗?
□ 能提供稳定的重现步骤吗?
□ 最近一次的修改是什么?(git diff)
□ 环境信息完整吗?(浏览器/Node 版本、操作系统)
□ 这个问题是一直存在还是最近才出现?
□ 是本地开发环境的问题还是生产环境的问题?
如果 AI 修复失败:
□ 提供了更多上下文?
□ 要求换一种实现方案?
□ 加了日志重新运行?
□ 回退到上一次正常工作的版本?
□ 让 AI 创建一个最小复现用例?
git diff 是最有价值的调试命令之一。把 diff 复制给 AI 让它分析。故意制造一个 Bug,练习调试循环:
"请在我的项目中制造一个 Bug(比如让一个 API 路由返回 500 错误,或者让 Canvas 不显示内容),然后教我如何按调试四步法找到并修复它。"
进阶练习:
模拟一个真实调试场景:让 AI "假装我的页面加载很慢。你扮演调试指导者,告诉我应该打开开发者工具的哪个面板、看什么信息、怎么把这些信息告诉你。我们一步步完成排查。" 这个练习会帮你把调试四步法变成习惯。