数据截至 (上游 commit 8ef9de35c36a)
两块积木 — 漏洞分类法 与 攻击算子
评测的两个正交维度:漏洞(Vulnerability)= 测什么风险,攻击(Attack)= 用什么手法变形提示词。任意漏洞 × 任意攻击都能组合。本章讲清这两套目录长什么样、怎么扩展。
1. 漏洞:测什么风险
1.1 分类法两层结构
漏洞分两层:细粒度类型(VulnerabilityType) 聚合成 风险域(LLMRiskCategories)。风险域只有 5 个(deepteam/risks/risks.py:25):
| 风险域 | 含义 | 包含的漏洞大类(举例) |
|---|---|---|
| Responsible AI | 负责任 AI | 偏见 Bias、毒性 Toxicity |
| Illegal | 违法 | 违法活动、图文暴力、人身安全 |
| Brand Image | 品牌形象 | 错误信息、越界代理、抢话、知识产权、竞品 |
| Data Privacy | 数据隐私 | 系统提示词泄露、PII 泄露 |
| Unauthorized Access | 越权访问 | RBAC、SQL/Shell 注入、SSRF、BOLA、BFLA、调试接口 |
映射关系是一张大字典 getRiskCategory(risks.py:33),把每个细粒度类型归到风险域。每个漏洞大类(如 BiasType)内部还有更细的枚举(性别偏见、种族偏见……),定义在 deepteam/vulnerabilities/<类别>/types.py。
1.2 一个漏洞类要提 供什么
所有漏洞继承 BaseVulnerability,对外暴露两件事:get_types()(它含哪些细粒度类型)和 get_name()。在合成阶段,框架对每个类型让模拟器模型生成种子提示词(见第 1 章 §2.1)。
1.3 两种「不靠模型现编」的特殊漏洞
这是平台最常用的两条路径,务必分清:
CustomPrompt——用户直接给一句提示词(命令行Custom:prompt=...)。基线就是这句话本身,不调模拟器。MultiDatasetVulnerability——从数据集文件批量读提示词当基线。配套的PromptLoader(deepteam/vulnerabilities/multi_dataset/multi_dataset.py:34)支持 json/jsonl/csv/tsv/parquet/xlsx/txt 七种格式,还会 自动探测哪一列是 prompt(候选列名prompt/question/query/text/input/content/instruction/message,见multi_dataset.py:43-46)。
仓库自带 16 个越狱数据集(位于 仓库根 data/eval/*.json,注意不在 AIG-PromptSecurity/ 子项目内),如 advbench.json、JADE-db-v3.0.json、CBRN-weapon.json、copyright-violation.json 等,覆盖暴力、隐私、版权、网络攻击等主题。数据集模式下,「测什么」直接来自这些真实样本,而非模型臆想。
2. 攻击:怎么把提示词变形
2.1 攻击算子的统一契约
所有攻击继承 BaseAttack(deepteam/attacks/base_attack.py:21),契约极简:
# 真实定义,base_attack.py:21
class BaseAttack(ABC):
weight: int = 1
@abstractmethod
def enhance(self, attack: str, *args, **kwargs) -> str: ...
async def a_enhance(self, attack, *args, **kwargs): return self.enhance(...)
def get_name(self): return type(self).__name__
一个算子 = 一个 enhance(提示词) -> 变形后提示词。weight 用于 random 策略的加权抽样。就这么简单——所以算子数量能堆到上百个。
2.2 两大族算子
按 enhance 需要的「材料」,算子天然分两族:
算子
┌─────┴─────────────────┐
│ │
确定性变换 LLM 驱动
(单回合,纯函数) (要模拟器模型/打目标模型)
───────────── ──────────────
· 编码族 73 种 · 角色扮演 Roleplay
Base64/Hex/Morse/ · 多轮越狱(5 种)
Braille/Emoji/盲文… Linear/Crescendo/Tree/
· 大小写/反转/泄元音 BadLikertJudge/SequentialBreak
· 行为控制族 27 种 · 系统覆盖/目标重定向(部分)
单回合(single_turn)算子有 111 个类,多回合(multi_turn)有 6 个类(按 class ...(BaseAttack) 计数)。utils/strategy_map.json 把它们组织成两大策略给前端选:Encoding(73 个方法)和 BehavioralControl(27 个方法)。
2.3 确定性算子示例:Base 编码
最纯的一族,纯字符串变换、不需要任何模型。BaseEncoding(deepteam/attacks/single_turn/encoding/base_encoding.py:24)一个类支持 base32/45/58/62/64/64url 六种,random 时随机挑一种:
# 真实逻辑,base_encoding.py:97 的 enhance,这里精简示意
def enhance(self, attack):
t = self.encoding_type if self.encoding_type != "random" else random_pick()
if t == "base64":
return base64.b64encode(attack.encode()).decode()
# base32/base45/base58/base62/base64url 各有分支
直觉:把「教我做炸弹」编成一串 Base64,模型若先解码再执行,就暴露了「会照做被编码的有害指令」。编码族下还有几十种猎奇变体——盲文、Emoji、克林贡语、楔形文字、Zalgo 乱码等(看 encoding/ 目录文件名),本质都是「换一种表示法绕过表层关键词过滤」。
2.4 LLM 驱动算子示例:线性越狱(多轮)
另一族要真正「和模型互动」。LinearJailbreaking(deepteam/attacks/multi_turn/linear_jailbreaking/linear_jailbreaking.py:43)是典型:它在 enhance 内部跑一个 最多 5 轮的迭代循环,每轮做 5 件事:
每一轮(最多 turns=5 轮):
1. 模拟器:基于历史改进出一版更狠的攻击提示词
2. 模拟器:判断这版是不是「拒答声明」→ 是则提前停
3. 模拟器:判断这版是否仍切题(on-topic)
4. 目标模型:用这版攻击打一次,拿回复 ← 唯一碰目标模型的地方
5. 模拟器:给「攻击+回复」打 1~10 分;≥10 提前停
把(回复, 分数)写回历史,进入下一轮
注意它 同时用 到模拟器模型和目标模型——所以它的 enhance 签名带 model_callback 和 simulator_model,正好被第 1 章 §2.2 的签名探测逻辑识别。真实循环见 linear_jailbreaking.py:73-148(同步)与 :171-246(异步)。它甚至有个小细节:若回复含特定「敷衍套话」(penalized_phrases)就扣 3 分(linear_jailbreaking.py:130-131),防止被空话骗过。
这族还有树状搜索(tree_jailbreaking)、渐进升级(crescendo_jailbreaking)、坏李克特评委(bad_likert_judge)等,共同点都是:用一个 LLM 当「攻击者」反复试探另一个 LLM。
3. 漏洞 × 攻击 是正交的
关键设计:漏洞和攻击 完全解耦。漏洞负责产出「赤裸的有害问题」,攻击负责「把任意一句话变形」。所以 N 个漏洞 × M 个攻击自由组合。在 RedTeamRunner 里,scenarios 解析成漏洞列表、techniques 解析成攻击列表(cli/red_team_runner.py:69-75、:144),二者在 AttackSimulator 里做笛卡尔式组合。
4. 代码地图
| 主题 | 文件路径 | 关键符号 |
|---|---|---|
| 风险域归类 | deepteam/risks/risks.py | getRiskCategory、LLMRiskCategories |
| 漏洞类型联合 | deepteam/vulnerabilities/types.py | VulnerabilityType |
| 数据集驱动漏洞 | deepteam/vulnerabilities/multi_dataset/multi_dataset.py | PromptLoader、MultiDatasetVulnerability |
| 攻击基类 | deepteam/attacks/base_attack.py | BaseAttack.enhance |
| 编码族算子 | deepteam/attacks/single_turn/encoding/base_encoding.py | BaseEncoding.enhance |
| 多轮越狱算子 | deepteam/attacks/multi_turn/linear_jailbreaking/linear_jailbreaking.py | LinearJailbreaking.a_enhance |
| 算子目录(给前端) | utils/strategy_map.json | configSchema.strategies |