接口文档
用 HTTP 提交一次中转站检测,再轮询拿到完整报告。检测流程和 新建检测 页面完全一样,由同一个检测引擎 rb-engine/2 执行。
接口根地址https://你的站点
鉴权不需要
频率每个 IP 每分钟 1 次
结果保留24 小时
快速开始
提交检测。填中转站的接口地址、key 和要测的模型。返回
202和检测编号。curl -X POST https://你的站点/api/v1/audits \ -H "Content-Type: application/json" \ -d '{ "base_url": "https://api.example.com", "api_key": "sk-...", "model": "claude-opus-5-5" }'轮询结果。每 3~5 秒查一次,直到
status不再是queued或running。完整检测一般要 2~5 分钟。curl https://你的站点/api/v1/audits/26c1c592bb6fb3129924c3646d590b64读结论。真伪判定在
verdict.verdict.status,质量分在verdict.quality.score,每一项的结论和证据在verdict.checks。curl -s https://你的站点/api/v1/audits/26c1c592bb6fb3129924c3646d590b64 \ | jq '{status, verdict: .verdict.verdict.status, score: .verdict.quality.score}'
限制与约定
| 项目 | 规则 |
|---|---|
| 鉴权 | 没有令牌,也不用登录。上游 key 只放在请求体的 api_key 里,不要放进 Authorization 头。 |
| 频率 | 同一个客户端 IP 每 60 秒只能创建 1 次检测;查询和读取 OpenAPI 不计次数。超出时返回 429,响应头 Retry-After 是需要等待的秒数。 |
| 排队 | 检测在服务器上排队执行。队列满时创建返回 429;排队期间查询结果里会带 queue,写明排在第几位和预计等待秒数。 |
| 保留 | 结果只存在服务器内存里,24 小时后过期,服务重启后也查不到。接口创建的检测不进入站内的检测记录,也不会出现在“我的检测”里。 |
| key | key 只用于这一次检测,不写入数据库、日志和报告。报告的请求账本只记录状态、耗时和用量。 |
| 请求体 | 必须是 Content-Type: application/json,最大 96 KB,只能有一个 JSON 对象,出现未列出的字段会被拒绝。 |
| 接口地址 | 要带 http:// 或 https://,末尾带不带 /v1 都可以;不能带用户名密码、查询参数或 #片段。内网和本机地址不会被连接。 |
| 用量 | 检测会真实调用上游,完整一次约 30~40 个请求,用量记在你的 key 上。 |
创建检测
POST/api/v1/audits
提交一次检测,立即返回检测编号。检测在后台执行,用返回的 poll_url 查询进度和结果。
请求体
| 字段 | 类型 | 说明 |
|---|---|---|
base_url 必填 | string | 中转站的接口地址,例如 https://api.example.com 或 https://api.example.com/v1 |
api_key 必填 | string | 中转站的 key,最长 4096 字节 |
model 必填 | string | 要检测的模型名,原样发给上游;1~256 字节,不能有换行或制表符 |
protocol | string | 接口格式:auto(默认,按模型名选择)、chat(/v1/chat/completions)、anthropic(/v1/messages)、openai(/v1/responses) |
timeout | integer | 单个请求的超时秒数,10~600,默认 360 |
sections | string | string[] | 要跑的检测项。省略或传 "all" 表示全部(含缓存读写);也可以传检测项数组,取值见 检测项 |
{
"base_url": "https://api.example.com/v1",
"api_key": "sk-...",
"model": "gpt-6-astra",
"protocol": "openai",
"timeout": 300,
"sections": ["identity", "reasoning", "tools", "effort", "signature"]
}响应 202
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 检测编号,32 位十六进制 |
status | string | 创建时总是 queued |
sections | string[] | 实际会跑的检测项,按固定顺序排列 |
skipped | object[] | null | 被跳过的检测项和原因;没有跳过时为 null |
poll_url | string | 查询这次检测的路径 |
expires_at | integer | 过期时间,Unix 秒 |
{
"id": "a7d15f85ea94f11b9f1a0b4445849a2f",
"status": "queued",
"sections": ["identity", "reasoning", "tools", "effort"],
"skipped": [{ "id": "signature", "reason": "思维签名只适用于 claude 模型,已跳过" }],
"poll_url": "/api/v1/audits/a7d15f85ea94f11b9f1a0b4445849a2f",
"expires_at": 1794081426
}查询检测
GET/api/v1/audits/{id}
返回检测的当前状态。检测进行中也能查,已完成的检测项会陆续出现在报告里。
响应 200
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 检测编号 |
status | string | 检测状态,见下表 |
model | string | 请求的模型名 |
base_url | string | 提交的接口地址 |
host | string | 接口地址的主机名 |
created_at | string | 创建时间,RFC 3339 格式 |
expires_at | integer | 过期时间,Unix 秒 |
queue | object | 只在排队时出现:position 第几位、waiting 排队数、running 运行数、eta_seconds 预计等待秒数 |
probes | object[] | 每个检测项的进度:id、name、status(queued、running、done、error、cancelled)、ms 耗时,出错时带 error |
verdict | object | 检测报告,结构见 报告结构。注意这个字段装的是整份报告,真伪判定本身在 verdict.verdict |
检测状态
| status | 含义 |
|---|---|
queued | 排队中,还没开始 |
running | 正在检测 |
done | 全部检测项都已结束 |
partial | 已结束,但有检测项因请求失败没有结论 |
cancelled | 超过最长运行时间(15 分钟)被停止,已完成的检测项照常保留 |
{
"id": "26c1c592bb6fb3129924c3646d590b64",
"status": "running",
"model": "claude-opus-5-5",
"base_url": "https://api.example.com",
"host": "api.example.com",
"created_at": "2026-11-06T19:57:06Z",
"expires_at": 1794081426,
"probes": [
{ "id": "identity", "name": "模型指纹", "status": "done", "ms": 31840 },
{ "id": "reasoning", "name": "推理题", "status": "running", "ms": 0 },
{ "id": "effort", "name": "推理强度", "status": "queued", "ms": 0 }
],
"verdict": { "engine": "rb-engine/2", "checks": [ … ] }
}报告结构
报告分两层结论:真伪判定只看模型指纹,回答“是不是声称的那个模型”;质量分由其余检测项按权重合成,回答“服务好不好”。两者互不影响。
| 字段 | 类型 | 说明 |
|---|---|---|
engine | string | 引擎版本,目前是 rb-engine/2 |
model | string | 请求的模型名 |
protocol | string | 实际使用的接口格式:messages、responses 或 chat |
verdict.status | string | genuine 真、suspicious 可疑(家族不符)、diluted 掺水(型号不符)、unknown 无法判断 |
verdict.title | string | 一句话结论 |
verdict.basis | string[] | 判定依据 |
quality.score | integer | 质量分,0~100 |
quality.parts | object[] | 每个计分项的权重 weight、重新分配后的占比 share、得分 points |
complete | boolean | 核心项(模型指纹、推理题、工具调用)是否都有结论 |
checks | object[] | 每个检测项的结论,字段见下表 |
usage | object | 本次检测在上游的总用量:input、output、cache_read、cache_write、reasoning |
requests | integer | 发出的请求数 |
ledger | object[] | 请求账本:每个请求的检测项、协议、HTTP 状态、第几次尝试、耗时和用量;不含对话内容 |
total_ms | integer | 总耗时,毫秒 |
checks[] 里的每一项
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 检测项编号,见 检测项 |
label | string | 检测项名称 |
state | string | pass 通过、anomaly 异常、unknown 没有结论(不扣分)、na 不适用(不计入)、info 只展示 |
score | number | 0~1,只有计分项有 |
summary | string | 一句话结论 |
reason | string | 这项是怎么测的 |
evidence | object | 原始证据,结构因检测项而异 |
error | string | 请求失败时的原因 |
ms | integer | 耗时,毫秒 |
requests | integer | 这一项发出的请求数 |
质量分只按有结论(通过或异常)的检测项计算,没有结论和不适用的项不计入,其余项按原权重重新分配到 100。详细规则见 评分方法。
检测项
sections 的可选值。传数组时会按下表顺序执行,不认识的名字会返回 400。
| id | 名称 | 权重 | 测什么 |
|---|---|---|---|
identity | 模型指纹 | 判定 | 连写几百个随机数,在指纹库里归因型号和家族;唯一决定真伪判定的一项 |
overhead | 注入开销 | 10 | 每次请求被额外塞进多少 token |
signature | 思维签名 | 5 | 思维块签名能否被上游验证;只适用于 Claude 模型 |
reasoning | 推理题 | 30 | 随机出题、程序判分,并抽两题重复作答看是否稳定 |
tools | 工具调用 | 15 | 能否按要求调用工具并接住工具结果 |
structured | 结构约束 | 10 | 能否严格按要求只输出一个 JSON 对象 |
hierarchy | 指令层级 | 10 | 系统提示是否生效、能否被用户消息覆盖 |
effort | 推理强度 | 5 | 推理强度参数是否原样传到上游 |
web | 联网搜索 | 5 | 原生联网工具能否返回来源;Chat 接口不适用 |
cache | 缓存读写 | 5 | 多轮对话里缓存是否被写入和命中;不传 sections 或传 all 时包含 |
protocol | 协议字段 | 5 | 统计其他检测项拿到的响应:id、model、结束原因和用量是否齐全 |
stream | 流式完整性 | 5 | 统计其他检测项的流式响应:开头、结束事件和数据格式 |
cutoff | 知识截止 | 参考 | 用已知日期的公开事件二分查找,只展示,不计分 |
signature只适用于 Claude 模型:模型不是 Claude 时会被跳过,写在skipped里;如果只选了这一项,返回400。protocol和stream不单独发请求,统计的是同一次检测里其他检测项拿到的响应,所以要和其他检测项一起选。- 权重是全部计分项都有结论时的分值;有项没结论时,按比例重新分配。
错误码
出错时响应体是 { "error": "原因" },原因是给人看的中文说明。
| 状态码 | 什么时候 | 怎么办 |
|---|---|---|
400 | 请求体不是合法 JSON、有多余字段、必填字段缺失或格式不对、检测项名字不认识 | 按 error 里的说明修正后重新提交 |
404 | 检测编号不存在,或者服务重启后结果已丢失 | 重新创建检测 |
410 | 检测已超过 24 小时有效期 | 重新创建检测 |
415 | Content-Type 不是 application/json | 加上 Content-Type 请求头 |
429 | 同一 IP 一分钟内重复创建,或检测队列已满。频率超限时响应体还带 retry_after | 等 Retry-After 响应头给出的秒数后再试 |
503 | 服务正在升级切换,暂时不接新检测 | 等 Retry-After 秒后重试 |
{ "error": "公共检测每分钟 1 次", "retry_after": 60 }服务信息
GET/api/v1
返回接口版本、引擎版本、频率限制、可选检测项和累计检测次数。不计入创建次数。
{
"name": "relaybench",
"engine": "rb-engine/2",
"version": "v1",
"public_audits": 128,
"rate_limit": { "limit": 1, "window_seconds": 60, "scope": "client_ip", "counts": "POST /api/v1/audits" },
"sections": ["identity", "overhead", "signature", "reasoning", "tools", "structured", "hierarchy", "effort", "web", "cache", "protocol", "stream", "cutoff"],
"docs": "/docs",
"openapi": "/api/v1/openapi.json",
"history": false,
"retention": "24h memory, dropped on restart"
}GET/api/v1/openapi.json
同一套接口的 OpenAPI 3.1 描述,可以直接导入调试工具或交给代码生成器。