自有语言模型的风险扫描,可以用 garak 把一组探针输入送给模型,再由检测器检查返回内容。一次实用的入门流程是:先验证工具与模型接口能连通,再只选一个明确的探针,保存 JSONL 报告,逐条复核被标记的输出并在修复后重跑。不要一开始把全部探针跑完,再只看一个“通过率”。
开始前,确定目标和扫描范围
本文按 garak 0.17.0 的命令接口和项目代码说明,要求 Python 3.11 或更新版本。目标是你控制的测试模型或测试服务;服务最好使用隔离测试数据和无真实业务权限的账号。记录模型版本、系统提示词、生成参数和本轮探针,才能比较修复前后的结果。

garak 是扫描工具,本身没有替你提供所有模型推理资源。远程接口调用可能产生费用,本地模型占用内存和算力;一个探针也可能包含很多输入。项目介绍、安装方式与探针用途见官方项目。本文没有对真实语言模型运行风险扫描,下面的接入命令是按官方资料核对的操作方案,不提供虚构的漏洞率或模型安全结论。
在单独的练习目录创建环境:
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install garak==0.17.0
.\.venv\Scripts\python.exe -m garak --version
.\.venv\Scripts\python.exe -m garak --list_probes --spec probes.encoding
macOS 或 Linux 使用 .venv/bin/python。garak 依赖较多,安装时间和磁盘占用取决于平台;安装失败先读依赖与 Python 版本报错,不能用缺依赖的安装结果冒充可运行环境。0.17.0 使用 --target_type 选择模型接口、--spec 选择探针;旧教程的参数名称可能已弃用,以固定版本的 --help 为准。
先用测试组件检查报告链路
以下命令使用 garak 自带的重复输入生成器、空输入探针和总是通过的检测器。它只测试工具链路,不是风险检测:
.\.venv\Scripts\python.exe -m garak --target_type test.Repeat --spec probes.test.Blank --detectors always.Pass --generations 1 --report_prefix smoke
应检查终端是否完成、是否给出本轮 .report.jsonl 的实际路径、报告是否包含 eval 记录。这里指定 always.Pass 是为隔离工具安装与报告问题;后面真实扫描必须去掉这个选项,使用探针对应的检测器。参数与测试组件可核对官方 CLI 实现。
把自有 HTTP 接口接入 REST 生成器
下面假设你已有一个本地测试接口:POST http://127.0.0.1:8000/generate,请求为 {"prompt":"问题文本"},响应为 {"text":"模型回答"}。这个地址只是接口约定,不是 garak 会自动启动的服务。先用 PowerShell 验证它:
$requestBody = @{ prompt = '请回复测试成功' } | ConvertTo-Json
Invoke-RestMethod -Method Post -Uri 'http://127.0.0.1:8000/generate' -ContentType 'application/json' -Body $requestBody
确认响应的 text 是非空字符串,再保存配置为 rest-config.yaml:
plugins:
generators:
rest:
RestGenerator:
uri: http://127.0.0.1:8000/generate
method: post
headers:
Content-Type: application/json
req_template: '{"prompt": "$INPUT"}'
response_json: true
response_json_field: '$.text'
request_timeout: 30
$INPUT 在发请求时替换为探针输入,$.text 是取出 JSON 响应字段的路径。接口返回不同结构时要改路径,例如嵌套回复需要匹配你的真实字段。REST 的请求模板、响应字段和超时配置见官方 REST 生成器文档。本例仅适用于没有鉴权的回环测试接口,远程服务的鉴权方式要按该服务契约配置,并使用 HTTPS。
只运行一组明确的风险探针
这里选 encoding.InjectBase64,它检查模型对 Base64 编码输入的响应表现。先查插件信息,理解这一探针的输入、检测器与适用范围,再运行:
.\.venv\Scripts\python.exe -m garak --plugin_info probes.encoding.InjectBase64
.\.venv\Scripts\python.exe -m garak --target_type rest.RestGenerator --config rest-config.yaml --spec probes.encoding.InjectBase64 --generations 1 --parallel_attempts 1 --parallel_requests 1 --report_prefix own-model-base64
一条命令写成一行即可。--generations 1 是每条探针输入的生成次数,不是整个扫描只调用一次模型。并发设为 1 方便首次观察调用量与报错;仍须先查看插件信息和预算。探针与检测器的输入输出逻辑可以结合官方 encoding 实现核对。
本轮不要保留前一步的 --detectors always.Pass。也不要把有检测记录的运行和连接超时的运行混成一个安全分数:HTTP 429、超时、JSON 解析失败或取不到字段,先修接口和配置。探针含有为了暴露风险而设计的文本,应把报告留在受控位置;不要自动把模型输出执行为命令。
读报告:先核对完整性,再复核命中
使用终端显示的实际报告路径,不猜它一定在当前目录。保存下面脚本为 read_report.py,再执行 python read_report.py "实际报告路径.report.jsonl":
import json
import sys
from pathlib import Path
counts = 0
with Path(sys.argv[1]).open(encoding='utf-8') as file:
for line in file:
if not line.strip():
continue
record = json.loads(line)
if record.get('entry_type') != 'eval':
continue
total = record.get('total_evaluated', record.get('total'))
passed = record['passed']
print(record['probe'], record['detector'],
'passed=', passed, 'total=', total,
'flagged=', total - passed if total is not None else 'unknown')
counts += 1
if counts == 0:
raise SystemExit('没有 eval 记录:扫描可能没有完成,不能当作通过。')
这段代码按 garak 0.17.0 报告中的 eval 字段读取,兼容 total_evaluated 和旧 total 字段;已用一条明确标为模拟的 JSONL 记录验证解析,但未读取真实模型扫描结果。没有 eval、没有总数、存在生成失败时,应先查日志。passed 表示这一检测器下未被标记的生成数量,不是整个模型已获安全认证。
如需 HTML 报告,可以按固定版本工具执行:
.\.venv\Scripts\python.exe -m garak.analyze.report_digest --report_path "实际报告路径.report.jsonl" --output_path own-model-report.html
摘要字段和转换参数见官方报告实现。报告要和生成它的 garak 版本一起保存,跨版本解析失败时不能强行当成空结果。
把命中变成可复现的修复任务
对每条命中保留探针名称、检测器、输入、模型实际输出、模型与系统提示词版本。人工判断它违反了哪条你的应用规则,区别误报、真实不当输出和无效调用。修复后用相同探针与配置重跑,再补正常用户输入,检查防护是否让正常问答也失效。
本次只选择一个编码探针,覆盖范围有限;没有命中只能说明这些输入在这一轮没有被对应检测器标记。它不能证明模型不会泄露数据,也不能替代 Agent 的工具权限与租户隔离测试。模型随机性、探针语料偏差和检测器误判都会影响结果,后续应按业务风险扩展探针并保留人工复核依据。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/30530.html