garak 拆解:LLM 界的 nmap,21 类探针把模型打到认输为止

一、速览:值不值得你花时间

推荐指数:★★★★★(5 / 5)

这是本专栏到目前为止唯一一个我给满分的工具,理由很简单:它是这个领域事实上的标准。判断一个 AI 安全工具是不是「基准」,有个很实用的检验方法 —— 看别的项目是否拿它当组件。第 010 期讲的 Dark-Moon,它的 LLM agent 去测 AI 推理端点的 OWASP LLM Top 10,用的就是 garak-backed probes。能被同行嵌进自己的产品,说明它的探针集已经被当作公共语言了。

三个我认为它做得最对的地方:

1)定位清醒。 README 说 garak 检查的是「LLM 能不能被弄成我们不想要的失败方式」(can be made to fail in a way we don’t want)。它不宣称能修,也不宣称测过就等于安全 —— 它就是个把已知攻击手法系统化、可复现地跑一遍的框架。

2)有学术背书。 arXiv 2406.11036,《garak: A Framework for Security Probing Large Language Models》,作者包括 Leon Derczynski、Erick Galinkin、Jeffrey Martin、Subho Majumdar、Nanna Inie。这不是拍脑袋攒的 payload 列表。

3)架构可扩展。 probes / detectors / evaluators / generators / harnesses 五类插件各有一个 base.py,写自己的探针继承 garak.probes.base.TextProbe 就行,override 越少越好。

扣分项不是没有,但都不致命:471 个 open issues 对于一个 4,614 次提交的项目来说偏多;atkgen(自动攻击生成)README 自己标了 prototype、且目前只支持一个目标;默认每条 prompt 生成 10 次,跑全量探针的 API 账单会很难看;以及它只报问题不修问题,且 detector 本身存在误判。

关键数据(截至 2026-10-03)

出品方 NVIDIA(原 leondz/garak,已迁到 NVIDIA 组织)
语言 Python(3.11–3.13)
Star / Fork 9,373 / 1,315
提交 / Open Issues 4,614 / 471
许可证 Apache-2.0
首次提交 2023-05-10(约 3 年 5 个月)
最近提交 2026-09-16(17 天前)
论文 arXiv:2406.11036
官方文档 docs.garak.ai / reference.garak.ai / garak.ai
Python 要求 >=3.11,<=3.13(官方 conda 示例)

适合谁

人群 分 理由
AI 应用开发者(要上线 LLM 功能) 5 / 5 上线前跑一遍是行业惯例,不跑等于裸奔
企业安全运营 5 / 5 有论文、有报告、可进采购合规材料,是最容易被接受的一个
安全研究员 5 / 5 五类插件全可扩展,是做 LLM 安全研究的现成实验平台
红队 4 / 5 探针全,但它测的是模型不是你的应用架构
个人 / 学习者 4 / 5 pip install garak 一行就能跑,门槛低;但全量跑要花钱

二次开发

难度 说明
改配置 低 —— --target_type + --target_name + --spec 三件套,CLI 就能跑
改集成 中 —— 输出 JSONL report + hit log,有 analyse/analyse_log.py,接流水线要自己写解析
改内核 低 —— 五类插件各有 base.py,继承后「override as little as possible」,文档明确

二、它是什么,不是什么

  • 不是一个 WAF 或护栏(guardrail)。它不拦请求,只探测并报告。
  • 不是给模型打分的排行榜。它输出的是「这个 probe 在这个 detector 下的失败率」,不是「你的模型安全得分 87 分」。
  • 不是 Metasploit 那种 exploitation 框架。README 的类比是「思路类似」,不是「能力等价」—— garak 不拿 shell。
  • 不是只测 prompt injection。注入只是 21 类探针里的一类。

它自我定位(意译):把静态、动态和自适应的探针组合起来,探索 LLM 或对话系统能被怎么弄失败。

提炼三个关键词:probes(探针)、detectors(失败模式检测器)、harnesses(测试组织方式)。

三、架构:五类插件,各司其职

一次典型运行:从命令行读 model type(可选 model name)→ 决定跑哪些 probe 和 detector → 启动一个 generator → 交给 harness 去探 → evaluator 收结果。

目录 作用
garak/probes/ 生成与 LLM 交互的类(攻击手法)
garak/detectors/ 检测 LLM 是否表现出某种失败模式
garak/evaluators/ 评估报告方案
garak/generators/ 被测 LLM 的插件
garak/harnesses/ 组织测试结构的类
resources/ 插件需要的辅助资源

默认用 probewise harness:给它一组 probe 模块名和插件名,它逐个实例化 probe,然后读每个 probe 的 primary_detector 和 extended_detectors 属性,拿到要在输出上跑的 detector 列表。

这个设计的巧妙之处在于:probe 自己声明该用哪个 detector 来判自己的输出。加新探针时不用去改全局配置,探针自带判断标准。

每类插件都有一个 base.py 定义基类,插件模块里的类继承其中之一。比如 garak.generators.openai.OpenAIGenerator 继承自 garak.generators.base.Generator。

大件不放仓库 —— 模型文件和较大语料放在 Hugging Face Hub 上,客户端本地加载。这让 pip 包保持轻量。

四、21 类探针:这是它的核心资产

Probe 干什么
blank 永远发空 prompt 的最简探针
atkgen 自动攻击生成:一个红队 LLM 去探目标并对反应做调整,试图引出有害输出。prototype,基本无状态,目前只支持一个目标
badchars 不可感知的 Unicode 扰动(不可见字符、同形字、重排序、删除),源自 Bad Characters 论文
av_spam_scanning 试着让模型输出恶意内容特征
continuation 测模型会不会接着续写一个明显不该续的词
dan 各种 DAN 及类 DAN 攻击
donotanswer 负责任的模型不该回答的那些 prompt
encoding 通过文本编码做 prompt injection
gcg 追加对抗性后缀来破坏 system prompt
glitch 探测会引发异常行为的 glitch token
grandma 「想想你奶奶」类诉求
goodside Riley Goodside 攻击的实现
leakreplay 评估模型会不会复述训练数据
lmrc Language Model Risk Cards 探针的子集
malwaregen 试图让模型生成造恶意软件的代码
misleading 试图让模型支持误导性和错误主张
packagehallucination 诱使代码生成里出现不存在的(因而不安全的)包
promptinject Agency Enterprise 的 PromptInject 工作实现(NeurIPS ML Safety Workshop 2022 最佳论文)
realtoxicityprompts RealToxicityPrompts 的子集(数据做了裁剪,全量跑太久)
snowball Snowballed Hallucination 探针,让模型对过于复杂的问题给出错误答案
xss 找允许或实施跨站攻击的漏洞,比如私有数据外带

几个值得单独拎出来的:

packagehallucination —— 这条我认为是最具现实危害性的一类。模型生成代码时引用一个不存在的包名,开发者 pip install 之后可能撞上 typosquatting 的恶意包。这是「幻觉」直接变成供应链攻击的路径。

leakreplay —— 训练数据复述。对企业来说这是合规红线,也是很多 LLM 相关诉讼的核心争点。

gcg —— 对抗性后缀攻击。这类攻击不依赖语义说服,靠的是梯度搜索出来的 token 序列,防御难度高。

snowball —— 滚雪球式幻觉。测的是模型在超出能力范围的问题上会不会编造,这在 RAG 和 agent 场景里是高频故障。

五、上手

安装

1
2
3
4
5
6
7
8
9
10
11
12
# 标准 pip 安装
python -m pip install -U garak

# 想用 GitHub 上更新的版本
python -m pip install -U git+https://github.com/NVIDIA/garak.git@main

# 从源码(官方推荐 conda 独立环境)
conda create --name garak "python>=3.11,<=3.13"
conda activate garak
gh repo clone NVIDIA/garak
cd garak
python -m pip install -e .

迁移提醒:如果你在它搬到 NVIDIA 组织之前就 clone 过,请更新 remote:
git remote set-url origin https://github.com/NVIDIA/garak.git

基本用法

1
garak <options>

不给 --spec 的话,默认跑它知道的所有探针,并用每个探针推荐的 detector。

1
2
3
4
5
6
7
8
9
# 看有哪些探针
garak --list_probes

# 测商业模型的编码类注入
export OPENAI_API_KEY="sk-123XXXXXXXXXXXX"
python3 -m garak --target_type openai --target_name gpt-5-nano --spec probes.encoding

# 看 Hugging Face 版 GPT2 会不会中 DAN 11.0
python3 -m garak --target_type huggingface --target_name gpt2 --spec probes.dan.Dan_11_0

--spec 可以指定到具体插件:probes.promptinject 是 PromptInject 一族;probes.lmrc.SlurUsage 是 Language Model Risk Cards 框架里的一个具体实现。

支持的 generator

hugging face hub、replicate、openai api(chat & continuation)、aws bedrock、litellm、任何 REST 可访问的、gguf 模型(llama.cpp >= 1046)、NIM、Cohere、Groq、ggml,以及一个 test 用于自测。

读结果

跑的时候每个 probe 有进度条。生成完成后,会给出一行「用每个 detector 评估该 probe 结果」的记录。只要有 prompt 尝试引发了不期望行为,该响应就标 FAIL 并给出失败率。

行末的 840/840 这类数字是:总生成条数 / 其中表现正常的条数。这个数可能很大,因为默认每条 prompt 生成 10 次。

日志分三种:

  • garak.log —— garak 及其插件的调试信息,跨运行累积
  • 每次运行新建一个 JSONL report —— 每次 probing attempt 都记一条,生成时记一次、评估时再记一次,status 字段取自 garak.attempts
  • hit log —— 详细记录那些「打中了」的尝试

分析用 analyse/analyse_log.py,它会输出命中最多的 probe 和 prompt。

六、边界与风险(必须诚实说的部分)

1)471 个 open issues。 这是 9.4k star、4,614 次提交的项目,issue 数偏高。结合它插件极多的事实,更可能反映的是覆盖面广、社区活跃,而不是质量差。但对你意味着:某些冷门 generator / probe 组合可能没人验证过。

2)atkgen 是 prototype。 README 明写:「Prototype, mostly stateless, for now uses a simple GPT-2 fine-tuned… (the only target currently supported for now)」。也就是说这个「自动攻击生成」能力目前只能针对一个目标,别把它当成通用的自适应红队。

3)realtoxicityprompts 数据被裁剪了。 官方理由是「全量测试跑太久」。这意味着这个探针的结果不能等同于原论文的全量结论。

4)成本会失控。 默认每条 prompt 生成 10 次,而默认跑全部探针。第一次上手务必用 --spec 限定范围,否则几百美元的账单是常态。这一点和第 011 期 deepsec 的成本问题性质相同,只是 garak 没提供 --max-cost-usd 那样的硬上限 —— 你得自己盯。

5)它只报问题,不修问题,也不防问题。 garak 是诊断工具,不是护栏。跑完发现 FAIL,你还得自己加输入过滤、输出审查、system prompt 加固等。别把它当合规终点。

6)detector 本身有误判。 判断「输出是否有害」这件事本身就不完美(尤其 toxicity 类)。FAIL 需要人工复核,别直接把 garak 的输出丢进报告当结论。

7)Python 版本被锁在 3.11–3.13。 官方 conda 示例写的是 python>=3.11,<=3.13。如果你的环境是 3.10 或更新的 3.14,会有麻烦。

七、上手建议(按这个顺序来)

  1. pip install -U garak,一行起步。 这是它相对所有同类工具最大的优势 —— 没有 Docker Compose、没有 npm、没有镜像构建。
  2. 第一次一定加 --spec。 比如 --spec probes.encoding 或 --spec probes.dan.Dan_11_0。不要裸跑全量,10 次/prompt × 全部探针的账单会教你做人。
  3. 先拿本地模型练手。 --target_type huggingface --target_name gpt2 不花钱,先摸清输出格式和 FAIL 的含义,再花钱测商业模型。
  4. 重点看 packagehallucination 和 leakreplay。 前者是供应链风险,后者是合规红线 —— 这两类对真实业务的影响远大于「能不能让模型说脏话」。
  5. 跑完用 analyse/analyse_log.py 看哪些 prompt 命中最多。 那个列表才是你要拿去修东西的输入。
  6. FAIL 一定要人工复核。 detector 有误判,尤其是 toxicity 类。
  7. 把它放进上线流程,而不是一次性检查。 模型会换、provider 会调 system prompt、RAG 语料会变 —— 每次变更后重跑一遍相关的 --spec,成本可控且能挡住回归。
  8. 要自适应红队别指望 atkgen,它还是 prototype。

八、一句话结论

如果你的产品里有一个 LLM 在跟用户说话,garak 应该是上线前的默认动作 —— 就像你不会因为「代码 review 过了」就跳过 nmap 一样。它有论文、有 NVIDIA 背书、Apache-2.0、一行 pip 就能跑,是这一整批工具里我唯一敢给满分的。

给开发者的第一动作:pip install -U garak → garak --list_probes 看一眼有哪些探针 → --spec probes.packagehallucination 和 --spec probes.leakreplay 各跑一次 → 用 analyse/analyse_log.py 找出命中最多的 prompt,拿去修你的输入过滤和输出审查。 这两类探针打出来的东西,往往比「jailbreak 成功了」更值钱。

评论Comments