外部校准接入(Headline Arena 试点)¶
状态:试点支撑,非自动接入。立项来源见 issue #1。 本文记录接入原则、题域边界、真实接口契约与试点操作流程。
为什么做这件事¶
本框架的反思闭环已经能把「预测对不对」当一等信息处理:
历史预测 → akshare 拉实际收益 → LLM 生成反思教训 → 写回记忆
但这套回路有一处方法论上的薄弱:判卷的是自己。记忆系统说「这次教训学到了」, 没有任何外部证据能证明它不是自我安慰。
外部校准通道补的就是这一环——接入一个结算规则出题时冻结、由平台按真实行情机械结算、 记分卡与校准曲线公开可复查的第三方记分板。两条线互相印证,是纯内部反思给不出的证据。
⚠️ 题域边界(必须随结论一起呈现)¶
这不是对本框架 A 股判断力的裁决
Headline Arena 结算的是宏观期货与官方统计方向(黄金、原油、标普、美债、铜、 美元指数、Civic Index 等),而本框架的预测对象是 A 股个股/ETF 评级。 两条线测的不是同一件事——外部校准曲线反映的是「同一批 agent 换到宏观市场、 换一套结算口径之后的校准度」,属于通用反作弊参照,不能作为本框架 A 股个股判断力的裁决。
该声明在代码里固化为 astock_trader.external_calibration.ASSET_DOMAIN_BOUNDARY,
并强制出现在每一份比对报告里——包括机器可读的 JSON 输出与 Markdown 报告,
避免报告被单独摘出去引用时丢失口径。相关测试:test_boundary_is_always_attached、
test_report_states_the_domain_boundary。
三条硬约束¶
| # | 约束 | 落地方式 |
|---|---|---|
| 1 | 题域错位要如实标注 | ASSET_DOMAIN_BOUNDARY 常量 + 报告强制内嵌 |
| 2 | 凭证纪律 | 凭据只从环境变量读,绝不入 repo、绝不写盘;无凭据时全链路优雅跳过 |
| 3 | 不污染反思闭环 | 外部结算写入独立台账,每条记录带 source: external_headline_arena;台账拒绝写入 trading_memory.* 路径 |
约束 3 是硬性的:ExternalCalibrationLedger 在构造时就会拒绝指向内部交易记忆文件名的
路径(_assert_isolated),把误用拦在第一次写入之前。内部 akshare 自检与外部机械结算
必须分开存放,否则反思闭环再也无法区分「哪些教训来自自评、哪些来自外部裁定」。
真实接口契约¶
以下契约于 2026-09-12 依据官方 OpenAPI 规范
(https://headlinearena.com/api/openapi.json)核对,并以真实公开 agent 实机验证通过。
读侧(公开,无需登录/凭据)¶
| 用途 | 端点 |
|---|---|
| 预测历史(含机械结算结果) | GET /api/v1/eval/agents/{agent_id}/predictions |
| 公开校准曲线 | GET /api/v1/eval/agents/{agent_id}/calibration |
| 公开记分卡 | GET /api/v1/eval/agents/{agent_id}/scorecard |
- 预测历史支持
since(ISO 8601)做增量同步,limit上限 100。 - 响应含
gated字段:往季归档需要 Pro/Max Data API key,当季公开。 被 gated 时接口照常返回当季数据,不影响试点。
写侧(需凭据,本仓库暂未启用)¶
| 用途 | 端点 |
|---|---|
| 换取 access token | POST /api/v1/agent/auth/token(client_credentials) |
| 提交方向性预测 | POST /api/v1/eval/challenges/{challenge_id}/predict |
按 issue #1 的约定,正式接入 PR 之前先跑一轮人工试点,因此本仓库当前 不包含自动提交预测的代码。提交由人工完成(官方插件或网页端), 本通道只负责记录、同步与比对。
实测踩坑:必须带 User-Agent
平台前置网关对缺少 User-Agent 的请求直接返回 403(即使端点是公开的)。
客户端已统一发送 UA;回归测试:test_requests_always_carry_user_agent。
快速开始¶
# 公开读端点只需要 agent id,不需要任何 secret
export HEADLINE_ARENA_AGENT_ID=<你的 arena agent id>
python3 scripts/external_calibration.py --force status # 台账与环境配置概览
python3 scripts/external_calibration.py --force sync # 拉取预测历史与结算结果
python3 scripts/external_calibration.py --force report # 生成两条线比对报告
试点期需要在提交给平台之前冻结内部判断,两条线才能配对:
python3 scripts/external_calibration.py --force mirror \
--challenge-id <challenge_id> \
--direction bullish --confidence 0.65 \
--asset GC --origin macro_assessment \
--rationale "实际利率见顶 + 央行购金延续"
本地判断默认写一次即冻结:重复写入会被拒绝,必须显式 --overwrite
才能修正。这是为了让「提交前的内部判断」在事后无法被结算结果反向污染。
环境变量¶
| 变量 | 必填 | 说明 |
|---|---|---|
HEADLINE_ARENA_AGENT_ID |
读侧必填 | 未配置时全部操作优雅跳过(退出码 0,不是错误) |
HEADLINE_ARENA_CLIENT_SECRET |
写侧 | 仅换取 access token 时需要 |
HEADLINE_ARENA_TOKEN |
可选 | 预置 bearer token |
HEADLINE_ARENA_BASE_URL |
可选 | 覆盖 API 根地址 |
ASTOCK_EXTERNAL_CALIBRATION_DIR |
可选 | 覆盖台账目录 |
配置项(default_config.py)¶
"enable_external_calibration": False, # 总开关,试点期默认关闭
"external_calibration_provider": "headline_arena",
"external_calibration_dir": "", # 空则 project_dir/external_calibration
"headline_arena_base_url": "https://headlinearena.com/api/v1",
"headline_arena_timeout": 15,
总开关默认关闭。CLI 是显式调用的试点工具,加 --force 可在开关关闭时照常运行;
将来自动通道落地时,这个开关就是唯一的总闸。
台账与来源隔离¶
默认位置:~/.astock_trader/external_calibration/headline_arena_ledger.jsonl
JSONL 追加式,一行一条,record_type 区分两类记录:
{"record_type": "arena_settlement", "source": "external_headline_arena",
"prediction_id": "...", "challenge_id": "...", "asset": "ZS",
"direction": "bearish", "confidence": 0.45, "result": "bearish",
"is_correct": true, "score": 72.5, "created_at": "...", "ingested_at": "...",
"payload": {"…平台原始返回,完整保留结算溯源…"}}
- 追加式 + 后者胜出:同一预测从「未结算」变为「已结算」时追加新行而非改写历史, 读取时取最后一次出现——既有幂等性,又保留完整溯源链。
- 平台原始返回整包保留在
payload字段,便于事后核对结算口径。
两条线怎么读¶
| 线 | 来源 | 含义 |
|---|---|---|
| arena 线 | 平台机械结算 | 我们真正提交的预测,由第三方按冻结规则判对错 |
| 本地镜像线 | 提交前冻结的内部判断 | 同一批 challenge 上本框架自己的宏观方向判断,用平台冻结结果机械打分 |
报告同时给出:命中率、平均置信度、Brier 分数(越低越校准)、两条线方向一致率, 以及平台公开校准曲线的分箱偏差(正=偏保守,负=过度自信)。
报告会自动标注小样本与低配对覆盖率,避免把「1 条样本 100% 命中」读成校准良好。
试点节奏与判定标准¶
- 手动注册 arena,用一周时间每天提交与内部宏观判断同源的方向性预测(可人工转写);
每次提交之前用
mirror冻结对应的内部判断。 - 两周后用
sync+report对比:arena 校准曲线 vs 本框架内部宏观判断命中率。 - 两条线方向一致 → 开正式接入 PR(插件本体 + 一条
reflection_loop外部参照通道)。 不一致 → 关闭 issue 并归档对比数据 —— 那份归档本身也是有价值的结果。
相关代码¶
| 路径 | 职责 |
|---|---|
src/astock_trader/external_calibration/schema.py |
数据结构、SOURCE_TAG、题域边界声明 |
src/astock_trader/external_calibration/arena_client.py |
只读 REST 客户端,无凭据优雅降级 |
src/astock_trader/external_calibration/ledger.py |
追加式台账 + 来源隔离守卫 |
src/astock_trader/external_calibration/reconciliation.py |
两条线配对与报告渲染 |
scripts/external_calibration.py |
试点 CLI(sync / mirror / status / report) |
tests/test_external_calibration.py |
80 项测试,覆盖三条硬约束与全部降级路径 |