VacantAI 的可究責層GitHub

 · 方法

我們量錯過的六件事

讀錯一個欄位、網路斷線被算成評審結果、退化成極限的 rng 種子、把 `defected <= BUDGET` 當成等預算、端點上的漂亮數字、以及預設關掉的規則——六個真實的量測陷阱與它們的教訓。

量測陷阱統計自我更正

這一篇把專題裡所有量錯過的事情集中起來。每一件都是真實發生過的,每一件都差點變成一個假的正面或負面結論。

#一、讀錯欄位,造出一個假結果

E10 真模型實驗的第一次分析:

讀 audit.passed用臂外判定
off 臂0 / 117 / 12
on 臂5 / 105 / 10
差異顯著(on 遠勝)消失

正確做法:品質判定必須與臂無關——用臂外的 compile_check(t.check)(answer) 獨立判定。

這條保留在 examples/realmodel_suite.py 的註解裡當作經典陷阱。}}

#二、網路斷線被算成「評審通過」

2026-06-30,群體路由複驗。第一輪 a2hard 印出 ✓,但逐呼叫 I/O 稽核抓到:

  • 第 20–23 次呼叫(剛好是 good_1 的 4 個同儕評審)撞上 Connection refused / reset by peer。
  • 回應是空字串,而比對規則是 \bYES\b 的否定式匹配——空字串被算成「不是 YES」,也就是「不通過」。
  • 結果:good_1 的同儕信譽被錯推到 0.50,同儕對真值的命中率從 88% 掉到 75%,抓獲率掉到 71%。

表面上的效應是 −4%。

#三、一個選用參數安靜地移動了所有數字

SimConfig.digest() 同時是兩件事:

  1. RNG 的種子。
  2. 所有欄位的雜湊。

所以開發者「加一個選用參數」之後,E1 到 E16 的每一個數字都變了,而且沒有任何錯誤訊息。

修法:

  • 後來加的欄位,若取預設值則不納入 digest。
  • 三個 config digest 釘死到能逐位元重現 15/15 個計數。

#四、把「不超過預算」當成「等預算」

我們的 E19 想比較「哪種攻擊策略比較省」,於是把總作惡次數設成上限 12:

臂綁住了嗎實際作惡次數
whitewash29 / 3011.97
sybil30 / 306.13
pulse(5,20)1 / 304.30
pulse(3,10)1 / 304.23
patient1 / 303.73

修法:改用 defected == BUDGET,並且事前驗證每一臂都真的被綁住。

在 budget = 1(唯一讓五個臂全部被綁住的點)重跑後,排名反轉:

臂效率對 whitewash
pulse(3,10)0.900+0.367,p = 0.0074
pulse(5,20)0.900+0.367,p = 0.0074
patient0.867+0.333,p = 0.0309
sybil0.5330.000(30 個種子全部相同)
whitewash0.533—

whitewash 是最弱的,不是最強的。}}

完整的規則與限制

#五、在退化端點上量效應

blindspot = 1.0 時,30 個種子塌成同一條軌跡:

標準差0.0
有效 n1(不是 30)

而我們的頭條數字——pulse 21.0、patient 79.0——正是這個端點。排除它之後,盲區效應從 8.9 倍降到 3.28 倍、從 54 倍降到 5.68 倍。

#六、預設值被關掉,而我們以為它是開的

arm_off5 在程式裡寫死 accepted = True——它沒有拒絕這條路。

所以 R437 那個「ON vs OFF5」的三臂比較,實際上是:

一個有免費閘門的臂 vs 一個被禁止拒絕的臂

#七(附帶):被拒絕的規則也算陷阱

E15 選擇性攻擊的第一輪,20 個種子下高價值命中是 0.00——這在數學上不可能,因為基線就是 20%。

根因:任務價值是輪次索引的確定性函數,而見習配額是「每 10 輪一次路由到見習者」,攻擊者的見習期剛好每 10 輪到期。兩者在所有 20 個種子��完全相關。

修成 sha256(seed, round) 之後,以 30 個種子重跑得到 18–20%。

#這七件事的共同點

沒有一次是有人說謊全部是設計或實作的問題
大部分產出的數字看起來正常沒有任何一處會報錯
全部是被逐筆稽核抓出來的印出來 vs 真的跑過,是兩件事

#接下來

相關

閱讀約 6 分鐘

世新大學世新大學資訊傳播學系Vacant

世新大學資訊傳播學系 2026 畢業專題・實體展覽