iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0
AI Engineering

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

# Day 10 — 它不是抓錯,是資料缺了一個維度

  • 分享至 

  • xImage
  •  

昨天結尾我留了一句話:

這不是「它拉錯了」,而是資料裡根本沒有那個答案。

今天要證明它。

因為這兩件事看起來很像,結論卻完全相反——如果是「它拉錯了」,那我該做的是把指令寫得更嚴格;如果是「資料裡沒有」,那我把指令寫到天荒地老都沒有用。

我一開始相信的是第一個。


先承認我原本的解釋

發現甲功能被寫到 B 頁面的當下,我的第一個反應非常直覺:

它讀得不夠仔細。

這個解釋很舒服,因為它有解法——下次規則再寫嚴一點、要求再講白一點,應該就會好。

但這個解釋撐不過三分鐘。

因為 Day 1 我就寫過,我當初給的指令是這樣的:

以頁面為單位拆分,每一頁都要各自寫出那項功能。不准寫在其中一頁,然後說「其他頁也有」。

這句話沒有模糊空間。它不是「請注意頁面」,是「每一頁各自寫」。

我交代了。而它還是把甲功能放到了 B 頁面。

所以「它沒照做」這個解釋,我沒辦法再拿來用。那就只剩下一個方向可以查:

問題不在它讀的方式,在它讀的東西。


那我自己去讀一遍

驗證方法其實很笨,但很有效:

我把那張原始票卡打開,自己讀,然後問自己一個問題——這張卡講的功能,是哪一頁的?

結果是我也答不出來。

不是讀不懂。那張卡寫得不算差,它把功能的行為講得清清楚楚:做了什麼、什麼條件下觸發、影響到什麼。

它只是從頭到尾沒有講,這是哪一頁。

不在標題。不在描述。不在留言。不在任何一個欄位裡。

而這張卡之所以會長成這樣,原因很具體:

這項功能做在好幾個頁面上,每個頁面的長相又不太一樣——然後,只開了一張卡。

一張卡,涵蓋多個頁面,而卡上沒有任何東西區分它們。

那一刻我就知道,這不是 AI 的閱讀問題。

因為我讀同一份資料,也得不到答案。


「資訊不足」和「缺一個維度」不是同一件事

這裡我想把話說精確一點,因為這兩個詞常常被混用,但它們的處理方式完全不同。

資訊不足,是這個欄位存在,但寫得含糊。

例:「這個功能在報表頁。」——哪一個報表頁?寫得不清楚,但追問得到。你知道要問什麼。

缺一個維度,是這個欄位根本不存在。

例:整張卡從來沒有出現過「頁面」這個概念。

差別在哪?

資訊不足的時候,你知道自己缺什麼。缺維度的時候,你連「有東西缺了」都看不出來——因為那份資料讀起來是完整的,它自洽、通順、每一句都成立。

我後來想到一個比喻:

一本只記了「幾點」、沒有記「哪一天」的行事曆。

每一條都是真的。九點開會、兩點回診,全部正確。

但你沒有辦法用它排出明天的行程——而且你翻的時候不會覺得哪裡怪,因為每一行看起來都很正常。

那份說明書的狀況就是這樣。

而接下來發生的事,幾乎是必然的:

我拿一份缺了「頁面」這個維度的資料,去要求一個需要「頁面」這個維度才答得出來的答案。


它那一刻其實只有兩個選項

站在它的位置上想一遍,選項其實很少:

選項一:回答「這張卡沒有寫是哪一頁,我無法判斷」。

這需要一個前提——它得知道自己少了什麼。也就是說,它要先有「這件事需要頁面這個維度」的認知,再比對出「而我手上沒有」,最後還要願意交出一個不完整的答案。

選項二:填一個最合理的。

它選了這個。

而我必須誠實:如果那份資料交到一個人手上,結果不會比較好。

任何人讀那張卡,都不知道那是哪一頁。差別只有一個:

人會說「這裡沒寫清楚,我去問一下」。

而這個動作看起來是「比較負責」,但拆開來看,它需要的不是比較聰明,是兩個很具體的條件:

  1. 有一個可以問的人——知道誰開的卡、找得到、對方還記得
  2. 知道自己被允許問——不會因為問了而顯得沒能力

這兩件事,那個當下的 AI 一個都沒有。它沒有同事、沒有 Slack、沒有「等一下再說」這個選項。它被要求現在就產出一份完整的文件,而它手上那份資料答不出來。

於是它做了一件在那個處境下最自然的事:把空格填滿。


第二個例子:同一種病,換一個器官

門檻那件事也一樣。原票卡寫的是「當數量 < 2」,統整之後變成「< 6」。

我一開始把它當成幻覺——它編了一個數字。

不是。

6 是真的。 那一區確實有卡片上寫著 6,只是那個 6 屬於另外一條規則。

同一個功能區,前後開了好幾張卡,各自寫了各自的門檻。它們散在不同的卡、不同的時間點,而卡片上沒有任何東西告訴你:哪一個是現在生效的那一個。

所以它做的不是「編造」,是在幾個互相衝突的來源之間做了一次選擇——而那份資料從來沒有告訴它該怎麼選。

這兩個例子擺在一起,病灶其實是同一個:

它缺的維度
甲功能被放到 B 頁面 空間——這是哪一頁
< 2 變成 < 6 時間——哪一個版本是現在

一個缺空間,一個缺時間。

而缺時間那一個,會把我整個作法推翻——那是明天的事。


對照組:為什麼資安那批全部正確

如果上面的推論成立,它應該要能解釋反面:同一個 AI、同一批卡片,為什麼資安相關的判斷一處都沒錯?

Day 8 我寫過那批的結果:某個服務的路由群組完全沒有身分驗證——屬實;連「為什麼不馬上修」的理由都對——因為呼叫端根本沒有帶憑證的能力。

那條判斷需要跨兩個系統、讀進實作細節。聽起來比「這是哪一頁」難得多。

但它對了。

原因只有一個:

答案就寫在檔案裡。

打開路由設定,看有沒有掛驗證;打開呼叫端,看那個參數有沒有被用到。它不需要推論,它只需要讀。

那個維度沒有缺。

於是 Day 8 那張表,今天可以再往下挖一層:

需要的維度在手上的資料裡嗎? 結果
資安判斷 在(程式碼本身就是答案) 全部正確
PR 編號 不在(要跨到另一個系統查) 開始猜
頁面歸屬 不在(卡片沒有這個欄位) 放錯位置
門檻數字 不在(沒有東西標示哪個是現行) 選錯來源

這四行看起來是四種不同的錯,其實是同一行:

答案在不在它手上的那份資料裡。

而這件事最重要的地方在於——這條線是可以事先畫出來的。

我不需要等它出錯才知道它會錯在哪。我只要問一個問題:這個問題需要的維度,在我餵給它的資料裡嗎? 不在,它就會猜;而它猜的時候,產出的東西讀起來會跟正確答案一模一樣。

後來整個知識庫的架構,基本上就是從這張表長出來的。


所以,這不能怪 AI 嗎?

先說我的答案:我不怪它——但這不是一句寬容。

因為在這個案子裡,它根本沒有被給到一個能答對的機會。而「有沒有給到機會」這件事,是可以事先判斷的。

我把自己的立場拆成三句話。

一、不論使用者是誰,給出去的都應該是最新的、真實的資料

這句話聽起來像廢話,但它有一個很具體的反面——

你不能假設使用者知情。

那張卡之所以可以不寫頁面,靠的是一個默認的前提:讀它的人知道自己在看哪一頁。開卡的人知道、做過的人知道、當時在場的人都知道,所以那一欄不寫也沒關係。

那不是資料完整,那是資料剛好遇到了對的讀者。

而一旦讀者換人——換成 AI、換成新人、換成三個月後已經忘記的我自己——那個前提就不成立了。資料沒有變,但它突然答不出問題了。

所以「給最新的真實資料」不是對善意的期待,是義務。而且是不管誰來讀都成立的義務。

二、不能把「使用者會回報錯誤」當成一道防線

這是我最想講的一句。

那 6 個問題,確實是新人幫我抓出來的。從結果看,好像「有人會回報」這件事發揮了作用。

但那不是防線生效,那是防線不存在的證據。

因為它成立的條件太苛刻了:要有人真的照著跑、要有人肯回報、要有人回報之後我還願意去查。中間任何一環斷掉,錯誤就直接活下來。

更麻煩的是 Day 9 那個結論——最需要這份文件的人,剛好是最沒有能力驗證它的人。 新人不知道甲功能原本在 A 頁面,所以回報的是「測試失敗」,不是「文件寫錯了」。能幫我抓到,靠的是撞牆,不是判斷。

把驗證成本轉嫁給讀者,然後說「有問題會有人講」——那不是流程,那是運氣。

三、不能 100% 信任 AI——但這句話有前提

這條我要講清楚,因為它很容易被誤讀成「AI 不可信」。

在我這個案子裡,票卡本身就是亂的。同一處改過好幾次、同一個功能散在好幾張卡、該有的欄位沒有。

所以我的不信任,對象其實不是 AI:

在那批資料的狀態下,不管是誰來整理,我都不會直接相信結果。

換一個資深工程師來做,我一樣要查。換我自己來做——Day 8 我已經寫過了,我連自己的記憶都不敢當對照組。

我不信任的不是那個讀者,是那份資料的產物。

補一條我沒辦法排除的可能:它可能只是「讀太多了」

上面整篇我都在講「資料缺了維度」。但我必須誠實:那不是唯一的可能。

還有一個解釋我沒有辦法排除——上下文太長。

一次餵進去的東西超過它能一次握住的量,中間就會被壓縮、被摘要、被丟掉一部分。而被丟掉的那部分不會跟你說一聲。接下來它繼續往下寫,寫出來的東西一樣通順、一樣有自信,只是有些東西已經不在它手上了。

這個失敗長得跟「缺維度」一模一樣。 從外面看,你只會看到一個放錯位置的答案,你分不出來它到底是「資料裡沒有」,還是「資料裡有但它已經忘了」。

我也沒有辦法從結果反推是哪一種。我能確定的只有:那張卡確實沒有頁面這一欄——這部分我自己讀過,是硬的。但那一整批卡加起來的份量會不會也踩到了第二條線,我不知道。

而這兩個原因,剛好指向同一個方向:

不要一次丟一大包資料進去,要它產出需要精確對應的東西。

一個是因為資料裡沒有答案,一個是因為答案進去了但沒被握住。兩種都不是靠「把指令寫得更嚴格」能解決的。

這件事後來直接影響了我怎麼切資料——那是後面的篇幅。


而這就是為什麼「不怪它」不等於「它不會錯」

上面三條合起來,會長出一個很具體的判準:

如果資料是乾淨的、是正確的,而它還是出錯——那我就會怪了。

這句話對我來說很重要,因為它把「怪不怪」從一個態度問題,變成一個可以檢查的問題:

  1. 先問:這個答案需要的維度,在我給它的資料裡嗎?
  2. 不在 → 它猜錯了,錯的是我。我拿一份答不出來的資料去要答案。
  3. 在,但我一次丟了一大包 → 也還是我的問題。答案有進去,但我沒有確保它握得住。
  4. 在、份量也合理,而它還是錯 → 那就是它的問題,而且是嚴重的問題。

第四種情況我沒有在這個專案裡遇到——但我不會假設它不存在。這條判準留著,是為了讓「不怪它」不要變成一張免死金牌。

我不怪它,是因為這一次資料不成立。不是因為它是 AI。


所以真正有用的問題,從來不是「該怪誰」,而是:

誰,該負責讓那個維度存在?

而這個問題一問出來,矛頭就指向一個比 AI 更早的地方——那張卡被開出來的時候,就已經少了一欄。

一項功能做在五個頁面上,只開一張卡。這在當下是最省事的做法,而且在當下也真的沒出事。

問題是那份資料後來被拿去做一件它從來沒有被設計要做的事:

餵給一個沒有背景知識的讀者,產出給另一群沒有背景知識的讀者看的文件。

而「沒有背景知識的讀者」——那不只是 AI,那也是新人。

這就回到 Day 9 那句話了:

抓到錯誤的前提,是你已經知道對的樣子。

AI 不知道。新人不知道。而那張卡,正好是寫給知道的人看的。

所以真正的錯不在讀的那一端。在於——我們一直用「寫給知道的人看」的資料,去服務不知道的人。


明天:而我還做了一件更根本的錯事

今天講的是資料缺了維度。

但你如果回頭看那兩個例子,會發現一件更麻煩的事:

它們缺的不是同一種東西。一個缺空間,一個缺時間。

而缺時間那一個,不是某張卡沒寫清楚的問題——是票卡這種東西,本質上就不該拿來回答「現在長什麼樣子」。

票卡記錄的是意圖,而且是會被後面的意圖覆蓋的意圖。同一個地方改過三次,前兩次的敘述現在都是錯的——但它們長得跟第三次一模一樣。

明天那篇要講的是:

我不是用錯了 AI。我是一開始就選錯了 source of truth。


上一篇
# Day 9 — 第三類錯誤:每個零件都是真的,只是組錯了位置
下一篇
# Day 11 — 我一開始就選錯了 source of truth
系列文
它說得頭頭是道 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言