自己玩儿的AIbug解决分享

作者:袖梨 2026-07-17
# 我用 AI 给自己搭了个"多窗口助手",结果踩了三个"自己坑自己"的 Bug

## 总:今天的核心收获——Bug 不是代码写错了,是"约定"被悄悄违反了

今天花了大约四个小时,给我的 AI 助手系统加上了"多窗口"能力——就像浏览器可以同时打开多个标签页,每个标签页独立工作、互不干扰。写了 1480 行代码,改了 30 个文件,跑通了 20 个自动化测试。

但在测试阶段,连续踩了三个 Bug。修完之后复盘发现:**这三个 Bug 没有一个是因为逻辑写错了,全是"你以为 A 模块会这样做,但 A 模块实际那样做"的约定冲突。**

更关键的收获是:如果我在写代码之前就用对了一个 AI 调试技能(`systematic-debugging`),其中两个 Bug 根本不会出现。

---

## 分 1:Bug 长什么样?——三个"自己坑自己"的故事

### Bug 1:创完会话就进不去

我想创建新会话,流程是:先 `create`(创建),再 `open`(打开)。

结果创建时顺手记了个"进程号"(PID),打开时系统一查"这个进程号还活着!"——以为是另一个窗口占用了,直接拒绝打开。

**真相**:那个"活着的进程"就是我自己。创建和打开在同一个进程里,自己拦住了自己。

**解法**:创建时不记进程号,只在真正打开时才记。责任边界清了,Bug 消失。

### Bug 2:换了模型引擎,但系统还不知道

系统原本用 Google 的 Gemini 模型做规划分析。一查才发现 Gemini 在我们的中转服务上根本不存在。于是把 Gemini 的全部职责迁移给了 Claude Opus。

改了 22 个文件、80 多处引用——代码、提示词、测试、文档。但运行中的飞书 Bot 是旧代码启动的,它还在试图调用不存在的模型。

**真相**:代码迁移了,但进程没重启。静态文件和运行状态的"约定"断了。

**解法**:迁移后重启 Bot,再加上启动自检——每次启动先验证所有配置是否一致。

### Bug 3:消息推送全部失败

飞书 Bot 每天应该推送日报,结果查看日志发现全部失败:`open_id cross app`。

排查发现:Bot 配置里写的是"推送到群聊(chat_id)",但发送方法写死了"推送到个人(open_id)"。配置说往东,代码说往西。

**真相**:Bot 身上存着正确的配置 `chat_id`,但方法的默认参数硬编码了 `open_id`。调用方没传参数,Python 用了硬编码的默认值,而不是 Bot 实例上存的那个正确的值。

**解法**:默认值改成"我没有默认值,你去问 Bot 自己的配置",然后加启动自检。

---

## 分 2:为什么这些问题能"悄悄"存在?

三个 Bug 有一个共同模式——**缺少"防御层"**。

| Bug | 缺少的防御 | 如果有会怎样 |

|-----|-----------|------------|

| PID 冲突 | 创建时不设 PID | 不会自我拦截 |

| 模型迁移 | 启动时自检 | 首次启动就会发现模型不存在 |

| 消息失败 | 参数默认值用实例配置 | 不会用错误默认值 |

用系统化调试技能(`systematic-debugging`)的方法论来解释:修复 Bug 本身只解决了"症状",真正的根因是**每一层边界都缺少验证**。输入没有校验格式、操作没有检查前置条件、输出没有验证一致性。

修复策略叫"纵深防御"——在每一层都加检查点:

- **输入层**:创建会话时校验名称格式

- **操作层**:重命名前先检查会话是否在运行

- **输出层**:保存数据用原子写入(先写临时文件再替换,崩溃不丢数据)

- **恢复层**:异常处理用 `try/finally` 保证状态恢复

---

## 分 3:提示词优化的启发

这次工作中用到的几个 AI 技能(skill),本身也是"好的提示词"的范例:

1. **`systematic-debugging`** — 它让 AI 必须先找到根因再修,不能"随手改一下试试"。这跟写作文不能上来就改措辞、要先理清结构是一个道理。

2. **`brainstorming`** — 强制 AI 先问清楚需求再动手。减少了一大半"做完了才发现不是你要的"的情况。

3. **`writing-plans`** — 把设计拆成一口一口的任务,每个任务有明确的输入、输出和测试标准。

**核心原则**:好的提示词不是"指令更详细",而是"流程更结构化"。告诉 AI **先做什么、再做什么、什么情况下停**,比堆砌细节描述有效得多。

---

## 总:今天可以复用的三条经验

1. **代码的"约定"要显式化**。默认值不要硬编码,去问那个存了正确答案的地方。参数设计上,`None`("我不设默认,你自己去查")比 `"open_id"`("我就用这个,错了我不管")安全得多。

2. **每个模块的边界都要验证**。输入校验格式、操作检查条件、输出验证一致性。现在多花的 10 分钟写检查,能省掉以后 2 小时的排查。

3. **启动时做一次自我体检**。系统启动时花 3 秒验证"我能用的东西是不是真的可用",比跑了 24 小时后才发现推送全部失败要强一百倍。

---

*本次工作使用了 4 个 AI 技能:`superpowers:brainstorming`(需求设计)、`superpowers:writing-plans`(实施计划)、`superpowers:subagent-driven-development`(分任务执行)、`superpowers:systematic-debugging`(Bug 排查与复盘)。* ","createTime":1783263339,"ext":{"closeTextLink":0,"comment_ban":0,"description":"","focusRead":0},"favNum":0,"html":"","isOriginal":0,"likeNum":0,img_6a59f8e50602830.webp

相关文章

精彩推荐