AI-Infra-Guard 内置 Ventor QTest 模块:长序列 EFL 与重复请求 AFL 双路模型保真度审计实战
【免费下载链接】AI-Infra-GuardA full-stack AI Red Teaming platform securing AI ecosystems via Agent Scan, Skills Scan, MCP scan, AI Infra scan and LLM jailbreak evaluation.项目地址: https://gitcode.com/GitHub_Trending/ai/AI-Infra-Guard
Ventor QTest 是 AI-Infra-Guard 的 API 供应商审计组件(aig_api_checker)中新增的内置模块,用于量化"同一模型提示词在多个 API 供应商/推理端点上的输出分布偏离程度"。本文以该模块的官方文档为主线,结合 services/api_checker/ventor_qtest 目录下的实际源码与配置,完整讲解qtest run(长序列 Expected Fidelity Loss)与qtest afl-run(重复请求 Average Fidelity Loss)两条互补审计路径的原理、配置、运行与结果解读,帮助读者在真实供应商环境中复现可验证的模型保真度排名实验。
一、模块来源与集成隔离设计
本模块由上游开源项目 kexinoh/ventor_qtest)。集成时最重要的工程约束是:不改变aig_api_checker已有行为。为此模块在 services/api_checker/ventor_qtest/README.zh.md 中明确了五条隔离设计:
| 隔离措施 | 说明 |
|---|---|
| 独立 Python 包命名空间 | 模块使用ventor_qtest独立包名,不与现有算法命名冲突 |
| 仅通过新 CLI 子命令启用 | 通过qtest/ventor子命令触发,默认不加载 |
| 独立配置文件 | 使用独立的config/default.yaml与config/afl.yaml |
| 零侵入既有能力 | 不修改现有算法、baselines.json或 HTTP API 路由 |
| 导入调整 | 将上游的绝对模块导入调整为包内相对导入 |
从目录结构看(services/api_checker/ventor_qtest),模块内部被划分为三块职责清晰的部分:
runner/:编排与 CLI 层,包含 cli.py(参数解析)、orchestrator.py(长序列测试编排)、repeated.py(AFL 采集与分析)、openrouter.py(OpenRouter provider 自动发现)、questions.py(默认问题生成);- 统计内核:
check.py(长序列假设检验)、repeated_request.py(AFL 统计量)、summary.py(结果汇总与排名导出); - 配置:
config/default.yaml(EFL 测试)、config/afl.yaml(AFL 测试)。
二、快速上手:调用方式与环境准备
在services/api_checker目录下,通过主入口python main.py qtest ...或包入口python -m ventor_qtest ...即可调用。官方文档给出的四组核心调用命令如下:
# 1. 长序列 EFL 测试(使用默认配置) python main.py qtest run # 2. 长序列 EFL 测试(指定配置文件) python main.py qtest run --config path/to/config.yaml # 3. 重复请求 AFL 测试(使用默认 AFL 配置) python main.py qtest afl-run # 4. 重复请求 AFL 测试(指定配置) python main.py qtest afl-run --config path/to/afl.yaml # 5. 查询 OpenRouter 上某模型的可用 provider python main.py qtest openrouter-providers --model moonshotai/kimi-k2.5 # 6. 查看 CLI 全部帮助 python -m ventor_qtest --help运行测试需要相应供应商的 API Key,默认配置通过以下四个环境变量注入(README.zh.md):
MOONSHOT_API_KEY:Moonshot 官方端点(长序列测试的 tester/参考分布与自营 vendor)SILICONFLOW_API_KEY:硅基流动端点OPENROUTER_API_KEY:OpenRouter 聚合端点(多家第三方推理商)DEEPSEEK_API_KEY:DeepSeek 端点(AFL 参考分布与对照 vendor)
配置文件中的api_key统一写成${VAR}占位符形式。CLI 在加载配置时会通过 cli.py 的_expand_env_vars递归展开环境变量:若整个字符串就是一个${VAR}则整体替换,若混在字符串中则逐段替换;环境变量缺失时保留占位符并打印[warn],不会静默失败。AIG_API_CHECKER_DATA_DIR未设置时会回退到services/api_checker/runtime目录(见 cli.py),所有结果默认落在${AIG_API_CHECKER_DATA_DIR}/qtest/result/下。CLI 模块在导入时即调用load_dotenv()自动加载项目根目录的.env文件。
三、qtest run:长序列 EFL 审计
3.1 方法原理
run采用长序列 Expected Fidelity Loss(EFL)思路:让被测 vendor 在给定提示词下生成一段长数字序列(默认 100 位),随后以"可信参考接口"返回的逐位置 token 概率分布为基准,对生成序列的每一个位置做重评分——计算该位置观测输出对应的负对数似然与参考分布期望的偏离,最终聚合成运行级偏离指标。官方文档的表述是:"通过可信参考逐位置重评分,报告运行级偏离及其上尾"。
底层实现位于 check.py 的DeepSeekSequenceTester:
- 参考分布获取:
get_token_probabilities请求支持logprobs/top_logprobs的 OpenAI/DeepSeek 兼容接口,从choices[0].logprobs.content[0]解析主 token 与 top 列表的对数概率,math.exp(logprob)还原为概率,并自动补一个<OTHER>桶保证归一化(check.py)。 - 逐位置并发重评分:
calculate_sequence_test_statistics_concurrent把目标回复按字符切分(文档注明"仍按字符切分前缀,如需严格 tokenizer 对齐需自行修改"),对每个位置构造assistant前缀消息并发请求参考分布(check.py)。 - 假设检验:
hypothesis_test汇总各位置的观测损失-log p(x_t)、期望均值 H 与信息方差 V,计算Z = (T_obs - μ_total) / W,并输出|Z|与"每 token log 偏差度"两个核心指标——|Z|越大偏离越强(check.py)。参考分布请求失败的序列会被整体标记无效并丢弃,不算入统计口径。
3.2 默认配置逐项解读
默认配置 services/api_checker/ventor_qtest/config/default.yaml 内置两个测试套件kimi-k2-multi与kimi-k2.5-multi,结构完全相同,仅模型与 vendor 列表不同。以kimi-k2.5-multi为例:
tests: - name: kimi-k2.5-multi result_dir: "${AIG_API_CHECKER_DATA_DIR}/qtest/result/json" questions: [] # 留空则运行时自动生成随机示例问题 runs_per_question: 2 digits: 100 # 提取数字序列长度 temperature: 0.6 top_logprobs: 20 vendor_max_workers: 2 # vendor 并发上限 max_inflight_ref_requests: 6 # 参考分布并发上限(vendor 并发会自动下调) align_tester_temperature: true # tester 温度自动对齐生成温度 tester: api_key: "${MOONSHOT_API_KEY}" base_url: "https://api.moonshot.cn/v1/chat/completions" model: "kimi-k2.5" temperature: 0.6 top_logprobs: 20 max_workers: 2 request_delay: 0.3 timeout_sec: 45.0 extra_payload: thinking: { type: "disabled" } vendors: [ ... ] # 被测端点列表 payload: official_baseline_vendor: "k2.5-self" # 官方基线 vendor 标记各关键字段的语义与底层对应关系:
questions:留空或省略时,orchestrator.py 会在运行时调用build_questions()自动生成。默认问题集见 questions.py:第一条是纯基础提示词"随机生成 100 位数字,逗号分隔",另附 3 条各带一段随机 7 位数字示例。runs_per_question/digits/temperature/top_logprobs:控制每道题的重复次数、抽取数字长度(normalize_to_digit_series用正则提取前 N 个数字并以逗号拼接,见 orchestrator.py)、生成温度与参考侧 top 概率数。max_inflight_ref_requests:参考分布的在途请求上限。从 orchestrator.py 可以看到,实际 vendor 并发会被自动下调为max_inflight_ref_requests // tester.max_workers,防止参考侧被打满。align_tester_temperature:为true时若tester.temperature与生成温度不一致,会强制对齐到生成温度(orchestrator.py),保证参考分布与生成条件一致。tester:参考分布端点,必须支持logprobs/top_logprobs。extra_payload可附加厂商特有参数(如禁用思考模式)。vendors:被测端点数组。每个 vendor 使用UnifiedClient(orchestrator.py)统一封装,支持schema: openai/schema: anthropic两种协议、provider.order+allow_fallbacks(OpenRouter 路由锁定)、extra_payload(如reasoning_effort: "none")、max_tokens、max_retries/retry_backoff_sec等。HTTP 408/429/500/502/503/504 被视为瞬态错误并指数退避重试;429 还会触发全局 60 秒限速暂停(_RATE_LIMIT_COOLDOWN_SEC = 60.0,见 orchestrator.py)。连续失败会以SkipVendor非致命异常跳过该 vendor 本轮。
kimi-k2-multi套件的 vendor 列表覆盖 12 个端点:Moonshot 官方kimi-k2-self与kimi-k2-turbo、硅基流动siliconflow-free/siliconflow-pro,以及经 OpenRouter 路由的 chutes/fp8、deepinfra/fp4、fireworks/fp8、novita/fp8、atlas-cloud/fp8、baseten/fp4、together、groq、wandb/fp8 等第三方推理商;kimi-k2.5-multi则对应k2.5-self及 deepinfra、chutes/int4、together、siliconflow/fp8、atlas-cloud/int4、novita、parasail/int4、gmicloud/int4、moonshotai、fireworks、baseten/fp4、venice 等 K2.5 路由,并统一附加reasoning_effort: "none"关闭推理以对齐参考条件。
3.3 运行流程与产物
run子命令加载配置后调用run_tests(orchestrator.py):按"问题 × 运行次数"双层循环,每轮对所有 vendor 并发发起"生成 → 数字序列规范化 → 参考分布逐位置重评分 → 假设检验"流水线,然后保持配置顺序写 JSON 结果。输出文件命名形如q-<问题slug>_<UTC时间戳>_run<N>.json,每个文件包含question、temperature、digits、vendors、vendor_models、vendor_meta、summaries(含abs_Z、token_log_dev、len、skipped状态)、details(原始序列与完整统计)以及payload附加元数据。sanitize_for_json会剔除 NaN/Inf 等非法浮点,保证产物可被下游直接解析(orchestrator.py)。
四、qtest afl-run:重复请求 AFL 审计
4.1 方法原理与设计要点
afl-run(别名repeated-run)实现论文中的重复请求 Average Fidelity Loss(AFL)方法:在若干已知概率分布的约束上下文下,对被测 API反复请求并收集其返回的文本,从文本计数重建有限类别分布,再与"可信参考接口"给出的理论概率对比,报告经过有限样本零假设偏差校正的平均 coarsened-KL。
官方文档特别强调一个关键设计:AFL 的目标接口不需要提供logprobs,仅可信参考接口需要。这意味着它能把审计范围扩展到一切只返回文本的 OpenAI 兼容端点——这正是许多第三方推理商路由、量化部署(fp4/fp8/int4)无法暴露 token 概率时的场景。底层验证见 tests/test_qtest.py:测试断言 AFL 配置中reference声明了top_logprobs: 20,而vendors[0]不包含top_logprobs字段。
统计内核位于 repeated_request.py,关键步骤:
- 参考类别粗化:
build_reference_categories把参考分布压缩为allowed_labels + <OTHER>的有限类别(repeated_request.py);pool_reference_categories按M*pi >= min_expected_count规则仅基于可信参考侧做稀有类别合并(repeated_request.py)。 - 结果映射:
map_outcome采用论文协议的"完全精确匹配"——目标文本必须与类别标签逐字符相等才计入该类别,否则归入<OTHER>(repeated_request.py)。测试test_outcome_map_requires_an_exact_label验证了" 1"、"1\n"、"Alright"都会落入<OTHER>。 - 有限样本零假设偏差校正:
estimate_repeated_context_kl从参考分布做参数化零假设抽样(默认 20,000 次),估计零假设下的期望 KL 作为基线null_baseline_mean,输出bias_corrected_KL = posterior_mean - baseline,并给出后验可信区间、plugin KL、无偏卡方、单侧 bootstrap p 值等(repeated_request.py)。 - 路由级聚合:
aggregate_context_estimates按样本量加权汇总各上下文,产出论文口径的average_fidelity_loss(即S_r)(repeated_request.py)。 - 推断与多重检验:
_add_route_inference用 Dirichlet 后验抽样计算 95% 可信区间afl_credible_interval_95、单侧零假设 p 值route_null_p_one_sided以及Holm 校正p 值route_null_p_holm(repeated.py)。
官方文档同时声明了一个重要边界:输出会保留负的有限样本 AFL(即不强制截断为 0,负值本身携带有限样本偏差信息),但不包含论文实验管理流程(三天采集、盲化、冻结、解盲等)——它提供的是统计引擎而非完整实验治理框架。
4.2 内置 12 个约束上下文
默认 config/afl.yaml 使用论文中的12 个约束上下文,完整列表硬编码在 repeated.py 的DEFAULT_CONTEXTS中,每个上下文由id、prompt、allowed_labels三元组构成,例如:
| id | 允许标签 | 提示词要点 |
|---|---|---|
coin_1_8 | 1, 8 | 抛虚拟硬币,正面 1 反面 8 |
tetra_0_3_6_9 | 0, 3, 6, 9 | 掷四面虚拟骰 |
wheel_2_5_7 | 2, 5, 7 | 转盘 P(2)=0.20, P(5)=0.50, P(7)=0.30 |
bag_1_4 | 1, 4 | 袋中 1 个"1"票与 3 个"4"票 |
urn_0_4_7 | 0, 4, 7 | 均匀随机取标签 |
urn_2_6_9 | 2, 6, 9 | 等量球罐均匀抽球 |
endpoint_0_9 | 0, 9 | 数字区间两端等概率 |
suits_1_3_7_9 | 1, 3, 7, 9 | 四种花色映射四位 |
biased_2_6 | 2, 6 | P(2)=0.65, P(6)=0.35 |
doors_3_5_8 | 3, 5, 8 | 三扇门均匀选择 |
lottery_1_2_7_8 | 1, 2, 7, 8 | 彩票 P(1)=0.10, P(2)=0.20, P(7)=0.30, P(8)=0.40 |
multiples_3_6_9 | 3, 6, 9 | 3 的非零个位数倍数均匀选择 |
这些上下文覆盖了均匀分布、非均匀分布、2~4 类别等多种概率形态,能有效区分"忠实复现分布"与"发生偏移"的端点。如需自定义,可在配置中新增contexts列表(id/prompt/allowed_labels)替换内置集合;_contexts函数会校验id唯一、标签非空且不重复(repeated.py)。
4.3 AFL 配置详解
afl: samples_per_context: 50 # 每个上下文每路由的请求次数 workers: 8 # 采集并发 checkpoint_every: 25 # 每完成 25 个请求写一次断点 temperature: 1.0 min_expected_count: 1.0 # 参考侧类别合并阈值(M*pi >= 1) prior_mode: reference # Dirichlet 先验模式:reference / uniform prior_strength: 1.0 # 先验总浓度 null_samples: 20000 # 参数化零假设抽样次数 posterior_samples: 20000 # 后验抽样次数 inference_samples: 20000 # 路由级推断抽样次数 seed: 20260814 output: "${AIG_API_CHECKER_DATA_DIR}/qtest/result/afl/latest.json" checkpoint: "${AIG_API_CHECKER_DATA_DIR}/qtest/result/afl/checkpoint.json" reference: api_key: "${DEEPSEEK_API_KEY}" endpoint: "https://api.deepseek.com/beta/chat/completions" model: "deepseek-v4-flash" temperature: 1.0 top_logprobs: 20 timeout_sec: 45.0 extra_payload: thinking: { type: disabled } vendors: - name: deepseek-official-control base_url: "https://api.deepseek.com/beta" path: "/chat/completions" api_key: "${DEEPSEEK_API_KEY}" model: "deepseek-v4-flash" schema: openai timeout: 45.0 extra_payload: thinking: { type: disabled }要点说明:
- 参考侧:
reference是唯一需要top_logprobs的端点;配置同时支持endpoint或base_url + path两种写法(_endpoint拼接逻辑见 repeated.py)。 - 被测侧:
vendors列表使用与长序列 QTest 完全一致的 schema,可自由扩展任意待审计路由。采集时目标客户端会强制max_tokens=1且strip_response=False(保留原始空白等非规范输出,见 repeated.py),因为精确匹配映射要求不丢失任何字符信息。 - checkpoint 续跑:采集支持断点续跑。每次写断点都会先计算
protocol_fingerprint(对采样数、温度、上下文、参考与 vendor 配置脱敏后的 SHA-256,见 repeated.py),续跑时若指纹不一致会直接报错拒绝混用,保证"同一个协议续跑,不同协议隔离"。测试test_collection_checkpoint_resumes_without_duplicate_requests验证了续跑不会产生重复请求(tests/test_qtest.py)。断点文件同样以0o600权限写入(repeated.py),与配置导出保持一致的密钥保护策略。 - 结果文件:
latest.json包含方法说明、协议指纹、protocol(采样数/上下文数/温度/先验参数/抽样次数/种子)、参考与路由的公开配置(API Key 会被脱敏为<redacted>)、base_reference_probabilities、逐上下文的context_results、逐路由的route_results以及raw_samples原始采集数据。
五、OpenRouter 自动发现与一键审计
除手工编写 vendor 配置外,模块还提供了两条自动化路径(实现在 openrouter.py):
qtest openrouter-providers --model <model>:调用 OpenRouter 的GET /api/v1/models/{model}/endpoints获取该模型的全部 provider endpoint,打印 provider 名称、tag、量化方式、近 30 分钟 uptime/延迟/吞吐与定价;--json可输出完整原始数据。可用--api-key或OPENROUTER_API_KEY环境变量。qtest openrouter-run:一步完成"发现 provider → 生成 vendor 配置 → 执行测试 → 汇总"。其关键参数(cli.py)包括:--openrouter-model:目标模型 ID(默认moonshotai/kimi-k2.5);--include-tags/--exclude-tags:逗号分隔的 provider tag 白名单/黑名单筛选;--provider-limit:限制最多选前 N 个 provider(0 不限制);--tester-*系列:参考分布端点的 key、model、provider、并发与请求间隔;--question:可重复传入自定义测试问题(默认使用内置问题集);--dump-config <path>:把自动生成的配置(API Key 一律替换为${OPENROUTER_API_KEY}占位符)以0o600权限写入文件;--dry-run:只做发现与配置生成,不执行测试;--no-summary:测试后不生成汇总。
build_openrouter_vendors会为每个 provider tag 生成独立 vendor 条目,并附加provider: {order: [tag], allow_fallbacks: false}锁定路由,vendor 命名前缀默认or(如or-deepinfra),tag 冲突时自动加序号(openrouter.py)。
六、结果汇总与供应商排名
运行结束后,CLI 会自动调用 summary.py 的summarize+export_reports生成三类产物:
- 供应商排名 CSV(
vendors_rank.csv):每个 vendor 一行,字段包括vendor、model、n_total/n_valid/n_skipped/n_errors、mean_abs_Z、median_abs_Z、mean_token_log_dev、mean_len、q_coverage、首次/末次出现时间,以及相对"self 基线"的偏差字段delta_abs_Z_vs_self、delta_token_log_dev_vs_self; - 运行明细 CSV(
runs_long.csv):每次运行一行,含问题、run_index、vendor、模型、abs_Z、token_log_dev、跳过原因等; - 聚合 JSON(
vendors_rank.json):与排名 CSV 同构,便于程序消费。
排名默认按mean_abs_Z升序(sort_by: mean_abs_Z,descending: false,见 default.yaml),可选字段见SORTABLE_FIELDS(mean_abs_Z/median_abs_Z/n_valid/n_total)。汇总逻辑会识别official_baseline_vendor标记或-self命名的 vendor 作为该模型的官方基线,自动计算其他 vendor 与基线的差值——这是判断"第三方推理商相对官方端点保真度损失"的核心参照系(summary.py)。
七、测试与可信度保障
模块附带了覆盖统计内核与协议的单元测试 services/api_checker/tests/test_qtest.py,可作为理解语义的活文档:
test_estimator_detects_a_large_known_shift:构造 90/10 与 50/50 的已知偏移,验证bias_corrected_KL逼近真实 KL(误差 0.08 内)且单侧 p < 0.01;test_reference_prior_and_chi_square_match_paper_code:验证参考先验默认参数与论文实现一致;test_outcome_map_requires_an_exact_label:验证精确匹配映射的边界行为;test_reference_only_pooling_conserves_probability:验证仅参考侧合并类别且概率守恒;test_target_client_can_preserve_nonconforming_whitespace:验证目标端保留空白等非规范输出;test_route_analysis_reports_afl_and_holm_p_value:端到端验证偏移路由的 AFL 高于忠实路由,且输出可信区间与 Holm p 值;test_collection_checkpoint_resumes_without_duplicate_requests:验证断点续跑零重复请求。
八、边界、限制与最佳实践
结合官方文档声明与源码实现,使用本模块时需注意:
- 实验管理流程缺省:AFL 采集支持断点续跑,但不包含论文的"三天采集、盲化、冻结、解盲"流程;若需要严格的受控实验,应在外部自行安排时间窗与盲化。
- API Key 依赖:所有测试都需要对应供应商的真实 Key;未设置的占位符会被原样保留并告警,测试会因鉴权失败而大量 skip。
- 参考侧必须是"可信"接口:长序列 EFL 要求参考接口支持
logprobs/top_logprobs,AFL 仅参考侧需要;被测侧可以是没有概率输出的纯文本端点。 - 字符级 vs token 级:长序列测试目前按字符切分前缀(
check.py文件头已注明),若需严格 tokenizer 对齐需自行扩展;digits默认 100 位。 - 并发与限速:vendor 并发会被参考侧在途上限自动压制;HTTP 429 会触发全局 60 秒冷却,长任务建议搭配
checkpoint_every控制断点频率。 - 隐私与安全:自动生成/保存的配置文件、断点与 AFL 结果均以
0o600权限写入,导出配置中 Key 一律替换为环境变量占位符,结果文件中的密钥字段脱敏为<redacted>。
总体而言,Ventor QTest 模块为aig_api_checker提供了"官方端点对照 + 全供应商横评"的双路径保真度审计能力:qtest run适合有概率输出接口的高精度逐位审计,qtest afl-run适合纯文本接口的大规模重复请求统计审计;两者共用一套 vendor 配置 schema、统一的结果落盘与排名汇总体系,可直接嵌入到 AI 基础设施供应商准入、路由质量巡检与推理部署回归测试等日常安全运营流程中。
【免费下载链接】AI-Infra-GuardA full-stack AI Red Teaming platform securing AI ecosystems via Agent Scan, Skills Scan, MCP scan, AI Infra scan and LLM jailbreak evaluation.项目地址: https://gitcode.com/GitHub_Trending/ai/AI-Infra-Guard
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考