Jev 批量形态落地记录:底座 + 场景准入
- 承接:
https://decision.ht1072.top/2026-09-21-jev-batch-form-stage1-record-2026-09-21.html - 回滚方案(本地):
~/llm-wikis/knowledge-ops/queries/jev-batch-form-rollback-plan-2026-09-21.md - 证据目录:
~/llm-wikis/knowledge-ops/evidence/jev-batch-form-2026-09-21/
Jev 批量形态落地记录:底座 + 场景准入
结论
批量原语已落地到 jev_client.py(decide_batch_records / decide_batch_multi),三个候选场景按「收益 ∝ 调用点数」逐场景评估后只有 retain 预筛准入批量。噪音复核与 wiki 分诊被实测否决:前者批量削弱了它的核心价值(救回规则误杀的真新闻),后者批量收益只有 0.5 秒而 notify_prob 是唯一门控信号。两个被否决的场景都保留了批量分支但默认关闭,可用 env 单独开启;生产净行为改变仅限影子模式的 retain 预筛。
推荐方案
保持当前默认:retain 预筛走批量,噪音复核与 wiki 分诊走串行。去重(7 对,收益约 3.5 秒)等 serial/batch 双写一周后再定。重要度扫描受 score 偏移门禁限制,维持影子。
底座:decide_batch 的两条形态
| 原语 | 用途 | 形态 |
|---|---|---|
decide_batch_records(records, spec) |
多条独立记录各问一个问题 | state 带 policy 隔离声明 + records 字典;每个问题自动加 scope 子句绑定到自己的记录 ID |
decide_batch_multi(state, spec) |
同一份材料问多个角度 | 单 state 多问,不涉及多记录绑定 |
三条硬性要求(全部来自阶段 1 的实测失败模式,写进代码不可省):
- 隔离句必带:无隔离句时 score 批量全部塌缩到 3.0 附近,完全失去区分度
- 绑定校验在客户端:网关对不存在的记录 ID 会编造带 0.91 置信度的答案,不会报错——发送前校验「问题 ID ⊆ state.records 键」,接收后比对「answers 键 == questions 键」,越界答案单独记账
- 分组上限 40 条:超限自动拆批(单请求约 200 tokens/条,32k ctx 下约 150 条为物理上限)
响应校验同时覆盖概率范围、有限性、label 覆盖,脏数据不入库。
自测结果(真实调用)
| 测试 | 结果 |
|---|---|
| 绑定校验 | 混入 r99(state 中无此记录)→ 拒绝发送,不发请求 ✅ |
| 真实批量 10 条 vs 串行 | 批量 0.46s / 串行 10 次 9.6s;逐条偏移全部 ≤0.01 ✅ |
| 拆批(group_limit=3) | 10 条 → 4 组,10/10 应答 ✅ |
| 同 state 多问 | 2/2 应答,notify=0.32 / urgency=1.2(与历史维护场景一致) ✅ |
| 响应校验 | 越界概率、非数值、inf、缺字段、空 choice 全部拒绝 ✅ |
| 旧原语回归 | decide_boolean / decide_score 行为不变 ✅ |
| 回滚路径 | JEVI_BATCH=0 → 两个批量原语返回失败 → 调用方自动退回串行,实测噪音复核 form=serial 且救回行为正确 ✅ |
场景准入评估
判据:批量收益随调用点数放大,风险随「该信号是否唯一门控」放大。
| 场景 | 调用点数 | 批量收益 | 风险 | 结论 |
|---|---|---|---|---|
| retain 预筛 | 35(20 对 + 15 条) | ~17.5s → 1.23s,成本 -42% | 影子模式,不拦截任何记忆 | 准入(默认开) |
| 去重 | 7 对 | ~3.5s | 不可逆删除,阈值邻域曾出现跨线 | 待双写一周 |
| 噪音复核 | 1–3 条 | ~1s | 实测削弱误杀救回 | 否决(默认关) |
| wiki 分诊 | 2 | ~0.5s | notify_prob 是唯一门控 |
否决(默认关) |
| 重要度扫描 | 20 | ~10s | score 偏移未过门禁 | 维持影子串行 |
关键发现:噪音复核的批量版本削弱了核心价值
4 条真实案例对照(2 条真导购 + 2 条曾被规则误杀的真新闻):
| 条目 | 串行 | 批量 | 动作 |
|---|---|---|---|
| TCL 电视限时折扣 | 0.99 confirmed_noise | 0.97 confirmed_noise | 一致 |
| 开学季教育优惠 | 0.98 confirmed_noise | 0.95 confirmed_noise | 一致 |
| Anthropic $45B deal(真新闻) | 0.01 rescued | 0.02 rescued | 一致 |
| Slate Auto 电动卡车(真新闻,曾被误杀) | 0.18 rescued | 0.41 落灰区 → 保持移除 | 不一致 |
这条场景的核心价值是「救回规则误杀」,批量把它从「救回」推到「保守移除」,方向是漏救。单条样本不足以断言系统性退化,但收益只有约 1 秒/天,风险/收益不划算——所以默认串行,代码保留开关供条目数变大时启用。
retain 预筛批量运行实测
扫描 40 条记忆
重复确认[batch]: 20/20 应答 | 0.72s | $0.000247
价值评分[batch]: 15/15 应答 | 0.51s | $0.000142
40 条 | 重复候选 28 对 | Jev确认重复 17 对 | 成本 $0.000388
对照串行基线:35 次调用约 17.5s、$0.00067 → 批量 2 次请求 1.23s、$0.000388(约 14× 速度、-42% 成本)。重复判定结果与串行版一致(16 → 17 对,同量级)。审计记录新增 form 字段。
影子数据保护:本次为验证运行,已备份并恢复 ~/.hermes/logs/hindsight-retain-prescreen/ 的 latest.json 与当日 history,避免 09-23 影子期汇总重复计数;运行产物另存证据目录。
风险与边界
- 被否决场景的开关仍在:默认关闭但可被 env 打开,若误开会让噪音复核回到「漏救」状态。已在代码注释写明实测依据
- 绑定校验是客户端责任:网关不报错,任何绕过
decide_batch_*直接构造 payload 的代码都会失去这层保护 - 分数跨形态不可比(承接阶段 1):批量与串行的分数不能混入同一条校准序列,run log 已带
form字段区分 - 去重尚未切:7 对场景的阈值邻域风险(阶段 0 曾观测 0.60→0.87 跨删除门槛)仍未解除
- 批量单点失败面:一个请求影响整批,靠分组上限 + 缺答按 ID 记账 +
JEVI_BATCH=0全局回退兜底
改动清单与回滚
| 文件 | 改动 | 默认行为 |
|---|---|---|
~/.hermes/scripts/jev_client.py |
新增三个批量函数(旧原语未动) | 批量可用 |
fetcher.py(morning-brief) |
噪音复核加批量分支 | 串行(开关默认 0) |
wiki_alert_triage.py |
分诊加批量分支 | 串行(开关默认 0) |
hindsight_retain_prescreen.py |
重复确认 + 价值评分走批量 | 批量(影子模式) |
回滚:JEVI_BATCH=0 一键全局退回串行(已实测);或按场景开关单独关;或按指纹还原 jev_client.py.bak-20260921-batch-form。完整指纹、三级回滚与触发条件见本地 rollback plan。
证据与验证
- 自测:
result_batch_selftest.json(7 项,含回滚路径) - 噪音复核对照:
result_switch_noise_verify.json - retain 预筛批量运行:
result_retain_prescreen_batch_run.json - 脚本:
jev_batch_selftest.py、verify_switch_noise.py - 本轮真实调用成本约 $0.003
行动清单
- 待确认:去重场景是否启动 serial/batch 双写一周
- 待确认:重要度扫描是否按批量形态重跑影子期(阈值需重新校准)
- 待观察:retain 预筛 09-23 影子期汇总会带上
form=batch数据,可对比历史串行样本