检测
用随机挑战检测一个 API 渠道,连续多轮,保存报告并离线重新计算。
示例
# 显式传入连接参数
npx lmfpd@latest -b https://api.example.com/v1 -k sk-xxx -m gpt-6-astra
# 从环境变量读取连接参数;使用 Chat Completions 并设置推理强度
npx lmfpd@latest -a cc -e high
# 连续检测 5 轮
npx lmfpd@latest -n 5
# 每轮只发一个请求
npx lmfpd@latest -b https://api.example.com/v1 -k sk-xxx -m gpt-6-astra --count 1
# 严格模式、关闭流式响应,并保存完整报告(不含凭据)
npx lmfpd@latest -s -ns --timeout 180 --output result.json
# 离线重新分析已保存的报告,不请求模型
npx lmfpd@latest --input result.json --json
# 同时做分词器探测(多发约 12 个请求)
npx lmfpd@latest -a cc --tokenizer参数
| 参数 | 说明 | 默认值 |
|---|---|---|
-b, --baseurl URL | Base URL 或完整端点;未写端点路径时自动补全 | $BASE_URL |
-k, --apikey KEY | API Key | $API_KEY |
-m, --model MODEL | 请求的模型名 | $MODEL |
-a, --api TYPE | responses、chatcompletion(或 cc)、message,可只写前缀 | responses |
-e, --effort LEVEL | 推理强度,例如 low、high,也可填供应商自定义值 | 不发送 |
-t, --service-tier TIER | 服务等级:flex、default、fast、ultrafast,可只写前缀;别名 slow(flex)、f(fast)、uf(ultrafast)、priority(fast)、standard(default) | default,不发送 |
-ns, --no-stream | 使用普通 JSON 响应代替 SSE | SSE |
--timeout SECONDS | SSE 首字节时限;JSON 模式下为完整响应时限,支持小数 | 120 |
--count N | 每轮样本数,1–3;少于 3 条时只给出排名 | 3 |
-p, --parallel N | 每轮并发数,1–3,不超过 --count,不改变请求总数 | 3 |
-n, --repeat N | 顺序执行的检测轮数 | 1 |
-s, --strict | 关闭自动截断,要求 3 条完整有效的回答 | 关闭 |
--challenges FILE | 每轮复用保存的挑战,数量必须等于 --count | 随机生成 |
--bank FILE | 使用自定义参考库;检测器读取同一目录下的 shared_detector.bin | 内置参考库 |
--tokenizer | 做分词器探测,多发约 12 个请求;有没有探测,排名都相同 | 不探测 |
--max-probes N | 分词器探测的测试文本数量上限,4–60;只能与 --tokenizer 一起使用 | 20 |
--tokenizer-bank FILE | 使用自定义分词器库;只能与 --tokenizer 或 --input 一起使用 | 内置分词器库 |
--input FILE | 离线分析保存的输出 | — |
--output FILE | 把所有轮次、请求设置、挑战、收到的文本和结果保存为 JSON | — |
--json | 向 stdout 输出 JSON,代替终端界面 | — |
--no-update-check | 关闭后台更新检查 | 开启 |
只写到主机名的地址(如 https://api.example.com)使用 /v1;带路径的 Base URL 保留该路径并追加所选端点。Messages 请求使用 x-api-key 与 anthropic-version 头。服务等级在 Messages 中作为 speed 发送,并附加 anthropic-beta: fast-mode-2026-02-01 头;在 Responses 与 Chat Completions 中作为 service_tier 发送。Responses 与 Chat Completions 的检测请求不设可选的输出上限;Messages 按该 API 的要求保留 max_tokens: 8192。
取样行为
每轮用共享的挑战生成器生成 --count 道随机挑战(默认 3 道),提示词保持不变以保证采样方法一致。-p 1 只是把请求串行化,-n 1 只运行一轮。固定一道挑战时使用 --count 1 --challenges one-challenge.json,文件是只含一个元素的数组,元素带 id、prompt 和 expected_count;数组长度不符会在发出任何请求前被拒绝。
流式样本收到要求数量的完整整数后停止,界面标为 Capped;JSON 响应超量时在收到后裁剪。取消前收到的原始文本保留在样本记录中;不完整的末尾整数不会触发截断。一两条有效样本也能给出排名,但没有置信度;置信度校准需要三条有效样本。
自然结束的样本至少需要 max(80, ceil(expected_count × 0.55)) 个有效数字,与评分器一致。拒答、供应商错误或未完成的响应会被拒绝,除非宽松模式已经在要求数量处停止它。失败的样本保持可见,并保存在结果中。
每轮等全部样本结束(包括失败的请求)后才开始下一轮;并发上限按轮计算,不超过样本数。检测不自动重试,某轮失败不影响后续轮次。
计时从每个请求发出时开始。SSE 的第一个非空响应体数据块(包括心跳或元数据事件)就会清除计时器,只收到响应头不算;SSE 开始后不再有客户端时限或 Bun 空闲超时。JSON 模式下整个响应都必须在时限内到达。
按 q 或 Ctrl+C 会取消进行中的请求,排队的请求和后续轮次不再开始;使用 --output 时,取消前收到的样本会被保存。最后一轮结束后分词器探测还在进行时,这两个按键只停止探测,结果全部保留。重定向输出得到静态报告,进度写入 stderr:每条样本、每轮评分后立即给出的第一候选,以及使用 --tokenizer 时的探测结果。--json 让 stdout 只含机器可读结果。
结果与离线重新计算
bun run fpd --output result.json
bun run fpd --input result.json
bun run fpd --input result.json --strict --json--input 接受:保存的报告、带 outputs 的报告、由一到三个 { "text": "...", "expected_count": 300 } 组成的数组,或采样批次的 result.json。采样批次按条件分组,每轮最多三条回答;多轮报告逐轮分析。严格重新计算会拒绝记录为截断或完整性未知的样本;纯输出数组无法核实原始的网络完成状态。--count 只用于在线检测,不能与 --input 同用。
三条样本都有效且校准与检测器匹配时,结果标为 Calibrated ranking,每个候选附带置信度;校准不匹配时标为 Uncalibrated ranking,只给出排名,置信度不可用。终端界面显示最新排名和最近几轮的摘要;至少一轮评分后,末尾以暗色显示 GitHub 仓库链接。JSON 保留每一轮。“最常见候选”统计的是各轮的第一名,不是合并概率。置信度只在参考库模型之间比较,不能确认上游模型的身份。自定义参考库与检测器不匹配时,检测报错停止,提示运行 fpd retrain --data-dir DIR。
每一轮只按数字指纹评分,样本完成后立即给出结果。使用 --tokenizer 时,分词器探测的结果单独显示在一个区块里,只作参考,不改变候选、顺序或置信度。使用 --input 时,报告里保存的分词器探测显示在同一个区块里;读取它不发送请求。
某条样本的最小有效数字不低于 200 时,界面提示该样本分布异常、结果不可靠。这种分布由提示词引起:随机挑战时重新运行会抽到新的提示词;使用 --challenges 时需要替换文件中对应的提示词。
退出码
| 退出码 | 含义 |
|---|---|
0 | 所有轮次都给出了排名(宽松模式下的部分排名也算成功) |
1 | 输入无效,或有任一轮未能评分 |
130 | 被取消,包括最后一轮结束后停止分词器探测 |
143 | 收到 SIGTERM |
最后更新于