lq_token_test 是一个 Rust 命令行工具,用来测试大模型中转站的协议兼容性、RPM 限流表现、并发表现,以及基于官方数据集的简单准确率表现。
当前支持:
cargo fmt --check
cargo test
cargo clippy --all-targets -- -D warnings
cargo run -- --help
编译 release 版本:
cargo build --release
release 二进制在:
target/release/lq_token_test
复制示例配置:
cp config.example.yaml config.yaml
示例:
default_provider: openai
providers:
openai:
protocol: openai
base_url: "https://relay.example.com/v1"
api_token: "${OPENAI_RELAY_TOKEN}"
default_model: "gpt-4o-mini"
thinking:
enabled: false
reasoning_effort: "medium"
reasoning_summary: "auto"
anthropic:
protocol: anthropic
base_url: "https://relay.example.com"
api_token: "${ANTHROPIC_RELAY_TOKEN}"
default_model: "claude-3-5-sonnet-latest"
thinking:
enabled: false
type: "enabled"
budget_tokens: 10000
display: "omitted"
google:
protocol: google
base_url: "https://generativelanguage.googleapis.com/v1beta"
api_token: "${GOOGLE_API_KEY}"
default_model: "gemini-3-pro-preview"
stream: true
thinking:
enabled: true
budget_tokens: 5000
effort: "high"
display: "summarized"
benchmarks:
data_dir: "data/benchmarks"
aime2026:
source: "huggingface:MathArena/aime_2026"
split: "train"
gpqa_diamond:
source: "huggingface:Idavidrein/gpqa"
split: "gpqa_diamond"
设置 token:
export OPENAI_RELAY_TOKEN="..."
export ANTHROPIC_RELAY_TOKEN="..."
export GOOGLE_API_KEY="..."
注意:工具只会解析当前使用的 provider token。比如只运行 --provider anthropic 时,不需要设置 OPENAI_RELAY_TOKEN。
thinking 参数可以写在 provider 配置里,也可以用 CLI 覆盖:
cargo run -- check --provider anthropic --prompt "hello" \
--thinking true \
--thinking-type enabled \
--thinking-budget-tokens 10000 \
--thinking-display omitted
cargo run -- check --provider openai --prompt "hello" \
--thinking true \
--reasoning-effort high \
--reasoning-summary auto
Anthropic 开启 thinking 时,请求体不会再发送 temperature。
Google Gemini 开启 thinking 时,会写入 generationConfig.thinkingConfig:budget_tokens 对应 thinkingBudget,effort 对应 Gemini 3 的 thinkingLevel,display: summarized 会发送 includeThoughts: true,display: omitted 会发送 includeThoughts: false。
OpenAI-compatible:
cargo run -- check \
--config config.yaml \
--provider openai \
--model gpt-4o-mini \
--prompt "Reply with the word ready."
Anthropic-compatible:
cargo run -- check \
--config config.yaml \
--provider anthropic \
--model claude-3-5-sonnet-latest \
--prompt "Reply with the word ready."
Google Gemini:
cargo run -- check \
--config config.yaml \
--provider google \
--model gemini-3-pro-preview \
--prompt "Reply with the word ready."
如果不传 --model,会使用配置里的 default_model。
AIME 2026:
cargo run -- dataset fetch aime2026
下载后会生成:
data/benchmarks/aime2026/aime2026.jsonl
data/benchmarks/aime2026/metadata.yaml
GPQA-Diamond:
cargo run -- dataset fetch gpqa-diamond
如果 Hugging Face 要求认证,先设置:
export HF_TOKEN="..."
数据集目录 data/benchmarks/ 不会提交到 git。
AIME 2026 小样本:
cargo run -- bench aime2026 \
--config config.yaml \
--provider anthropic \
--limit 3 \
--concurrency 1
AIME 2026 完整测试:
cargo run -- bench aime2026 \
--config config.yaml \
--provider anthropic \
--concurrency 4
AIME prompt 会要求模型把最终答案写进 \boxed{}。评分时优先提取最后一个 boxed integer,其次只接受 Final answer: 393、Answer: 393、The answer is 393 这类明确 final-answer 格式;解释文本末尾的普通数字不会再被当成答案,会记为 no_answer。
GPQA-Diamond 小样本:
cargo run -- bench gpqa-diamond \
--config config.yaml \
--provider anthropic \
--limit 5 \
--concurrency 1
GPQA-Diamond 完整测试:
cargo run -- bench gpqa-diamond \
--config config.yaml \
--provider anthropic \
--concurrency 4
GPQA-Diamond 的 prompt 和评分按 OpenAI simple-evals 风格处理:要求模型最后一行输出 Answer: $LETTER,其中 LETTER 是 A、B、C 或 D。评分只按这个严格 Answer: 格式提取答案;如果模型只在最后单独输出 C,或输出 I choose C,会记为 no_answer。
benchmark 会输出:
当前支持 6 种 RPM 模式:
sustained
burst
token-bucket
sliding-window
window-boundary
diagnose
适合测试服务是否能长期稳定承受目标 RPM。
cargo run -- rpm \
--config config.yaml \
--mode sustained \
--provider anthropic \
--rpm 120 \
--duration 60s \
--prompt "hello"
逻辑:
每 60 / rpm 秒启动一个请求
请求可以重叠
持续 duration
适合测试瞬时并发、突发容量、初始桶容量。
cargo run -- rpm \
--config config.yaml \
--mode burst \
--provider anthropic \
--burst 120 \
--prompt "hello"
逻辑:
t=0 同时发送 burst 个请求
适合测试桶容量和 token refill 速率。
cargo run -- rpm \
--config config.yaml \
--mode token-bucket \
--provider anthropic \
--rpm 120 \
--burst 120 \
--probe-seconds 30 \
--prompt "hello"
逻辑:
先 burst 打空桶
再按 rpm 推导的 refill 速率发送探针请求
例如:
rpm = 120
refill rate = 2 req/s
适合测试滚动 60 秒窗口的恢复行为。
cargo run -- rpm \
--config config.yaml \
--mode sliding-window \
--provider anthropic \
--rpm 120 \
--burst 120 \
--probe-seconds 90 \
--prompt "hello"
逻辑:
t=0 burst
之后每秒发送探针
观察是否接近 60 秒后恢复
适合测试 fixed window 是否在自然分钟边界重置额度。
cargo run -- rpm \
--config config.yaml \
--mode window-boundary \
--provider anthropic \
--rpm 120 \
--burst 120 \
--window-offset-ms 500 \
--prompt "hello"
逻辑:
在分钟边界前发送一批请求
在分钟边界后发送一批请求
观察边界后是否明显恢复
如果不知道后端是什么限流模式,可以用 diagnose。
cargo run -- rpm \
--config config.yaml \
--mode diagnose \
--provider anthropic \
--rpm 120 \
--burst 120 \
--probe-seconds 90 \
--prompt "hello"
报告中会给出 best-effort 推断:
token_bucket
fixed_window
sliding_window
unknown
注意:真实大模型服务通常同时包含 RPM、TPM、并发数、队列长度、账号级限流、模型级限流、区域级限流等多种机制。诊断结果是强信号,不是绝对证明。
benchmark 和 rpm 都会生成 JSON 报告:
reports/*.json
查看最新报告:
ls -lt reports | head
格式化查看:
jq . reports/<报告文件>.json
当上游返回 400、429、504 等非成功 HTTP 状态时,check、bench、rpm 会自动在 outputs/debug/ 写入请求/响应 debug JSON,不需要额外参数。请求在拿到 HTTP 响应前失败时,例如连接超时、读取响应失败、流式响应中断并被统计成 request_error,也会写入 *-request-error debug JSON。
debug JSON 包含:
request_error 场景为 nullrequest_error 场景为空对象request_error 场景为空字符串request_error 场景额外包含 response.error_kind: "request_error" 和本地错误信息 response.errorAPI token 会被脱敏,但 prompt、题目内容和模型输出会原样保存。排查完后可以按需清理 outputs/debug/。
如果需要排查中转站是否改写了成功响应,可以开启 --debug-raw:
cargo run -- check --provider anthropic --stream --debug-raw --prompt "hello"
cargo run -- bench aime2026 --provider anthropic --stream --debug-raw --limit 3
cargo run -- rpm --provider anthropic --rpm 60 --duration 30s --stream --debug-raw --prompt "hello"
开启后,成功请求的原始响应也会写到:
outputs/debug/
非流式成功请求保存完整 JSON body;流式成功请求保存原始 SSE 行,包括 event: 和 data:。文件不包含 API token,但可能包含模型输出内容,所以 outputs/ 不会提交到 git。
benchmark report 包含:
RPM report 包含:
RPM report 不会保存原始 prompt,也不会保存 token。
第一次测试建议:
1. check 单次请求
2. sustained 低 RPM
3. burst 小突发
4. 数据集 limit 小样本
5. 提高 concurrency
6. token-bucket / sliding-window / window-boundary
7. diagnose
8. 完整 benchmark
示例:
cargo run -- check --provider anthropic --prompt "hello"
cargo run -- rpm --mode sustained --provider anthropic --rpm 10 --duration 30s --prompt "hello"
cargo run -- rpm --mode burst --provider anthropic --burst 10 --prompt "hello"
cargo run -- bench aime2026 --provider anthropic --limit 3 --concurrency 1
使用 benchmark 结果对比官方宣传分数时,需要尽量对齐:
当前工具的结果更适合作为:
中转站 relay benchmark signal
不要把单次结果直接当作官方 benchmark 的严格复现。