iT邦幫忙

2026 iThome 鐵人賽

DAY 8
0
AI Engineering

它說得頭頭是道系列 第 8 篇

# Day 8 — 8 處錯誤:包括三個根本不存在的 PR 編號

  • 分享至 

  • xImage
  •  

昨天講了方法,今天講結果。

18 張統整卡,逐項查完之後:8 處錯誤。

但這篇真正想講的不是那個數字。是錯誤的分佈——它們不是隨機落下來的。

關於編號: 以下所有 PR 編號與卡片名稱都經過代換。但「這個編號存不存在」「哪一個在前哪一個在後」「主旨符不符合」全部與實際情況一致——會影響推論的部分,我一個都沒有動。

關於執行: 昨天講過,實際去搜尋、grep、比對日期的是 AI,我下指令。判準、範圍與最後的判定是我的。每一項都是二元結果、都附查詢證據、都可以被重跑——這是我敢把執行交出去的理由,也是它跟「讓 AI 自己寫 AC 自己測」的差別。


🔴 第一類:狀態誤判(最嚴重的一處)

組織管理卡上有兩處寫著:

❌ 仍是問題(根因已明,待實作)……尚未看到對應的 PR / merge 紀錄

查下去的結果是:兩項都已經修好並合併了:

  • 「系統管理員看不到自己剛建立的組織」→ 已修,PR #4501,而且附了 red-on-revert 測試
  • 「指派畫面的組織下拉漏掉尚未加入的組織」→ 已修,PR #4478,新增了一條專用 API 路由,由權限把關

這一處為什麼最嚴重?不是因為它錯得最離譜,而是因為:

它在時間上是不可能的。

那兩個 PR 的合併日期,早於這張卡片最後更新的日期。也就是說,在那份統整被寫下來的時候,「已經修好了」這件事早就存在於資料裡了。

它不是「還沒更新到最新狀態」——它是看著已經存在的資料,寫出了相反的結論。

而這種錯的下游成本很具體:有人會照著這張卡去修一個已經修好的東西、或是重新開一張卡追一個已經結案的問題。它製造的不是困惑,是工。


🟠 第二類:PR 編號根本不存在(三處)

卡片 卡片上的宣稱 實際
行銷來源卡 PR #1305 修了分頁的歸屬邏輯 該 repo 沒有 #1305;同卡提到的另一個編號存在,而且確實涵蓋了這件事
技術屬性卡 PR #2016 把某欄位併進列資料 該 repo 沒有 #2016
頂部導覽卡 PR #1211、#1254 修了組織切換跳回 沒有 #1211;#1254 存在,而且確實涵蓋了該修復

這一類是最容易查的——輸入編號、按 Enter,存在或不存在,五秒鐘。

但它也是最容易騙過人的。

因為一個 PR 編號長什麼樣子?四位數字。沒有校驗碼、沒有格式特徵、沒有任何東西能讓你一眼看出 #1305 是假的而 #1312 是真的。

它們長得一模一樣。

而且注意那兩張卡的模式:假編號旁邊,就坐著一個真編號。 #1211 是假的,#1254 是真的,寫在同一行。

這就是 Day 1 那段假規則的結構——錯的東西被對的東西夾著,而你會用對的那個去替整行背書。


🟠 第三類:編號存在,但主旨不符(一處)

技術屬性卡說:

#2108 把 carrier 相關欄位併進了列表的資料結構

#2108 確實存在。但它做的是另一件事——伺服器端分組的欄位解析。

真正把那個欄位暴露到列表資料裡的,是 #2002。

我特別把這一處單獨列出來,因為它跟前兩類性質不一樣。

前兩類你去查一下就破功了:狀態誤判,比對日期就知道;假編號,按 Enter 就知道。

但這一處,如果只查「#2108 存不存在」——它會通過。

編號是真的、格式是對的、PR 也真的跟這張卡的主題沾得上邊。要抓到它,查核得多做一步:點進去,讀它到底做了什麼。

而那一步是我在指令裡自己加上去的,不是方法本身要求的。如果我當時沒有多寫那一句,這一處就會活下來。

而它正好是明天那篇的預告。


🟡 第四類:計數與命名(兩處)

這一類最輕,但很有代表性。

檢視設定卡寫著「共有九個分頁」——然後在同一張卡上,自己列出了 10 條路由。程式碼裡也確實是 10 個。

它列對了清單,卻數錯了自己列的東西。

帳號狀態卡提到一個前端訊號叫 unreadableAccountId。這個名字在程式碼裡不存在。實際的實作用的是另外兩個變數名。

有意思的是:那張卡對「行為」的描述完全正確。 它知道那個機制在做什麼、什麼時候會觸發、影響到哪裡——只有名字是編的。

它理解了那件事,然後幫它取了一個聽起來很合理的名字。


但另外一半,全部正確

如果這篇只寫到這裡,它會變成一篇「AI 不可靠」的文章。而那是錯的。

同一批卡片裡,資安相關的宣稱,全部正確。

其中最關鍵的一條是:某個服務的主要路由群組完全沒有身分驗證,任何人都可以直接讀到資料。這是一個真實存在、而且當時還沒修的授權缺口。

查證結果:屬實。

而更讓我意外的是下一層:卡片還寫了為什麼不馬上修。理由是另一個系統呼叫它的時候,根本沒有帶憑證的能力;如果現在強制加上驗證,正式環境會全面失效。

那個說法也被逐項查過——也屬實。 那個客戶端程式收了金鑰參數,但從頭到尾沒有使用它;所有呼叫端傳進去的都是空字串。

那不是一句「看起來很合理」的話。那是一個需要跨兩個系統、讀進去看實作細節才能得到的判斷,而且它是對的。

同一批驗證裡:10 個 PR、3 個前端 PR、5 個 commit hash——全部存在,主旨與日期都吻合。 另外 13 張卡,所有可驗證的宣稱都與程式碼一致。


所以這 8 處錯,是有結構的

把對的跟錯的擺在一起看,分界線其實很清楚:

結果
有程式碼可以直接讀的 準確
需要跨系統推論的 開始猜

資安那批為什麼全對?因為答案就寫在檔案裡。打開路由設定、打開那個客戶端的實作,看一眼就能斷定——它不需要推論,它只需要讀。

PR 編號為什麼會錯?因為那需要跨出手上這份資料:你得去另一個系統查一個號碼、確認它的主旨、比對時間軸。而在做統整的當下,那個資訊不在它手上。

於是它做了一件很人性的事:填一個最合理的。

我覺得這是整個驗證裡最重要的發現,而且它是好消息:

它不是隨機出錯的。它的錯誤有結構。

隨機的錯只能靠運氣抓;有結構的錯可以預測,而可以預測的東西可以設計防線。

後來整個知識庫的架構,基本上就是從這張表長出來的:把需要推論的事情移到建置期去做,因為只有那裡驗證得了。


那我會不會懷疑「查核結果本身」是錯的?

會。而且是兩種完全不同的懷疑。

第一種:我懷疑我自己

這些票卡是層層疊疊、反反覆覆地被修改過的。同一個地方,三個月內可能被動過四次,每一次都留下一段敘述。

而更關鍵的是:開票的人不是我。

我不是那張卡的作者。我不確定當初預期它要長成什麼樣子,我只有事後看到的那些字。

所以我怕的是兩件事:

  • 怕我理解錯了 —— 那句話本來就不是寫給我看的,我讀出來的意思可能根本不是它的意思
  • 怕我記憶混淆 —— 我可能把這張卡的內容,跟另一張長得很像的卡,在腦袋裡疊在一起了

昨天我說過,判斷哪一本書才是「現在」,除了出版日期以外,唯一的途徑是我的腦袋。

今天要補一句更誠實的:

而我對那個索引本身,也沒有信心。

第二種:我懷疑 AI

這個直接一點——我怕他騙我。

我知道這個說法不精確。它不會「騙」,它沒有動機、沒有意圖,它只是在資訊不足的時候產生了一個最合理的東西。

但對我來說,那個區別沒有意義:

「它不是故意的」和「它給了我一個錯的東西」,我承受的後果一模一樣。

昨天講的那 8 處錯,沒有一處是惡意的。而那份文件差點就被拿去給新人用了。

所以這兩種懷疑,指向同一個答案

如果我不能相信自己的記憶,也不能相信它的判斷,那我還剩下什麼?

剩下證據。

那個編號存不存在,不取決於我記得什麼,也不取決於它說什麼——去儲存庫裡看一眼就知道。那個符號在不在程式碼裡,grep 的結果是零或不是零。

這就是為什麼昨天那張「判準必須二元」的表,對我來說不是形式主義。它是我在兩個都不可靠的證人之間,唯一的立足點:

當兩個證人都不可靠的時候,你需要的不是找一個更可靠的證人,是找物證。

(而這句話再往前推一步,就會推翻我整個作法。那是 Day 11。)


但這 8 處,其實不是最可怕的

最後講一件事,它是明天那篇的入口。

這 8 處錯誤有一個共同點:它們全部都被我抓到了。

聽起來像廢話,但它其實是一個很強的性質——它們是可被查證的錯。去查一下就破功:編號不存在、日期對不上、數字兜不攏。

真正讓我後來睡不好的,是另一類錯:

那一類,你去查證的時候,每一項都會通過。

因為它的每一個零件都是真的。

明天那篇是這整個系列裡我最想寫的一篇。


上一篇
# Day 7 — 我決定去驗證 AI 幫我寫的東西:待測物是一份文件
下一篇
# Day 9 — 第三類錯誤:每個零件都是真的,只是組錯了位置
系列文
它說得頭頭是道 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言