當 AI 三分鐘寫出一個醫療劑量計算器,你敢用它算你小孩的藥量嗎?

一場關於「AI 生成的測試,誰來驗證?」的實驗


這場演講在談什麼

英國 Bluefruit Software 的創辦人 Paul Massie 做了一個很誠實的實驗。

他用 vibe coding 工具在三分鐘內生出一個「兒童 ibuprofen 劑量計算器」,然後花了接下來的兩個小時,試圖把它變成一個他敢交給病人用的東西。

過程中他用了兩個工具:BDD突變測試(Mutation Testing)。結論不是「AI coding 很安全」,也不是「AI coding 不能用」,而是一個更有價值的東西——一套讓 AI 產出可被驗證的分層防護,以及一個他自己都沒預料到的轉折。

這個轉折,正好命中了 AI 時代測試最核心的難題。

Bluefruit 是一家成立 25 年、約 60–70 人的嵌入式軟體公司,客戶橫跨醫療、功能安全、航太、國防——全都是高度受規範的領域。這件事很重要:他不是在實驗室裡玩,他是真的要把這些東西交出去


第一幕:三分鐘的奇蹟

Paul 用 bolt.new 下了一段 prompt:

做一個 ibuprofen 劑量計算器,詢問病人年齡以判斷是兒童或成人,輸入體重與症狀,自動計算合適劑量並提供適當警語。

三分鐘後,網站生出來了。前端、後端資料庫、部署,全部完成。輸入年齡體重症狀,它回你建議劑量、服用頻率、警語。

好處是真的好

  • 生產力:三分鐘 vs. 兩三天
  • 創造力:可以一口氣生五個原型丟給使用者試,而且常常出現你沒想到的解法
  • 原型設計:比 Figma 的點擊式原型更進一步——這是可以真的動的軟體,回饋品質完全不同

但代價也是真的

Paul 列了四個問題,其中第三個是重點:

  1. 缺乏透明度——你不知道它到底做了什麼
  2. 沒有追溯性——需求、規格、程式碼、測試之間的連結斷掉了
  3. 不安全的假設——這是最致命的
  4. 不符合法規——在醫療領域,這代表不能出貨

關於第三點,他講了一段我覺得整場最有份量的話:

身為工程師,我們整天都在做決策。有些是小的技術決策,靠經驗判斷;有些是高層次的決策,要跟使用者和利害關係人討論。做決策、而且做對決策,就是我們被付錢做的事

而 AI 做了成千上萬個決策——沒有問任何人、沒有 check in、沒有確認假設對不對。

現場投票:「你敢用它算你小孩的藥量嗎?(1–10 分)」平均約 3 分


關鍵洞察:AI 就像你團隊裡的資淺工程師

這是整場演講的樞紐。

Paul 說,當他把這四個缺點列出來的時候,他發現一件事:這些問題我太熟悉了

不透明、不追溯、自己亂做假設、不遵守規範——這正是他 25 年來帶資淺工程師時,一再遇到的同一組問題。有時候資深工程師也會犯。

那麼問題就變成:我們用來讓資淺工程師不出包的那套工具箱,能不能直接拿來用在 AI 上?

這個框架之所以有力,是因為它把「AI 該怎麼管」從一個全新的、令人焦慮的問題,翻譯成一個軟體工程界已經處理了三十年的舊問題。


第一層:標準(Standards)

依領域不同:IEC 61508(功能安全)、IEC 62304 / 82304(醫療)、DO-178(航太)。

這些標準的核心價值是什麼?

決策的追溯性。 從 user needs → 軟體需求 → 設計 → 詳細設計 → 程式碼,V model 的每一層都有對應的驗證(verification),最後對著 user needs 做確效(validation)。加上風險管理,以及全程可稽核。

但標準單獨用不夠。 Paul 講得很直白:

  • 標準能防止混亂,但也會拖慢創新——而創新本身是高品質軟體的一部分
  • 更糟的是打勾心態(tick-box mentality):團隊照著流程做了,但沒有交付出流程原本想要的品質

他舉的例子非常具體:很多團隊是在程式碼寫完之後才補單元測試。覆蓋率數字有了,稽核通過了,但那些測試根本沒有效果。

記住這個例子,等一下突變測試會回頭把它打爆。


第二層:敏捷與 BDD

敏捷實踐帶來的是平衡:在安全與速度之間,同時把品質內建在做法裡,而不是事後檢查。TDD 就是最好的例子——它讓單元測試在寫的當下就有效。

在醫療領域,這不是想像。AAMI TIR45 這份 2012 年的指引文件,明確說明如何用敏捷實踐去滿足法規期待。BDD 產出的規格與測試,是可以放進法規文件包的。

BDD 的兩個面向

技術面:可執行的需求模型

用 Given / When / Then 寫成自然語言的規格,然後自動化它。BDD 最聰明的一手是:它把「規格」和「測試」合併成同一個 artifact。所以你隨時可以跑一次,看到目前的程式碼跟大家講好的行為,有多少對得上、多少對不上。

協作面:Three Amigos

business、dev、tester 坐下來一起談出驗收條件。這件事沒有被 AI 取代,反而更重要——因為它是人類定義正確行為的場合。

Paul 的實驗流程

  1. 準備 PRD(3 個 user needs、20 條需求)
  2. 丟給 Claude Code,請它產出 BDD 規格檔——帶需求編號,可回溯 PRD
  3. 自動化:產生 55 個情境,52 個通過
  4. 產出 living documentation 與覆蓋率報告,跟程式碼一起放進 git

第 3 步是關鍵。Paul 說了一句很值得畫線的話:

Bluefruit 所有專案都做 BDD,但我們不一定會自動化——因為要自動化那些測試的負擔太大了。

自動化成本一直是 BDD 落地最大的阻力。這正是 AI 幫上最大忙的地方。

而「跟程式碼一起進 git」的意義是:任何一個 release,你都能翻出當時的規格、測試步驟、測試結果,三者同步。這在受規範領域是硬需求。

還有一個副作用:那三個失敗的測試,抓到了真 bug。所以剛剛投低分的人,直覺是對的。

進度盤點

  • 透明度 ✅ living documentation
  • 追溯性 ✅ PRD → 規格 → 測試 → 程式碼
  • 不安全的假設 ✅ 有護欄了,AI 自作主張的地方會顯示為「與規格不符」
  • 法規合規 🟡 有了驗證框架,再疊上 TDD、code review 等實踐,算是好的開始

現場再投票一次:從 3 分升到 4.5–5 分


轉折:他不信任這些測試

這是整場演講最有價值的一段,也是我認為所有在推 AI + BDD 的人都該停下來想的一段。

Paul 說,他自己還是不滿意。為什麼?

我們用 Claude Code 產生了程式碼,也用 Claude Code 產生了測試。這中間缺乏獨立性。

當你真的去看那些測試,會擔心 AI 產生幻覺,或者它太想取悅你、給你它認為你想看到的結果

而 BDD 這整套工作流,非常依賴你信任那些測試。

所以我的結論是:我不信任這些測試。

他自己形容這是個 plot twist:BDD 不是銀彈。

這其實是「Oracle Problem」

用測試理論的語言講:當 AI 同時產生實作與測試,誰來定義什麼是正確的行為?

測試本來的功能,是提供一個獨立於實作的正確性判準(oracle)。一旦兩者來自同一個模型、同一次推理、同一組被誤解的假設,測試就從「驗證」退化成「複述」。它們會漂亮地全部通過——通過的是 AI 對需求的理解,不是需求本身。

這也是 AI 時代最典型的「驗證瓶頸」:程式碼生成快了一百倍,但瓶頸只是往下游移動到審查、驗證與理解。而如果連驗證工具本身都是 AI 生的,瓶頸沒有被解開,只是被藏起來了。

你需要一個 AI 無法說服的東西。


第三層:突變測試(Mutation Testing)

Paul 回頭去翻他管資淺工程師的工具箱,找到了這個他自己也不常用的技術。

它怎麼運作

突變測試的目標,是測試你的測試有多有效

工具會掃過你的整個 codebase,在每一個分支、每一個 if、每一個迴圈,注入一個 bug(稱為 mutant)。然後跑你的測試,看測試抓到了幾隻

抓到的比例,就是 mutation score。

這跟覆蓋率的差別是根本性的:覆蓋率只告訴你測試「碰過」多少程式碼,不告訴你測試「檢查」了什麼。那些事後補寫的單元測試,覆蓋率可以很漂亮,mutation score 會很難看。

實驗結果

Paul 用 Stryker 跑他那個 ibuprofen 計算器:

  • 產生 141 個 mutants
  • 原本那套 AI 生的 BDD 測試,只抓到 30%

一個這麼小、這麼簡單的 codebase,30%。他的不信任是有根據的。

接著他做了一件很聰明的事:把 Stryker 交給 Claude Code,讓它自己跑 feedback loop——診斷為什麼這些測試抓不到 mutants,然後修。(Claude Code 是 agent,可以自己列 to-do、自己用工具、自己迭代。)

需要人在旁邊引導,花了一段時間,最後拉到 80%。漏掉的多半是字串常數這類本來就會變動、可以理解的東西。


它揪出了什麼:問題貫穿整個 V Model

這段是我覺得最精彩的。突變測試找到的問題,不只在測試層

PRD 有缺口。 六個月以下嬰兒的年齡區間,需求文件根本沒寫清楚。而 AI 沒有抗議、沒有提問、沒有標記——它就自己猜了一個

我不能接受這樣。AI 很能接受。是一直到跑了突變測試,這個缺口才浮現出來。

規格有缺口。 從 PRD 生出來的 Given/When/Then 沒有他以為的那麼完整。

測試有缺口。 這是預期中的。

程式碼也有問題。 它找到了 dead code——因為工具往那段死碼裡注入 bug,而測試永遠不可能抓到。

換句話說,一個純粹的、非 AI 的、機械式的工具,反向照出了從需求到實作每一層的破洞。這是我認為這場演講最值得帶走的一件事。


成本帳:慢了幾倍,但還是快

階段耗時累計
Vibe coding3 分鐘3 分鐘
+ BDD 規格、自動化、文件+20–30 分鐘~30 分鐘
+ 突變測試與迭代修正+90 分鐘~2 小時

慢了 40 倍

但原本手工做這件事要 兩到三天

這個帳算得很清楚:AI 的價值不是「三分鐘做完」,而是「兩小時做完一件本來要三天、而且品質更高的事」。省下來的時間,不是拿去多寫功能,是拿去做驗證。

最終投票:又往上升了一些,但仍然有很大的分歧——包括 Paul 自己。他沒有假裝問題解決了。


Q&A 裡的重點

Q:有跟人類團隊做對照組嗎?

沒有,但他引用了一篇比較 test-first 與 test-last 的論文(用 mutation score 當作測試有效性的指標):

  • test-last:平均約 60%,而且離散度極大——資淺開發者只有 20–30%
  • test-first:平均 80 多分,而且分佈非常集中,大家都在 80 幾

第二點比第一點更有意思:TDD 的價值不只是平均值高,是它壓縮了品質的變異數。它讓「這段程式碼的測試好不好」不再取決於是誰寫的。

Q:突變測試要一直留在流程裡嗎?

要。提問者的觀察很尖銳:就算一開始測試寫得很好,只要你叫 AI「讓這些測試通過」,它試不出來的時候,就會去改測試把它變綠

Paul 認同:「確實有作弊的傾向。」

但突變測試很慢(一次只能注入一個 mutant 跑一輪,不可能 141 個一起注入),所以不適合放在每次 commit 的 pipeline,比較適合當作低頻率的定期檢查

Q:PRD 有大小上限嗎?

有,受 context window 限制。解法是拆成元件,或改用 context window 更大的模型(他提到 Gemini)。但追問者指出真正的難題:如果需求是橫切整個系統的,拆開之後一致性怎麼維持? 這題沒有好答案。

Q:導入最大的阻力是什麼?

三個:

  1. 讓開發者上車——他觀察到很多人一兩次壞經驗就全盤否定。但下 prompt、把 AI 拉回正軌,是一組要練的新技能,需要撐過去。
  2. 讓客戶上車——資料留存、程式碼會不會被拿去訓練,這些疑慮要處理。
  3. 確保淨產出是正的——不能為了用 AI 而用 AI。

然後他講了一句我認為是整場最重要的定位:

我研究這件事的主要動機,其實不是生產力。是我們能不能藉此把軟體品質推上去——去做那些我們從來沒有餘裕、沒有資源去做的實踐

例如,把所有 BDD 測試都自動化。我們從來沒有足夠的產能做到這件事。如果現在做得到,而寫程式的方式維持不變——那我們什麼都沒失去,卻多拿到了一整套實踐。

這是一個把 AI 當作「品質預算」而不是「速度預算」的思考方式。 我覺得比大部分談 AI 生產力的內容都更值得參考。

Q:技術上怎麼串的?用 MCP 嗎?

沒有。就是在 Claude Code 提示字元打「我們來做個突變測試吧」。Claude Code 一開始問「要我幫你做一個工具嗎?」(Paul 笑說:我認識的工程師也都從這裡開始),他說不要,先去查有沒有現成的。Claude Code 上網找到 Stryker,安裝、設定、跑報告、迭代,全部自己來。

Q:那你怎麼知道測試是對的?它不就是在對著測試最佳化嗎?

這題問到了核心,Paul 的回答也是全場最好的一段:

我們有測試,我們也有「測試的測試」。

AI 對突變測試沒有任何控制權。突變測試是一個非 AI 的工具,純粹客觀——它看你的 codebase,找出每一個分支,在那裡注入 bug,然後跑你的測試。

從那種抽象的 AI 世界——它建模、它描述、它解釋——切換到這裡,有一種很清爽的感覺。這裡有個具體的東西,我可以把手放上去。 它幾乎像是找了一支獨立團隊來驗證。

但他也立刻補了但書:不會單靠它。在真正的醫療專案上,程式碼要 review、自動化測試要 review、測試步驟要 review。而且——

Code review 從來不是 100%,它大概是 80% 的檢查。突變測試給了我們額外的一個工具。


這場演講真正的貢獻

把三層疊起來看:

解決什麼為什麼不夠
標準給框架、給追溯性、可稽核會變成打勾文化,拖慢創新
BDD給透明度、給規格與程式碼的對齊測試本身可能是 AI 幻想出來的
突變測試給「測試值得信任」的客觀證據慢、只能低頻跑、不能單獨依賴

三層有一個共同的邏輯:每一層都在為上一層提供它自己無法提供的獨立性。

而最深的一點是——當 AI 同時生成程式碼與測試,你需要在鏈條的某個地方,放進一個AI 無法說服、無法討好、無法繞過的東西

突變測試之所以有效,不是因為它多聰明,恰恰是因為它夠笨。它不理解你的意圖,不在乎你想聽什麼,它只是機械地注入 bug,然後數你抓到幾隻。

在一個充滿了會說話、會解釋、會道歉、會保證自己做對了的工具的時代,「無法被說服的東西」本身就是一種稀缺資源

值得補上的一句:這三層都沒有取代 Three Amigos。PRD 裡那個「六個月以下嬰兒」的缺口,最理想的攔截點不是突變測試,是一開始就有人問出那個問題。突變測試是最後一道網,不是第一道。


來源

Safe AI Coding in Regulated Domains: BDD, Mutation Testing & Medical Devices 講者:Paul Massie(Founder & Director, Bluefruit Software) https://www.youtube.com/watch?v=S9NZCDGnauI

延伸參考

  • AAMI TIR45 — 醫療器材軟體開發使用敏捷實踐的指引(2012)
  • IEC 62304 / IEC 82304 — 醫療器材軟體生命週期標準
  • IEC 61508 — 功能安全;DO-178 — 航太軟體
  • Stryker Mutator — 演講中使用的突變測試工具(JS/TS、C#、Scala)
  • 其他語言的突變測試工具:PIT(Java)、mutmut / cosmic-ray(Python)、go-mutesting(Go)

發表迴響

探索更多來自 轉念學 - 敏捷三叔公的學習之旅 的內容

立即訂閱即可持續閱讀,還能取得所有封存文章。

繼續閱讀