跳到主要内容

三阶段流水线 — 合成 / 增强 / 评分 / 汇总

本章讲整条主线怎么转:一批有害问题如何被造出来、如何被变形、如何打目标模型并评分、最后如何汇总。读完你能在脑子里跑一遍完整流程。

1. 先看整条主线(一句话版)

模拟器造一批「赤裸的有害问题」(基线攻击)→ 攻击算子把它们「伪装变形」(增强)→ 逐条打目标模型拿回复 → 裁判模型给每条回复打分 → 按漏洞/手法两维度汇总成防御率。

入口在 RedTeamRunner.run_red_team(cli/red_team_runner.py:41)。它做三件事:① 测三个模型连通性;② 解析 scenarios(漏洞)与 techniques(攻击);③ 调 RedTeamer.red_team 跑评测。真正的两大阶段在 RedTeamer 内部。

2. 阶段一:合成 + 增强攻击(AttackSimulator)

这一阶段把「测哪类风险」变成「一批具体的、已伪装的攻击提示词」。它内部又分两步:先造基线,再增强

2.1 第一步:造基线攻击(baseline)

要解决的小问题: 我说「测违法活动」,但攻击需要的是一句句具体的有害问题。谁来造?

思路:模拟器模型 根据漏洞类型 + 目标用途(purpose)现编。每个漏洞类型默认造 attacks_per_vulnerability_type 条(默认 1)。

真实实现见 AttackSimulator.a_simulate_baseline_attacks(deepteam/attacks/attack_simulator/attack_simulator.py:359):对漏洞的每个子类型,调 a_simulate_local_attack 让模拟器模型按模板吐出 JSON 列表,每条包成一个 SimulatedAttack,此时 original_input == input(还没变形)。

一个例外很重要: 如果漏洞是 CustomPrompt(用户直接给定提示词)或 MultiDatasetVulnerability(从数据集读提示词),就 跳过模拟器,直接用现成的 vulnerability.custom_prompt 当基线(attack_simulator.py:368-369)。这就是平台「自带数据集跑评测」的路径——不让模型现编,而用人工/公开数据集的真实越狱样本。

2.2 第二步:增强攻击(enhance)

要解决的小问题: 赤裸的「教我造毒」几乎一定被拒。要测出真实抗性,得把它伪装成模型不易识别的形态。

思路: 每个攻击算子(BaseAttack)实现一个 enhance(attack) -> str,输入一句提示词、输出变形后的提示词。增强阶段就是把基线逐个过算子。

一个微妙处:不同算子需要的「材料」不同。有的纯字符串变换(Base64),有的要模拟器模型帮忙改写(角色扮演),有的还要能打目标模型(多轮越狱)。所以增强时用 inspect.signature 探测算子 enhance 的参数,按需注入 simulator_model / model_callback:

# 真实逻辑在 a_enhance_attack(attack_simulator.py:532),这里是示意,非源码
sig = inspect.signature(attack.a_enhance)
if "simulator_model" in sig.parameters and "model_callback" in sig.parameters:
new_input = await attack.a_enhance(attack=text, simulator_model=sim, model_callback=cb)
elif "simulator_model" in sig.parameters:
new_input = await attack.a_enhance(attack=text, simulator_model=sim)
elif "model_callback" in sig.parameters:
new_input = await attack.a_enhance(attack=text, model_callback=cb)
else:
new_input = await attack.a_enhance(attack=text) # 纯字符串变换

重点看:同一个增强入口,靠签名探测兼容三类算子——这是后面攻击算子能无限扩展的关键解耦。真实分支见 attack_simulator.py:547-569

一个有用的小标记: 如果增强前后字符串没变(baseline_attack.input == enhanced_attack.input),就标 useless = True(attack_simulator.py:269-270)。汇总时这类既不算通过也不算失败,避免污染防御率。

3. 三种攻击编排策略(choice)

choice 参数决定「一条基线攻击,要被多少个算子怎么处理」。这是个容易忽略但影响很大的开关(attack_simulator.py:236-242):

choice含义效果
random按算子 weight 加权随机抽 1 个每条基线只被 1 个随机算子增强,快但覆盖浅
parallel每个算子各来一遍一条基线裂变成 N 条(N=算子数),覆盖最全、最贵
serial所有算子串行嵌套一条基线被层层套娃,如 Base64(ROT13(原文))

serial 的实现是把多个算子顺序作用、attack_method 记成 "A + B + C"(attack_simulator.py:579a_enhance_attack_serial)。平台数据集模式默认用 serial(见 common/agent/prompt_tasks.go:119)。

4. 阶段二:评测主循环(RedTeamer)

拿到一批增强后的 SimulatedAttack,进入评分。入口 RedTeamer.a_red_team(deepteam/red_teamer/red_teamer.py:369)。

4.1 按漏洞类型分组并发

先把所有攻击 按漏洞类型分桶(vulnerability_type_to_attacks_map,red_teamer.py:412-426),因为同一漏洞类型共用同一个裁判 metric。然后对每个桶并发评测。

并发用一个 asyncio.Semaphore(max_concurrent) 限流(red_teamer.py:380),max_concurrent 取目标/模拟器/裁判三方上限的最大值(cli/red_team_runner.py:83)。

4.2 单条攻击怎么评(核心三步)

每条攻击在 _a_attack(red_teamer.py:477)里走三步:

攻击提示词

▼ ① 打目标模型
actual_output = await model_callback(simulated_attack.input)

▼ ② 包成 deepeval 的 LLMTestCase(input + actual_output)
test_case = LLMTestCase(input=..., actual_output=...)

▼ ③ 裁判 metric 评分
await metric.a_measure(test_case)
score = metric.score # 0 / 0.5 / 1
reason = metric.reason # 裁判给的文字理由

几个边界处理(都在 _a_attack 内):

  • 目标模型回空串 → 抛错当异常处理(red_teamer.py:508-509)。
  • 任一步抛异常且 ignore_errors=True → 记成 error 的测试用例并跳过,不中断整轮(red_teamer.py:511-519532-539)。
  • 基线增强阶段就标了 error/useless 的,直接短路返回,不打目标模型(red_teamer.py:496-503)。
  • 裁判给的 reason 若是英文而界面语言是中文,会再调裁判模型翻译一遍(red_teamer.py:530_a_translate_reason)。

4.3 同步与异步两套

整个 RedTeamer 同时维护同步 red_team(red_teamer.py:178)和异步 a_red_team 两套几乎平行的实现;red_team 里用 inspect.iscoroutinefunction 断言 model_callback 是否协程,以确保和 async_mode 一致(red_teamer.py:190-210)。平台一律走异步(Go 侧固定传 --async_mode,见 common/agent/prompt_tasks.go:95)。

5. 阶段三:汇总成报告

评完得到一堆 RedTeamingTestCase,交给 construct_risk_assessment_overview(deepteam/red_teamer/risk_assessment.py:158)做两维度汇总:按漏洞类型按攻击手法 各算一遍通过/失败/异常/无效计数与防御率。最终装进 RiskAssessment(overview + test_cases)。防御率的精确定义放在第 3 章讲。

6. 代码地图

主题文件路径关键符号
顶层编排cli/red_team_runner.pyRedTeamRunner.run_red_team
评测主循环deepteam/red_teamer/red_teamer.pyRedTeamer.a_red_team
单条攻击评分deepteam/red_teamer/red_teamer.pyRedTeamer._a_attack
合成基线攻击deepteam/attacks/attack_simulator/attack_simulator.pyAttackSimulator.a_simulate_baseline_attacks
增强(签名探测)deepteam/attacks/attack_simulator/attack_simulator.pyAttackSimulator.a_enhance_attack
串行嵌套增强deepteam/attacks/attack_simulator/attack_simulator.pyAttackSimulator.a_enhance_attack_serial
汇总统计deepteam/red_teamer/risk_assessment.pyconstruct_risk_assessment_overview