iT邦幫忙

2026 iThome 鐵人賽

DAY 4
0
Vibe Coding

讓 AI Agent 維護一個 Open Source Project系列 第 4

Day 04:案例——AI 判斷一個 issue 是不是重複回報,準不準

  • 分享至 

  • xImage
  •  

前言:標題關鍵字比對,不就是最省事的查重方法嗎?

「兩份 issue 標題都提到 coverage,內容都在講『coverage 沒顯示』,這不是重複回報是什麼?直接關掉其中一個、請回報者去看另一份就好了吧?」

這是最直覺、也最危險的查重方式。昨天講的是 AI 做第一輪 triage 該產出什麼樣的結構化摘要,今天要把「是否可能重複」這一項單獨拉出來,用 PHPUnit & Pest Test Explorer 幾個真實 issue 示範:光憑標題關鍵字比對做查重判斷,錯誤率比想像中高得多——因為表面文字跟根因之間,常常是兩條不對齊的線。

今日目標

  • 理解查重判斷容易誤判的兩種情況:表面文字不同但根因相同、表面文字相似但根因不同
  • 看兩組真實 issue,具體感受「讀懂錯誤訊息/重現步驟」跟「比對標題關鍵字」差在哪裡
  • 看一個真實案例:連回報者自己都猜測兩份 issue 相關,但深入查證後發現只有部分吻合
  • 建立一套查重判斷的具體檢查項,而不是只看標題

情況一:表面文字相似,根因完全不同

#416 標題是「Failed to run docker compose command」,#417 標題是「Impossible to run individual test」。這兩份回報表面上關聯度很高:同一位回報者、隔天提出、同樣的 Docker + docker-compose 環境設定、環境版本資訊幾乎一字不差。如果查重流程只看「同一個人、同樣的 docker 關鍵字、時間相近」,很容易被判成同一個問題的兩種描述。

但讀進錯誤訊息跟重現步驟,會發現這是兩個完全不同的根因:

  • #416 的輸出訊息是 unknown shorthand flag: 'f' in -f——問題出在擴充套件組出的 phpunit.command 字串裡,docker compose -f docker-compose-test.yml up -d ... 這段指令的參數順序或組合方式讓 shell 解析出錯,是指令組裝層級的問題。
  • #417 的輸出訊息是 Test file "/home/<my user>/.../AccountControllerTest.php" not found——問題出在「執行單一測試」這個動作時,擴充套件沒有把 phpunit.paths 定義的路徑映射套用到測試檔案路徑上,導致容器內找不到宿主機的絕對路徑,是路徑映射沒有被套用到特定執行路徑的問題。

回報者自己在 #417 的設定檔註解裡寫著「bugged! wait until the fix #416」,清楚意識到這是兩件事,只是暫時繞開 #416 的問題才踩到 #417如果 AI 查重只比對「同人、同環境、同關鍵字」,會直接誤判成重複;但讀懂兩份錯誤訊息各自指向哪一段程式邏輯,就能看出這是指令組裝跟路徑映射兩個獨立的缺陷。

情況二:表面文字不同,根因可能同一類

反過來的情況更難抓。#368(已關閉)標題是「Opening file from Test Coverage panel fails when folder mapping is used」,#417 標題是「Impossible to run individual test」。這兩個標題完全看不出關聯——一個講「點 Coverage 面板裡的檔案打不開」,一個講「無法執行單一測試」,連功能區塊都不一樣(Coverage 面板 vs. Test Explorer 執行)。

但兩份回報的重現路徑裡,都出現同一種症狀:phpunit.paths 定義的路徑映射(宿主機路徑 ↔ 容器內路徑),在某個特定觸發點沒有被正確套用——#368 是「點 Coverage 面板的檔案時,VS Code 拿著容器內的 /var/www/html/... 路徑去宿主機找,當然找不到」;#417 是「執行單一測試時,擴充套件把宿主機的絕對路徑丟給容器內的 PHPUnit,容器裡當然沒有這個路徑」。兩者都是「路徑映射邏輯只在某些程式路徑生效,沒有在所有觸發點一致套用」這一類根因,只是分別在 Coverage 面板跟單一測試執行這兩個不同的功能入口被踩到。

單看標題,這兩份幾乎不會被聯想在一起;但讀懂錯誤訊息裡「哪一段路徑沒有被轉換」,才會發現它們其實在提醒維護者同一件事:路徑映射這個功能,是不是每一個會用到檔案路徑的程式碼路徑都記得套用轉換? 這種「表面不相關,但指向同一類系統性缺陷」的關聯,是純標題比對完全抓不到的。

對照範例:查重判斷該看什麼

❌ 只比對標題關鍵字:
「#416 跟 #417 都提到 docker compose,而且是同一位回報者、
  時間又相近,應該是重複回報,合併處理。」
→ 沒有讀錯誤訊息就下結論,會把「指令組裝參數順序錯誤」
  跟「路徑映射沒套用到單一測試執行」這兩個獨立缺陷合併成一個,
  修好其中一個之後,另一個問題還在,回報者會覺得「你說修好了,
  怎麼還是有問題」

✅ 讀懂錯誤訊息跟重現步驟裡的根因:
「#416 錯誤訊息指向 shell 解析 docker compose 指令失敗,
  是指令組裝層級的問題;#417 錯誤訊息指向路徑映射沒有
  套用到單一測試執行這個路徑,是另一個獨立缺陷;
  雖然 #368(已關閉)標題完全不同,但它跟 #417 屬於
  同一類『路徑映射沒有在所有觸發點一致套用』的根因,
  修 #417 時建議一併檢查 #368 的修法有沒有涵蓋到這個新入口。」
→ 兩份各自成案,但額外標註跟 #368 的根因關聯性,
  提醒維護者這可能是同一類系統性問題,值得一次盤點所有
  用到路徑映射的程式碼路徑,而不是頭痛醫頭

這正是查重判斷裡最容易被忽略的一條原則:判斷是不是重複回報,靠的不是標題文字距離,而是錯誤訊息跟重現步驟指向的是不是同一段程式邏輯——表面文字只是線索,不是答案。

連回報者自己的直覺,也需要查證

查重判斷不只是 AI 容易誤判,回報者自己的直覺也一樣。#415(Pest --parallel 執行時測試結果不顯示,顯示成 skipped),回報者自己在內文寫「Seems related to #402 and #408」。查證下去會發現,這個「我猜可能相關」的直覺只對了一部分:

  • #402(已關閉)講的是切換成 ParaTest 之後,編輯器裡的測試狀態圖示不會即時更新,要等全部測試跑完才顯示結果——這份 issue 最後在討論串裡不了了之,回報者自己也表示「調整之後沒辦法再重現」,沒有明確的根因結論。
  • #408 其實是一個已合併的 PR,修的是 Pest v4 把測試定位格式從 pest_qn:// 換成 php_qn://...eval'd code... 之後,擴充套件解析錯誤定位資訊失敗的問題,屬於 Pest v4 特有的識別碼解碼邏輯。

#415 描述的症狀(--parallel 搭配 Pest v4 的 eval()'d code 路徑,導致測試結果顯示異常),讀起來跟 #408 修的那類「Pest v4 定位格式解析」問題更接近,跟 #402(ParaTest 圖示不更新,且從未釐清根因)的關聯反而比較薄弱。連回報者自己標註的「這應該跟哪個 issue 相關」都需要重新查證,不能照單全收——這件事對 AI 跟對人類都成立,唯一差別是 AI 更容易把「有人這樣講」當成結論,而不是當成一條待驗證的線索。

用同樣的邏輯查一次目前的 open issue

把這套邏輯套到 PHPUnit & Pest Test Explorer 目前的 5 個 open issue(#430#420#417#416#415)上:光看標題,#430「Code coverage not working」很容易讓人聯想到過去已關閉的 #330「Code coverage is not shown」——但讀進 #330 的討論串會發現,那份回報最後定位在 clover XML 解析器沒有處理 <package> 巢狀結構(命名空間類別),修復進了 v3.9.5;而 #430 的錯誤訊息是「Test file "../coverage-00000000-0.xml" not found」,指向的是暫存 coverage 檔案路徑找不到,跟 clover XML 解析完全是兩回事。誠實地說:目前 5 個 open issue 之間,沒有一組能判定是同一個根因的重複回報,但示範查證的過程,才是這篇要交付的東西——查重判斷從來不是「找到答案」,而是「把每一個表面關聯都拿去對錯誤訊息跟重現步驟查證一次」。

今日思考題

回想你處理過的任何一次「這兩個問題看起來很像」的判斷——不管是 issue、bug 回報,還是同事口頭轉述的「這跟上次那個問題一樣吧」。你當時是靠標題/描述的文字相似度下結論,還是真的去對過兩邊的錯誤訊息、重現步驟、觸發程式碼路徑?如果現在回頭查,你有把握這個判斷是對的嗎?

今日重點回顧

  • 查重容易誤判的兩種情況:表面文字相似但根因不同(#416 vs #417,同人同環境卻是指令組裝跟路徑映射兩個獨立缺陷)、表面文字不同但根因可能同一類(#368 vs #417,標題完全不相關卻都指向路徑映射沒有一致套用)
  • 判斷依據不是標題文字距離,而是錯誤訊息跟重現步驟指向的是不是同一段程式邏輯
  • 連回報者自己標註的「這應該跟哪個 issue 相關」(#415 自稱跟 #402#408 相關)都需要重新查證,不能照單全收
  • 誠實檢查目前 5 個 open issue,沒有找到明確的重複回報,但查證過程本身才是這套判斷邏輯真正的產出

明日預告

明天要換一個場景:PR Review 交給 AI——怎麼設計一份給外部貢獻者的審查清單,讓 AI 能檢查機械性的規範(測試涵蓋、命名慣例、CI 是否過),但不越界去評判貢獻者的設計決策。


上一篇
Day 03:Issue 分類——讓 AI 先做第一輪 triage,人做最終判斷
系列文
讓 AI Agent 維護一個 Open Source Project4
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言