Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions evals/reports/recall-judge-effort-20261017.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# RJ-B1:召回判断推理档位与延迟(2026-10-17)

推荐只将 `recall_judge.reasoning_effort` 设为 `low`,保留 `[chat]` 的 `high`。插件上线观察先采用 `judge_budget_seconds=7`、`prepare_timeout=12`。两档各跑完七份公开语料:low 的判断 P95 为 2.214 秒(high 3.657 秒),各语料 Recall 与 relevant 精确率均不下降,无答案误返均为 0;合计 nDCG 下降 0.0013,主要来自更完整召回后的顺序变化。符合 AGENTS「召回与验证」守则,无须申请退化例外。此结论限本轮公开 dev,不代替隐藏验收或线上延迟验证。

**运行口径与复现材料**

基线为任务启动时 fetch 得到的 `origin/main`:`189cce89c04a1e219c82c2ca6b7f4abb4e39b1da`;当时本地 main 与之相同。独立分支 `eval/recall-judge-effort`,worktree 为 `/Users/cassia/Local/Code/iris-core-recall-judge`。真实实验时间 2026-10-17 18:39:15—19:08:11(Asia/Shanghai),先 low 连通探测,再 high 全轮、low 全轮。产品代码、提示词、语料、迁移、默认设置均未修改;仓库仅新增本报告。

提交前观察到 origin/main 已前进至 `d9fc539`(#122,询问过期设置)。本报告的运行材料、源码指纹及双版本测试均绑定上列 `189cce8` 基线。

方舟文档对 GLM-5.3-Flash 的实际档位映射为 low/high/max,其中 medium 与 high 等效,因此本次只比较有不同实际含义的 high 和 low;该模型始终启用思考。文档依据为[方舟深度思考说明](https://docs.volcengine.com/docs/ark/deep-thinking?lang=zh)(2026-10-17 查询)。当前配置端点的 low 探测成功,响应报告了 13 个推理 token;未发送关闭推理参数。探测不计入下面 191 次正式判断。

原 `IRIS_TEST_MODELS=/Users/cassia/Local/Code/iris-core/test-models.toml` 通过产品配置加载器用于连通检查和本次运行;`uv run iris models check` 的 chat、embedding 均成功,只查看成功结论。临时 `configs/high.toml`、`configs/low.toml` 只用 `api_key_env` 引用进程环境变量,密钥不写文件。程序逐项核对 `[chat]` 以及其他用途配置不变,仅为 recall_judge 单独设置档位。

旧 `m2-recall-judge/run-review-1/`、旧执行脚本和主仓库 `data/recall-embeddings.db` 在本机均不存在。本次从公开语料重新生成 471 个 embedding,全部成功;low 复用同端点、模型、2048 维及完整输入文本的缓存,新增 embedding 请求为 0。

采用产品 `run_recall_eval` 的 `default_judged`、全部七份冻结语料、243 条固定记忆和 228 条查询;各语料隔离入库。217 条 prepare 中 191 条实际判断、26 条无候选,另 11 条 search 不判断;历史 split 只保留为分组,全部公开样本按 dev 使用。K=8、支持分 50、recall_judge_v1、召回参数均沿用基线。没有重新标定或修改标签。

外部执行脚本只增加留档和首错停止:embedding 串行预取;每个 prepare 前间隔 1 秒(预算外);正式判断使用产品 10 秒上限。任何一次非成功调用或 prepare 降级立即作废当前轮并停止整个实验,不重试或继续下一档。两轮复用建库后的同一快照,避免随机主体 ID 导致 about 顺序变化;191 对实际请求除 reasoning_effort 外逐项完全相同,输入 token 总量也相同。调用记录和响应正文留在仓库外,推理只保留出现标志、长度和用量,不保存全文。

质量由既有固定标注和 `recall_metrics` 计算,未另调模型判分。Recall/nDCG 对有答案查询计算,包含人物要点;relevant 精确率按标注正确的 relevant 返回数/全部 relevant 返回数合并计数;无答案误返只检查 reason=relevant。合计按全部查询重新计算,非七个均值的简单平均。

**质量:每格为 high → low**

| 语料/分组 | 查询数 | Recall@8 | nDCG@8 | relevant 精确率 | 无答案误返 |
| --- | ---: | --- | --- | --- | --- |
| recall_v1 | 38 | 0.9667 → 0.9667 | 0.9843 → 0.9843 | 0.9722 → 0.9722 | 0/8 → 0/8 |
| recall_v2 | 66 | 0.9733 → 0.9733 | 0.9490 → 0.9490 | 1.0000 → 1.0000 | 0/16 → 0/16 |
| recall_conversation_v1 | 24 | 0.9167 → 0.9444 | 0.9399 → 0.9283 | 1.0000 → 1.0000 | 0/6 → 0/6 |
| recall_short_terms_v1 | 16 | 1.0000 → 1.0000 | 1.0000 → 1.0000 | 1.0000 → 1.0000 | 0/4 → 0/4 |
| recall_conversation_v2 | 24 | 1.0000 → 1.0000 | 1.0000 → 1.0000 | 1.0000 → 1.0000 | 0/6 → 0/6 |
| recall_conversation_v3 | 20 | 1.0000 → 1.0000 | 1.0000 → 1.0000 | 1.0000 → 1.0000 | 0/4 → 0/4 |
| recall_no_answer_v1 | 40 | 1.0000 → 1.0000 | 1.0000 → 1.0000 | 0.9474 → 1.0000 | 0/22 → 0/22 |
| 合计 | 228 | 0.9763 → 0.9794 | 0.9747 → 0.9734 | 0.9880 → 0.9940 | 0/66 → 0/66 |
| 原三集合计(子集) | 128 | 0.9609 → 0.9660 | 0.9581 → 0.9560 | 0.9901 → 0.9902 | 0/30 → 0/30 |
| 对话中准备(子集) | 88 | 0.9750 → 0.9833 | 0.9820 → 0.9785 | 1.0000 → 1.0000 | 0/28 → 0/28 |

合计 Recall +0.003086、nDCG −0.001281、relevant 精确率 +0.006024,误返均为 0/66。high 为 164/166 个 relevant 返回标注正确,low 为 165/166。对话中准备 Recall +0.008333、nDCG −0.003458、精确率不变,误返均为 0/28。

七份语料、原三集合计及对话中准备均满足更严格的 Recall 不下降;精确率均未下降,误返没有增加,守住 AGENTS 的精确率降幅不超过 0.03、误返最多增加一条的要求,也未触及 evals/README.md 的单语料 Recall 下降超过 0.05 需规划者决定的线。nDCG 的下降单列,不能说所有指标都改善。

228 条查询中仅两条返回不同,其余 226 条的 ID/顺序/reason 完全一致:

| 查询 | high → low | 支持分变化与影响 |
| --- | --- | --- |
| recall_conversation_v1 / T11 | C10 → C09、C10 | C09 20→60,C10 95→90;补回等级 1 的 C09,等级 3 的 C10 排到第二。本集 Recall +0.027778,nDCG −0.011528。判断不重新排序。 |
| recall_no_answer_v1 / NA03 | N09、N41 → N09 | N41 65→30,N09 均为 95;去掉未标注相关的 N41,本集精确率 18/19→18/18。该题有答案,故不改变无答案误返数。 |

**判断耗时与预算**

单位为秒,来自 model_calls.duration_ms;包括实际 HTTP 等待与响应解析/校验,不含排队及随后记账。P50/P95 用 NumPy 线性百分位。只统计实际判断,search 和无候选项不作为零耗时样本。

| 语料 | 每档调用数 | P50 high → low | P95 high → low | 最长 high → low |
| --- | ---: | --- | --- | --- |
| recall_v1 | 35 | 1.6570 → 1.0950 | 2.6607 → 2.0299 | 2.7710 → 3.3510 |
| recall_v2 | 58 | 1.7555 → 1.1305 | 3.5705 → 3.0681 | 5.3560 → 4.0010 |
| recall_conversation_v1 | 19 | 1.7460 → 1.2040 | 3.0557 → 1.7905 | 3.6830 → 2.1640 |
| recall_short_terms_v1 | 4 | 2.3230 → 1.1030 | 3.4946 → 1.3225 | 3.5750 → 1.3530 |
| recall_conversation_v2 | 20 | 1.4940 → 1.0235 | 2.7945 → 1.6906 | 3.3160 → 1.7220 |
| recall_conversation_v3 | 19 | 1.8870 → 1.1550 | 4.8303 → 3.2359 | 6.0030 → 4.1800 |
| recall_no_answer_v1 | 36 | 1.8850 → 1.2025 | 3.5133 → 2.4192 | 4.8810 → 3.8330 |
| 合计 | 191 | 1.7330 → 1.1280 | 3.6565 → 2.2135 | 6.0030 → 4.1800 |

| 档位 | 5 秒预算:估算超阈值 | 7 秒预算:估算超阈值 | 10 秒预算:实际超时 | 429 | prepare 降级 |
| --- | ---: | ---: | ---: | ---: | ---: |
| high | 2/191(1.05%) | 0/191 | 0/191 | 0 | 0/217 |
| low | 0/191 | 0/191 | 0/191 | 0 | 0/217 |

5/7 秒列是同一轮 10 秒预算下的逐调用耗时阈值统计,没有重新发出 5/7 秒请求,也不模拟连续错误暂停后的级联降级。按整个 judgment.duration_ms 重算,计数仍为 high 的 2/0 和 low 的 0/0。它们是预算风险估计,不是线上短预算实测超时率。10 秒列则为调用记录中的实际 timed_out。

high 超过 5 秒的两次为 recall_v2/H06(5.356 秒)和 recall_conversation_v3/V05(6.003 秒)。包含材料组织、排队、记录和健康状态更新的整个 judgment,high 的 P50/P95/最长为 1.805/3.734/6.103 秒,low 为 1.202/2.281/4.270 秒;此整体计时也包含外部留档的少量开销。

| 档位 | 输入 token | 输出 token | 其中推理 token(已含在输出) |
| --- | ---: | ---: | ---: |
| high | 137348 | 11253 | 7710 |
| low | 137348 | 4392 | 904 |

low 的调用 P50 下降约 34.9%,P95 下降约 39.5%。本轮各档只运行一次,顺序固定为 high 后 low;供应商负载、缓存和随机性可能影响差异,不能把全部差异都归因于档位。公开输入与真实群聊不同,查询 embedding 在评测中预缓存;这不是插件端到端 prepare 的 P95。尤其不能由本表断言线上原 34% 超时会降为 0。

**现行暂停机制与建议改动(仅报告,未实施)**

结论是会计入,但须区分 HTTP 已发出与纯本地排队两种情况。`models.py:416—454` 将宿主预算转为共享 deadline,HTTP 超时参数使用剩余预算;`models.py:532—556` 将 FutureTimeout、HTTP 客户端超时及截止后才收到的成功结果记为 retryable、timed_out=1,并调用 health.observe。`model_health.py:215—229` 每次累加 consecutive_errors,第三次进入 temporarily_unavailable,首次 60 秒后探测。计数属于 recall_judge 用途,不暂停 chat;跳过判断不产生成功观测,也不重置计数。召回判断本身每次只有一次尝试;探测走独立用途预算,成功可恢复。

因此“服务商在 5 秒时还未回答”与“服务商/网络故障”会进入同一错误计数路径;错误摘要虽可能是 total timeout 或 ReadTimeout,仍没有宿主预算来源的语义区分。纯排队满/排队耗时用尽,以及发请求前预算已经耗尽,则在 observe 之前返回,不增加计数。迟到 HTTP 工作线程继续占用准入槽位直到结束,建议继续保持此约束以限制在途负载。

外部假网络复现走原 Gateway 和 ModelHealth,使用假时钟,不发真实请求:

| 场景 | 三次后的状态 | 错误计数 | 60 秒后成功探测 |
| --- | --- | --- | --- |
| 宿主 5 秒预算,HTTP 200 在假时钟 5.01 秒返回 | temporarily_unavailable | 1→2→3 | 恢复 normal |
| HTTP 客户端 ReadTimeout | temporarily_unavailable | 1→2→3 | 恢复 normal |
| 服务商 HTTP 504 | temporarily_unavailable | 1→2→3(timed_out 字段为 0) | 恢复 normal |
| 本地队列连续耗尽 5 秒预算 | normal | 始终 0,无模型调用记录 | 不需探测 |

建议规划者安排独立实现任务:在 `src/iris/models.py` 显式区分 caller_budget、用途内部超时和上游错误来源;在 `src/iris/model_health.py` 将宿主主动缩短预算的到期作为中性结果,不累加服务商错误,也不冒充成功清零。网络连接错误、服务商 408/504、429 和账户错误沿用相应健康规则。保留当前降级、短预算、有界排队、迟到结果丢弃与槽位约束,不能因区分原因而延长宿主等待。

同时在判断诊断/运行记录里单列预算、排队和网络耗时及超时来源,并在 `tests/test_recall_judge.py`、`tests/test_model_health.py` 覆盖三次宿主预算到期不暂停、真正网络错误仍暂停、混合事件计数以及迟到请求占槽位。诊断字段和持久化方案需规划者审查 v1 兼容性后安排;本报告不改接口或迁移。

**推荐配置与上线观察边界**

推荐 `recall_judge.reasoning_effort=low`、`judge_budget_seconds=7`、`prepare_timeout=12`;其他用途和 chat high 不变。落地时保留现用端点、模型和凭据引用,保存完整的独立 recall_judge 用途配置并设置 low。本轮 low 的整个 judgment 最长 4.270 秒,5 秒已能容纳全部样本;考虑真实负载未知且线上原 5 秒截断严重,建议上线观察期间保留额外 2 秒判断余量。

prepare_timeout 额外保留 5 秒:查询 embedding 上限为 2 秒,剩余用于接收消息等待、HTTP 往返及本地处理。已只读核对 iris-connectors `78633912a0466f9787724f90173c6c6bf3335d26` 的 bridge.py:155,插件总预算从 receive 前开始,包含等候消息提交,不能简单与 judge 预算设成相同。12 秒是上线观察用的工程余量,不是经本次端到端测量证明的上界;持续积压时仍可能用尽。

本次只提出组合,不写线上设置。上线先复核既有超时、排队、prepare 总耗时与降级记录;若落实上述原因区分,再单列 caller_budget 和上游失败。上线效果仍需真实日志确认。

**作废运行与验证**

作废运行:无。high、low 两轮均有效,正式判断成功 382/382,429=0、实际超时=0,prepare 降级 0/434;另一次 low 能力探测和 471 次 embedding 均成功。没有超时后重跑、按结果挑选或追加模型调用。

Python 3.13.13(`uv run pytest`):3713 passed、8 warnings,1153.36 秒;随后 Python 3.12.12(`uv run --locked --isolated --python 3.12 pytest`):3713 passed、8 warnings,1152.90 秒。两个版本顺序运行,`.venv` 保持 Python 3.13;自己的 `.pytest-tmp` 已删除。四项假网络健康机制复现全部通过。测试在真实评测结束后运行;产品源码及七份语料哈希再次核对一致。

全部完整材料在 `/Users/cassia/Local/Code/iris-eval-artifacts/RJ-20261017/`:manifest.json、两份临时环境变量引用配置、rj_evaluate.py、rj_analyze.py、rj_health_repro.py、calls.jsonl、high/ 与 low/ 的完整 JSON/正文、summary.json、health-reproduction.json、embedding 缓存与语料快照、执行及测试日志。没有复制虚拟环境或 node_modules,未另做 CPU 压测。旧材料缺失不影响本次两轮自包含对照。

源码 SHA-256:`fe29aa8d21919100628f755c0b60362e2ce7fe70f4d9c15cb55ff60487c1e965`(两轮前后相同);提示词 SHA-256:`0260a07b58977c42435a3379dbdb23455a653a53060c82df2e773abdbf1f2ed3`;外部执行脚本 SHA-256:`fddd9189f865cca28343dd70c5fccf07174784e7c80f5764d543d88768b851fa`。七份语料的原文件哈希在 manifest.json 中。执行脚本拒绝覆盖既有 manifest;未来若规划者安排新实验,须用新的材料目录保留独立运行,不能覆盖本次材料。