跳转到内容

6.2 调试与问题排查

AI 调试不是"把错误信息粘贴给 AI"——而是一套系统化的排查流程:描述症状 → 提供上下文 → AI 分析 → 验证修复。


这一节在讲什么?

调试是开发者最耗时的活动之一——据统计,开发者平均花 35%~50% 的时间在调试上。OpenCode 的 Agent 能力在调试场景下特别有用,因为它能同时读取代码、执行命令、查看日志、分析错误——这些操作如果手动做,需要频繁切换工具。这一节我们学习用 OpenCode 进行错误诊断、日志分析、性能优化和测试驱动调试,帮你建立高效的 AI 辅助调试工作流。


错误诊断:从错误信息到根因分析

场景一:运行时错误

最常见的调试场景——程序运行时报错了。

差的提问方式

我的程序报错了,帮我看看

AI 不知道什么程序、什么错误、什么环境,只能给泛泛的建议。

好的提问方式

$ npm start 报错了,错误信息是:
TypeError: Cannot read properties of undefined (reading 'id')
    at UserController.getUser (src/controllers/user.controller.ts:25:32)
    at Layer.handle [as handle_request] (node_modules/express/lib/router/layer.js:95:5)

帮我分析一下 @src/controllers/user.controller.ts 第 25 行的问题

这个提示词做了四件事:

  1. $ npm start 引入了错误发生的上下文
  2. 提供了完整的错误信息和堆栈
  3. 指向了出错的文件和行号
  4. @ 引用了相关文件

AI 会读取文件,分析第 25 行的代码,找出 undefined 的来源,给出修复方案。

场景二:类型错误

TypeScript 项目的类型错误是另一种常见的调试场景:

$ npx tsc --noEmit 的输出有 3 个类型错误,帮我修复

AI 会:

  1. 执行 npx tsc --noEmit 获取错误列表
  2. 读取出错的文件
  3. 分析类型不匹配的原因
  4. 修改代码修复类型错误
  5. 再次运行类型检查确认修复

场景三:测试失败

$ npm test 有 2 个测试失败了,帮我分析原因并修复

AI 会:

  1. 执行测试获取失败信息
  2. 分析失败原因(断言不匹配、异常、超时等)
  3. 读取相关的源码和测试文件
  4. 修复代码或更新测试
  5. 再次运行测试确认修复

日志分析:让 AI 看懂日志

日志是调试的重要线索,但日志通常很长、格式不统一、关键信息淹没在大量输出中。OpenCode 的 AI 能帮你从日志中提取关键信息。

分析错误日志

$ cat logs/error.log | tail -100 里的错误是什么原因?

AI 会读取日志的最后 100 行,分析错误模式,找出根本原因。

分析应用日志

$ cat logs/app.log | grep "ERROR" | tail -50 里的错误有什么规律?

AI 会分析错误日志的模式——是不是特定接口频繁报错?是不是在特定时间段集中出现?是不是跟特定用户操作相关?

分析 Docker 日志

$ docker logs my-app --tail 200 里的 OOM 错误是什么原因?

AI 会分析容器的内存使用模式,判断是内存泄漏还是配置不足。


性能优化:让 AI 分析瓶颈

性能问题的调试比功能错误更复杂——因为瓶颈可能在任何地方(数据库查询、网络请求、算法复杂度、内存使用)。

场景:API 响应慢

GET /api/articles 接口响应时间超过 2 秒,帮我分析一下性能瓶颈。
看一下 @src/routes/articles.ts 和 @src/services/article.service.ts

AI 会:

  1. 读取路由和服务文件
  2. 分析可能的瓶颈(N+1 查询、缺少索引、大量数据序列化等)
  3. 给出优化建议

场景:数据库查询慢

如果你配置了 PostgreSQL MCP,AI 可以直接分析数据库:

articles 表的查询很慢,帮我看看有没有缺少索引

AI 会查询数据库的索引信息和查询计划,找出缺少索引的查询。

场景:内存泄漏

$ node --expose-gc src/index.js 运行一段时间后内存持续增长,
帮我分析一下 @src/cache/ 目录下的缓存逻辑有没有内存泄漏

AI 会分析缓存逻辑,找出可能导致内存泄漏的模式(无限增长的 Map、未清理的定时器、未移除的事件监听器等)。


测试驱动调试

测试驱动调试是一种高效的调试方法——先写一个能复现 bug 的测试,然后让 AI 根据测试的失败信息修复代码。

第一步:让 AI 写复现测试

用户报告了一个 bug:当购物车中有 0 元商品时,总价计算错误。
帮我写一个测试来复现这个 bug

AI 会写一个测试用例,覆盖这个边界条件。

第二步:运行测试确认失败

$ npm test 确认测试失败了

第三步:让 AI 根据失败信息修复

测试失败了,错误信息是:
Expected total to be 100.00, received 0.00
帮我修复 @src/services/cart.service.ts 的总价计算逻辑

第四步:验证修复

再运行一次测试,确认通过了

测试驱动调试的好处是:你有一个自动化的验证机制——修复后运行测试就知道是否成功,不需要手动验证。


调试的最佳实践

1. 提供完整的错误信息

❌ 差的做法:
"程序报错了"

✅ 好的做法:
"$ npm start 报错:TypeError: Cannot read properties of undefined (reading 'id')
at UserController.getUser (src/controllers/user.controller.ts:25:32)"

2. 指向具体的文件和行号

❌ 差的做法:
"帮我看看代码有什么问题"

✅ 好的做法:
"帮我看看 @src/controllers/user.controller.ts 第 25 行的问题"

3. 描述复现步骤

❌ 差的做法:
"登录功能有 bug"

✅ 好的做法:
"当用户用邮箱登录时,如果密码包含特殊字符(如 #&@),
会返回 500 错误。正常密码没有这个问题"

4. 让 AI 一次只修一个问题

❌ 差的做法:
"有 5 个 bug,帮我一起修了"

✅ 好的做法:
先修最关键的 bug,确认修复后再修下一个

常见误区

误区一:只粘贴错误信息不给上下文

错误信息只是"症状",不是"病因"。AI 需要看到相关的代码才能分析根本原因。用 @ 引用出错的文件,用 $ 引入命令输出,给 AI 足够的上下文。

误区二:AI 修了一个 bug 引入了新 bug

这是常见的"打地鼠"问题——修了一个地方,另一个地方又出错了。解决方法:修复后运行全量测试,确认没有引入新的问题。如果你有完善的测试覆盖,AI 的修复会更安全。

误区三:让 AI 猜测错误原因

如果你不提供错误信息,让 AI "猜猜为什么程序不工作",它的回答通常是泛泛的——"可能是网络问题、可能是配置错误、可能是数据格式不对"。提供具体的错误信息和上下文,AI 才能给出精准的分析。

误区四:性能问题只看代码

性能问题的根因可能在代码、数据库、网络、配置等任何地方。如果只让 AI 看代码,它只能分析代码层面的瓶颈。配合 PostgreSQL MCP 分析数据库查询、用 $ 引入系统监控输出,才能全面排查性能问题。


小结

这一节我们学习了用 OpenCode 进行调试的四种方式:错误诊断(提供完整错误信息 + 上下文)、日志分析(用 $ 引入日志输出)、性能优化(代码分析 + 数据库分析 + 系统监控)、测试驱动调试(先写复现测试再修复)。调试的核心原则是"提供足够的上下文"——错误信息、相关文件、复现步骤、环境信息,缺一不可。下一节我们看 Git 工作流集成。

基于 MIT 许可发布