iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0
AI Engineering

從 Claude Code 到無人值守:我的 AI Agent 工程化實戰系列 第 26 篇

Day 26|一個真的要對外負責的專案

  • 分享至 

  • xImage
  •  

Day 26|一個真的要對外負責的專案

Day 25 收在一個問題:這些護欄保護的都是我自己的機器;如果會痛的是別人呢?今天開始的第五幕,就是那個「別人」出現的地方。主角是一個對外服務的專案。先講一個讀者可以檢查的矛盾:這個專案的資料來源全部公開,任何人都查得到;可是它叫什麼、資料從哪裡來、收的是哪一類資料,我在這篇文章裡一個字都不能寫。資料是公開的,名字卻不能公開,這聽起來說不通。這一篇要講的,就是為什麼說得通。

事故:出錯的那一刻,先痛的不是我

先交代背景,只講一句:這個專案從 2026 年 5 月就開始有版本紀錄,真正的考驗是它交給無人值守的輪次自己跑之後。

內部工具出錯,痛的只有我。紀錄漏了一批,我自己補;腳本在另一台跑不起來,我自己改。對外服務不一樣,它出錯的時候,看到錯誤的是不認識我的人,而且他們不會知道那是錯的。

事故清單裡有三類,換到內部工具身上我都可以忍,放在這個專案上就不行。

第一類是假成功。某一輪版本提交其實全部失敗,同一支腳本卻照樣往下跑,收尾回報「已上線」。在自己的工具上,這只是我被騙一次;在這裡,我以為對外的資料已經更新,實際上沒有。

第二類是靜默停更。匯入關卡原本逐列嚴格檢查,只要有一列缺值,整批就拒收。我本來以為這是保守的設計,結果它讓無人值守的管線安靜地停住,沒有報錯,站上的資料就一直停在舊的那一天。

第三類是收尾步驟被跳過。站台上顯示的「最後檢查時間」停住了,因為收尾流程根本沒去寫它。這個數字是給外人看的,外人只能相信它。

但這三類都還算好修。真正讓我停下來的,是一件沒有變成事故的事:公開來源的同一份文件裡,常常同時列著好幾個人。我只收其中一筆,可是全文裡其他人的姓名也會一起被搬過來。每份文件本身都公開,被我整理成可以搜尋的形式之後,性質就變了。

另外,專案文件裡有一句話我一直記著:姓名如果讀錯,就等於指名道姓地誤指另一個人。

證據:邊界畫得出來,可用性量不到

先看資料怎麼流。整條線分四段,圖裡只畫形狀,不寫來源,也不寫資料是哪一類。

公開來源經過正規化、去識別後才進入對外服務的四段資料流

四段依資料流向排列。去識別放在寫入資料表之前,不是寫入之後才補;驗不過的姓名在正規化那一段就被擋下,不會進資料表。最後一段的對外服務只有文件承諾,沒有實測。

去識別這一段有幾個數字。全文裡他人姓名的替換,符合預期樣式的比例是 100%,替換後仍含他人姓名的有 0 筆。之後再拿全庫做一次滑窗掃描,量級是數萬筆,掃完殘留也是 0 筆。這幾個數字出自專案文件,不是這輪重跑的。

這一輪我實際重查的是資料表本身。2026-10-04 當天的快照:主資料表 9 欄,姓名欄只有 1 個,存的是遮罩後的值;沒有任何一欄存原始姓名,也沒有證件號碼欄。這比承諾硬:那個欄位根本不存在,至少從欄位這一層外洩不了。

同一天的缺口佇列快照裡,有 2 列因為只有單一來源、沒辦法交叉驗證姓名,維持永久缺。它們不是漏掉,是我選擇不收。

哪些內容一律不落地、哪些一律不對外的邊界表

第一組是會落地、也就是會寫進資料表的欄位,只寫功能類型;第二組是一律不落地的內容;第三組是落地了也一律不對外的東西。其中「可以反查的欄位組合」那一格,連這篇文章也算在內。

這張圖就是開頭矛盾的答案。單一欄位都公開,危險的是組合:日期加地理單位再加資料類型,就可能找到那一筆。我寫的文章也是一個對外的出口,所以邊界對它同樣有效。不能寫專案名,不是來源見不得人,而是名字一出來,組合就全對上了。

老實交代兩件量不到的事。第一,附件裡可能夾帶證件號碼,這件事存在,也被記錄成一筆待複核的缺口,後來已經歸檔,但處理後實際掃描了多少,我取不到。第二,對外服務的可用性我量不到。我手上沒有服務端的流量、回應時間與索引狀態,所以不推估,也不拿別的數字頂替。

最後一個數字說明壓力落在哪個月。這個專案從 2026-05 到 2026-10-04 查詢當下共有 604 筆版本紀錄,2026-09-01 之後有 400 筆;光是 9 月就有 392 筆,占全期約 65%。

解法:同一套制度,標準換成別人的

我沒有為這個專案另外發明一套制度。審查循環、延後佇列、危險指令攔截、收尾摘要,全都是前面幾幕做出來的東西。改變的只有一件事:判斷「夠不夠好」的標準,從我自己受不受得了,換成別人會不會受傷。

這個改變落在三個地方。

第一,遮罩前移。姓名在入庫前就遮罩,資料表裡從頭到尾沒有未遮罩的版本。內部工具習慣先存原始資料、需要時再處理;這裡反過來,能不落地的就不落地,這樣就沒有後續外洩的問題。

第二,驗不過就寧可缺。內部工具缺一筆,頂多報表少一行;這裡缺一筆,最多是頁面上少一個人,讀錯一筆卻是誤指一個人。所以那 2 列不讓無人值守的流程自己決定,要等我授權,並且先訂好逐列人工核對的方式才能入庫。

第三,靜默比失敗更糟。前面那三類事故的修法方向都一樣:出了問題要被看見,不能被後面的步驟吞掉。匯入關卡改成看缺值比例,而不是一列缺值就整批拒收;版本提交失敗時,後面的步驟要直接短路。對外的資料寧可明說「這次沒更新」,也不要假裝更新了。

這三條都不是新規則,是舊規則換了一個受害者之後,才知道哪幾條真的撐得住。

新問題:邊界畫好了,線還沒走過

這一篇我能畫出的是邊界:哪些內容不落地、哪些不對外、哪些組合連文章都不能寫。但邊界是靜態的。它只告訴我資料不該出現在哪裡,沒有告訴我一個功能從登記、派工、審查到提交,是不是每一步都守住了這些線。

我手上的證據也停在這裡。替換率和殘留數是文件寫的,資料表結構是我重查的,至於對外服務那一端,我連它現在是不是正常都量不到。真正要知道制度有沒有被考過,就得回到這個問題:邊界畫得出來了,那一個功能要怎麼真的走完整條線?


明日預告:Day 27|一個功能怎麼走完整條 pipeline


上一篇
Day 25|護欄:允許自動化到哪裡為止
下一篇
Day 27|一個功能怎麼走完整條 pipeline
系列文
從 Claude Code 到無人值守:我的 AI Agent 工程化實戰 共 27 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言