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
羽毛球分组比赛记分
小程序二维码

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

小夜