PIF AI Whitepaper

第 17 章:標示與宣稱合規引擎

PIF 十六項回答的是「這個產品的資料齊不齊」,本章回答的是另一個問題:「這個產品印在盒子上的那些字,合不合法」。這兩件事在台灣分屬兩套法源——§7 法定標示要素與 §10 宣傳廣告認定準則——而後者的罰則上限是前者的五倍。本章記錄從一張外包裝照片到一份可具結的法規判定之間,我們建了什麼、以及六個真的踩過的假陰性。

📌 本章重點

17.1 為什麼標示與宣稱要獨立於十六項

PIF 十六項的驗收標準是齊備性:配方表有沒有、GMP 證書在不在、安定性試驗做了沒。這是一種文件盤點。

但業者真正會被罰的第一線,常常不是文件缺漏,而是包裝上多寫了一句話。台灣《化粧品衛生安全管理法》把這兩件事分開規範:

  §7 法定標示要素 §10 宣傳廣告認定準則
問題 該印的有沒有印 印的能不能這樣講
依據 衛授食字第 1081603869 號 L0030099 認定準則 + 四份附件
罰則 NT$1 萬–100 萬 虛偽誇大 NT$4 萬–20 萬;涉醫療效能 NT$60 萬–500 萬,得廢止登記
判定 欄位存在性 詞句比對 + 佐證條件 + 成分連動

第二欄的罰則是第一欄的五倍上限,而且判定複雜得多——它不是「有沒有」,而是「這個詞在這個語境下算不算」。認定準則第 2 條明訂應依整體表現綜合判斷,所以任何自動化判定都只能是輔助,最終認定權在主管機關。這個邊界決定了本章所有設計。

17.2 標籤影像 → 結構化欄位

入口是一張外包裝照片或 PDF。app/services/label_parser.py 用 Claude Vision 搭配 tool use 強制結構化輸出——與第 7 章的配方擷取同一個範式:LLM 負責看圖與對齊,不負責下結論。

單次呼叫抽出三組資料:

  1. §7 法定標示要素——品名(中/英)、用途、使用方法、保存方法、淨重容量、注意事項、製造/輸入業者三聯(名稱/地址/電話)、原產地、製造日期、有效期間、批號、許可證字號,共 21 個欄位,附 confidencemissing_elements
  2. 全成分陣列——依法必列,且必須保持標籤上的原始排列順序。順序本身有法規意義(應由高濃度往低排,≤1% 與彩粧色素除外),重排會讓後續的標示順序檢核失去依據。
  3. 宣稱與圖示——detected_claims 詞句陣列、SPF/PA 數值、警語句、以及 certification_marks(驗證標章,含純圖案無文字者如 USDA Organic / ECOCERT / COSMOS,以 text_visible: false 標記)。

17.2.1 一個類別型陷阱:tool schema 與回應模型必須對齊

certification_marks 一直寫在 tool schema 裡,description 明列那些純圖案標章,模型也照回——但 Pydantic 的 LabelDetectedSymbols 沒有這個欄位,於是驗證時靜默丟棄。結果是:我們付費請 AI 辨識了標章,拿到結果,然後扔掉,而且沒有任何錯誤訊息。下游的標章比對器因此從來收不到東西。

這不是單一 bug 而是一類 bug——凡是 tool schema 要了、回應模型沒接的欄位,都會靜默消失。修補之外我們加了欄位對齊測試,把 tool schema 的頂層 properties 與 Pydantic 模型欄位做集合比對。這類「多花 token 換來的東西被丟掉」的失效沒有任何外顯症狀,只能靠結構性檢查發現。

17.3 L0030099 語料:262 條官方詞句

判定的基準不是 LLM 的法規記憶,而是一份從官方 PDF 逐條抽取的結構化語料 l0030099_claims.json:

附件 內容 結構 詞句數
附件一 虛偽誇大例示 平列 34
附件二 得宣稱之詞句 15 個類別 184
附件三 特定成分連動宣稱 8 個群組 24
附件四 涉及醫療效能例示 平列 20
    合計 262

每條詞句攜帶:所屬附件、依據條號、罰則級距、佐證註記(*1*5)。其中 *2 特別值得注意——它直接指向《化粧品產品資訊檔案管理辦法》,也就是宣稱的佐證義務會回頭要求 PIF 本身完整,兩套制度在此交會。

語料整檔附 content_sha256,判定結果快照會記下當時的 rule_version(pcode、公布日 2019-06-04、施行日 2019-07-01、內容雜湊)。這讓每一次判定都能回答「當時依據的是哪一版法規」。

17.3.1 語料抽取的兩個坑

CJK 相容字元:官方 PDF 中夾雜 Unicode CJK Compatibility Ideographs——「亮」U+F977、「復」U+F966、「麗」U+F988 等,共 65 處。這些字視覺上與常用字完全相同,但碼位不同,直接比對會全部落空。處理方式是只正規化 U+F900–FAFF 區段,而不套用 NFKC——後者會連帶改寫官方標點,破壞條文原貌。

跨頁與換行:濃度限值常被換行切斷(如「三氯沙 0.3」與「%」分屬兩行),抽取器需針對這類模式做續行合併,否則限值會遺失而讓該條詞句變成無條件可宣稱。

17.4 五態判定

比對結果不是二元的合規/違規,而是五態:

狀態 意義 依據
red 涉及醫療效能或明確虛偽誇大 附件一 / 附件四
amber 得宣稱,但須提出佐證 附件二 *1*5
pending_data 詞句綁成分濃度,但成分尚未建檔 附件三
green 比中附件二且無附加條件 附件二
gray 本次未比中任何官方詞句

pending_datagray 的存在是刻意的。租戶的實際順序常是「先上傳中文標籤與外觀照片,成分之後才建」——那個時點附件三只能回 pending_data,而不是給一個假的綠燈。同樣地,gray 在介面上必須讀作「本次未比中」而非「合法」:262 條是官方例示,不是窮舉,沒比中完全可能只是換了個說法。

顯示優先序為 red > amber > pending_data > green > gray——任何一句紅燈就整份紅。

17.5 官方源監控與一個指紋陷阱

法規會修訂,語料就會過期。我們對官方法規頁做週期性內容指紋比對,連續兩次一致才視為穩定基準。

第一版直接對整頁 HTML 取雜湊,結果每次抓都不同——該頁是 ASP.NET,__VIEWSTATE 隱藏欄位每次回應都變。這讓「連續兩次一致」的條件永遠不成立,監控看似在跑,實際上對真正的法規修訂完全失明

修法是 stable_rule_signature():只抽取沿革段與條文本體再取雜湊,略過所有動態欄位。這類「監控在跑但恆為假」的失效模式,與 §17.2.1 的靜默丟棄同屬一類——沒有錯誤訊息的失效,只能靠對機制本身的懷疑找出來。

17.6 只提示不阻擋:責任如何轉移

引擎輸出一律帶 advisory_only: true,不阻擋任何儲存或產出流程。這是使用者定錨的產品決策:平台提示、業者決定、後果自負

但「提示過」需要證據。租戶對一份判定按下「我已知悉暫不修改」時,系統寫入一筆具結:時間、對象、當時看到的完整明細、以及當時依據的法規版本。這裡有一個刻意的設計——具結時不重跑檢核。重跑可能得出不同結果(例如期間成分建檔了,pending_data 變成 red),那就不再是租戶當下確認過的那一份。要存的是他看到的東西,不是現在的真相。

17.7 六個假陰性

以下每一個都曾讓引擎對實際違規的標籤回綠燈。假陰性比誤報危險得多——誤報只是打擾,假陰性是讓業者帶著違規上市。

# 陷阱 後果
1 頓號分隔的複合詞句未拆(「消炎、抗菌」視為單一字串) 只寫其中一項時比不中
2 ○○ 佔位符未轉為萬用比對 官方以 ○○ 表示可替換部位,原樣比對永不命中
3 CJK 相容字元(§17.3.1) 視覺相同、碼位不同,整條落空
4 濃度限值被換行切斷 有條件宣稱誤判為無條件可用
5 純圖案標章未送達比對器(§17.2.1) 包裝貼滿有機標章卻完全不提醒
6 pending_data 未進提示橫幅 待驗證的項目在介面上等同消失

第 5 項的成因值得再說一次:它不是「沒做這個功能」,而是功能做了、AI 也辨識了,結果在型別層被丟掉。做了但沒接上,與沒做的外顯行為完全相同,而前者更難發現,因為程式碼裡看得到它。

17.8 觀察與限制

標示與宣稱引擎的設計核心,與本書其他章節一致:把法規變成可比對的結構化資料,讓 LLM 做它擅長的對齊與擷取,把結論留給規則與人。差別在於這一層的錯誤方向極不對稱——寧可多提示一次,不可漏掉一句涉醫療效能的宣稱。

📚 參考資料

📝 修訂記錄

版本 日期 摘要
v0.4 2026-08-24 首次撰寫。涵蓋 §7/§10 雙法源分工、Claude Vision 標籤擷取(21 欄位 + 全成分 + 驗證標章)、tool schema 與回應模型對齊的類別型陷阱、L0030099 262 條語料建置(CJK 相容字元/跨行限值)、五態判定、官方源 VIEWSTATE 指紋陷阱、具結歷程、六個假陰性。

© 2026 Baiyuan Tech. Licensed under CC BY-NC 4.0.

導覽 ← 第 16 章:自駕進化與計算基準文獻化 · 附錄 A:縮寫與術語 →