isSuicide(); 開放做法 | Meltfire Monitor
一直以來,大家認識 Meltfire,大多是因為它為 HKSPD 提供自動化的新聞報道監察服務,但對於關心生命安全的人來說,新聞往往是「事後」的統計與記錄,真正的危機、痛苦與微弱的求救訊號,通常在成為新聞之前,早已悄悄浮現在各大討論區、社交平台的貼文與留言區裡。
為了將防線前移,我將 Meltfire 的監察範圍延伸到了社交平台的留言脈絡,然而這帶來了一個極大的工程挑戰,**社群海量的數據噪音,以及龐大的 AI API 運算成本**,如果對每一條留言都直接呼叫頂級 AI 模型(如 Claude Opus 或 GPT-4),不僅 API 費用會瞬間讓專案破產,過多的無效運算也會讓系統變得極度遲鈍,失去即時預警的意義。
因此我開發並驗證了一套**極度輕量、低成本且高準確度**的預警過濾機制 —— **`isSuicide();`**。今天我將這套架構與邏輯完全公開,希望這套「開放做法」能為同樣致力於數位社群防護、心理健康監測或 Civic Tech 的朋友提供一些參考。
---
## 架構思維:兩階段「漏斗式」過濾機制
這套機制的的核心哲學只有八個字:**「層層把關,精準資源」**。
我將整個判定流程拆解為兩個部分:
1. **前端(Google Sheets 邏輯門)**:使用零成本的試算表公式,擋下 95% 以上不符條件的資料。
2. **後端(Google Apps Script 遞進式 AI)**:使用「一票否決制」的三層 AI 模型,從極廉價模型過濾到頂級模型裁決。
```
[ 社群海量留言 ]
│
▼
┌─────────────────────────┐
│ 1. 試算表 7 道規則閘門 │ ──(不符條件/超時/非香港語系/重複)──► [ 直接拋棄 FALSE ]
└────────────┬────────────┘
│ (僅通過檢驗者)
▼
┌─────────────────────────┐
│ 2. Nano 級極輕 AI 模型 │ ──(判定安全)──► [ 終止,回傳 FALSE ]
└────────────┬────────────┘
│ (疑有風險)
▼
┌─────────────────────────┐
│ 3. Haiku 級中階 AI 模型 │ ──(判定安全)──► [ 終止,回傳 FALSE ]
└────────────┬────────────┘
│ (高度疑似)
▼
┌─────────────────────────┐
│ 4. Opus 級頂級 AI 裁決 │ ──(最終確認)──► [ 觸發預警 True ]
└─────────────────────────┘
```
---
## 第一部分:試算表上的 7 道安全閘門(零成本前置過濾)
在資料接觸任何付費 API 之前,我先在 Google Sheets 透過 `LET` 與 `IFS` 建立了 7 道規則防線:
```excel
=LET(
val_I, INDIRECT("I"&ROW()),
val_J, INDIRECT("J"&ROW()),
val_H, INDIRECT("H"&ROW()),
val_G, INDIRECT("G"&ROW()),
val_F, INDIRECT("F"&ROW()),
len_total, LEN(val_I) + LEN(val_J),
is_ignored, COUNTIFS('ignore_author_id'!A:A, val_H) > 0,
is_f_too_much, COUNTIFS('isSuicideLog'!A3:A, val_F) >= 4,
is_recorded, COUNTIFS('actionRecord'!A2:A, val_F) > 0,
IFS(
NOT(ISNUMBER(val_G)), FALSE,
(NOW() - val_G) > 0.5, FALSE,
OR(len_total <= 30, len_total >= 1000), FALSE,
OR(val_J = "", is_ignored, is_f_too_much, is_recorded), FALSE,
OR(val_I = "error", val_J = "error"), FALSE,
REGEXMATCH(val_I & val_J, "[ぁ-んァ-ン]|[个这为么国对们产发拥专关号实则]|[가-힣ㄱ-ㅎㅏ-ㅣ]"), FALSE,
TRUE, isSuicide_ALL(val_I, val_J, 'isSuicide();'!$B$8)
)
)
```
### 設計重點解析:
1. **時效性限制 (`(NOW() - val_G) > 0.5`)**
社群預警的關鍵在於「黃金介入時間」。如果貼文已經發布超過 12 小時(0.5 天),其即時干預的效益會大幅降低,因此系統會主動摒棄舊資料,將運算資源全部留給最新的訊息。
2. **內文長度區間 (`len_total <= 30` 或 `>= 1000`)**
過短的留言(如「加油」、「RIP」、「好難過」)缺乏足夠的情境來判定發言者本身的傾向,容易造成 AI 誤判;而過長的文本(如轉貼新聞、長篇小說或廣告)則極度消耗 AI Token。經實測,30 至 1000 字是精準度最高的黃金區間。
3. **在地語系過濾器 (Regex 正則表達式)**
HKSPD 專注於香港本土的社群狀況。為了避免日文(平假名/片假名)、韓文以及簡體中文用語干擾系統,我在前端直接以正則表達式剔除這些非目標語系的內容,確保資源只投放在香港在地繁體中文的脈絡中。
4. **去重與防護機制 (`is_ignored`, `is_f_too_much`, `is_recorded`)**
透過工作表動態交叉比對,排除黑名單作者、已處理過的案件以及異常重複重複判定的貼文,徹底避免系統進入死循環或重複發出告警。
---
## 第二部分:三層遞進式 AI 漏斗(極致成本與準確度的平衡)
當一條留言穿過了前端的 7 道閘門,它就會進入後端的 Apps Script 進行真正的語意分析:
```javascript
function isSuicide_ALL(title, body, systemPrompt) {
// 第一關:輕量級模型過濾(低成本、極急速)
let isFirstTrue = isSuicide_poe_gpt54nano(title, body, systemPrompt);
if (isFirstTrue !== true) return false;
// 第二關:中階模型確認(語意深度複查)
let isSecondTrue = isSuicide_poe_claudehaiku45(title, body, systemPrompt);
if (isSecondTrue !== true) return false;
// 第三關:旗艦模型最終裁決(高智商終審)
let isThirdTrue = isSuicide_poe_claudeopus48(title, body, systemPrompt);
return isThirdTrue;
}
```
### 為什麼採用「一票否決」的三層架構?
在自殺傾向的判定上,我面臨兩個極端:
* **誤報(False Positive)**:會浪費社群管理員與救援團隊的精力,甚至對發言者造成不必要的打擾。
* **漏報(False Negative)**:錯失救人的機會。
為了同時解決「成本」與「準確度」問題,我採用了**階梯式過濾**:
1. **第一關(極輕量 AI)**:主要充當「粗篩網」。它的任務是迅速排除掉 90% 以上雖然字數符合、但顯然無害的日常對話。這一關的呼叫成本極低、速度極快。
2. **第二關(中階 AI - 如 Claude Haiku)**:當輕量 AI 認為「有疑慮」時,資料會交給對語境與隱喻更敏感的中階模型做第二次審查。
3. **第三關(旗艦 AI - 如 Claude Opus)**:只有前兩關**同時亮起紅燈**的極少數高風險貼文,才會送交頂級的旗艦模型做最終的審慎裁決。
這種設計讓我能以**不到單次全旗艦模型 5% 的營運成本**,達到近乎頂級模型全量審查的精準度與嚴謹度。
---
## 結語:技術是雷達,關懷才是解答
建立 Meltfire 與 HKSPD 的初衷,始終是用數據與技術為社會築起一道防護網。
這套 `isSuicide();` 的架構邏輯並不複雜,也沒有高深莫測的黑科技,它代表的是一種**在有限資源下追求極致實用性**的工程哲學。我選擇將這套做法開放,是希望能鼓勵更多關心數位社會安全的朋友、NGO 或開源社群,以極低的門檻建構出屬於你們的社群預警工具。
程式碼與邏輯是冷冰冰的,但它代表的是我希望及時抓住每一聲微弱呼救的溫度。