10 · Debug 模式
不用打断点、不用 print 插到手软——让 AI 帮你找到 Bug 的根因。
01 Debug 模式是什么
Debug 模式是 Cursor Chat 中的一种子模式(和 Agent、Plan、Ask 并列),专为”找到并修复 Bug”这个场景优化。
传统调试是一套固定的流程:
- 你怀疑某段代码有问题
- 你手动插一屏幕
console.log/print - 你重新运行程序,看日志
- 你通过日志推理根因
- 你手动修代码
- 你移除刚才插的日志(或者忘了移除,留在代码库里吃灰)
这个流程的核心问题不是哪一步难——每一步都很简单——而是来回切换上下文太消耗注意力。你一边想着业务逻辑,一边想着”我该在哪插日志”,一边还在回忆刚才的输出有没有打印那条记录。Debug 模式做的就是把”插日志→分析输出→定位根因”这个循环交给 AI,你只负责描述问题和验证结果。
| 维度 | 传统调试 | Cursor Debug 模式 |
|---|---|---|
| 插日志 | 手动逐行加 print | AI 自动在关键路径插入 |
| 日志分析 | 人眼扫终端 | AI 理解输出内容 |
| 根因推理 | 靠经验和直觉 | AI 基于日志+代码推理 |
| 清除日志 | 手动删除(经常忘) | 一键还原或 AI 移除 |
| 修复建议 | 自己决定 | AI 给出可 apply 的代码修改 |
02 如何进入 Debug 模式
有三种方式进入 Debug 模式:
方式一:Chat 下拉菜单
按 Cmd+L 打开侧边栏 Chat → 在输入框上方找到模式选择器(默认是 Agent)→ 点击切换为 Debug。
方式二:通过快捷键切换
Chat 打开后,连续按 Cmd+.(句号键)可以在模式间循环切换。在状态栏可以看到当前模式。
方式三:直接描述你的问题
即使你没有手动切换到 Debug 模式,你在 Chat 中对一段代码说”这段代码跑起来有问题,帮我调试”——AI 自己会意识到应该用调试的方式处理,主动给你插日志、分析输出。但手动切换到 Debug 模式会更精确:它会用一套专门针对调试优化的 prompt 模板来执行任务。
进入 Debug 模式后,界面会有视觉提示——输入框旁边的图标会变成 🔍 或显示 “Debug” 标签,告诉你现在不是普通对话模式了。
03 Debug 工作流:五步循环
Debug 模式的核心是一个五步循环,每一步 AI 和你分工明确:
你: 描述 Bug
↓
AI: 在代码中插入日志语句
↓
你: 复现 Bug(运行程序产生日志)
↓
AI: 读取并分析日志输出
↓
AI: 定位根因 + 给出修复方案第 1 步:你描述 Bug
你需要告诉 AI:什么场景下,做了什么操作,看到了什么错误或异常行为。
描述的质量直接决定调试效率。好的描述包含三要素:
- 触发条件:“当用户输入邮箱格式不对时…”
- 实际表现:“页面没有提示,直接白屏”
- 预期表现:“应该显示’请输入正确的邮箱格式’的提示”
一个糟糕的描述:“这段代码有问题,帮我看一下。”
一个好的描述:“validateEmail 函数当输入 test@ 时返回 true,但按业务规则它应该返回 false,因为域名不完整。“
第 2 步:AI 插入日志语句
AI 会根据你的描述,在代码中推测最可能导致 Bug 的位置,并在这些位置插入日志语句。
这不是随机的”加一堆 print”——AI 会:
- 判断哪些变量值在 Bug 场景下可能异常
- 在条件分支的每个岔路口插日志,以便追踪执行路径
- 在函数入口和出口插日志,记录入参和返回值
- 在异常捕获处插日志,捕获完整的错误堆栈
- 加日志前缀(如
[DEBUG:validateEmail]),方便后续搜索
实际效果:
// 原始代码
function validateEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
// AI插入日志后
function validateEmail(email) {
console.log('[DEBUG:validateEmail] input:', email);
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const result = regex.test(email);
console.log('[DEBUG:validateEmail] regex:', regex);
console.log('[DEBUG:validateEmail] result:', result);
return result;
}心智模型:AI 像一个老练的排障工程师——虽然他没亲眼看到 Bug,但他知道”在可疑的地方装探头”是最快找到问题的方式。日志就是探头。
第 3 步:你复现 Bug
AI 插完日志后,会自动或提示你运行程序来产生日志输出。
- 如果你在 Chat 中直接运行了程序(用 Agent 模式的终端权限),AI 可以自己拿日志输出
- 如果你在本地手动运行程序,AI 会告诉你去哪里跑,并把终端输出贴回来给它
这个步骤的关键在于:你要做的是复现 Bug 本身,而不是找 Bug。你的注意力只需要集中在”做那个会触发问题的操作”上。
第 4 步:AI 分析日志
你把终端输出(或者 AI 自己拿到的输出)给到它,AI 开始分析:
- 每个日志点的值是否符合预期
- 程序的执行路径是否和预想的一致
- 哪个变量的值在某个节点突然偏离预期
- 异常堆栈的关键帧在哪里
AI 会输出它的推理链——比如它在日志中发现 validateEmail 的入参是 "test@",正则匹配结果是 true,但分析后发现这个正则把 "test@" 误判为合法——因为它没有要求 @ 后面必须跟至少一个字符。
第 5 步:AI 给出修复方案
最后,AI 基于分析结果给出具体可执行的修复代码。它会:
- 说明 Bug 的根因是什么
- 展示修复后的代码(通常以 diff 形式)
- 解释修复原理
- 如果可能,补充一个测试用例来防止未来回归
修复方案通常可以直接 apply——和 Inline Edit(Cmd+K)或 Agent 一样,AI 会生成 diff,你审阅后一键接受。
04 一个完整的调试案例
让我们看一个更实际的例子。假设你有一个 React 组件:
function PaymentSummary({ items, discountCode }) {
const [total, setTotal] = useState(0);
useEffect(() => {
let sum = 0;
items.forEach(item => {
sum += item.price * item.quantity;
});
if (discountCode === 'SAVE10') {
sum = sum * 0.9;
} else if (discountCode === 'SAVE20') {
sum = sum * 0.8;
}
setTotal(sum);
}, [items]);
return <div>总计:¥{total.toFixed(2)}</div>;
}Bug 表现:当 items 为空数组时,页面显示 总计:¥0.00——这是对的。但当用户批量添加商品后再次清空购物车,页面还是显示上次的总价,而不是 ¥0.00。
传统调试做法
你可能会这样调:
- 在
useEffect第一行加console.log('items changed:', items) - 加
console.log('sum after loop:', sum) - 加
console.log('after discount:', sum) - 重新跑,发现
useEffect根本没执行第二次 - 思考原因 → 发现依赖数组里只写了
[items],而 React 判断items引用没变(因为清空操作是splice而不是新建数组),所以跳过了 effect - 手动删掉日志
- 加一个新的依赖或者把清空改成新建数组
总共 7 步,耗时可能需要 5-10 分钟,还要在调试过程中来回切换注意力。
Cursor Debug 模式的做法
- 你描述 Bug:“
PaymentSummary组件在items从有到无时,总量不更新” - AI 在
useEffect的入口、setTotal之前各插一条日志,并记录了items的长度 - 你复现操作,把终端输出贴回来
- AI 分析日志发现
useEffect没有重新执行——直接告诉你”依赖数组缺少对items引用的正确追踪” - AI 给出修复:要么把
items展开成[...items]确保引用变化触发更新,要么改用更适合的依赖策略 - 你审阅 diff,一键接受
相当于 AI 帮你做了第 1、4、5、7 步——你只需要描述问题、复现操作、确认修复,剩下的事 AI 包了。
05 Debug 模式 vs 传统调试:什么时候用哪个
用一个决策矩阵来帮助你判断:
| 场景 | 传统调试 | Debug 模式 | 原因 |
|---|---|---|---|
| 定位问题区域不明确 | ✗ | ✓ | AI 可以广撒网插日志,覆盖可疑路径 |
| 日志输出非常大 | ✓ | ✗ | AI 上下文窗口有限,大量日志可能超限 |
| 涉及异步/竞态条件 | ✗ | ✓ | AI 能追踪 Promise 链和时序依赖 |
| 简单逻辑错误 | ✓ | ✓ | 两种方式效率差不多 |
| 跨国文件调用链 | ✗ | ✓ | AI 一次性在多个文件中插入日志 |
| 需要实时断点调试 | ✓ | ✗ | Debug 模式依赖日志,不支持 live stepping |
| 性能瓶颈分析 | ✗ | ✓ | AI 可以加时间戳日志分析耗时分布 |
| 隐私敏感代码 | ✓ | ✗ | 日志内容可能发送给 AI 模型 |
核心判断原则
当你不知道问题在哪里时,Debug 模式更快;当你已经知道问题在哪时,传统调试更快。
Debug 模式的核心价值在于缩小搜索范围——从”整个代码库里哪里可能出问题”缩小到”这三个函数里某个变量值异常”。一旦定位到了具体行,后续的修复往往用 Cmd+K 就能搞定。
06 Debug 模式的心智模型
要最有效地使用 Debug 模式,需要建立正确的心智模型。
模型一:AI 是你的”排障搭档”
想象一个场景:你面前有一块焊满了元件的电路板,出了奇怪的故障。传统的做法是你自己拿万用表一个一个节点测。Debug 模式是你叫来了一个搭档——他拿万用表测关键节点,口述读数,你在旁边根据这些读数推理故障位置。
AI 不是那个准确知道”第三个电容坏了”的预言家——它是那个帮你放大信号、收集数据的工具。最终的诊断和决策权在你手上。
模型二:日志插桩,而非断点调试
Cursor Debug 模式本质上是日志插桩(log instrumentation),不是断点调试(breakpoint debugging)。
- 断点调试适合你已经知道要看哪里——你设一个断点,单步逐行观察
- 日志插桩适合你还不知道问题在哪——你在关键路径上装多个探头,一次性捕获全貌
两者没有绝对的优劣。在 Cursor 中,你完全可以在关键代码上手动打断点(VS Code 调试器是集成的),同时用 Debug 模式在更大范围内插日志——它们互补而非互斥。
模型三:问题描述 = 调试效率
在 Debug 模式中,你对 Bug 的描述精确度和 AI 找到问题的速度成正相关。
这里有一个量化的理解:
| 描述方式 | AI 需要尝试的日志点 | 平均调试时间 |
|---|---|---|
| ”这段代码有问题” | 全部函数入口出口 | 3-5 轮对话 |
| ”返回结果不对,应该是排序后的数组” | 排序相关路径 | 1-2 轮对话 |
”输入为 [3,1,2] 时输出 [3,1,2],但期望 [1,2,3]” | sort 函数内部 | 0-1 轮对话 |
越精确的描述,AI 就能把日志插在越靠近根因的地方。
07 典型场景 vs 非典型场景
Debug 模式表现出色的场景
场景 1:数据流追踪
前端组件传 prop → API 调用 → 后端处理 → 数据库返回 → 渲染结果,这个链条中任何一个环节出问题都会导致最终结果不对。用 Debug 模式可以在整个链路中自动插日志,一次性建立起”完整的数据流图谱”。
场景 2:条件判断分支问题
一段复杂的 if-else 逻辑,你怀疑某个分支走了意外路径。AI 会在每个分支入口插日志,复现后你看到的是”执行了分支 C 而非分支 A”,瞬间定位问题。
场景 3:异步操作时序问题
Promise.all、setTimeout、requestAnimationFrame 等异步 API 的执行顺序问题——AI 会在每个异步操作的 resolve/reject 回调中插时间戳日志,帮助判断执行顺序是否符合预期。
场景 4:状态更新未触发渲染
React/Vue 中的状态已经改变但 UI 没有响应——AI 会检查状态更新的时机、依赖项、以及组件的重新渲染条件。
Debug 模式不太擅长的场景
场景 1:海量日志
如果你在循环中插了日志,每次迭代打印大量数据(比如每次打印一个完整的 JSON 对象),AI 的上下文窗口很快被填满。解决方法:给 AI 指令只在特定迭代下打印,或者只打印关键字段而不是整个对象。
场景 2:实时交互调试
正在运行的 WebSocket 连接、实时数据流、用户交互序列——这些场景很难用”跑一次看日志”的方式调试。传统断点调试仍然是最佳选择。
场景 3:外部依赖问题
Bug 的根因在第三方库内部、或者网络请求异常、或者数据库配置错误。AI 能看到的只有你的代码库,它无法调试外部系统的内部状态。
场景 4:需要断点观察的复杂状态
有些 Bug 需要你手动在断点处检查作用域链、闭包变量、或者浏览器的渲染状态——这些超出了一次性日志插桩的能力范围。
08 Debug 模式的局限性
诚实面对工具的边界,才能做出更好的判断。
局限一:它不会自动”发现”Bug
Debug 模式需要你描述 Bug——AI 不会主动扫描你的代码找出 Bug。它不是静态代码分析器,也不是测试框架。如果你描述的问题不准确,AI 可能在错误的方向上浪费多轮对话。
局限二:上下文窗口限制
每次 Debug 会话中,AI 能看到的日志量和代码量受限于模型的上下文窗口(目前约 200K tokens)。如果你的应用日志非常大(比如每次请求打印 50 行 JSON),几个复现操作就把窗口填满了。
应对策略:
- 复现时只做最小复现序列,不要做无关操作
- 请求 AI 只在关键节点打印简明的字符串日志,而不是完整对象
- 如果日志太大,手动过滤后只贴相关部分给 AI
局限三:不支持交互式断点
没有步进(step in/over/out)、没有监视(watch)、没有条件断点。这些仍然是 VS Code 调试器的专属能力。Debug 模式不是要替代调试器——在需要交互控制流的场景,你应该回到 VS Code 的调试面板。
局限四:日志本身可能改变行为
在异步代码中插入日志(特别是 console.log 执行时间不确定时)可能改变竞态条件的时序——Heisenberg Bug(海森堡 Bug):观测行为本身改变了被观测系统的行为。
这种情况虽然不常见,但当你调试的是时序敏感的异步逻辑时,需要注意日志插桩本身是否引入了新的时序变化。
局限五:AI 可能误判
AI 分析日志的结论不一定对。它可能:
- 误读日志值(把
undefined当正常值) - 过度拟合你的描述(你说”可能是 A 的问题”,它就倾向于找到 A 的证据)
- 忽略日志中没有直接体现的隐藏条件
一个务实的建议:把 AI 的定位结论当作”高优先级嫌疑线索”而非”最终判决”。让它说服你——它的推理链应该是透明的、可验证的。
09 高效使用 Debug 模式的技巧
技巧 1:用”最小复现描述”开头
不要说”这个页面好多地方都炸了”——给 AI 一个具体的触发序列。好的描述模板:
组件 X,当用户做了操作 Y 并且传入了参数 Z 时,结果应该是 A,但实际得到了 B。
技巧 2:一次只调一个 Bug
Debug 模式是为单一问题设计的。如果你说”帮我看看为什么登录按钮不亮,同时也帮我看一下为什么积分计算不对”,AI 会混在一起分析,效率大幅下降。先调最重要的那个 Bug,修完再处理下一个。
技巧 3:善用 @ 符号引用上下文
在 Debug 模式中,你仍然可以用 @file、@folder、@function 等符号引用特定文件或函数,帮助 AI 把注意力集中在正确的区域。特别是在大型代码库中,手动引用相关文件可以节省一轮”AI 搜索代码库”的时间。
技巧 4:检查 AI 插的日志
接受 AI 的日志插桩之前,快速扫一眼——日志位置是否合理?有没有在热循环路径里插了太多日志?有没有打印敏感信息(密码、Token、用户隐私数据)?你对自己代码里的日志内容负有最终责任。
技巧 5:完成后清理日志
AI 插的日志不是永久的——你可以:
- 部分接受修复代码(日志和修复在一起时,接受 diff 即可)
- 让 AI 最后一步自动移除所有临时日志
- 使用
git diff查看哪些行被修改,手动还原 - 如果你在 Composer 中调试,可以用 Undo 一键回退
10 Debug 模式与 Agent 模式的关系
你可能会困惑:Agent 模式也能跑命令、看输出、修代码——那 Debug 模式存在的意义是什么?
关键在于分工不同:
| 维度 | Agent 模式 | Debug 模式 |
|---|---|---|
| 核心目标 | 完成任务 | 找到问题 |
| 对错误的态度 | 出错时尝试自动修复 | 主动分析错误机制 |
| 日志策略 | 能跑通就行,日志是副产品 | 日志是诊断工具,精心设计 |
| 工作流 | 计划-执行-验证 | 假设-验证-分析-结论 |
| 最适配场景 | 开发新功能 | 定位已有代码的 Bug |
实际使用中,一个好的组合策略是:先用 Debug 模式找到根因,把结论告诉 Agent 模式,让 Agent 执行修复——虽然 Debug 模式也能给出修复方案,但在跨文件、多步骤修复场景下,Agent 模式的执行力更强。
甚至你可以在同一次对话中切换模式——在 Chat 里先让 AI 以 Debug 模式工作,分析完了切换到 Agent 模式让它修。
11 小结
| 关键问题 | 一句话答案 |
|---|---|
| Debug 模式是什么 | Cursor Chat 中专用于调试的子模式,核心是 AI 自动日志插桩 |
| 工作原理是什么 | 你描述 Bug → AI 插日志 → 你复现 → AI 分析 → 给出修复 |
| 和传统调试的区别 | AI 替你做了”插日志 + 分析日志 + 推理根因”三个环节 |
| 什么时候最好用 | 数据流追踪、分支判断、异步时序、状态更新问题 |
| 什么时候别用 | 海量日志、实时交互调试、外部依赖问题、需断点观察的场景 |
| 最大优势 | 缩小搜索范围:从”整个代码库”缩小到”特定函数、特定变量” |
| 最大局限 | 日志可能改变行为、上下文窗口有限、AI 可能误判 |
下一篇:11 Agent 模式高级用法 —— 当 Agent 不能只是”写代码”,学习如何让它做计划、跑测试、联网搜索、操作外部工具,变成一个真正的自动编程搭档。