真实案例:用 AI 快速定位一次代码问题

0 阅读7分钟

在这里插入图片描述

代码出现问题时,很多人会直接把一句“为什么重复提交”发给 AI。

这样得到的答案往往是一长串可能性:缓存、网络重试、数据库重复写入、按钮连点、接口幂等……看起来都对,但很难马上解决问题。

真正高效的方式是:

先收集事实,再让 AI 根据事实缩小排查范围。

这篇文章用一个经过脱敏的典型案例,带你走一遍完整过程。

一、问题现象:点击一次,却创建了两条订单

一个 Vue 3 订单创建页面出现了问题:

  • 用户点击一次“提交订单”。
  • 页面显示提交成功。
  • 后台却创建了两条内容相同的订单。

第一反应很容易是“数据库写重复了”。

但这个阶段不能下结论,因为重复数据可能发生在不同位置:

  • 前端调用了两次接口。
  • 浏览器或网络层重试了请求。
  • 后端路由被执行两次。
  • 数据库写入逻辑重复执行。
  • 用户快速连续点击了按钮。

先把问题拆开,才能避免一开始就查错方向。

二、第一步:收集最小证据

排查前,先记录可以确认的事实。

1. 看浏览器网络面板

打开浏览器开发者工具的 Network 面板,筛选创建订单接口:

POST /api/orders    201    10:12:08.421
POST /api/orders    201    10:12:08.435

两次请求间隔只有 14 毫秒,请求体也完全一致。

这时可以确认一件事:

重复请求在浏览器发出请求之前或浏览器发出请求时就已经发生了。

因此,优先检查前端事件绑定和请求函数,而不是先修改数据库。

2. 看后端日志

后端日志中也能看到两次请求:

POST /api/orders requestId=req_demo_001
POST /api/orders requestId=req_demo_002

这说明后端确实分别收到了两次请求,并不是同一次请求被日志重复打印。

3. 保留相关代码,不上传整个项目

此时只需要收集:

  • 表单模板。
  • 提交函数。
  • 请求函数。
  • 两条脱敏后的网络记录。
  • 运行环境和复现步骤。

不需要把整个项目、数据库配置或真实订单数据交给 AI。

三、第二步:把事实交给 AI 分析

不要这样问:

订单为什么会重复创建?

更有效的 Prompt 是:

请帮我分析一个 Vue 3 页面重复提交订单的问题。

已确认事实:
1. 用户只点击了一次提交按钮。
2. 浏览器 Network 面板出现两次 POST /api/orders。
3. 两次请求体相同,时间间隔约 14 毫秒。
4. 后端收到两个不同 requestId 的请求。
5. 没有看到 3xx 跳转或网络重试标记。

相关代码:
[粘贴表单模板、提交函数和请求函数]

请输出:
1. 最可能的 3 个原因,按概率排序。
2. 每个原因对应的验证方法。
3. 下一步优先检查哪个位置,为什么。

要求:
- 不要直接修改代码。
- 不要把未确认的原因当成结论。
- 区分“已知事实”和“待验证假设”。

这个 Prompt 的重点不是让 AI 立即给答案,而是让它生成一份可验证的排查路线。

四、第三步:检查最可能的问题点

相关模板代码如下:

<form @submit.prevent="submitOrder">
  <input v-model="form.productId" />
  <button type="submit" @click="submitOrder">提交订单</button>
</form>

提交函数:

async function submitOrder() {
  await createOrder({
    productId: form.productId
  });
}

AI 的第一条假设通常会是:

buttonclick 事件会调用一次 submitOrder,而 type="submit" 又会触发表单的 submit 事件,再调用一次 submitOrder

这不是最终结论,但它可以立刻验证。

在函数开头临时加入一条本地日志:

async function submitOrder() {
  console.count('submitOrder called');

  await createOrder({
    productId: form.productId
  });
}

点击一次后,控制台输出:

submitOrder called: 1
submitOrder called: 2

至此,我们拿到了完整证据链:

一次点击
  ↓
click 事件调用 submitOrder
  ↓
submit 事件再次调用 submitOrder
  ↓
浏览器发出两次 POST 请求
  ↓
后端创建两条订单

注意:console.count 只用于本地定位问题,修复后要删除,不能带到正式环境。

五、第四步:做最小修复

表单提交只保留一种触发方式即可。

这里保留表单的 submit 事件,删除按钮上的 click 事件:

<form @submit.prevent="submitOrder">
  <input v-model="form.productId" />
  <button type="submit">提交订单</button>
</form>

为什么推荐保留 submit

  • 点击按钮可以提交。
  • 用户在输入框中按 Enter 也可以提交。
  • 表单行为集中在一个入口,更容易维护。

修改完成后,再点击一次按钮并检查 Network 面板:

POST /api/orders    201    10:26:18.702

只剩下一条请求,问题得到修复。

六、修复重复调用,不等于解决所有重复订单风险

前端事件冲突解决后,仍然要考虑用户快速连续点击的情况。

可以在请求期间禁用按钮:

<button type="submit" :disabled="submitting">
  提交订单
</button>
async function submitOrder() {
  if (submitting.value) {
    return;
  }

  submitting.value = true;

  try {
    await createOrder({
      productId: form.productId
    });
  } finally {
    submitting.value = false;
  }
}

这能减少重复点击,但不能替代后端保护。

对于订单、支付、扣库存等高风险接口,后端还应该根据业务设计幂等机制,例如:

  • 使用客户端提交标识,重复请求返回同一个结果。
  • 使用业务唯一键防止重复创建。
  • 在数据库层增加合适的唯一约束。

具体方案取决于业务,不能只复制一段通用代码。

七、让 AI 帮你补充验证场景

修复后,可以继续让 AI 列出测试场景:

订单提交重复调用问题已经修复。

修复方式:
- 删除按钮上的 click 提交逻辑。
- 只保留 form 的 submit 事件。
- 请求期间禁用提交按钮。

请列出需要手动验证和自动化测试的场景。

要求覆盖:
1. 鼠标点击提交。
2. 在输入框按 Enter 提交。
3. 快速连续点击。
4. 请求成功。
5. 请求失败后再次提交。
6. 表单校验失败。

每个场景说明:操作、预期请求次数、预期页面结果。

我们至少要验证下面这些内容:

场景操作预期结果
鼠标提交点击一次提交按钮只发起一次请求
键盘提交在输入框按 Enter只发起一次请求
连续点击请求未完成时连续点击只发起一次请求
请求失败接口返回错误后再次提交按钮恢复可用,可再次提交
校验失败商品未选择就提交不发起创建订单请求

八、这个案例中,AI 真正帮了什么

AI 没有替我们“猜中答案”,它主要帮助完成了三件事:

  • 根据已有事实列出排查假设。
  • 把“重复订单”拆成前端、网络、后端和数据库几个层次。
  • 提醒我们在修复事件冲突后,继续考虑重复点击和接口幂等。

真正定位问题的证据,仍然来自:

  • Network 面板中的两次请求。
  • 后端的两个请求记录。
  • console.count 的两次函数调用。
  • 修复后只剩一次请求的验证结果。

这也是使用 AI 排查问题的正确方式:让 AI 帮你提出下一步,而不是替代证据。

九、一份可复用的排查模板

以后遇到报错或异常行为,可以先按下面格式整理,再发给 AI:

问题现象:
[用户看到了什么]

复现步骤:
1. [步骤 1]
2. [步骤 2]

已确认事实:
- [网络、日志、调用次数或返回数据]

运行环境:
- [框架、版本、浏览器或服务信息]

相关代码:
[最小相关代码]

已经尝试:
- [已经做过的检查或修改]

请输出:
1. 最可能原因,按优先级排序。
2. 每个原因的验证方法。
3. 最小修复建议。
4. 修复后需要补充的测试。

要求:先分析,不要直接重写整个项目;区分事实与假设。

总结

AI 能帮助我们更快定位问题,但前提是先给它可靠的上下文。

这个案例的排查顺序是:

发现重复数据
  ↓
查看 Network 和后端日志
  ↓
确认是两次独立请求
  ↓
让 AI 提供可验证假设
  ↓
用最小日志确认函数调用次数
  ↓
最小修改并再次验证
  ↓
补充防重复提交和幂等保护

记住:AI 给出的“可能原因”只是排查起点;日志、请求记录、测试结果才是最终证据。

下一篇文章将介绍:

《我的 AI 编程日常习惯:如何真正提升效率》


✍坚持原创,求关注,点赞,收藏