jevaudit — 通用校准审计器
Audit ANY decision model, not just Jev. decide → HCTDIP 物理闸门 → 三指纹账本 → Brier + 基线 + 校准曲线报告。
Why
任何"模型给概率、事后有真值"的决策系统都需要审计:置信度 p 和真实结果 o 到底差多少?是不是瞎猜?基线是多少?jevaudit 把审计变成三件套: 账本(可回溯)+ Brier(可比较)+ 校准曲线(可诊断)。
- 三指纹账本:input_hash / output_hash / code_hash——输入给偏了、模型漂移了、 判定脚本改了,首查指纹
- 基线内置:全猜 0.5 的 Brier = 0.25 常数(与结果分布无关),模型低于 0.25 才是有用——报告自动对比,难听话自动打(>0.4 直接写"接近随机")
- 前视防护:审计时只看决策时点可得的信息,结算后的信息严禁进输入
Install
pip install jevaudit
Quickstart
from jevaudit import add_record, load_ledger, input_hash, output_hash, code_hash
from jevaudit import gate2, brier_score, calibration_curve, report
# 1) 每次决策记一条(三指纹 + check_spec 必填)
add_record("ledger.jsonl", {
"id": "dec-001",
"input_hash": input_hash(state, questions), # sha256(规范输入)[:32]
"output_hash": output_hash(response), # sha256(响应)[:32]
"code_hash": code_hash(), # 默认哈希当前主脚本
"p": 0.95, # 模型给的置信度
"outcome": 1, # 真实回填结果 (1/0)
"check_spec": {"baseline": "implied_price", "tick": 0.01}, # 用的什么基准
})
# 2) 审计:Brier + 基线 + 校准曲线
rows = load_ledger("ledger.jsonl")
b = brier_score([r["p"] for r in rows], [r["outcome"] for r in rows])
curve = calibration_curve([r["p"] for r in rows], [r["outcome"] for r in rows])
report(rows, "calibration_report.md") # 产出 Markdown(含 0.25 基线对比行)
# 3) 门控:KEEP / CONFIRM / DROP
action = gate2(0.75) # KEEP (>=0.7) / CONFIRM (0.3-0.7) / DROP (<0.3)
HCTDIP 物理闸门(0.2.0 新增)
两层闸门,分工不同,不互相替代:
| 层 | 函数 | 判什么 | 输出 |
|---|---|---|---|
| 物理层 | hctdip.gate(state, decision) |
延迟 / 因果链 / 算力 / 越界——系统在物理上安不安全 | ACT / VETO + 理由码 |
| 置信层 | gate2(p) |
按 p 分档 | KEEP / CONFIRM / DROP |
先过物理层,ACT 之后才进置信层。物理层不评判决策内容。
| 理由码 | 条件 |
|---|---|
BOUNDARY |
boundary_violation 为真,或决策值非数字 / NaN / 越出 [0,1] / 空 |
A4_NO_CAUSAL_TRACE |
缺响应 id / usage / p |
A1_DELAY |
latency > max_latency(默认 1.5s) |
A6_COMPUTE |
compute_usage > compute_limit(默认 440 input tokens,按 100 条真实调用校准) |
from jevkit import Client
from jevaudit import audited_call, hctdip
c = Client() # 读 OPENROUTER_API_KEY
q = {"resolve_yes": {"type": "noul", "instructions": "Will X happen?",
"criteria": {"true": "X happens", "false": "X does not"}}}
out = audited_call(lambda: c.decide(q, state="..."), ledger_path="ledger.jsonl",
record_id="dec-001", inputs=q)
if out["gate"]["decision"] == "ACT":
... # 再交给 gate2(out["p"]) / 执行层
rows = load_ledger("ledger.jsonl")
print(hctdip.scorecard(rows, known_code_hashes={rows[0]["code_hash"]: "my runner v1"}))
调用抛异常 → 无决策值 + 无因果记录 → 必然 VETO,不会放行。
实测(2026-09-29):100 条真实 Jev 调用全部 ACT(延迟最高 0.74s,tokens 最高 400);
100 条物理故障注入(A1/A4/A6/BOUNDARY 各 25)拦截 100%,正常对照组 0 误拦。
两组数据都在 tests/data/,测试逐条复现闸门结论。
因果记录 + 审计前置验证(0.2.0)
每次 gate() 返回 gate_evidence,4 条规则各一条,ACT 也记:
{"rule": "A1_DELAY", "check": "latency <= max_latency (s)", "value": 0.33, "limit": 1.5, "passed": true, "ts": "2026-09-29T15:14:35.356Z"}
出成绩单前必须过两条验证,任何一条不通过 → AuditRejected(拒审):
from jevaudit import require_verified, AuditRejected
KNOWN = {"src-0daa5ad4e46b": "runner v1", "src-...": "runner v2"} # 已知版本指纹登记表(历史版本也登记)
try:
require_verified(rows, KNOWN) # = verify_ledger_integrity + verify_causal_completeness
except AuditRejected as e:
print(e.report) # 逐条失败明细
verify_ledger_integrity():用账本里存的input_payload/raw_response重算 input_hash / output_hash;code_hash 必须在登记表里(不给登记表 = 全部失败,fail-closed)verify_causal_completeness():4 条证据齐全、字段齐全、passed 与 value/limit 自洽、ACT/VETO 与证据一致;audit_mode必须是 LIVE / REPLAY,REPLAY 必须同时有call_ts和replay_ts
physical_gate(并入自 0.1.1)
from jevaudit import require_task_env, log_action
task, agent = require_task_env() # 缺 R0T_TASK_ID / R0T_AGENT_ID → exit 2
log_action(task, agent, "hctdip:VETO", evidence=gate_result) # 目录:参数 > R0T_LOG_DIR > /var/minis/shared/logs/r0t
audited_call(..., task_id=task, agent_id=agent) 会自动把每次闸门结果连同证据写进 R0-T 日志。
Gotchas(三轮实战沉淀,踩不到的坑)
- Brier 难看时,第一步永远是证伪校验基准(真值语义/价格语义/结算语义), 第二步才怀疑模型——两次实战:真值生成器语义反了 → Brier 必然反向
- price 列严禁精确校验:展示价是截断/舍入价(残差恒 < 0.0125),
真执行价 =
implied_price(usdcSize/size);校验用 tick 级容差(0.01/0.001) - check_spec 必填:记录用的什么基准/容差,让"度量分歧"可回溯, 不然下个人又把基准当真值查一遍
- ["0","0"] 是退化态:已结算二元市场必须恰好一边=1,两边全 0 = 未真结算,拒
- outcomePrices 可能是字符串(JSON 编码数组),先 json.loads 再算
- 残差 <0 的反例(~1.4%)疑似 SELL 侧语义:标注
reverse,不判死不混入 - 样本 <3 不下结论;漂移率 |mean_p − mean_o| > 0.01 如实打 ❌,不圆场
配套
- jevkit(PyPI):OpenRouter Decisions API (Jev) 的第一个开源第三方客户端 —— client + CLI + gate 模式
- 实战战绩:n=100 黑箱审计(Polymarket 真实交易 vs Jev,前视防护 100/100)
License
MIT
Metadata
Release files for jevaudit 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jevaudit-0.2.0.tar.gz | 22.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jevaudit-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.3 kB
Release files / jevaudit-0.2.0.tar.gz
| Download URL | jevaudit-0.2.0.tar.gz |
|---|---|
| Size | 22.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a95368a3dfed22fd5eeae285e4d32f3a19800fec710e8b5a80da39c6a93b912c
|
|
BLAKE2b-256 checksum How to use checksums |
be739372eededf2a133271f8746f641cd236411216838df31add523907b380b9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / jevaudit-0.2.0-py3-none-any.whl
| Download URL | jevaudit-0.2.0-py3-none-any.whl |
|---|---|
| Size | 19.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d7cd01b8eb03207d9e70348aafe308293e796dd05e1a0fc81e775e0e4d59f39f
|
|
BLAKE2b-256 checksum How to use checksums |
e15fd43a38ce3c44db3973b4fd700a9d30666849e732218d034682f79911b9ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|