Day 26:怎麼寫 AI 平台的驗收清單
這是什麼、解決什麼問題
導入案走到最後,你要交的是一份驗收清單。
而多數驗收清單長這樣:
☑ 已安裝 OpenShift AI ☑ 已完成模型部署 ☑ 已建立 pipeline
這種清單的問題不是不對,是它誰都能過。 「已完成模型部署」——部署了什麼模型?怎麼知道它在服務? 用什麼證據?沒有一條答得出來。
這篇講一條合格的驗收長什麼樣。
什麼時候你會用到
- PoC 要結案
- 要驗收廠商的交付
- 要說服自己「這個東西可以上線了」
步驟一:一條驗收的四個欄位
每一條都要有這四樣,缺一不可:
| 欄位 | 意思 |
|---|---|
| 做什麼 | 一個明確的動作 |
| 怎麼做 | 具體的指令或操作步驟 |
| 預期什麼 | ⭐ 可以用眼睛判定對錯的結果 |
| 留什麼證據 | 截圖、指令輸出、檔案 |
對照一下:
❌ 不合格
確認模型服務正常運作
✅ 合格
做什麼:確認線上服務跑的是預期的模型版本 怎麼做:
oc exec <predictor-pod> -c kserve-container -- sha256sum /mnt/models/model.bin預期:輸出等於e3b0c442...(發布單上的 digest) 證據:指令輸出截圖,含 pod 名稱與時間
差別在第三欄。 「正常運作」沒有判定標準, 「等於這串 digest」有。
步驟二:⭐ 每一條都問「這條會不會擋下東西」
這是我認為最能提升清單品質的一個問題。
拿你寫好的每一條問一次:「如果環境是壞的,這一條會不會發現?」
| 條目 | 環境壞掉時 | 判定 |
|---|---|---|
| 「已安裝 operator」 | operator 裝了但元件沒起來 → 還是過 | ❌ 沒用 |
| 「DSC 上你開的元件都 Ready」 | 會抓到 | ✅ |
| 「pipeline 執行成功」 | 空的 step 也成功 → 還是過 | ❌ 沒用 |
| 「artifact 存在且大小 > 1MB」 | 會抓到 | ✅ |
過不了這一關的條目,寫了只是好看。
步驟三:分層——七層,由淺到深
一份好的清單有層次,因為不同層次的失敗代價不同:
| 層 | 驗什麼 | 例子 |
|---|---|---|
| 1 環境 | 環境本身 | 版本、資源、網路可達 |
| 2 安裝 | 平台裝起來 | DSC 你開的元件 Ready |
| 3 功能 | 基本功能 | workbench 開得起來、pipeline 跑得完 |
| 4 端到端 | 一條路走通 | 資料 → 模型 → 上線 → 打得到 |
| 5 證據鏈 | 說得出來源 | 線上模型對得回訓練資料 |
| 6 護欄 | 擋得住東西 | 壞東西真的被拒絕 |
| 7 維運 | 撐得住日常 | 回滾、輪替、重建演練過 |
多數 PoC 只做到第 3 層,然後在報告裡宣稱平台可用。
第 4 層以上才是真正回答「能不能上線」的部分, 而第 6 層是最常整層缺席的——因為它需要你故意做壞事。
步驟四:護欄層的條目長什麼樣
護欄的驗收條目要有一個「反向測試」。
| 護欄 | 正向(不夠) | ⭐ 反向(才算數) |
|---|---|---|
| 資源上限 | 建一個正常的 workbench | 要超過 maxCount,確認被拒絕(⚠️ 見下) |
| 品質閘門 | 好模型通過 | 餵一個爛模型,確認被擋 |
| 權限隔離 | alice 看得到 team-a | alice 看不到 team-b |
| image 來源限制 | 內部 image 拉得到 | 外部 image 拉不到 |
| 憑證最小權限 | 讀得到 | 寫不進去 |
⚠️ 第一列我自己做過,而結果正是這一節要講的事。
Day 13 我去驗那條「資源上限」:default-profile 寫著上限 4 CPU / 8Gi,
我送一個 16 CPU / 64Gi 的 workbench 進去——
notebook.kubeflow.org/d13-oversize created
建起來了。 那個上限在 dashboard 以外的任何路徑上都不擋 (它是 mutating webhook,不是 validating)。
如果我只做正向測試——「建一個正常的 workbench,成功」—— 我會簽收一道根本不存在的護欄。
這就是為什麼反向測試不是「比較嚴謹」,是唯一會告訴你真相的那一半。 正向測試證明的是「正常情況能用」,那從來不是護欄存在的理由。
沒有反向測試的護欄條目,證明的是「它沒有擋錯」, 不是「它會擋」。 這兩件事差很多。
步驟五:避免三個常見的坑
坑一:用管理員帳號驗收
Day 21 講過。用 kubeadmin 驗過的東西,
不代表真實使用者做得到。 驗收清單要註明用哪個身分執行。
坑二:驗收環境不是上線環境
在 lab 驗過的,到正式環境常常不成立—— 離線、權限、資源、網路全都不同。 清單上要標明每一條是在哪個環境驗的。
坑三:一次性的驗收
驗收通過那一天是對的,三個月後呢? 把清單裡可以自動化的部分寫成腳本,定期跑。
我自己把 lab 的驗收條目寫成一支腳本(37 個檢查點), 第一次跑就發現 5 個「失敗」——其中 4 個是腳本自己的 bug。 這件事本身很有教育意義:檢查工具也需要被檢查。
怎麼確認你的清單是好的
| 檢查 | 判準 | |
|---|---|---|
| 1 | 每條有四個欄位 | 尤其是「預期什麼」 |
| 2 | 每條會擋下壞環境 | 步驟二那個問題 |
| 3 | 第 6 層(護欄)至少三條 | 有反向測試 |
| 4 | 標明執行身分與環境 | |
| 5 | ⭐ 找人照著做一次 | 見下 |
第 5 項:把清單交給一個沒參與建置的人,請他照著執行。
他卡住的地方就是你寫得不夠清楚的地方, 而那些地方在稽核或交接時會變成問題。
常見問題
Q:要寫幾條? A:不是數量問題。第 4 到第 6 層有沒有東西,比總數重要。 三十條全是第 2 層「有沒有安裝」的清單,價值等於零。
Q:廠商給的驗收清單可以直接用嗎? A:可以當起點,但要自己加護欄那一層。 廠商的清單會證明他們交付了什麼, 不會證明這套東西擋得住什麼——那不是他們的責任。
Q:驗收沒過怎麼辦? A:先分清楚是設定問題還是能力問題。 設定問題可以修,能力問題(平台就是做不到)要寫進報告, 而且要寫清楚「所以我們還缺什麼」。
Q:這份清單交給誰? A:至少三個讀者:主管(能不能上線)、 稽核(有沒有證據)、接手的人(怎麼重做一次)。 第三個最常被忘記,但它決定了這份文件半年後還有沒有用。
你們的 PoC 驗收清單有幾條?其中幾條是「有沒有」以外的?
🧪 這篇的實驗環境與 lab 檔案(最後更新 2026-08-30)
本篇在 ODH 3.6.0-ea.1 上對帳(共用區塊寫的 3.5.0 是 Day 1–9 的版本)。
叢集
- CRC 2.63.0 · OpenShift 4.22.7 · Kubernetes v1.35.6
- 單節點:13 vCPU / 40 GiB RAM / 120 GB disk
- 宿主:Framework Laptop 16(Ryzen AI 7 350 · 8C/16T · 64 GB RAM · 1 TB NVMe · RTX 5070 顯卡模組)
- ⚠️ 叢集內看不到 GPU(CRC 是 VM,RTX 5070 未 passthrough)
Operator
opendatahub-operator.v3.5.0← 即 RHOAI 3.x 的上游開源版cert-manager-operator.v1.20.0(3.x 的必要相依;2.x 不需要)openshift-pipelines-operator-rh.v1.23.2、openshift-gitops-operator.v1.21.3
DataScienceCluster 開啟的元件
kserve、aipipelines、dashboard、workbenches、modelregistry、kueue(Unmanaged)- 其餘(
ray/trustyai/feast/aigateway…)為Removed
叢集外的依賴(跑在宿主的 podman 上,crc start 不會帶起來)
- Harbor v2.15.2(私有 registry)· MinIO(S3)
模型端
- Python 3.12.13 · PyTorch 2.11.0+cu128 · FastAPI + uvicorn · prometheus-client
lab 檔案
- YAML/Containerfile/腳本:github.com/ryanGTR/openshift-ai-30days
(含 Day 對照表;主機名是佔位符,跑
set-lab-host.sh換成你自己的) - 服務的那個模型:llm-from-scratch(從零手刻的小 GPT)
⚠️ ODH ≠ RHOAI:元件同源,但 namespace 與部分名稱不同
(我這裡是 opendatahub,商用版是 redhat-ods-* 那一套)。
指令的邏輯可以照用,字串要自己對一次。
留言與指正
我特別想知道:你們的 PoC 驗收清單有幾條?其中幾條是「有沒有」以外的?