错误使用 AI 进行调试的方式(以及真正有效的思维模型)
抱歉,我需要您提供要翻译的具体文本内容。请把文章的正文粘贴在这里,我会按照要求将其翻译成简体中文并保留原有的格式、代码块和链接。
Staging Incident – AI 辅助调查
TL;DR – 三位资深工程师花了数小时追查死胡同。我用一次开放式提示在约 20 分钟内解开了谜团。突破点在于让 AI 改变自己的调查方式,而不是用具体的 “检查 X” 指令限制它。
症状
Slack 信息
Staging is broken. We're investigating.
在 staging 数据库上运行迁移工具时出现:
alembic current
ERROR: Can't locate revision identified by 'ba29cdc8739d'
FAILED: Can't locate revision identified by 'ba29cdc8739d'背景说明:Alembic 是一个 Python 数据库迁移框架。每个迁移文件都有唯一的修订 ID。staging DB 认为自己处于一个代码库中已不存在的修订上——这是来自一个从未合并的分支的迁移。
资深团队的做法
| Engineer | Prompt to Claude | Result |
|---|---|---|
| A | “检查 CloudTrail 中的 GetSecretValue 调用——最近谁获取了数据库密码?” | 没有异常;只有应用容器访问了 secret。 |
| B | “在 staging 服务器上搜索错误分支检出的证据。” | 未发现痕迹。 |
| C | “通过 git 历史追踪缺失的修订。” | Claude 报告该修订在后来的提交中被 重命名,并声称重命名导致了问题。该说法看似合理,却 不正确——重命名发生在问题出现之后,浪费了宝贵时间。 |
要点 – 当 AI 给出自信但错误的答案时,调查人员容易被锚定在该思路上(哈佛/BCG 所描述的 “Jagged Frontier” 效应)。
经过数小时后,团队只能说:
“我们知道是什么导致了故障,但找不出 谁 做的以及 何时 做的。”
我的(11 个月前的)做法
我对 CloudTrail、ECS 等了解有限。我的提示故意保持最小化:
Prompt – “Staging is broken, can you look into it? Pull the latest release branch and check.”
没有具体指令,没有 “检查 CloudTrail”。Claude:
- 确认缺失的修订在任何主分支上都不存在。
- 将该修订追溯到 单个特性分支,该分支只有一位开发者的提交。
- 遇到了与资深团队相同的障碍(SSH 失败、SSO 令牌过期、没有相关 RDS 日志)。
随后我只提出了一个后续问题:
Prompt – “Is there a smarter way to find this?”
Claude 改变了策略。
突破
Claude 检查了 迁移源代码,注意到 INSERT 使用了 NOW() 为 created_at 列赋值。这意味着数据库中存储的时间戳正是迁移执行的瞬间。
SELECT rule_type, created_at
FROM firewall_rules
WHERE rule_type IN ('PolicyTypeA', 'PolicyTypeB');结果:
| rule_type | created_at |
|---|---|
| PolicyTypeA | 2026-03-31 22:40:25.477889+00 |
| PolicyTypeB | 2026-03-31 22:40:25.477889+00 |
时间戳(3 月 31 日 15:40 PDT)对应特性分支上的一次 git 提交:
2026-03-31 15:41:20 -0700 — fix: rename migrations and split enum ALTER from seed INSERT迁移在该提交 55 秒 后执行。
# 谁在该分支上提交?
git log origin/develop..origin/feature/the-branch --format="%an" | sort -u只有 一位 作者出现。
CloudTrail 没有记录的原因:开发者可能在本地缓存了数据库密码(.env),因此没有新的 GetSecretValue API 调用。
SSH 日志为空的原因:迁移是直接从本地机器针对数据库执行的,而不是通过 staging 服务器。
数据库本身保存了答案——没有人想到去查询它。
思维模型的转变
| Human instruction | AI action | Outcome |
|---|---|---|
“检查过去 48 小时内的 GetSecretValue 调用。” | 执行检查 → “无结果。” | 调查陷入死胡同 |
| “找出缺失修订的来源。” | 只在代码库中搜索 → “未找到。” | 同样无果 |
| “有没有更聪明的办法?” | 改变策略,直接查询 DB 时间戳 → 定位到具体提交和作者 | 问题快速解决 |
Source: …
| “Staging is broken, go look at it.” | 调查时遇到死胡同。 | 人类询问 “有没有更聪明的办法?” | | “Is there a smarter way?” | AI 重新评估问题,改变方法(从日志 → 数据库制品)。 | 突破。 |
关键洞见 – 人类 设定目标;AI 选择调查路径。当路径错误时,人类必须提供新的方向。如果人类改为 把AI锚定 在某个特定、熟悉的技术上(例如 “检查 CloudTrail”),调查可能会卡住。
要点
- 开放式提示 让 AI 探索替代证据来源。
- 具体、狭窄的提示 可能把 AI(以及团队)锁定在死路上。
- 数据库(或系统)本身往往包含取证线索(时间戳、日志、审计列),这些很容易被忽视。
- 我使用的模式 不是正式框架——它是单一事件的观察。可能不具普遍性,但它突显了 AI 增强调试的有用思维模型。
TL;DR
- 高级工程师花了数小时追踪错误线索,因为他们 规定了 AI 的调查步骤。
- 一名初级工程师给 Claude 一个 高层目标 并一次 “更聪明的办法?” 的提示。
- Claude 转向 数据库层面的证据(迁移时间戳),在几分钟内找到了罪魁祸首。
在使用 AI 进行事故响应时,让 AI 决定 如何 搜索,只有在需要它改变方向时才介入。
对调试过程的反思
高级工程师的工作很有价值。他们系统性地排除了可能性——错误的分支部署、未授权访问、CI 流水线问题。他们的排除缩小了搜索空间。我受益于知道 哪些不是 导致问题的原因。
“不知道” 并非普遍优势。在此特定案例中,我不能过度指定,因为我不熟悉领域。但在事故响应、编写修复或事后报告时的无知——那是负担,而非特性。
狭义的教训是:当没有强假设时,保持 AI 的搜索空间开放要比坚持一个薄弱假设更好。
AI 仍然完成了技术工作。Claude 对时间戳进行关联,阅读迁移源码,并运行 git 命令。这是精确、分析性的工作。所谓 “开放式” 方法仅意味着我没有阻止它自行决定要执行的具体工作。
实用技巧:当使用 AI 调试卡住时
如果你卡住且当前方法无效,尝试以下步骤再放弃:
停止告诉 AI 去哪里找。
不要说: “检查 X 的日志” → 改为: “我们已经检查了 A、B、C,未发现线索。系统中可能还有哪些证据?”从具体命令转向问题框架。
不要说: “grep 这个函数” → 改为: “这个端点出问题了,调查一下。”
这并非总能奏效,但只需要一句话的代价,有时能打开你想不到的角度——因为你真的想不到。
我这次的突破:一句话 – “有没有更聪明的办法?”
这不是哲学,只是一个有用的问题。
结果
分支环境的事故得到了解决。证据已共享。开发者确认是他们的机器导致的。
取证小贴士
如果迁移使用 NOW() 在 INSERT 中,created_at 时间戳就是你的 犯罪现场时间戳。将其与 git 日志对比,可能会发现你的 55 秒关键证据。