跳转至

外部校准接入(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% 命中」读成校准良好。

试点节奏与判定标准

  1. 手动注册 arena,用一周时间每天提交与内部宏观判断同源的方向性预测(可人工转写); 每次提交之前用 mirror 冻结对应的内部判断。
  2. 两周后用 sync + report 对比:arena 校准曲线 vs 本框架内部宏观判断命中率。
  3. 两条线方向一致 → 开正式接入 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 项测试,覆盖三条硬约束与全部降级路径