這篇寫給想建立垃圾內容偵測系統的工程團隊。它整理 Matters 在模型選擇、資料回收、錯誤放大與校正流程上的經驗。本文不介紹完整架構,重點放在一個中小型平台如何在有限資源下,把模型錯誤控制在可逆範圍內。
Matters 是一個 2018 年起於香港、文章寫入 IPFS 的中文書寫社群。它的偵測工程有一個始終不變的約束,這個約束決定了後面每一個技術選擇的方向。寧可漏看一篇垃圾,也不要錯刪一篇正當發言。日常內容裡有七到八成是垃圾,卻只有大約 1% 是受保護的公民與政治書寫,因此誤判正常內容的代價更高。這個原則不只是價值表述,也會影響模型調整方式,讓系統寧可放過部分垃圾,也不要把正常內容擋下來。本篇依序說明模型怎麼選、資料怎麼累積、錯誤怎麼放大,以及團隊如何校正。材料來自團隊自述與兩個公開程式碼庫,凡屬站方自評而未經第三方獨立驗證的數字,文中都會明白標示。
先界定任務,再選擇理解型模型
內容過濾不是一開始就靠語言模型。早期反濫用分成兩條路。行為層靠 真人驗證(reCAPTCHA/Turnstile) 註冊或登入時用來分辨「你是真人還是機器人」的小測驗或背景檢查。 把關,先是 Google reCAPTCHA,後來換成 Cloudflare Turnstile,放在註冊、登入與文章讚賞三處,從源頭擋掉大量機器帳號。內容層則一度只能靠關鍵字過濾。問題是關鍵字規則看不懂上下文內容過濾機制(工程端)若只透過傳統關鍵字過濾也無法有效判斷上下文
。機器人發文的字句不斷變化,會把違規訊號藏進看似正常的長文,傳統規則很難攔住。
2024 年 8 月,內容分析模型上線。第一個要決定的是模型類型。這個任務需要讀懂文字語意、判斷字詞之間的關係,因此適合使用 理解語意的模型(Encoder) 專門「讀懂、理解」文字語意的 AI 模型,和負責「生成」文字的聊天型模型分工不同;常見的有 BERT 這一類。 (BERT 類模型),而不是主要負責生成文字的 Decoder(GPT 類模型)。除了任務相符,理解型模型通常較小、推論速度較快、硬體門檻較低內容過濾機制(工程端)BERT 模型小需要調整的參數更簡單,推理速度快硬體需求門檻較低,適合 Matters 規模的公司使用
,對一家小公司是比較務實的選擇。
確定使用理解型模型後,團隊把人工標記的樣本拿來測試不同模型,越接近人工判斷的模型越適合內容過濾機制(工程端)評估出來與人工辨識結果越接近的則更適合,目前選擇模型為:ibm-granite/granite-embedding-107m-multilingual
。最後選定 ibm-granite/granite-embedding-107m-multilingual,再用 LoRA 微調(LoRA) 一種低成本的模型微調法:只調整一小部分參數,就能把通用模型訓練成專做某件事。 方法訓練。樣本則來自日常運營。值班人員在後台工具裡一筆一筆標記違規與正常文章,初期累積 4 萬多篇正負樣本內容過濾機制(工程端)初期累計正負樣本總數 4 萬多篇文章
。也就是說,模型所謂的「正確答案」全部來自人的判斷,這一點會影響後續所有訓練結果。
處置原則是不刪除,只降低可見度
談偵測系統之前,必須先說明模型輸出會造成什麼後果,否則就無法評估誤判代價。Matters 在 2024 年中確立的處置原則是,不刪除內容,只降低可見度對抗濫用內容的演算法筆記處置原則為「不刪除內容,只是不再被看見」。高分的可疑文章被排除於推薦、熱門、標籤與頻道等地方,但內容、頁面與既有連結均保留
。被判違規的文章不會被強制隱藏,只是不出現在首頁精選、熱門與各頻道列表;文章本身、頁面與既有連結都還在,用直連網址仍可開啟。
對一個抗審查的中文書寫平台來說,這個設計很重要。它把「抑制垃圾」的後果限制在降低觸及,不走到刪除內容,因此為模型未來可能犯的錯保留了回復空間。政治評論、學術考據等內容被模型誤判,是完全可以預期的風險對抗濫用內容的演算法筆記從而為日後模型的偏差,比如誤判政治、學術內容,這是完全可預期的,保留了可逆性
。工程上先承認這件事,再用架構吸收誤判代價,是這套偵測系統最重要的安全設計。
兩代模型並存,文章與留言分開處理
線上目前是兩代模型並存。一個是較早的開源 BERT 分類器,至今仍在運作;另一個是新的 spam-detection-scaffold,使用 Granite 文字向量模型,加上 LoRA 微調,並在需要時交給 大型語言模型(LLM) 像 ChatGPT、Claude 這類能讀寫、理解語言的大型 AI 模型。 覆核。兩者負責不同場景,新系統沒有直接取代舊系統。對資源有限的團隊來說,這是常見的遷移方式。舊系統如果仍能運作,就先保留;新系統則先放在比較適合的任務上。
留言模型的選擇特別值得注意。留言和長文是兩種任務。留言短、訊號少、歧義高,也常常高度模板化,不容易靠上下文判斷。團隊原本可能以為,較複雜的模型會比較準,結果正好相反。文章使用 Granite 加 LoRA,因為長文訊號較多,適合學習細部特徵;但在留言這種極短文字裡,Granite 加 LoRA 的錯誤率比 e5 高很多對抗濫用內容的演算法筆記實際上在留言這種極短的文字串中,錯誤率比 e5 高很多
。最後留言改用微軟的 multilingual-e5-small,也就是參數量約 0.1B、擅長比較語意相似度的多語小模型。
這些數字必須謹慎判讀。文章模型上線後,攔阻無效文章的成功率從 96% 升到 99.7%內容過濾機制(工程端)從上線開始以來,攔阻無效文章成功率從 96% 逐漸上升至 99.7%
,誤判使用者文章的比例則從 3.1% 降到 0.13%內容過濾機制(工程端)模型原本誤判用戶文章比例從 3.1% 降至 0.13%
;留言小模型那邊,偽陽性僅 0.33%對抗濫用內容的演算法筆記採用了 multilingual-e5-small 模型……比更笨重的模型效果還好,偽陽性僅 0.33%
。對極短、模板化的文字,擅長比較語意相似度的小模型,可能勝過費工微調的較大模型。模型大小不是唯一判準,任務性質才是選擇模型前應先確認的條件。
於是 Matters 同時跑著兩條不對稱的偵測線。可以整理如下。
| 場景 | 模型 | 為什麼 |
|---|---|---|
| 長文 | granite-embedding-107m + LoRA | 訊號較多,需要學習細部特徵,可承受較重的微調 |
| 留言 | multilingual-e5-small(約 0.1B) | 文字極短且常有固定模板,擅長語意比較的小模型錯誤率反而較低(站方自述) |
訓練資料如何被污染
對想複製這套流程的團隊來說,最需要預先處理的是資料污染。過了兩年,團隊本來想換更新的模型(如 Qwen3-Embedding、BGE-M3)重新訓練,後來卻發現原本的模型其實夠用,只需要微調。真正的問題不在模型太舊,而在訓練資料本身被慢慢污染。
污染機制大致如下。一個帳號某天的文章被標記有問題,後來它變正常了,但後續正常文章仍可能被系統識別為有問題,並進入下一輪訓練資料。錯誤被當成事實反覆送回模型,就像把可樂倒進麵團,越揉越分不出可樂在哪裡對抗濫用內容的演算法筆記就像是不小心把可樂倒進去麵團裡一樣,越揉越分不出可樂在哪裡
。結果是政治評論、學術考據、日記、詩這類本該被保護的長文,逐漸被看成垃圾。
「誤判不是被惡意協同攻擊導致的(雖然這個站台確實一天到晚一堆協同攻擊),反而是被錯殺放大導致。」
對一個每天回收新資料、定期重新訓練的系統來說,最大的偏差來源往往是它自己。系統把自己的錯誤輸出當成下一輪訓練標籤,比外部攻擊更難防。任何打算「自動回收垃圾內容、定期重新訓練」的團隊,都要先處理這種回饋污染,否則模型會在沒有外力攻擊的情況下自己偏移。
這次沒有造成更大問題,是因為前面那套處置架構先擋住了後果。被污染的分數只出現在後台,沒有直接進入排序對抗濫用內容的演算法筆記好在基於相對安全的設計,這些分數僅見於後台,並沒有被真正落實在演算法的排序上面
。分數與排序分開處理,在這裡發揮了作用。模型可以先在後台出錯,但錯誤不會立刻影響公共頁面。如果偵測分數直接接到排序,又沒有人工覆核層,這種資料污染就可能變成大規模誤刪。
用低成本校正降低偽陽性
校正資料的成本,比重新訓練大型模型低得多。團隊用 Claude 的批次代理流程搭配 Sonnet 模型,抓出 5,000 筆可疑內容重新校正,成本只花了 1 美元對抗濫用內容的演算法筆記抓出 5,000 筆資料重新校正可疑的內容(成本只花了 1 USD)
。校正後,偽陽性降低 10 倍以上對抗濫用內容的演算法筆記校正完模型之後,偽陽性降低了 10 倍以上,進入可以上線操作的階段
,已經接近可上線使用的狀態(皆為站方自述)。校正過程還辨識出一批需要注意的樣本。許多看似防詐騙科普的文章,其實是貸款公司的宣傳文。
由此團隊歸納出一個成本/成效上的混合部署結論,也是本篇對外部團隊最有參考價值的一點。
「『小模型(0.1B)+ LoRA 微調模型』+『LLM(可能超大幾 T 之類的)校正垃圾文品質』的混搭模式,可能比更新模型的效果還要好,在成本與成效方面。」
這個分工的重點,是不要把所有資源都花在追逐更大、更新的基礎模型。日常評分交給成本較低的小模型,高品質標籤校正與疑難案例覆核才動用大型語言模型。小模型處理大量例行判斷,大型模型處理較難判斷的案例。對預算有限、又需要高品質標籤的團隊,這樣的搭配比一味升級模型更有效。
用棄權機制處理不確定案例
新一代處置不再是「分數過線就判定」。spam-detection-scaffold 的決策規則(policy.py)分成三種結果:分數低於門檻就放行(allow),分數夠高且命中高風險訊號才封鎖(block),介於中間或帶有可疑訊號的內容則交給大型語言模型覆核(review)。高風險訊號來自實務上常見的色情廣告樣態,包括外部連結、刻意變形的聯絡方式(line/telegram/微信/賴)與成人服務關鍵字。
在這之上,部署在無伺服器架構上的服務還加了一層 「不確定就不判」機制(conformal) 讓模型沒把握時不要硬判,改回答「不確定、交給人看」,而不是勉強分類。它用統計上界控制誤擋正常內容的風險,但不是逐案硬保證。 (保形)機制。它輸出的不只是一個分數,而是 decision ∈ {allow, block, review},把「不確定,交給人看」變成系統可以明確回傳的結果,並用統計上界控制合法內容被誤擋的風險。這個上界屬於有限樣本下的期望性保證,不能解讀為逐案硬保證。部署狀態也要寫清楚。舊的測試環境部署文件寫明,conformal 棄權層在 2026 年 6 月 13 日已合併到主線程式碼,並部署到獨立測試環境;後續正式環境部署流程在 2026 年 6 月 16 日以人工確認觸發,成功更新正式環境 CloudFormation 堆疊 article-spam-model-v20251229spam-detection-serverless/STAGING_DEPLOY.md(2026-06-13)+ GitHub Actions run 27609961704(2026-06-16)+正式環境端點煙霧測試(2026-07-07)staging 已部署並可用,CI workflow deploy-staging-conformal.yml 可重複部署;conformal 的『誤殺 ≤ eps』是期望上成立、有限樣本鬆弛,非硬保證;Successfully created/updated stack - article-spam-model-v20251229;正式環境端點回傳 score、decision、reason、p_spam、p_ham
。截至 2026 年 7 月 7 日複核,正式環境端點已回傳 score、decision、reason、p_spam、p_ham。因此,舊稿將正式環境視為尚待驗收的判斷已不準確。較準確的說法是,conformal 棄權層已部署到正式環境,正式服務已能回傳三段式決策;但實際治理效果、人工複查量,以及下游服務如何使用 decision,仍需要後續觀察。
另外一件事也需要中性描述。部署流程是後補的。以映像檔為基礎的 Lambda 必須在有 Docker 的環境才能建置,因此團隊是先有模型,再補上能在持續整合環境執行的部署流程spam-detection-serverless/STAGING_DEPLOY.mdimage-based Lambda 必須在有 Docker 的機器 build(本機 Mac 無,需 CI 或他機)
。這是真實小團隊常見的工程狀態,不是一開始就完成的理想流程。
標籤從哪裡來
這套系統能不能修正自己,最後取決於標籤品質;而標籤品質取決於人是否持續參與。機器人的文章編排與用字會變,所以運營仍要人工辨識漏網違規文,並把它們標成下一輪訓練樣本內容過濾機制(工程端)管理團隊仍會保持人工辨識的工作,當有違規文章出現在公共頁面,則進行標記作為後續再次訓練的樣本
。反過來,使用者若發現自己的文章沒有出現在公共頁面,也可以提出建議,由團隊確認後重新標註。這個回饋會讓模型知道先前判斷錯了。幾輪再訓練後,誤判率才從 3.1% 降到 0.13%內容過濾機制(工程端)經過幾輪再訓練,模型原本誤判用戶文章比例從 3.1% 降至 0.13%
(站方自述)。
留言模型的回饋流程更直接。正樣本來自社群志工累積的真實移除紀錄,負樣本來自正常留言,形成從群眾標註到模型訓練的資料來源。自動處理也有嚴格條件:同一垃圾樣態必須重複出現,或符合 垃圾集團(Ring) 同一個人或團隊操作、用相同版型大量洗版的一群帳號;原始碼裡稱為 Ring。 樣態,或模型分數高到足以判斷。可疑但不確定的留言,一律不自動處理,交給人看。留言防治疊了四層對抗濫用內容的演算法筆記在留言防治措施上,我們上了好幾層保護,包含志願者打掃、模型訓練志願者提供的資料並且自動打掃(Auto)、辨識垃圾集團(Ring)、還有管理員判斷機制,總共四層機制
:志願者打掃、模型自動處理、垃圾集團辨識、管理員判斷。因為垃圾留言侵入性高,設計上比文章更積極。
回收資料重新訓練,是為了對抗會不斷變動的濫用方式。模型訓練好後會固定下來,但對方會調整策略,把關鍵字從標題挪到內文深處,或用人工智慧產生模板變體,讓偵測任務越來越難對抗濫用內容的演算法筆記最近也發現用 AI 將 Ring 產生變異的垃圾內容,實在是道高一尺,魔高一丈,越來越難抓了
。所以「定期回收沒被判出來的垃圾內容,再重新訓練」仍然必要。不過同一個迴圈如果缺乏人工覆核,也會成為資料污染的來源。它既提供模型更新資料,也可能把錯誤重新送回系統。
可複製的實作原則
把這台引擎拆開看,有幾條經驗可以帶走。
- 任務性質比模型大小重要。理解語意的任務適合理解型模型,極短文字可先測試擅長比較語意的小模型,不要預設「更大更新就更好」。
- 處置要可逆。讓偵測後果停在「不被看見」這一步,不要直接走到「被刪除」,模型才有犯錯空間,人也才有救回的餘地。
- 分數與排序要分層。把模型分數隔在後台,不要直接接到排序,資料污染才不會變成上線事故。
- 校正可以交給大型語言模型。成本較低的小模型負責日常大量處理,大型語言模型做標籤校正與疑難案例覆核,才能同時控制成本與品質。
- 未完成的地方要明確標註。棄權機制已部署到正式環境,但實際治理效果、人工複查量與下游服務採用方式仍要持續觀察;部署流程才剛補上,存取權杖輪替仍待辦。這些限制寫清楚,別人才知道哪些部分可以複製,哪些部分仍需要自行補上。