Files
Jyotisha/docs/tasks/TASK-rectification-jev-intent-classifier-research-v2-20260927.md
T
Jesse_ChenandClaude Fable 5.1 710c848b30 docs(tasks): Jev intent research v2 — put previous turn into state
Research brief reopening the 09-19 Jev evaluation: same model
(jev-1.13.0), only the state changes (previous turn + previous
decision + continuation Noul, per Magpie v0.1.142). Re-extract
source B with case_id; thresholds unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0199rbQDTsUbCVw84wc8BTFe
2026-09-27 11:15:07 +08:00

11 KiB
Raw Blame History

TASK · Jev 意图分类研究 v2:把上一轮放进 state(2026-09-27)

  • 类型:研究单(只离线测,不改线上代码路径)
  • 基线:origin/staging @ 828aca0a
  • 执行分支:codex/jev-intent-v2-20260927,worktree .worktrees/jev-intent-v2-20260927
  • 前序:TASK-rectification-jev-intent-classifier-research-20260919.md(含 -fix / -fix2),报告 docs/research/jev_intent_2026_09_19.md
  • 产品指示(2026-09-27):"请你忽略上次用 jev 测试的结果 …… 写吧然后 push 我去拿 key"

1. 为什么重开

外部信号:Magpie v0.1.142 把 TypeSafe Jev 接成语义路由分类器后,作者称效果"比之前好太多",改动点是把上一轮的决策加入决策链——"只承接上一轮的消息(如「继续」)沿用上一轮的 kind 与 effort;新问题单独分类;路由视图显示 Jev 被告知了上一轮什么"(发布说明原文意译)。

核实结果(2026-09-27 查官方文档):

项 事实 来源
模型 TypeSafe 只有一个模型 jev-1.13.0;jev-latest / jev-preview 都指向它。与 09-19 所测同一版本,模型没变 docs.typesafe.ai/models
上下文 64k tokens/请求;state 可为 string / object / array,官方建议"消息串用 array" docs.typesafe.ai/concepts/state
语言 "English is primary; other languages have lower accuracy currently" 同上
置信度 Choice 的 confidence ≈ (n·peak − 1)/(n − 1);建议 >0.9 自动、0.5–0.9 复核、<0.5 回退 docs.typesafe.ai/confidence
多轮 官方:Jev "holds no conversation",每次只看你送的 state;没有任何官方多轮指引。Magpie 的做法是把上一轮塞进 state OpenRouter What-is-Jev;Magpie 发布说明
价格 / 限流 $0.042 / M 输入,输出免费;250k tok/s、1200 req/min(动态) docs.typesafe.ai/models

所以博文里"效果好太多"只能来自喂法。而我们 09-19 给 Jev 的 state 与线上分类器输入完全一致,都没有上一轮。这一点是可测的新变量,重开有依据。

2. 事故实证(按符号定位,基线 828aca0a)

  1. 线上分类器输入没有上一轮:frontend/src/lib/rectification-agentic/v9/turn-intent-classifier.ts classifyRectificationTurnIntent(L212);L252–256 送模型的 JSON 只有 current_question / options / user_message / case_status。
  2. 09-19 的 Jev state 照抄线上:scripts/research/jev_intent_questions.py build_state(L204)返回同样四个字段。
  3. 真人语料没抽上一轮:scripts/research/jev_intent_samples/README.md L16–33 的抽取 SQL 只取 turn_id / user_message / created_at / case_status / question_id / expected_answer_schema,没有 case_id,也没有上一轮的 assistant_message,因此本地 source_b.jsonl 无法反推上一轮,必须重抽。
  4. 表里有可用字段:frontend/supabase/migrations/20260812010000_agentic_rectification_v9_runtime.sql L76–78 agentic_rectification_turns 有 case_id / user_message / assistant_message,索引 (case_id, created_at)(L88–89),可按案件顺序还原上一轮。
  5. 09-19 挡住上线的数(docs/research/jev_intent_2026_09_19.md §代表性检验):真人 157 条 Jev intent 91.1% vs 线上 89.2%;高置信错误 6.4%(无焦点层 12.1%)> 3%;低置信召回 24% < 60%。无焦点层 Jev 7 条错全是 gold=unclear → pred=answer_current_focus。
  6. 延迟:Jev 中位 908 ms / P95 1194 ms;线上 Flash 中位 685 ms。宣传的 70–500 ms 在本地区不成立。

3. 根因(研究假设,待本单验证)

无焦点层错例"unclear 被判成回答当前题"的共同点是:模型不知道上一轮问了什么、用户这句是接着上一轮说还是另起话头。上一轮的题和判定恰好是区分这两种情况的信息。09-19 置信度不可用(高置信错误 6.4%)可能部分源于这批错例——信息缺失时模型仍给高置信。

不做假设的部分:中文准确率天花板(官方明说非英语更差)与延迟不会因 state 改变而变,本单不指望这两项改善。

4. 决策记录

  1. 推翻 09-19 关单里的"不再造语料":产品 2026-09-27 授权重抽真人来源 B(带 case_id 与上一轮),因为旧抽样结构上无法测本单变量。仍不造新的模拟语料(来源 C 不重造、不扩)。
  2. 09-19 关单里"不接管、不影子双跑"维持:本单只离线测;过门后是否接入、是否影子双跑由产品另行拍板。
  3. 09-15"分类只用贵模型"口径维持到本单出结论。
  4. 门槛沿用 09-19,不放宽:高置信错误 ≤ 3%、低置信召回 ≥ 60%、intent 准确率 ≥ 现行 −3pp(同一样本)。
  5. 模型固定 jev-1.13.0(不用 jev-latest),响应 model 字段落报告。

5. 硬红线

  1. 不改 frontend/src/** 任何生产代码;不加 Jev 到线上调用链;不加环境变量到部署文件。
  2. 真人来源 B 原文不得提交(延续 09-19:本地 .cache/jev_intent/,gitignore);报告只出计数、混淆矩阵、脱敏错例画像(≤3 条/类,已去姓名年份地名)。
  3. 不得用正则或关键词表做任何标注、复核或"延续判定"(BUG-976/977 口径同样适用于研究代码)。
  4. 不得用模型代标 gold;上一轮的 previous_intent 若来自 Jev 自己的上一轮输出,报告里必须标明"链式(自喂)",不得写成真值。
  5. docs/BUG_HISTORY.md 只在发现研究脚本自身缺陷时记录;不得把研究结论写成 Bug。
  6. 不得顺手升级 typesafe-sdk 以外的依赖;SDK 版本写进报告 meta。
  7. 报告 JSON rows 必须含每条每个变体的原始输出,所有表内数字可由 --offline 重算(延续 09-19 验收方法)。

6. 任务分解

T1 · 重抽真人来源 B(带上一轮)

  • 改 scripts/research/jev_intent_samples/README.md 的 SQL:加 t.case_id、t.assistant_message,按 (case_id, created_at) 排;本地脚本按案件顺序为每条生成 previous_turn = {assistant_message, user_message}(案件第一轮为 null)。
  • 旧 157 条的 gold 按 turn_id 对回;新增行由执行方人工标注(延续 09-19 标注规范,runtime_intent 只作参考)。
  • 验收:报告 meta 写明 n(总 / 有上一轮 / 无上一轮)、三层分布、gold 来源(对回 / 新标)计数;n_有上一轮 ≥ 100,否则 T3 只报数不判定。原文未入库(git ls-files | grep source_b 为空)。

T2 · state 三个变体(只改 jev_intent_questions.py,加参数不删旧路径)

变体 state 问题
V0 09-19 原样(四字段) intent / answer_class / has_new_dated_event(原样)
V1 V0 + previous_turn: {assistant_message, user_message} 同 V0
V2 V1 + previous_decision: {intent, answer_class} + 新增 Noul continues_previous_turn("这句是否只是承接上一轮,没有新的意思") V0 三问 + 该 Noul;continues_previous_turn ≥ 0.9 时沿用 previous_decision.intent(Magpie 规则),否则按本轮 intent
  • previous_decision 取值顺序:链式(同案件上一条的 Jev V2 输出)为主;另跑一份用 gold 上一轮做上界,两份都进报告并分别标注。
  • enforce_combo 的结构不变量对 V1/V2 照常生效。
  • 验收:python3 -m unittest tests.test_jev_intent_research 新增 ≥3 个用例(V1/V2 state 形状、continues 规则、案件首轮 previous_turn=null)全绿,旧 11 个不动;test_criterion_map_covers_production_prompts 仍过(说明 Choice 语义没漂)。

T3 · 跑数与对照

  • 来源 B 全量:Jev V0 / V1 / V2(链式 + gold 上界)各两次(自洽率);线上 Flash 顶生产提示各一次(V0 输入 = 生产原样;另加一列 Flash + V1 输入,用于区分"上下文对任何模型都有用"还是"Jev 特有"——Flash 提示不改,只在 JSON 里多给 previous_turn)。
  • 来源 C(900 条)只跑 V0 一次做回归锚(state 未变,应与 09-19 一致 ±1pp);来源 C 没有上一轮,不跑 V1/V2。
  • 指标沿用 09-19:intent / answer_class / dated 准确率、高置信错误、低置信覆盖 / 召回、自洽率、中位 / P95 ms、次均 input tok、θ 曲线;新增:按"有上一轮 / 无上一轮"分组,以及无焦点层 unclear→answer_current_focus 计数逐变体对比。
  • 验收:报告 docs/research/jev_intent_2026_09_27.md + JSON;结论三选一:过门(三项门槛全过且 V2 相对 V0 在无焦点层高置信错误下降)/ 未过门 / 缺数据(n 不足或 B/C 分层差 > 10pp)。任何一项写不出数字就写 blocked,不得写"通过"。

T4 · 记录

  • docs/tasks/PROGRESS-rectification-jev-intent-classifier-research-v2-20260927.md:SDK 版本、模型响应 model、token 总量与费用、每变体耗时、偏离项。
  • docs/tasks/README.md 状态板改本单一行。
  • 09-19 报告顶部加一行指向本报告(不改旧数)。

7. 让步顺序

  1. 来源 B 重抽后 n_有上一轮 < 100 → T3 照跑但只报数,结论写 缺数据,不得判"过门"。
  2. gold 上界那份跑不了(旧 gold 对不回上一轮)→ 只跑链式,报告注明。
  3. Flash + V1 那一列可省(它只是归因辅助),但 Flash V0 生产原样对照不可省。
  4. typesafe-sdk 0.7.x 与 09-19 所用不兼容 → 固定到 09-19 报告 meta 里的版本,写进 BLOCKED.md。
  5. API 限流 / 超时 → 复用 call_jev_retry 与缓存,--offline 聚合;不得降样本。

8. 开工前置命令

git fetch origin --prune
git worktree add -b codex/jev-intent-v2-20260927 .worktrees/jev-intent-v2-20260927 origin/staging
cd .worktrees/jev-intent-v2-20260927
python3 -m unittest tests.test_jev_intent_research          # 基线 11 passed
pip install "typesafe-sdk==<09-19 报告 meta 版本或 0.7.2>"      # 只装 SDK,版本写进 PROGRESS
export TYPESAFE_API_KEY=…                                     # 只在 shell,不进任何文件
python3 scripts/research/jev_intent_probe.py --offline        # 应能从 09-19 缓存重算旧报告,确认工具链完整

来源 B 抽取在执行方本机对 staging 库执行,SQL 见 T1;原文落 .cache/jev_intent/source_b_v2.jsonl。

9. BUG 编号起点

docs/BUG_HISTORY.md 当前最大号 BUG-1059;本单若发现研究脚本缺陷从 BUG-1060 起编,研究结论本身不编号。

10. 验收时 Claude 会做的事

  • origin/<执行分支> 上跑 python3 -m unittest tests.test_jev_intent_research,对照 11 → ≥14。
  • 用报告 JSON rows 以 --offline 重算全部表;抽 3 处数字核对。
  • 核对 git ls-files 无来源 B 原文;报告错例画像无姓名 / 年份 / 地名。
  • 对照 §4 门槛逐条给出 过门 / 未过门 / 缺数据 / blocked。