AI 辅助 Debug 与问题排查

Debug 是开发者日常中最耗时的活动之一——一个隐蔽的 Bug 可能让你花半天时间在错误的方向上排查。AI 工具改变了 Debug 的方式:你把错误信息、日志、代码片段"甩"给 AI,它用模式匹配能力快速缩小范围、定位根因。本章覆盖 Next.js 全栈开发中最常见的 Debug 场景,给出经过验证的 AI 辅助排查策略。

1. AI Debug 方法论

1.1 传统 Debug vs AI Debug

传统 Debug 流程:
  看错误 → 猜原因 → 加 console.log → 复现 → 验证猜想
  → 猜错了 → 换方向 → 再加 log → 再复现...
  耗时:30 分钟 ~ 数小时

AI Debug 流程:
  看错误 → 给 AI 完整上下文 → AI 分析可能原因(排序)
  → 按概率从高到低验证 → 修复
  耗时:5 ~ 30 分钟

关键差异:AI 能同时考虑数十种可能的原因并按概率排序,而人类往往会陷入某一个假设中无法自拔。

1.2 给 AI 的信息清单

Debug 效果 = f(信息完整度)。给 AI 的信息越完整,定位越准:

信息类型重要性示例
完整错误堆栈★★★★★整个 stack trace,不要截断
复现步骤★★★★★1. 打开页面 2. 点击按钮 3. 报错
相关代码★★★★@引用出错的文件
期望 vs 实际★★★★"应该显示列表,实际显示空白"
环境信息★★★Node 版本、浏览器、开发/生产
最近改动★★★"刚升级了 Next.js 到 15"
网络请求★★DevTools Network 截图
日志输出★★终端或浏览器 console

1.3 AI Debug 的四步法

Step 1: 收集信息(不要急着问 AI)
  → 复制完整错误
  → 确认复现步骤
  → 找到相关代码文件

Step 2: 分析(让 AI 先分析,不要直接让它修复)
  → "分析这个错误的可能原因,按概率排序"

Step 3: 验证(确认根因后再修复)
  → "我验证了,确实是原因 2。现在帮我修复"

Step 4: 回归(确认修复没有引入新问题)
  → "运行测试,确认修复没有破坏其他功能"

2. Next.js 常见错误诊断

2.1 Hydration Mismatch

这是 Next.js 中最常见也最头疼的错误:

Error: Text content does not match server-rendered HTML.
Error: Hydration failed because the initial UI does not match
       what was rendered on the server.

给 AI 的提示模板

页面出现 Hydration mismatch 错误。

错误信息:
[粘贴完整错误]

相关组件:@components/user-profile.tsx

请分析可能的原因,这个组件中哪些代码可能导致
Server 和 Client 渲染不一致?

常见原因参考:
1. 使用了 Date.now(), Math.random(), new Date()
2. 条件渲染依赖 window, localStorage, navigator
3. 使用了 typeof window !== 'undefined' 条件
4. CSS-in-JS 样式注入顺序
5. 浏览器扩展修改了 DOM
6. 使用了 useId() 但组件树不匹配

AI 通常能快速定位

分析结果:
第 15 行使用了 new Date().toLocaleDateString()
→ Server(UTC时区)和 Client(用户时区)渲染结果不同

修复方案:
1. 将日期格式化移到 Client Component
2. 或使用 suppressHydrationWarning(仅限已知安全的场景)
3. 推荐方案:使用 useEffect 在客户端更新日期显示

2.2 Server Component 错误

Error: useState/useEffect can only be used in Client Components.
       Add 'use client' directive at the top of the file.
这个错误出现在 @app/(dashboard)/projects/page.tsx

请分析:
1. 这个组件是否应该是 Client Component?
2. 如果不应该,是哪个 import 引入了客户端依赖?
3. 能否把需要客户端交互的部分提取为子组件?

要求:保持 page.tsx 为 Server Component,
只把必要的交互部分拆分为 Client Component。

2.3 Server Action 错误

Error: Server Actions must be async functions.
Error: Only plain objects can be passed to Client Components from Server Components.
Server Action 调用报错:

错误:[粘贴错误]
Action 文件:@lib/actions/project.ts
调用处:@components/project-form.tsx

请检查:
1. Action 函数是否声明了 async
2. 文件顶部是否有 'use server'
3. 返回值是否可序列化(不能返回 Date, Map, Set, Error)
4. 参数是否可序列化
5. 是否在 Client Component 中正确传递了 action

2.4 数据库查询错误

错误:
DrizzleError: column "tenantId" does not exist

文件:@lib/actions/project.ts
Schema:@lib/db/schema.ts

请分析:
1. 检查 schema 中的列名是否与查询中使用的一致
2. Drizzle 的命名映射规则(camelCase vs snake_case)
3. 迁移是否已经运行(pnpm db:push)
4. 是否在正确的表上查询

2.5 认证和权限错误

我在访问 /dashboard 时被重定向到 /login,但我已经登录了。

相关文件:
- @middleware.ts(Clerk 中间件)
- @app/(dashboard)/layout.tsx

请分析:
1. middleware 的路由匹配规则是否正确
2. Clerk session 是否正确传递
3. 是否有缓存导致的 session 过期
4. 开发环境和生产环境的域名配置

3. 根因分析

3.1 五个 Why 分析法

让 AI 帮你做深层根因分析:

用户在提交表单时偶尔会丢失数据。

请用"5 个 Why"分析法,逐层深入:

Why 1: 为什么数据丢失?
Why 2: 为什么 Server Action 没收到数据?
Why 3: 为什么请求超时了?
Why 4: 为什么数据库连接慢?
Why 5: 为什么连接池耗尽了?

给我每一层的验证方法(如何确认是/不是这个原因)。

3.2 对比分析

这个功能上周还正常,这周突然不工作了。

请帮我分析:
1. git log --since="7 days ago" 中修改了哪些文件
2. 哪些修改可能影响到 [功能名称]
3. 依赖是否有版本变更(package.json 的 diff)
4. 环境变量是否有变更

@package.json
@package-lock.json(最近的 diff)

3.3 环境差异分析

功能在本地开发环境正常,部署到 Vercel 后报错。

错误信息:[粘贴 Vercel 日志]

请分析开发和生产环境的差异:
1. Node.js 版本(本地 vs Vercel)
2. 环境变量是否都配置了
3. 数据库连接(localhost vs 远程)
4. 文件系统差异(Vercel 是只读的)
5. 边缘函数 vs Node.js 运行时的差异
6. 构建时 vs 运行时行为差异

4. 性能瓶颈定位

4.1 页面加载慢

/dashboard 页面加载需要 5 秒,分析性能瓶颈。

页面组件:@app/(dashboard)/page.tsx
数据查询:@lib/actions/dashboard.ts

请检查:
1. 有多少个 await 是串行的?哪些可以改为并行?
2. 每个数据查询预估耗时多少?
3. 是否有 N+1 查询(for 循环中查数据库)?
4. 返回了多少数据?是否可以减少?
5. 是否有不必要的关联查询?
6. 建议添加哪些数据库索引?

AI 的典型分析

分析结果:

1. 串行瓶颈(2.8s):
   第 12 行 await getProjects()        → 800ms
   第 13 行 await getRecentActivity()   → 600ms
   第 14 行 await getTeamMembers()      → 400ms
   第 15 行 await getUsageStats()       → 1000ms
   
   → 改为 Promise.all(),总耗时从 2.8s 降至 ~1s

2. N+1 查询(第 23 行):
   getProjects() 内部对每个 project 额外查询了 memberCount
   → 改用 JOIN 或子查询

3. 缺少索引:
   projects 表的 (tenant_id, updated_at) 复合索引缺失
   → 添加后查询从 800ms 降至 ~50ms

4.2 API 响应慢

POST /api/ai/chat 的首字节时间(TTFB)超过 3 秒。

路由代码:@app/api/ai/chat/route.ts

请分析每个阶段的耗时:
1. 请求解析和验证
2. 认证检查
3. 数据库查询(获取历史消息)
4. AI 模型调用
5. 响应序列化

哪个阶段最可能是瓶颈?怎么优化?

4.3 内存泄漏

应用运行几小时后内存持续增长,最终 OOM。

请帮我排查常见的 Next.js 内存泄漏原因:
1. 全局变量缓存无限增长
2. 事件监听器未清理
3. setInterval 未清除
4. 闭包引用大对象
5. Server Component 中的模块级缓存

相关代码:
@lib/cache.ts
@lib/db/index.ts

4.4 构建性能

pnpm build 耗时从 2 分钟增长到了 8 分钟。

请分析:
1. 哪些页面构建最慢(查看 build 输出)
2. 是否有重复的大型依赖
3. 动态 import 是否过多
4. 图片优化是否在构建时进行
5. TypeScript 类型检查是否可以优化

build 输出:[粘贴 build 日志]

5. 日志分析

5.1 生产错误日志分析

以下是最近 24 小时 Sentry 上报的 Top 5 错误:

错误 1: TypeError: Cannot read property 'name' of undefined
  出现 342 次
  @app/(dashboard)/projects/[id]/page.tsx:45
  
错误 2: DrizzleError: connection terminated unexpectedly
  出现 89 次
  @lib/db/index.ts:12

错误 3: Error: NEXT_NOT_FOUND
  出现 67 次
  @app/(dashboard)/settings/page.tsx

请分析每个错误的:
1. 可能原因
2. 影响范围
3. 修复优先级
4. 修复方案

5.2 访问日志分析

分析这段 Vercel 访问日志,找出异常模式:

[粘贴日志]

请关注:
1. 404 错误集中在哪些路径?(可能是爬虫或配置问题)
2. 500 错误的时间分布(是否有规律?)
3. 响应时间超过 3 秒的请求(性能瓶颈)
4. 是否有异常的访问频率(可能是攻击)

5.3 结构化日志查询

帮我写一个日志分析脚本,从 JSON 格式的日志中提取:
1. 过去 1 小时的错误率
2. 响应时间 P50/P95/P99
3. 最慢的 10 个 API 端点
4. 错误按类型分组统计

日志格式:
{ "timestamp": "...", "method": "GET", "path": "/api/...", 
  "status": 200, "duration_ms": 45, "error": null }

6. Debug 工具组合

6.1 Cursor + 浏览器 DevTools

1. 浏览器出现错误 → 打开 DevTools Console
2. 复制完整错误信息
3. Cursor Cmd+L → 粘贴错误 + @引用相关文件
4. AI 分析原因
5. Cmd+K 选中有问题的代码 → 让 AI 修复

6.2 Claude Code + 日志文件

# 把日志文件交给 Claude Code 分析
$ claude
> 分析 logs/error.log 中最近 100 行的错误模式。
  按错误类型分组,给出每种错误的根因分析。
 
# 或者管道输入
$ tail -100 logs/error.log | claude -p "分析这些错误"

6.3 AI + MCP 浏览器调试

如果配置了 Playwright MCP:

> 打开 localhost:3000/dashboard
  截图看看页面渲染是否正常
  如果有 JS 错误,告诉我 console 输出
 
AI:
  [调用 MCP: navigate("http://localhost:3000/dashboard")]
  [调用 MCP: evaluate("JSON.stringify(window.__errors)")]
  [调用 MCP: screenshot()]
  
  "页面渲染正常,但 console 有一个警告:
   'Warning: Each child in a list should have a unique key prop'
   出现在 ProjectList 组件中。"

7. Debug 策略清单

7.1 按错误类型选策略

错误类型AI 工具策略
类型错误Cursor(红线修复)点击 Fix with AI
运行时错误Cursor Chat / Claude Code粘贴完整堆栈 + 相关文件
Hydration 错误Cursor Chat分析 Server/Client 差异
构建错误Claude Code"运行 build,修复所有错误"
性能问题Claude Code代码分析 + 数据库查询优化
生产错误Claude Code + 日志日志分析 + 根因定位
间歇性 BugClaude Code竞态条件分析 + 边界条件检查
第三方库问题Cursor @Web搜索已知 issue 和解决方案

7.2 黄金法则

1. 不要猜——让 AI 列出所有可能原因并排序
2. 不要急——先分析后修复,避免修了症状不修根因
3. 不要省——给 AI 完整的错误信息和上下文
4. 不要忘——修复后写测试防止回归
5. 不要藏——修复后更新 Rules,让 AI 下次避免同类问题

本章小结

  • AI Debug 四步法:收集信息 → AI 分析原因 → 验证根因 → 修复并回归
  • 信息完整度决定效果:完整错误堆栈 + 相关代码 + 复现步骤 + 环境信息
  • 常见 Next.js 错误:Hydration mismatch、Server Component 限制、Action 序列化、数据库命名映射
  • 根因分析:五个 Why 分析法、对比分析(上周还正常)、环境差异分析
  • 性能定位:串行查询 → Promise.all、N+1 查询 → JOIN、缺少索引 → 复合索引
  • 日志分析:Sentry 错误分组、访问日志异常模式、结构化日志查询
  • 工具组合:Cursor(快速修复)+ Claude Code(深度分析)+ MCP 浏览器(可视化调试)
  • 黄金法则:不猜、不急、不省、不忘、不藏