| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 |
I4 · 响应时间专项评测 —— 这一批数据是怎么来的
任务书(用户 2026-09-23 11:25):「需要相同数据库和服务器,评估响应时间, 对比 opencode,重点看响应时间」。
1. 把变量压到只剩引擎
| 变量 | 做法 | 证据 |
|---|---|---|
| 机器 | 专用评测机 hca-bench-01(8 核 31G,只跑评测,不与任何项目共用);两侧栈同时在机器上,交错执行、每轮换先手 |
每批的 same-db-proof.txt 头两行记了 hostname 与 uptime;每一次运行的 loadavg_before/after 在 index.json 里 |
| 数据库 | 两边共用同一个 api 进程、同一个 postgres 实例、同一个库、同一行用户 | 每批开跑前跑一次 deploy/eval/i4-same-db-proof.sh,输出存 <批次>/same-db-proof.txt,七条判据全绿才开跑 |
| 数据 | 每一次运行前把两侧工作区账本恢复成同一份种子(run_ab.py 的 reseed);用户域数据在同一个库里,本来就是同一份 |
index.json 每行的 reseed_rc |
| 缓存 | 两边共用同一套 api + redis + postgres,缓存状态天然一致;每批先预热一次、数据丢弃 | 预热跑进 <批次>/warmup/,汇总脚本不读它 |
| 模型通道 | 同一个网关、同一把 key、同一个模型名 hunter-chat |
每一次运行记 quota_used_before/after 与差值 quota_delta |
1.1 为什么没按任务书那条「基线栈改指到 HCA 那套 postgres」去改
因为不需要改,现状已经比那条更强。评测拓扑里本来就只有一套后端:
- HCA 侧只起
daemon+llm-shim(deploy/eval/docker-compose.i2.yml), 它的 hunter 系 MCP 通过HERMES_API_URL打基线那套 api (deploy/eval/docker-compose.hca-api.yml,网络别名hunter-api); - 社区版
opencode打的是同一个容器(服务名api); - 那个 api 只连一个 postgres,而整台机器上只有这一个 postgres 容器。
所以两边共用的不是「两个同构的库」,是同一个 api 进程 + 同一个库 + 同一行用户。 任务书里那条退路(两库同构 + 每次恢复同一份 dump)因此没有被触发, 也就没有「两种口径各一组数」这回事 —— 只有一种口径,而且是更强的那种。
2. 七条同库判据(deploy/eval/i4-same-db-proof.sh)
- 整台机器在跑的 postgres 容器只有 1 个;
- 两个引擎的
HERMES_API_URL在各自容器里解析出来的 IP,都属于同一个 api 容器; - 那个 api 的
DATABASE_URL解析出来就是那唯一的 postgres,库名与实例system_identifier都打出来; users表里那一行的 id == HCA daemon 的HUNTER_USER_ID== 社区版会话登记表chat_session_owner里的user_id;- / 6. 真调用:两个引擎各打一次
/api/internal/quant/market_screen, 每次调用前后各读一次pg_stat_database.xact_commit—— 事务数涨了, 才算这次调用真的落到了这个实例上(不是看配置,是看行为)。 - 社区版走它自己那条身份解析链路(登录 → 建会话 → 登记 →
GET /api/internal/session/{sid}/user)必须解析出同一行用户,零 token。 这一条是本轮补的 —— 前六条全绿的那一批后来被作废了,见下面第 8 节。
任何一条不成立,i4-batch.sh 直接退出,不开跑。负向验证过:故意把口令写错 →
第 7 条 ✗、脚本 rc=6、批次不开跑。
3. 题与遍数
| 批次 | 题集 | 线 | 每题每边 |
|---|---|---|---|
idle-b |
q0-idle(纯引擎空载题) |
产品形态(HCA 全量 MCP) | 20 |
i4-b |
I1 的 10 道题 | 产品形态 | 10 |
idle-a |
q0-idle |
A 线(HCA 压成与社区版相同的 6 个 MCP) | 20 |
i4-a |
I1 的 10 道题 | A 线 | 6 |
四批实跑:idle-b 40 次 / i4-b 200 次 / idle-a 40 次 / i4-a 120 次,
七条同库判据全绿;社区版共 199 次运行,会话归属登记 199 次全部 HTTP 200。
唯一没产出记录的是 q9-multiturn-opencode-r4(撞 600 s 上限,index.json 记 rc=1)。
空载题题面:「用一句话说明你是什么。不要调用任何工具。」—— 两边同一句,实测两边都是 1 轮、0 次工具调用。
4. 分段计时的口径
见 tools/eval/i4_summary.py 的模块注释(那份是权威口径,报告与
summary.json 都由它生成,不手抄)。一句话版本:一次运行切成
模型段 / 工具段 / 出字段 / 收尾段,HCA 侧四段之和 == 墙钟(实测残差 < 1 ms);
社区版的收尾段量不到(阻塞 POST,没有独立的结束事件),写 null,
它的上界就是残差(实测 24~32 ms)。
两个首字延迟都给:
ttft_ms= 第一块正文到达 —— 但本部署的人设要求模型在一批工具调用前 先发一行「路标」,所以这一块正文可能是进度提示而不是答案; 表里「其中路标」那一列标出了 n 次里有几次是这样。ttft_answer_ms= 末轮第一块正文开始 = 真正的答案开始出字。 两边同一口径,不受路标影响。跨产品比较以这一个为准。
5. 「原样」与「都真做题」两套数
I1 §3.11 记过:q2 上社区版有几次没做这道题 —— 反过来要用户把论点贴出来
(而 theses/601088.md 就在它自己的工作区里)。这种运行又快又短,
混进中位数里会让对照组显得很快。所以每道题给两套数。
判据与耗时无关、逐句判:一句话里同时出现「祈使 + 索要动作 + 要的是这道题的
材料」三件事才算(i4_summary.punt_sentence,会把命中的原话吐出来);
空答案也算没做题;不作用于 q4 / q10。
在全部 597 次有记录的运行上逐条打印命中并人工核过:命中 12 次、全部属实、0 误伤。
summary.json 每道题带「剔除明细」(剔了哪一次、为什么、原话)。
6. 这批数据不能拿去做什么
- 不能跨天和 I1 / I2 / I3 的绝对值比。 I3 §1 用同一份配置隔一夜重测, D 维度差了 1.4 分 —— 漂的是 HCA 这种大请求在不同时段拿到的服务质量 (待办池 U-19)。能比的只有同一批次内两边的相对关系。
- 不能当评分用。 这一轮不打四维分,只量时间;题目的对错口径仍以 I1 为准。
- HCA 的代码是 main(v0.2.1),不是 I1 当时的 v0.2.0;Kronos key 与 I1 一样是接上的,
所以
q4的 B 线数字与 I2 / I3 不可比(I2/I3 那几轮 key 是空的)。 - 更不能和 I1 的绝对值相减:I1 那一轮社区版没有用户身份(见第 8 节), 它的绝对值本身偏快。
7. 目录里有什么
docs/eval/i4/
README.md ← 这份
summary.json ← 机器可读,给 PPT 取数;每个数字带 source
tables.md ← 逐题分段计时表(由 i4_summary.py 生成)
hook-bench.json ← HCA 侧 hook 开销直测(社区版没有 hook 机制)
idle-b/ i4-b/ idle-a/ i4-a/
<题>-<边>-r<n>.json 结构化记录(含全文、瀑布、配额差值)
<题>-atomcode-r<n>.sse HCA 侧原始 SSE(带到达时刻注释行,可完整重放)
<题>-opencode-r<n>.raw.json 社区版原始消息
<题>-*-r<n>.shim.jsonl llm-shim 的请求瀑布追踪(只记尺寸与耗时)
index.json 每次运行的 rc / 负载 / 剩余配额 / 账本恢复结果
same-db-proof.txt 本批开跑前的同库取证
warmup/ 预热,**汇总时不读**
8. 两个作废的批次(*-作废-token401)
i4-b-作废-token401(150 次)与 idle-b-作废-token401(20 次)是开跑后才发现
口径不成立而作废的,原样留档、去掉 .sse 省体积,claim_status 逐条可查。
原因:eval-account.json 里存的是建号那一刻的 access token,而 api 发的 access token
只活 1 小时(实测 exp − iat = 3600)。评测账号 2026-09-22 16:50 建的,所以
从 17:50 起社区版的会话归属登记一直是 401 —— 包括 I1 的全部 60 次社区版运行。
失败是静默的:watchlist_* / portfolio_* 照样返回数据,只是那是「没有用户」的数据。
三处修法(提交 ca5cc86):eval_opencode.py 每次运行前用口令文件换新 token;
同库判据补第 7 条;i4_summary.py 每批输出「社区版身份解析」块,有一次失败就判不可用。
详见 docs/开发文档/I4-响应时间评测报告.md §6.1。