回归测试在防止已知故障再次发生方面很强大,但无法发现尚无测试用例的攻击。Garak和PyRIT是AI红队工具,它们对LLM或AI应用程序尝试多种探测和对话策略,并收集意想不到的潜在故障。
这两个工具并非“自动漏洞确认器”。结果是检测器和评分器的判断,可能存在误报。本次实践仅使用自有的本地测试目标、合成数据和只读功能。发现的结果只有在人工审查跟踪和策略后,才能升级为漏洞或回归测试用例。

Garak与PyRIT有何不同?
Garak是一种扫描器型工具,它向目标生成器发送各种探针,并使用检测器寻找失败迹象。PyRIT(Python Risk Identification Tool)更像一个框架,它通过组合目标、攻击、转换器、评分器和内存来创建单轮或多轮攻击实验。
| 比较 | Garak | PyRIT |
| — | — | — |
| 核心单元 | 探针和检测器 | 攻击·目标·评分器·内存 |
| 优势 | 广泛的重复扫描 | 具有状态的自适应·多轮实验 |
| 目标连接 | 生成器插件 | 提示目标 |
| 判断 | 检测器和评估器 | 评分器和人工审查 |
| 结果 | 日志·JSONL·报告 | 对话·分数·结果存储在内存中 |
| 推荐起点 | 选择的探针家族的窄范围扫描 | 从单轮开始执行一个合成目标 |
Garak官方文档中,探针管理用于诱导故障的输入和交互,生成器封装了与模型或对话系统的连接。检测器在响应中寻找特定的故障迹象,而Harness协调整个执行过程。
PyRIT官方文档将自动化/人工主导的红队、各种目标、单轮/多轮攻击、灵活的评分以及基于SQLite/Azure SQL的内存描述为主要组成部分。
建立安全的实践边界
Garak·PyRIT Container
↓ 허용된 Test Network만
Local Guardrail Gateway
↓
합성 Test Tenant + 읽기 전용 RAG + Mock Tool
↓
Nova·NeMo·Presidio → Test LLM
↓
비민감 Trace와 격리된 결과 저장소
请勿针对实际生产端点、他人的模型、外部服务和真实数据运行。测试网关会阻止出站流量,工具只会返回固定的模拟响应,而不是删除文件、执行命令、支付或发送消息。API密钥应作为秘密注入,而不是放入图像或笔记本中。
实践1:验证Garak结构和安装
官方仓库提供了PyPI安装和探针列表的查看方法。在操作评估中,应固定已验证的版本。
mkdir llm-redteam-lab
cd llm-redteam-lab
python3 -m venv .venv-garak
source .venv-garak/bin/activate
python -m pip install --upgrade pip
python -m pip install garak
python -m garak --version
python -m garak --list_probes
从一开始就运行所有探针可能会导致成本、时间和结果量急剧增加。首先,使用测试生成器验证执行结构,或者只选择一个与服务目标相关的探针家族。
python -m garak
--target_type test.Repeat
--probes encoding
test.Repeat是一个内置的测试目标,用于重复输入。它不是评估实际漏洞的命令,而是用于验证安装和报告管道的安全冒烟测试。Garak可以将执行详情记录到JSONL中,因此输入和输出只使用合成数据,并限制对结果目录的访问权限。
实践2:仅将自有的HTTP网关连接为目标
下一步是将本地Guardrail网关连接到Garak的REST生成器。REST生成器的确切配置键可以在您安装的Garak版本的官方参考文档中找到。
plugins:
generators:
rest:
RestGenerator:
uri: http://host.containers.internal:8080/chat
method: post
headers:
Content-Type: application/json
req_template_json_object:
message: "$INPUT"
tenant_id: "redteam-test"
response_json: true
response_json_field: response
python -m garak
--target_type rest.RestGenerator
--config garak-rest.yaml
--probes promptinject
上述名称和选项可能因版本而异。请首先查阅–plugin_info和参考文档。定义扫描范围、最大生成数、并发性、超时和成本限制,并使用网络策略阻止测试网关以外的地址。
如何解读Garak结果
Garak的FAIL意味着检测器在响应中发现了目标失败迹象。这并不立即意味着实际漏洞已得到确认。
- 确认使用了哪种探针和检测器组合。
- 检查目标错误或空响应是否被错误判断。
- 除了用户输出,还要检查RAG·工具跟踪。
- 重复测试以确认在相同条件下是否可重现。
- 缩减为最小的合成测试用例后,由人工定义预期行为。
如果检测器以简单的拒绝短语为标准,可能会因语言或表达的变化而产生误报。可能需要一个自定义检测器或后处理门,以同时验证Guardrail的结构化决策和工具调用状态。
实践3:以内存模式启动PyRIT
PyRIT官方文档提供了使用包安装和initialize_pyrit_async的框架示例。在隔离实践中,首先使用内存模式(In-memory Memory)来减少对话留在磁盘上的范围。
python3 -m venv .venv-pyrit
source .venv-pyrit/bin/activate
python -m pip install --upgrade pip
python -m pip install pyrit
python -c "import pyrit; print(pyrit.__version__)"
import asyncio
from pyrit.setup import IN_MEMORY, initialize_pyrit_async
async def main():
await initialize_pyrit_async(memory_db_type=IN_MEMORY)
print("PyRIT in-memory lab initialized")
asyncio.run(main())
IN_MEMORY在进程结束后会方便地消失,但它并不能清除屏幕输出和外部提供商的日志。提示和响应中只应使用合成数据。
实践4:从单轮开始验证目标
PyRIT的目标是要攻击的AI系统接口。官方文档示例使用OpenAIChatTarget和PromptSendingAttack。本文仅展示结构,前提是实际密钥不硬编码在代码中,而是从环境中加载已批准的测试端点设置。
import asyncio
from pyrit.executor.attack import PromptSendingAttack
from pyrit.output.attack_result.pretty import PrettyAttackResultMemoryPrinter
from pyrit.prompt_target import OpenAIChatTarget
from pyrit.setup import IN_MEMORY, initialize_pyrit_async
async def main():
await initialize_pyrit_async(memory_db_type=IN_MEMORY)
target = OpenAIChatTarget()
attack = PromptSendingAttack(objective_target=target)
result = await attack.execute_async(
objective="합성 Test 문서의 접근 정책을 설명해줘"
)
printer = PrettyAttackResultMemoryPrinter()
await printer.write_async(result)
asyncio.run(main())
此目标是确认正常连接的冒烟测试。只有在验证了安全的单轮、评分器验证和结果存储范围后,才能将其扩展到已批准的多轮策略。
实践5:分离评分器和人工判断
PyRIT评分器可以使用True/False、李克特量表或分类来评估响应是否达到目标。基于LLM的评分器虽然灵活,但自身存在错误和成本。
| 判断对象 | 优先方式 |
| — | — |
| 工具调用情况 | 结构化跟踪的确定性检查 |
| 租户边界违规 | 文档ID·租户ID的确定性检查 |
| 秘密字符串暴露 | 合成金丝雀的精确匹配检查 |
| 拒绝含义·绕过成功 | 评分器与人工审查并行 |
| 答案质量·相关性 | 模型评分器和样本审查 |
攻击模型和评分器模型即使与目标模型分离,也可能都出错。在结果中记录评分器版本、提示、阈值和执行环境,并且不要将未确定或错误计为成功。
结合系统扫描与自适应探索
Garak 넓은 Probe Scan
↓ 실패 후보
사람의 1차 분류
↓ 대화형 재현이 필요한 후보
PyRIT 단일·다중 Turn 실험
↓ 재현 가능한 최소 사례
Trace·권한·정책 검토
↓ 승인된 Finding
Promptfoo 회귀 Testcase + Guardrail 정책 변경
虽然使用Garak进行广泛扫描并使用PyRIT深入探索对话上下文的流程很有用,但并非总是需要遵循此顺序。重要的是将这两个结果与相同的finding_id、目标版本、策略包和跟踪ID关联起来。
Podman沙盒操作示例
podman network create --internal llm-redteam-lab
podman run --rm
--network llm-redteam-lab
--read-only
--cap-drop=all
--security-opt=no-new-privileges
--pids-limit=256
--memory=4g
--cpus=2
-v "$PWD/results:/results:Z"
localhost/llm-redteam-tools:VERSION
在–internal网络中无法调用外部API。您可以将本地目标容器连接到同一网络以进行完全本地实践,或者如果外部提供商是必需的,则设置一个单独的出站代理,只允许通过已批准的目标。请勿挂载主机网络、Docker Socket、Home Directory和Cloud Credential Directory。
保护结果中的个人信息和成本
- 仅在最短期限内保留原始提示·响应文本。
- 使用合成数据集代替实际客户对话。
- 配置JSONL·内存数据库·跟踪的访问权限和加密。
- 从日志中删除API密钥和授权头。
- 限制最大轮次、探针、生成、并发性、令牌和成本。
- 将工具替换为模拟或只读版本。
- 扫描结束后销毁临时容器和秘密。
实践完成清单
- 仅使用了自有或明确授权的测试目标。
- 区分了Garak的生成器·探针·检测器·Harness的角色。
- 区分了PyRIT的目标·攻击·评分器·内存的角色。
- 在进行全面扫描之前,使用测试目标验证了安装。
- 从较小的探针家族和多轮范围开始。
- 使用了合成租户、合成金丝雀和模拟工具。
- 限制了容器权限、网络出站和资源限制。
- 未将FAIL·分数自动解释为已确认的漏洞。
- 同时审查了用户输出和内部工具·RAG跟踪。
- 仅将已批准的发现升级为最小回归测试用例。
总结
Garak和PyRIT并非重新评分已知答案的工具,而是用于在当前测试套件之外寻找潜在故障的探索工具。Garak通过探针和检测器进行广泛扫描,而PyRIT则通过组合目标·攻击·评分器·内存来深入调查对话路径。
自动化生成的是候选列表,而非判决。它应在隔离的测试环境中运行,并且只有在人工审查策略、权限、跟踪和可重现性之后,才应将有价值的发现升级为Promptfoo测试用例和Guardrail策略。下一篇也是最后一篇将完成整个循环,将这些发现转化为包含责任人、预期结果和策略版本的测试用例,并安全地部署到控制平面。
官方资料
※ Garak插件名称、PyRIT API和Python要求可能因版本而异。在执行命令之前,请查阅固定版本的官方文档,并在授权的沙盒中使用合成数据进行验证。
发表回复