實作:以 Garak 掃描
入門5 分鐘閱讀更新於 2026-03-13
安裝並對本地模型執行 Garak LLM 漏洞掃描器。學習組態 probe、generator 與 evaluator 以進行完整掃描。
先備知識
- 已完成 環境設置
- 已完成 打造測試 Harness(供比較)
- Ollama 執行中且至少安裝一個模型
- Garak 已安裝(
pip install garak)
背景
Garak(Generative AI Red-teaming and Assessment Kit)是用於自動化 LLM 漏洞掃描之最廣為使用之開源工具。它提供結構化框架,具數百個依漏洞類別組織之預建攻擊 probe。
實作練習
驗證 Garak 安裝
檢查 Garak 已安裝且可存取:
garak --version garak --list_probes | head -20預期輸出:
garak v0.9.x probes: atkgen continuation dan encoding gcg glitch goodside knowledgegraph leakreplay lmrc malwaregen ...若
garak未找到,則安裝之:pip install garak理解 Garak 之架構
執行掃描前,理解四個元件如何互動:
元件 角色 範例 Generator 目標模型之介面 本地模型之 ollamageneratorProbe 攻擊 payload 或測試案例 dan.DAN送 DAN 風格 jailbreakDetector 分析模型回應 檢查是否存在安全拒絕 Evaluator 做通過/失敗決策 判定 probe 是否成功 列出可用元件:
# 列出所有 probe 類別 garak --list_probes # 列出所有可用 generator garak --list_generators # 列出所有 detector garak --list_detectors執行你的第一次掃描
對本地 Ollama 模型執行使用小型 probe 集之基本掃描:
garak --model_type ollama --model_name llama3.2 \ --probes dan.DAN_Jailbreak \ -v此指令:
- 經 Ollama 後端鎖定
llama3.2 - 執行
DAN_Jailbreakprobe(經典 jailbreak 測試) - 使用詳細模式(
-v)以顯示詳細輸出
預期輸出:
garak LLM vulnerability scanner v0.9.x Running probes: dan.DAN_Jailbreak Target: ollama:llama3.2 dan.DAN_Jailbreak: 100%|████████████████| 10/10 Results ┌───────────────────────┬────────┬────────┐ │ Probe │ Passed │ Failed │ ├───────────────────────┼────────┼────────┤ │ dan.DAN_Jailbreak │ 7 │ 3 │ └───────────────────────┴────────┴────────┘ Report saved to: garak_runs/...- 經 Ollama 後端鎖定
執行多類別掃描
執行涵蓋多個漏洞類別之更廣掃描:
garak --model_type ollama --model_name llama3.2 \ --probes dan,encoding,continuation,leakreplay \ -v這測試四個類別:
- dan:DAN 風格 jailbreak 與人格攻擊
- encoding:Base64、ROT13 與其他編碼繞過
- continuation:提示延續攻擊
- leakreplay:系統提示擷取嘗試
掃描可能依你的硬體耗時數分鐘。
解讀掃描結果
Garak 產生 HTML 報告與 JSONL 日誌檔。開啟 HTML 報告:
# 找到最新報告 ls -la garak_runs/ # 於瀏覽器開啟(Linux) xdg-open garak_runs/garak.*.html # 或以程式方式檢查 JSONL 日誌 python3 -c " import json import sys results = [] with open(sys.argv[1]) as f: for line in f: results.append(json.loads(line)) # 依 probe 計數結果 from collections import Counter probes = Counter() for r in results: probe = r.get('probe', 'unknown') status = r.get('status', 'unknown') probes[f'{probe}:{status}'] += 1 for key, count in sorted(probes.items()): print(f'{key}: {count}') " garak_runs/garak.*.jsonl於結果中要尋找之關鍵:
- 依類別之失敗率:哪種漏洞類型之失敗率最高?
- 具體失敗之 probe:哪些確切提示造成模型失敗?
- 一致性:模型於同一 probe 是一致失敗或間歇失敗?
組態客製掃描
建立用於針對性掃描之 Garak 組態檔。存為
garak_config.yaml:# 客製 Garak 掃描組態 plugins: generators: - ollama probes: - dan.DAN_Jailbreak - dan.ChatGPT_Developer_Mode - encoding.InjectBase64 - encoding.InjectROT13 - leakreplay.LiteralSequenceReplay - continuation.ContinueSlur extended: generations: 5 # 每 probe 之嘗試次數 seed: 42 # 供可重現性以你的客製組態執行:
garak --model_type ollama --model_name llama3.2 \ --config garak_config.yaml與人工結果比較
將 Garak 之自動化結果與你人工測試 harness 之發現(於 前一實作 打造)比較:
#!/usr/bin/env python3 """將 Garak 結果與人工測試 harness 結果比較。""" import json import csv import os from collections import defaultdict def load_garak_results(jsonl_path): """自 Garak JSONL 日誌載入結果。""" results = defaultdict(lambda: {"pass": 0, "fail": 0}) with open(jsonl_path) as f: for line in f: data = json.loads(line) probe = data.get("probe", "unknown") if data.get("status") == "pass": results[probe]["pass"] += 1 else: results[probe]["fail"] += 1 return dict(results) def load_harness_results(csv_path): """自人工測試 harness CSV 載入結果。""" results = defaultdict(lambda: {"pass": 0, "fail": 0}) with open(csv_path) as f: reader = csv.DictReader(f) for row in reader: category = row.get("category", "unknown") if row.get("success", "").lower() == "true": results[category]["fail"] += 1 # 攻擊成功 = 防禦失敗 else: results[category]["pass"] += 1 return dict(results) def compare(garak, harness): print(f"\n{'Category':<30} {'Garak ASR':>10} {'Harness ASR':>12}") print("-" * 55) all_categories = set(list(garak.keys()) + list(harness.keys())) for cat in sorted(all_categories): g = garak.get(cat, {"pass": 0, "fail": 0}) h = harness.get(cat, {"pass": 0, "fail": 0}) g_total = g["pass"] + g["fail"] h_total = h["pass"] + h["fail"] g_asr = 100 * g["fail"] / g_total if g_total > 0 else 0 h_asr = 100 * h["fail"] / h_total if h_total > 0 else 0 print(f"{cat:<30} {g_asr:>9.1f}% {h_asr:>11.1f}%") if __name__ == "__main__": # 更新此路徑以匹配你的實際輸出檔 garak_path = "garak_runs/garak.latest.jsonl" harness_path = "results/test_run_latest.csv" if os.path.exists(garak_path) and os.path.exists(harness_path): garak = load_garak_results(garak_path) harness = load_harness_results(harness_path) compare(garak, harness) else: print("Run both Garak and the manual harness first to compare.")
疑難排解
| 問題 | 解方 |
|---|---|
garak: command not found | 確保你的虛擬環境已啟用並執行 pip install garak |
| Ollama 連線被拒 | 以 ollama serve 啟動 Ollama 並驗證其於 port 11434 執行 |
| 掃描卡住或非常慢 | 減少 probe 數或於組態設 generations: 1 |
| JSONL 檔為空 | 檢查 Garak 日誌輸出以找錯誤;確保模型回應中 |
| HTML 報告未產生 | 更新 Garak:pip install --upgrade garak |
相關主題
- 打造測試 Harness - 你打造之客製 harness——遵循與 Garak 相同之架構模式
- PyRIT 活動 - Microsoft 之 PyRIT 框架——用於協作編排之紅隊活動
- Promptfoo 迴歸測試 - 另一自動化測試工具,補充 Garak
- 工具景觀 - 所有可用紅隊工具與框架之完整概觀
參考資料
- "Garak: A Framework for LLM Vulnerability Scanning" - NVIDIA/garak(2024)- Garak 掃描器之官方文件與 probe 目錄
- "Red Teaming Language Models to Reduce Harms" - Ganguli et al.(2022)- 系統化漏洞掃描方法論研究
- "OWASP Top 10 for LLM Applications" - OWASP(2025)- Garak probe 設計以測試之漏洞類別
- "Garak GitHub Repository" - NVIDIA(2024)- 擴展 Garak 之原始碼、probe 定義與貢獻指引
Knowledge Check
於 Garak 輸出中,『Passed』意味什麼?
Knowledge Check
Garak 架構之四個模組化元件為何?