有人問你一個問題:你們產品裡總共用了幾個模型,每一個是拿什麼資料訓出來的。

你打開 repo。權重檔躺在那裡,旁邊一個 README 寫了三行;另外兩個模型是從 Hugging Face 拉下來的,各自附一張 model card,格式不一樣,其中一張的訓練資料那欄填的是一個連結,點進去是一篇論文。

三個模型,三種寫法,全部是給人讀的。要回答那個問題,只能一份一份打開來看,然後手寫一份總表。下個月再被問一次,整套重來。

資料其實都在,只是躺在工具讀不懂的地方。你沒辦法在 CI 裡問這個問題,也沒辦法寫一支腳本掃出全公司的模型清單。能做的只有靠人記得,而靠人記得的事,在那個人離職的那天就會斷。

而且這個問題通常由外面的人問出來:客戶的資安問卷、稽核、某個合作方的採購流程。問的人要一份可以歸檔的東西,你手上只有三個風格不一樣的 README。

這就是 AI-BOM 要處理的事。至於你該不該弄一份,答案比「當然要」複雜,而且關鍵完全不在格式好不好。

它沒有另立新格式

先講清楚這東西的實際長相,不然沒辦法談值不值得。

規格本體是 CycloneDX v1.7,由 ECMA-424 第 2 版定義,2025 年 12 月發布。把 1.7 的 JSON Schema 打開,component.type 那個 enum 的全部合法值是這 13 個:

1
2
3
application, framework, library, container, platform, operating-system,
device, device-driver, firmware, file, machine-learning-model, data,
cryptographic-asset

前面十個你大概都認得。AI-BOM 的全部祕密就在後面那兩個:machine-learning-modeldata

模型跟資料集在這套規格眼裡,跟 library、跟 container 是同一個層級的東西。同一張依賴圖、同一組雜湊欄位、同一套授權欄位。沒有新格式、沒有新檔案、沒有另一套工具鏈。

data 成為合法的元件型別這件事尤其關鍵。訓練資料集本身可以在清單上佔一個條目,有自己的雜湊、自己的授權欄位、自己在依賴圖上的位置。「這個模型是拿什麼資料訓的」於是有機會變成圖上的一條邊,不用再寫成 README 裡的一句話。

這件事的份量比聽起來大。評估要不要吃下一個標準,第一個該問的通常是「我現有的東西要改多少」,而這裡的答案是:如果你已經在產 SBOM,多出來的只是幾個元件條目。

標準能不能活下來,採用它的邊際成本往往比設計品質更有決定性。另外開一套 AI 專屬格式,代表每個既有工具都要多支援一種檔案;塞進既有的元件型別清單,代表工具只要多認得兩個字串。這兩條路的採用曲線差很多,而 CycloneDX 選了後者。這個選擇比欄位設計更能決定這東西三年後還在不在。

ECMA-424 的 scope 自己寫得很明白,它管的範圍從頭到尾就不只是 AI:

“describing software and hardware components, services, dependencies, vulnerabilities, and compositions”

“supporting domain-specific modelling for cryptographic artefacts and machine learning models”

模型被塞進一個已經在跑的骨架裡,當作「特定領域的建模」處理。這是它最值得肯定的設計決策,也是它最大的限制來源。

同一份 scope 裡還有一句,我覺得是整段最該畫線的:

“asserting claims, attestations, and supporting evidence for conformance to standards or requirements”

規格自己用的字是 claim,主張。清單上寫的東西,本質是某個人對某件事的主張,外加他願意附上的佐證。它從頭到尾沒宣稱自己是事實。這個定位誠實得可以,但也把責任整包留給了填表的那個人。

七個欄位,把倫理評估變成一格

模型元件底下掛的是 modelCard,頂層五個鍵:bom-refmodelParametersquantitativeAnalysisconsiderationsproperties

modelParameters 裝技術身家,底下是 approachtaskarchitectureFamilymodelArchitecturedatasetsinputsoutputsquantitativeAnalysis 只有兩個,performanceMetricsgraphics。這些都還算預期之內。

真正有意思的是 considerations

欄位 它在問什麼
users 這個模型給誰用
useCases 用在哪
technicalLimitations 有什麼技術限制
performanceTradeoffs 效能上做了什麼取捨
ethicalConsiderations 倫理疑慮
environmentalConsiderations 環境成本
fairnessAssessments 公平性評估

Model Card 本來是論文圈的慣例,一張表加幾段散文,寫得好不好全看作者的自覺。這七個欄位做的事是把它變成 key。機器可以查、可以比對,可以在 CI 裡直接問「這個模型的 technicalLimitations 是不是空的」。把一個靠自覺維持的慣例變成可查詢的資料結構,這是整件事真正的技術意義。

三個候選模型要選一個,欄位化之後你可以把三份 technicalLimitations 併排看,不用開三個分頁讀三篇風格完全不同的散文。再往後一步,模型換版本的時候可以 diff 前後兩份 considerations,看哪一格從有值變成空的。這種操作在自由文字上做不了。

資料那一側也配了一整組定義:componentDatadataGovernancedataGovernanceResponsiblePartydataClassificationdataFlowDirection。中間那個 dataGovernanceResponsibleParty 值得停一下。規格設計者顯然知道「誰負責」這件事需要有個地方寫名字。

這組欄位還透露了另一件事:規格預期的讀者不只是工程師。dataClassificationdataFlowDirection 這種東西,會用到的人是要回答「這批資料能不能出境」「這個模型碰得到哪些個資」的那些人,跟拉模型下來跑的工程師根本不是同一群。清單的閱讀者從一開始就被設定成跨部門,這個前提會影響後面所有的判斷。

誰有誘因把 fairnessAssessments 填對

到這裡為止聽起來都很好。問題從這一段開始。

一份清單的價值不在欄位設計得多完整,在填表的人有沒有理由把它填對。這兩件事在傳統 SBOM 裡本來是綁在一起的:library 那一行版本號填錯,弱點掃描就會漏,漏了會出事,出事會找到人。誘因跟正確性是同一條線上的東西。

fairnessAssessments 不是這樣。填的人通常是把模型推上產線的工程師,讀的人(如果真的有人讀)是法務、稽核、或者三年後接手的另一個工程師。填錯不會有人立刻踩到,填得敷衍也不會有任何一支測試變紅。

結構化本身還帶來一個額外的麻煩。自由書寫的 README 至少誠實,它空白的時候看起來就是空白。而一個結構化欄位只要有值,不管裡面是「我們有評估過公平性」這種廢話,還是真的掛了一份報告連結,在機器眼裡都只是「這個 key 存在」。

人眼掃過去看到有填,也很容易當成有做過。

再往下追一層會更清楚。SBOM 在弱點掃描這件事上之所以能運作,是因為有一條完整的回饋鏈:資料庫裡有 CVE,掃描器比對得到,比對到就擋 build,build 被擋的人會抱怨,抱怨會回頭逼填表的人把版本號寫對。整條鏈上每一環都有人在乎。

ethicalConsiderations 這一側,那條鏈目前是斷的。沒有對應的比對資料庫,沒有自動化的判準可以說「這一格填得不合格」,也沒有任何一個下游環節會因為它填得爛而停下來。

格式那一側該給的都給了,缺的是鏈。

這段是我的推論,規格沒有這樣寫,我手上也沒有資料證明實務上大家填得多敷衍。但誘因結構長成這樣的時候,賭填表品質通常會輸。

倒過來問會快很多:什麼情況下這份清單一定變成廢紙?答案是沒有任何人會因為它填錯而付出代價的時候。這條判準不需要等資料,你現在就可以拿它去量自己的團隊。

反過來說,誘因對得上的欄位就很值得做。modelParameters 那一組裝的是技術事實:架構家族、輸入輸出、用了哪些資料集。這些填錯,下游載模型的人第一時間就會撞到,回饋鏈是通的。同一份 modelCard 裡面,不同欄位的可信度差很多,評估的時候要分開算,不要整份一起當成可信或不可信。

什麼情況下它反而是壞選擇

先講最單純的一種。你的系統裡只有一個模型,而且是呼叫別人家的 API。那份清單上會有一行。維護一份只有一行的 JSON,成本大於資訊量;你真正需要的是把那個 endpoint 跟版本記進部署文件,不用動到標準格式。

接著是機會成本那一題。清單只描述,它不擋任何東西。同樣的工時拿去在部署流程加一道「模型來源不明就不准上」的檢核,會比產出一份沒人開過的檔案有用得多。這兩件事理論上不互斥,實際上團隊一週就那幾個人天。清單這種東西還有個討厭的特性:它會持續吃維護成本。模型換一版、資料集補一批、微調參數動了,清單沒跟著更新就開始失真。而一份失真的清單比沒有清單危險,因為它會讓讀的人以為自己知道現況。沒有清單至少大家還知道自己不知道。

第三種比較隱蔽,是你打算拿它當合規證明。欄位齊全跟評估做過是兩件事。一份填滿的 considerations 只證明有人填了七個欄位,不證明有人真的跑過公平性評估。把描述當成保證,是這整類文件最容易出的事故,而且真的出事的時候,那份文件會變成對你不利的證據。

最危險的是最後一種。模型是你自己微調的,訓練資料從哪來你自己也講不太清楚。這種時候產一份 AI-BOM,等於把「講不清楚」包裝成格式正確、欄位齊全、看起來很專業的東西。那個含糊本來留在 README 裡誰讀都看得出來,現在它躲進一個 schema 認可的欄位裡,反而不容易被抓包。格式正確性跟內容正確性是兩個獨立的軸,而工具只驗得到前者。

這篇沒做到的部分

這篇從頭到尾只做了一件事:把 CycloneDX 1.7 的 JSON Schema 打開,把 component.type 的 enum 跟 modelCard 底下的欄位讀出來。我沒有跑過任何工具產出一份真的 AI-BOM,所以填一份要花多久、工具鏈成不成熟、產出來的檔案實際長什麼樣,我答不出來。上面關於「誘因」的判斷是從規格結構推的,不是從實務樣本推的。

另外那份 OWASP CycloneDX 出的《Authoritative Guide to AI/ML-BOM》,版次是 First Edition (Revision 1)。它的出版日期我查到三個兜不攏的答案,所以這篇一個都不印。數字沒有條件就不該印,這條比湊齊細節重要。

所以到底要不要做

回到最開始那個問題。

建議很直接:如果你手上有兩個以上自己維護或自己微調的模型,而且流程裡已經在產 SBOM,那就加上去。邊際成本接近零,那 13 個型別值本來就在等這兩行。其他情況,先不要。先去回答「誰會讀、誰會因為填錯付出代價」這兩題,答不出來就代表你現在要做的是一份文件,不是治理。

要自己跑一遍這個判斷,順序是這樣:先數你有幾個真的由自己控制的模型;再看現在的流程裡有沒有已經在產 SBOM;然後找出那份清單產出來之後會被誰讀;最後確認填錯的時候,那個讀的人有沒有辦法回頭找到填的人。四題裡有兩題答不出來,這件事就先放著。

會讓我改口的條件也寫清楚。如果出現能從訓練管線自動把 datasetsinputsoutputs 抽出來填進去的工具,填表成本掉到接近零,那「沒人有誘因填」這條就自動失效,因為根本不需要人動手偷懶。有沒有這種工具,我沒查證。同樣地,哪天法規真的要求逐欄位查核、而且填錯有人要具名負責,誘因那一側就補上了,上面「拿它當合規證明」那一條也會跟著翻過來。

一份清單的可信度,不會超過填它的那個人願意承擔的責任。格式再乾淨都一樣。