
garak 测试生成器 generators.test 全解析从 Blank 到 ReasoningLipsum 的测试基座【免费下载链接】garakthe LLM vulnerability scanner项目地址: https://gitcode.com/GitHub_Trending/ga/garakgarak 是一套开源的 LLM 漏洞扫描框架其generators.test模块为整条扫描流水线提供了一组不依赖任何真实模型、可离线运行、行为完全确定的测试生成器。本文基于 docs/source/generators/test.rst 对应的模块文档结合 garak/generators/test.py 源码与 tests/generators/test_test.py 测试用例系统讲解该模块中 7 个生成器的行为语义、可配置参数、默认值与典型使用场景。读完本文你将掌握如何用test.*生成器快速验证 probe、detector 的逻辑如何在无 GPU、无 API Key 的情况下完整跑通一次 garak 扫描以及如何模拟“带思考痕迹reasoning trace”的长结构化输出。一、为什么需要测试生成器generators 在 garak 中的角色garak 的扫描链路大致为probe 构造攻击性 prompt → generator 调用目标 LLM 获取回复 → detector 判定回复是否“越狱”。其中 generator 是对“文本到文本服务”的抽象封装所有生成器都必须继承 garak/generators/base.py 中的Generator基类。真实生成器如 OpenAI、Anthropic、HuggingFace需要网络、API Key 和模型部署这会成为开发与回归测试的瓶颈写一个新的 probe 或 detector 时你只关心自己的逻辑是否正确而不是网络是否通畅。generators.test模块正是为此而生——它提供“简单、确定的系统级响应”专门用于测试不产生任何真实模型调用。从模块的类结构看所有测试生成器都只覆写了一个方法_call_model(prompt, generations_this_call)而把“迭代生成、结果校验、后处理、去前缀”等通用逻辑全部交给基类Generator.generate()完成garak/generators/base.py。这既是理解本文各生成器的前提也是后续学习如何编写自定义生成器docs/source/extending.generator.rst的入口。二、模块总览7 个生成器与默认类模块garak/generators/test.py共定义 7 个生成器并在文件末尾通过DEFAULT_CLASS Lipsum指定了默认类类名类属性名name输出行为支持多路生成BlankBlank恒定返回空字符串✅RepeatRepeat原样返回输入的最后一轮消息✅SingleSingle恒定返回固定字符串ELIM❌NonesNones每次生成都返回None✅LipsumLorem Ipsum按 unit/count 生成随机的 Lorem Ipsum 文本❌ReasoningLipsumReasoning Lipsum生成“思考痕迹 输出”结构化文本❌BlankVisionBlankVision接受文本图像输入恒定返回空字符串✅DEFAULT_CLASS的含义是当用户在命令行只指定到模块级如-m test而不指定具体类时插件加载器会回落到该类。这一机制在 garak/_plugins.py 的加载逻辑中生效。因此-m test等价于-m test.Lipsum。在 garak/resources/plugin_cache.json 中可以查到全部 7 个类的元数据DEFAULT_PARAMS、modality、supports_multiple_generations等这些元数据与源码定义完全一致是 garak 插件自省--list_config、-L的信息来源。三、六个基础测试生成器逐个详解3.1 Blank恒定空输出class Blank(Generator): This generator always returns the empty string. supports_multiple_generations True def _call_model(self, prompt, generations_this_call1): return [Message()] * generations_this_callBlank对任何 prompt 都返回。它是 garak 中最常用的测试生成器之一常见用途包括单独测试 probepython3 -m garak -t test.Blank -p mymodule -d always.Pass把生成器固定为空输出从而隔离 probe 构造 prompt 的逻辑docs/source/extending.rst。单独测试 detectorpython3 -m garak -t test.Blank -p test.Blank -d mymodule让 probe 与生成器都“哑化”只验证 detector 对空回复的判定。supports_multiple_generations True表示一次_call_model调用即可按请求批量返回多个结果。测试 tests/generators/test_test.py 验证了generations_this_call5时会返回 5 个空Message。3.2 Repeat回显最后一条输入消息class Repeat(Generator): This generator returns the last message from input that was posed to it. supports_multiple_generations True def _call_model(self, prompt, generations_this_call1): return [prompt.last_message()] * generations_this_callRepeat通过prompt.last_message()取回对话Conversation中用户提交的最后一条消息并原样返回。测试用例 tests/generators/test_test.py 断言输入especially the lies输出即为Message(especially the lies)。这种“输入即输出”的行为非常适合测试基于反射/回显语义的 detector例如检查回复是否复述了恶意指令或验证 probe 对多轮对话的处理。3.3 Single固定字符串且拒绝多路生成class Single(Generator): supports_multiple_generations False test_generation_string ELIM def _call_model(self, prompt, generations_this_call1): if generations_this_call 1: return [Message(self.test_generation_string)] else: raise ValueError( Test generator refuses to generate 1 at a time. Check generation logic )Single恒定返回字符串ELIM并且supports_multiple_generations False——当请求多路生成时会主动抛出ValueError而不是静默出错。这个类的真正价值在于验证框架自身的多路生成逻辑。在基类 garak/generators/base.py 中当生成器不支持多路生成且请求generations_this_call 1时框架会退回逐次调用_call_model(prompt, 1)并聚合结果若配置了parallel_requests还会走多进程并行分支。测试 tests/generators/test_test.py 覆盖了“随机 2~12 路生成均正确聚合”以及“直接调用_call_model(..., generations_this_call2)抛出 ValueError”两种路径。3.4 Nones恒定无响应class Nones(Generator): This generator always returns a None for every generation. supports_multiple_generations True def _call_model(self, prompt, generations_this_call1): return [None] * generations_this_callNones每次生成都返回None。注意基类的_call_model签名允许返回Message | Nonegarak/generators/base.pyNone语义上代表“模型未给出任何响应”。它用于测试无响应/超时/拒答场景下 detector 的行为——例如 tests/detectors/test_detectors.py 中要求detect()在输入为None时仍返回合法的浮点数或None列表。3.5 Lipsum可变的非零输出模块默认类class Lipsum(Generator): Lorem Ipsum generator, so we can get non-zero outputs that vary DEFAULT_PARAMS Generator.DEFAULT_PARAMS | { unit: sentence, count: 1, } supports_multiple_generations False _unit_separators {sentence: , paragraph: \n, text: \n}Lipsum是模块的默认生成器DEFAULT_CLASS Lipsum作用是产生非空且每次不同的输出用于测试那些需要“有内容回复”才能触发的逻辑同时保证可重复性不受外部服务影响。它依赖第三方库lorem按unit指定的粒度生成内容再用count控制拼接数量。参数说明均有默认值均可通过DEFAULT_PARAMS覆盖参数类型默认值取值范围/说明unitstrsentencesentence、paragraph、text三者之一text为多段落文本块countint1每个输出中拼接多少个unit单元单元之间的连接符由_unit_separators决定句子之间用空格段落/文本块之间用换行。若传入非法unit_call_model会抛出ValueError: Invalid unit ...。测试 tests/generators/test_test.py 验证了完整行为矩阵默认输出非空unitsentence时输出以句号结尾且不含换行unitparagraph时包含多个句子unittext时包含换行多段落count5时句子数不少于 5unitchapter会触发ValueError连续 200 次调用输出各不相同len(results) 1。注意Lipsum的supports_multiple_generations False与Single一样会走基类的逐次/并行聚合路径。3.6 BlankVision多模态文本图像输入的空输出class BlankVision(Generator): This textimage input generator always returns the empty string. supports_multiple_generations True modality {in: {text, image}, out: {text}} def _call_model(self, prompt, generations_this_call1): return [Message()] * generations_this_callBlankVision与Blank行为相同恒定返回空字符串但通过modality {in: {text, image}, out: {text}}声明其输入模态包含文本与图像。garak 的模态声明遵循“支持主流 any-to-any 大模型”的约定garak/generators/base.py合法输入元素包括text、image、audio、video、3d。因此它专门用于视觉模型流水线的离线测试例如配合visual_jailbreak类 probe 验证多模态输入的处理链路。四、ReasoningLipsum模拟思考痕迹的长结构化输出ReasoningLipsum是Lipsum的子类也是该模块中参数最丰富、设计意图最明确的生成器为测试长结构化输出场景如带think推理痕迹的模型回复提供确定性模拟数据。其输出格式固定为{skip_seq_start}{reasoning text}{skip_seq_end}{output text}即开头定界符 推理文本 结尾定界符 正式输出。4.1 参数与默认值DEFAULT_PARAMS Lipsum.DEFAULT_PARAMS | { skip_seq_start: think, skip_seq_end: /think, reasoning_length: 2000, output_length: 500, variance: 0.1, respect_max_tokens: False, unit: sentence, }参数类型默认值说明skip_seq_startstrthink推理痕迹的起始定界符skip_seq_endstr/think推理痕迹的结束定界符reasoning_lengthint2000推理文本的目标字符数output_lengthint500输出文本的目标字符数variancefloat0.1实际长度相对目标长度的允许偏差比例0.0–1.00.1即 ±10%respect_max_tokensboolFalse是否按max_tokens * 1.4字符上限截断输出文本不影响推理痕迹unitstrsentence生成文本的基本单元继承自Lipsum其中skip_seq_start/skip_seq_end在基类Generator.DEFAULT_PARAMS中默认是NoneReasoningLipsum将其覆盖为think//think——这也让它可以无缝接入基类的skip sequence 清理机制当生成器同时配置了skip_seq_start与skip_seq_end时Generator.generate()会调用_prune_skip_sequences()garak/generators/base.py用正则将定界符包裹的推理段从输出中剥离模拟真实推理模型在“后处理阶段剔除思考痕迹”的行为。4.2 核心实现_generate_lorem 与长度控制_generate_lorem(min_length, variance)garak/generators/test.py是长度控制的内部实现若variance 0先用self._rng.uniform(-variance, variance) * min_length计算随机偏差得到实际目标长度下限为 1 个字符校验unit合法性从lorem库取一个生成函数逐句拼接文本直到长度达到目标。_call_model中若respect_max_tokensTrue且设置了max_tokens则output_length会被裁剪为min(output_length, int(max_tokens * 1.4))——用字符数粗略模拟 token 预算1 token ≈ 1.4 字符且只限制输出文本、不限制推理痕迹这与真实推理模型“思考可长、输出受限”的特性一致。4.3 测试如何验证其结构tests/generators/test_test.py 对该类做了极为细致的验证可作为理解其语义的“行为契约”输出必须以skip_seq_start开头且skip_seq_start必须出现在skip_seq_end之前定界符之后必须还有非空输出文本after_end长度 0默认参数下总长度落在expected与2 * expected之间expected reasoning_length output_length 定界符长度自定义定界符如[[REASON]]/[[/REASON]]与自定义长度reasoning_length5000、output_length2000均按预期生效variance0.0时输出长度恒 ≥ 目标长度随机variance时长度有变化但始终非空一次请求 200 路生成也能全部返回且都包含定界符。五、命令行与配置实战5.1 通过 CLI 指定测试生成器garak 主入口是python -m garak生成器通过-m/--model_type指定模块、-n/--model_name指定类garak/cli.py。使用测试生成器的典型命令# 用模块默认类Lipsum跑一个 probe python -m garak -m test -p dan.Dan_10_0 # 显式指定具体生成器类 python -m garak -m test.Lipsum -p test.Blank # 空输出 空 probe验证 detector 逻辑 python3 -m garak -t test.Blank -p test.Blank -d mymodule # 开发 probe 时固定空生成器配 always.Pass 隔离 detector python3 -m garak -t test.Blank -p mymodule -d always.Pass后两条来自官方扩展指南 docs/source/extending.rst 的推荐调试配方“测试 probe 用空生成器 always.Pass测试 detector 用空生成器 空 probe测试生成器用空 probe always.Pass”——三种组合把链路中的无关变量全部固定定位问题一目了然。5.2 在配置文件中覆盖参数test模块的类全部继承自Configurable其DEFAULT_PARAMS可通过 garak 的插件配置机制按层覆盖详见 docs/source/configurable.rst 中“插件包/模块/类”的命名约定如generator.test.Lipsum。例如要调整Lipsum的输出粒度只需在配置中设置plugins: generator: test: Lipsum: unit: paragraph count: 2同理ReasoningLipsum的reasoning_length、output_length、variance、respect_max_tokens、skip_seq_start/skip_seq_end均可这样覆盖从而在不改任何代码的前提下为不同测试场景定制“思考痕迹”的规模与形态。六、如何选择一张决策速查表你的测试目标推荐生成器理由只测 probe固定生成器行为test.Blank输出恒为空probe 结果完全可预期只测 detector 对空回复的判定test.Blank配合test.Blankprobe 隔离所有上游变量测 detector 对“复述输入”的判定test.Repeat输出 输入最后一条消息语义清晰验证框架多路生成/并行逻辑test.Singlesupports_multiple_generationsFalse会触发逐次与并行聚合路径测 detector 对无响应的处理test.Nones恒返回None模拟模型未应答需要非空且变化的输出做压力/统计测试test.Lipsum默认输出有内容、每次不同且零外部依赖测长输出 / 带思考痕迹的结构化输出test.ReasoningLipsum可精确控制推理段与输出段的长度与定界符测多模态文本图像链路test.BlankVision声明modality.in {text, image}的空输出生成器七、总结garak.generators.test模块用不到 210 行代码为 garak 的“probe → generator → detector”链路提供了完整的离线测试基座Blank/Repeat/Single/Nones覆盖确定性的空输出、回显、固定串与无响应四类极简行为Lipsum提供可变非零输出并作为模块默认类ReasoningLipsum通过skip_seq_start/end、reasoning_length、output_length、variance、respect_max_tokens精确模拟现代推理模型的思考痕迹结构还能与基类的 skip-sequence 清理机制联动BlankVision则将测试能力扩展到多模态输入。配合 tests/generators/test_test.py 中详尽的断言矩阵你可以把这些生成器当作“可编程的假模型”在无网络、无密钥、无 GPU 的环境下快速验证 probe 与 detector 的正确性或参照 docs/source/extending.generator.rst 以它们为模板开发自己的生成器。【免费下载链接】garakthe LLM vulnerability scanner项目地址: https://gitcode.com/GitHub_Trending/ga/garak创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考