dsh-bisect-debug:用二分法快速定位 bug 的 DeepSeek Harness 插件

前言

排查 bug 时,最耗时间的往往不是修,而是定位。「bug 肯定在当前代码里,但不知道在哪一段」「点击授权报 405,说不清是前端、网关还是下游 API 的锅」「上周还好好的,不知道哪次提交改坏的」——遇到这类问题,靠通读代码或凭经验猜,效率很低,还容易演变成东改一下西改一下。

二分法是处理这类问题的标准做法:每轮把搜索范围砍一半,几轮之内就能收敛到具体函数、具体边界或具体 commit。dsh-bisect-debug 是一个 DeepSeek Harness(DSH)工作流插件,把这套方法固化成了可执行的流程。DSH 的理念是「一切皆插件」,排查类工作流以插件形式提供,装上即可使用。

这是什么

dsh-bisect-debug 由 PangYiMing 维护,分类为工作流,许可证为 MIT。一句话定位:用二分法把搜索范围每轮砍一半,快速锁定 bug 到具体函数/边界/commit。

插件内置三种二分模式——代码二分、边界二分、commit 二分,并附带模式选择指引、跳过条件和执行纪律,解决的核心问题是「bug 存在于某个范围内,但不知道具体位置」。下面按模式介绍。

三种二分模式

先判断用哪种:有明确好/坏时间点 → commit 二分;跨层问题不确定哪层 → 边界二分;确定 bug 在当前代码里 → 代码二分(最常用)。

代码二分

适用场景:bug 确定在当前代码里,要缩小到具体函数/组件。前提是手上有当前代码和一个可复现的 bug。

流程如下:

  1. 范围里有 N 个候选(函数/组件/中间件/import);
  2. 注释掉后半 N/2 个;
  3. bug 消失 → 根因在被注释的后半里,继续对后半二分;
  4. bug 还在 → 根因在前半里,继续对前半二分;
  5. 反复直到缩小到具体函数/具体行。

注释时保留原代码,加 bisect-disabled 标记,方便恢复:

// [bisect-disabled] <OriginalComponent />
// <OriginalComponent />

注意三点:有依赖关系的模块不能乱注释,否则会引入新报错;注释后验证的是「bug 还在不在」,不是「有没有新报错」;每轮只注释一半。

边界二分

适用场景:跨层问题,不确定是前端还是后端、哪一层的锅。前提是能画出数据流节点图,且不少于 3 层。

思路是:任何 bug 都是「数据在某个环节不再正确」。沿数据流逐跳验证,找到数据正确到达的最后一站——从中间节点验证,midpoint 正确则 bug 在下游,错误则 bug 在上游。不同架构的验证方式不同:

  • HTTP 前后端:curl 直连后端 API,绕过前端;
  • 微服务链:逐服务 curl 或查日志;
  • 数据库:DB 客户端直接查;
  • 浏览器渲染:DevTools Network + Console;
  • 函数调用链:调用方/被调用方各加 log。

典型组合是先用边界二分定层,再在该层内用代码二分定函数。

commit 二分

适用场景:之前还好好的,不知道哪次提交改坏的。前提是有 git 历史和明确的好/坏 commit。

这一模式的关键,是把「好/坏判定」固化成退出码脚本——exit 0 表示好,exit 1 表示坏,exit 125 表示跳过——再交给 git bisect run 全自动收敛。

安装与启用

官方安装命令如下:

dsh plugin --profile demo add dsh-bisect-debug
# 或从 GitHub 安装
dsh plugin --profile demo add github:PangYiMing/dsh-bisect-debug

说明一点:第一种方式对应 npm 发布,资料中标注为「发布到 npm 后」可用;想现在就装,用第二种从 GitHub 安装。

典型用法

边界二分实战:3 个 curl 定位 405

真实案例:点击授权报 405。沿数据流连发 3 个 curl——MCP 登录返回 200(正常)、网关 POST 返回 405(异常)、下游 API 返回 422(正常)。结论:网关 nginx 拦截了 POST。全程 3 个 curl,0 行代码改动。

commit 二分完整流程

先校验好坏 commit 的关系,再写判定脚本,最后交给 git bisect run 自动跑:

# 1. 确认好/坏 commit(good 从 tag/log 推断,不问用户)
git merge-base --is-ancestor <good> <bad>   # 校验 good 在 bad 祖先链上

# 2. 写判定脚本 .temp/bisect-judge.sh
npm run build >/dev/null 2>&1 || exit 125
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 30 "http://localhost:8080/")
[ "$code" = "200" ] && exit 0 || exit 1

# 3. 全自动跑
git bisect start
git bisect bad <bad-commit>
git bisect good <good-commit>
git bisect run bash .temp/bisect-judge.sh

# 4. 收尾(必做)
git bisect reset

脚本先构建、再请求本地服务并按返回码判定:构建失败退出 125 跳过该提交,返回 200 判好,否则判坏。git bisect run 据此自动切提交,收敛到引入 bug 的那一次。

commit 二分有三点注意:base 过期要校验,upstream 合入新文件会误导二分;启动前工作区必须干净;git bisect reset 必做。

什么时候不用二分

插件明确了跳过条件:从现象到根因不超过 2 步,就不进二分。具体包括四种情况——编译器已指出文件+行号;用户明确说了根因;改一行就能验证;已知版本依赖问题。

二分是为「范围大、位置不明」准备的,问题一眼能看穿时不必套流程。

执行纪律

插件附带的执行纪律,几条值得单独列出:

  1. 连续改了 ≥2 处还没解决,停下,回到二分——这是最强的反偷懒规则。
  2. 每轮只切一半,测完再切下一半,禁止一次改多处再测。
  3. 现象优先,代码最后:先用 curl/log/ping 确认现象和边界,不要一上来就读代码。
  4. bug 不可复现时按情况调整:总是复现就直接二分;间歇复现就加诊断日志等下一次;只发生一次就做最大日志注入并部署监控。

适用场景与注意

适合经常需要定位「知道大概范围、不知道具体位置」这类 bug 的 DSH 用户,尤其是让智能体执行排查的场景——模式选择、跳过条件、每轮只改一半这些约束写进了流程,能约束智能体按纪律走,而不是随手乱改。

安全提示:插件以当前 dsh 进程权限运行,安装前建议检查源码与许可证。本项目许可证为 MIT,源码在 GitHub 上可直接查看。

小结

dsh-bisect-debug 的价值在于把「定位 bug」从凭经验乱翻,变成一个有模式选择、有跳过条件、有纪律约束的标准流程:范围大就二分,每轮砍一半,直到收敛到具体函数/边界/commit。如果你常被「不知道 bug 在哪」耗掉大半天,值得一试。

  • GitHub:https://github.com/PangYiMing/dsh-bisect-debug
  • 社区目录页:https://www.skillhub.cn/plugins/PangYiMing/dsh-bisect-debug
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜