第 9 章:调试与排错 — 遇到 bug 不要慌

⏱ 预计阅读 8 分钟 更新于 2026/5/18
💡 进群学习加 wx: agentupdate
(申请发送: agentupdate)

你将学到什么

  • 用 superpowers 的 /systematic-debugging 科学方法调试
  • 用 gstack 的 /investigate 调查代码问题
  • 模拟一个真实 bug 的完整调试过程

9.1 调试不是瞎猜

很多开发者调试的方式是:改一下试试、再改一下再试试。这不叫调试,叫碰运气。

科学的调试方法:

flowchart TB
    A["1. 复现
稳定地触发 bug"] --> B["2. 假设
猜 bug 在哪里"] B --> C["3. 验证
用测试或日志确认"] C --> D{"假设正确?"} D -- "是" --> E["4. 修复"] D -- "否" --> B E --> F["5. 回归测试
确认修复没改坏别的"] style A fill:#fecaca,stroke:#dc2626 style E fill:#dcfce7,stroke:#16a34a style F fill:#dbeafe,stroke:#2563eb

9.2 /systematic-debugging — 科学方法调试

命令语法

/systematic-debugging [bug 描述]

实战:模拟一个真实 bug

Bug 描述: 用户报告"搜索功能有时找不到明明存在的笔记"。

/systematic-debugging

Bug:搜索笔记时,某些情况下搜索不到应该存在的结果。

复现步骤:
1. 创建一条笔记,标题"工作计划"
2. 再创建一条,标题"项目计划"
3. 搜索"计划"
4. 预期:显示两条笔记
5. 实际:有时只显示一条,有时显示两条

环境:React 18 + Chrome 120

Claude 会做什么:

  1. 复现 — 读取搜索相关代码,理解搜索逻辑
  2. 假设 — 分析可能的原因
  3. 验证 — 通过代码审查或测试确认
  4. 修复 — 提供修复方案

调试过程

第 1 步:复现

Claude 读取 useSearch.jssearch.js

// src/hooks/useSearch.js
export function useSearch(notes, query) {
  return useMemo(() => filterNotes(notes, query), [notes, query]);
}

第 2 步:假设

可能的原因:

  • A) useMemo 依赖项不对,notes 引用变化导致缓存失效
  • B) filterNotes 函数有 bug
  • C) 搜索时机问题:笔记还没加载完就搜索了

第 3 步:验证

Claude 检查 useNotes Hook:

// src/hooks/useNotes.js
export function useNotes() {
  const [notes, setNotes] = useState(() => loadNotes());

  const addNote = (note) => {
    const updated = [...notes, note];  // ← 这里!
    setNotes(updated);
    saveNotes(updated);
  };

  // ...
}

发现问题: addNote 使用 notes 闭包变量而不是函数式更新。如果快速连续添加笔记,notes 可能是旧值。

第 4 步:修复

// 修复前
const addNote = (note) => {
  const updated = [...notes, note];
  setNotes(updated);
  saveNotes(updated);
};

// 修复后
const addNote = (note) => {
  setNotes(prev => {
    const updated = [...prev, note];
    saveNotes(updated);
    return updated;
  });
};

第 5 步:回归测试

npm test

全部通过。再加一个测试覆盖这个场景:

test('快速连续添加笔记不会丢失', () => {
  const { result } = renderHook(() => useNotes());

  act(() => {
    result.current.addNote({ id: '1', title: 'A' });
    result.current.addNote({ id: '2', title: 'B' });
  });

  expect(result.current.notes).toHaveLength(2);
});

9.3 /investigate — gstack 代码调查

命令语法

/investigate [调查目标]

gstack 的 investigate 更偏向"理解代码为什么这样写",适合排查复杂的历史问题。

实战:调查搜索性能

/investigate NoteFlow 搜索功能在笔记数量多时的性能表现

调查结果:

发现:

  1. NoteList.jsx 使用 Array.map() 渲染所有笔记,没有虚拟滚动

    • 100 条笔记:正常
    • 500 条笔记:渲染延迟约 200ms
    • 1000 条笔记:渲染延迟约 500ms,输入卡顿
  2. useSearchuseMemo 缓存有效,搜索本身不是瓶颈

  3. 瓶颈在 DOM 渲染,不在搜索逻辑

建议:

  • 短期:限制列表渲染数量(最多显示 50 条,加"加载更多")
  • 长期:引入虚拟滚动库(如 react-window

9.4 两个命令怎么配合

flowchart LR
    A["遇到 bug"] --> B{什么类型?}

    B -- "逻辑错误
结果不对" --> C["/systematic-debugging
科学方法找 bug"] B -- "性能问题
运行慢" --> D["/investigate
调查瓶颈"] B -- "不确定" --> C C --> E["修复 + 回归测试"] D --> E style C fill:#dbeafe,stroke:#2563eb style D fill:#fef3c7,stroke:#d97706

简单判断:

  • 功能不对(搜索结果错误、数据丢失)→ /systematic-debugging
  • 性能不好(卡顿、慢)→ /investigate
  • 不知道怎么了 → 先 /systematic-debugging,排除逻辑问题

动手做

  1. 故意引入一个 bug:在 useNotes.js 中把函数式更新改回闭包方式
  2. 运行 /systematic-debugging,描述搜索结果偶发丢失的 bug
  3. 观察 Claude 的调试过程:复现 → 假设 → 验证 → 修复
  4. 运行 /investigate 调查 NoteFlow 的性能瓶颈
  5. 全量测试确认修复有效

本章小结

命令 来源 适合场景
/systematic-debugging superpowers 逻辑 bug、结果不正确
/investigate gstack 性能问题、代码调查

核心原则: 调试不是猜,是科学实验。复现 → 假设 → 验证 → 修复 → 回归测试,每步都有依据。