Python 除錯:根因分析與修正建議
用途
從完整的 traceback 與程式碼系統追溯根因(不只找症狀),給你一份有信心等級的 Bug 分析,附帶最小化修正與驗證方式。
何時用
- 適合:測試失敗或 runtime 錯誤、自己看 traceback 找不到問題所在、或同樣的錯誤已出現兩次以上時。
- 不要用:不是 Python 的除錯情境(請用通用 Debug 根因分析助理);或問題已定位只是不確定怎麼修(那直接問怎麼修比跑完整分析快)。
Prompt
請幫我分析這個 Python bug 的根本原因,不要只描述症狀。
完整 traceback:
{{完整 traceback,從最上面的 Traceback (most recent call last): 開始貼}}
相關程式碼(traceback 提到的函式或模組):
{{相關程式碼}}
預期行為:{{描述這段程式碼應該要做什麼}}
實際行為:{{描述實際發生什麼,包含錯誤訊息或異常輸出}}
請輸出 Bug 分析報告:
- 症狀:表面上看到什麼
- 根因:真正的問題在哪一層(資料層 / 邏輯層 / 環境層)
- 信心等級:HIGH / MEDIUM / LOW(附理由)
- 問題位置:精確到檔案 + 行號(如可辨識)
- 最小化修正:只改必要的地方,不要順手重構無關程式碼
- 驗證方式:修改後如何確認問題已解決(測試指令或步驟)範例 / 變體
- 填好變數:traceback 貼入實際錯誤輸出(例:
KeyError: 'invoice_id')、相關程式碼貼入出錯的函式、預期行為填回傳訂單的發票 ID、實際行為填在生產環境每天 14:00 觸發 KeyError。 - 變體(只給錯誤訊息沒有程式碼):
{{相關程式碼}}欄位填「程式碼無法提供」,讓 AI 根據 traceback 給出可能的根因假設清單,你再對照去找。 - 變體(環境差異除錯):在 prompt 後加「這個錯誤只在生產環境出現,本機跑不出來,請特別分析可能的環境差異因素(Python 版本、套件版本、環境變數)」。
🎯 範例輸出(實測)
在 Claude.ai 跑這句、traceback 填一個
KeyError: 'invoice_id'、預期行為填「回傳訂單的發票 ID」、實際行為填「每天 14:00 左右觸發 KeyError,早上跑都正常」的結果:
點開看 AI 實際輸出
測試輸入 traceback:
Traceback (most recent call last):
File "/app/workers/invoice_worker.py", line 58, in process_batch
invoice_ids = [r['invoice_id'] for r in results]
File "/app/workers/invoice_worker.py", line 58, in <listcomp>
invoice_ids = [r['invoice_id'] for r in results]
KeyError: 'invoice_id'相關程式碼:
def process_batch(order_ids: list[str]) -> list[str]:
results = db.query("SELECT order_id, invoice_id FROM invoices WHERE order_id = ANY(%s)", [order_ids])
invoice_ids = [r['invoice_id'] for r in results]
return invoice_idsBug 分析報告:
症狀: results 列表中存在某筆資料沒有 invoice_id 欄位,導致 dict key 存取失敗。
根因: 資料層問題 — invoices 資料表的 invoice_id 欄位允許 NULL,在某些訂單(例:還在等 ECPay 回應的待開立狀態)的記錄裡,invoice_id 為 NULL,Python DB driver(psycopg2)把 NULL 回傳為 Python None,這本身不會觸發 KeyError;推測實際根因是 SELECT 的結果型別:若 results 是 RealDictRow,NULL 欄位存在且值為 None;但若某些記錄來自不同查詢路徑(例:JOIN 後欄位名稱衝突),欄位可能根本不在 dict 裡。
信心等級: MEDIUM — 有時間規律(14:00 左右)暗示與批次排程有關,可能是下午批次訂單有特殊狀態,尚需確認 results 的實際型別。
問題位置: invoice_worker.py 第 58 行,但根因在資料進入 process_batch 之前的狀態管理。
最小化修正:
# 只改必要的地方,不重構無關程式碼
invoice_ids = [r['invoice_id'] for r in results if r.get('invoice_id') is not None]驗證方式:
- 在第 57 行加
print(type(results[0]) if results else "empty", results[:3]),確認 dict key 是否真的不存在 - 直接對下午時段的訂單 batch 執行
db.query(...)並檢視回傳結果
💡 實測心得:「只在 14:00 左右出現」這個時間規律帶進 prompt 讓 AI 把根因鎖定在「批次排程 + 特定訂單狀態」這個方向,而不是給一個通用的 KeyError 解釋。實際除錯時間規律是很有價值的上下文,不要省略。
延伸
你有沒有遇過這種情況?traceback 指向的那一行根本沒有問題,真正的錯誤在三層之外的資料進來時就已經壞了?這道 prompt 的設計重點就是逼 AI 分層分析,把症狀和根因分開說清楚,而不是直接跳到「在這一行加個 try-except」。信心等級欄位也很重要,LOW 的根因假設表示需要你再提供更多資訊才能確定。