Files
Jyotisha/docs/tasks/TASK-rectification-latency-20260926.md
T

62 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TASK · 生时校正每轮等待过长:埋点 + 分类超时 + 发出后立即反馈(2026-09-26)
## 基线
- `origin/staging` 当前 head。分支 `codex/rectification-latency-20260926`。
- **串行**:排在 `TASK-rectification-dup-question-20260926`(同样改校正面组件)之后。
## 事故实证(产品 09-26 真机)
打字回答后「正在分析 / 正在处理…」要等很久才出正文。排查结论(`origin/staging` a57c4310,本地实测 + 代码阅读):
- 一轮打字回答串行 **5 次模型调用**,全部开思考:
1. 开流前意图分类 `classifyTurnIntentWithRetry`(`v9/turn-intent-classifier.ts`;`agent/route.ts` 约 L453 / 534 / 643 / 751 调用),用会话模型、供应商默认开 thinking,**每次尝试无超时**、最多 2 次,且发生在 `new ReadableStream` 之前 → 用户看到的是一段没有任何字节的空等;L643 分支继续时 L751 还会再分类一次。
2–5. Agent 四步(`v9/agent-run.ts` `streamAttempt`,`agentGenerationSettings(..., { thinking: "enabled", thinkingTokens: 8192 })`):强制第 0 步 `rectification-read-case`(路由已读过档案)→ `record-evidence-batch`(含引擎重算)→ `set-focus`(改写服务端定好的下一问)→ 最终正文模板句。推理内容不下发(`stream-mapping.ts`),界面只显示「正在分析…」。
- 引擎:09-15 性能审计四单(BUG-721~726)**已全部落地**;本地实测 20 个候选 0.4–0.5 s、61 个候选 2.3–2.5 s、带 `refresh_probes` 5.8–6.1 s;cProfile 热点是 `build_refinement_packet`(57–73%),refresh 分支探针算两遍;交付阶段 `vedastro-validate` 串行调外网(≤12 s)。
- 收尾 `persistNextInterviewIfIdle` 在 `agent-run.ts` 与 route `finalizeSuccessfulTurnExit` 各调一次,第二次多为空转但会重读档案。
- `RectificationRunDiagnostic` 的 `inputTokens` / `reasoningTokens` 恒为 null,`stepCount` 实际是"用过几种工具",分类耗时只在失败时记录 → 线上无法核实各段耗时。
- 估计单轮 25–90 s,模型占 85–95%;evidence_not_written 重跑时翻倍。
## 根因
串行多步 + 每步深度思考 + 开流前无超时空等 + 无进度反馈。
## 决策记录(产品 2026-09-26)
- D1 **不改**每轮最后两步(set-focus 改写与最终正文仍由模型生成,口吻不变)。
- D2 **分类保持深度思考与会话模型**(维持 09-15 决定),只给每次尝试加 **10 秒超时**;超时按现有失败路径处理(重试一次后走既有兜底),不得换模型、不得关思考。
- D3 **发出后立即反馈**:用户发出后 ≤ 300 ms 内在活动状态处出现确定性进度句,随后按阶段更新,替代一直不变的「正在分析 / 正在处理…」:
- 发出即:「收到,正在对照你的档案…」
- 记录经历开始:「正在记下这件事…」
- 引擎重算:「正在重新对照盘面…」
- 准备下一问:「正在准备下一个问题…」
- 阶段信号来自现有 `persistCommittedPhase` / 工具调用事件,不新增模型调用。这些句子属于"流式生成中",不违反"揭幕后不得出现加载态";进度句不写入 `assistant_message`。
- 为此把分类移到流内:先建流、立刻推第一句进度,再做分类。
- D4 **补埋点**:每步开始 / 结束时间、每步推理 token(供应商能给则记)、分类耗时(成功也记)、引擎每次调用耗时,写入 `RectificationRunDiagnostic`(不含用户资料与模型原文,符合隐私红线)。
- D5 **无口吻影响的服务端优化**(输出必须逐位不变,A/B 证明):
- refresh 分支里 `build_refinement_packet` 探针只算一遍;
- `persistNextInterviewIfIdle` 第二次调用在第一次已完成时跳过;
- 部署未配置时 `readV9EngineScoringIdentity` 的 `/v5/versions` 结果在进程内按版本号缓存(短 TTL)。
- D6 不在本单:去掉强制 read-case 第 0 步(需改 Skill 原文与回执不变量,另议);vedastro-validate 改后台(交付语义,另议)。
## 硬红线
1. 不换分类模型、不关分类思考、不改 Agent 各步是否开思考;不改 Skill 文本与 VOICE 口吻(进度句除外,需进 VOICE)。
2. D5 每项:同一虚构输入改前改后结果逐位一致(Python 用同机 A/B,不写死跨机浮点哈希,见 BUG-985)。
3. 分类超时测试:模拟挂起的分类调用,10 秒后进入既有失败路径,不无限等待。
4. 进度句测试:发出后第一帧(或 ≤ 300 ms)出现第一句;阶段事件驱动更新;结算后进度句消失,不进入持久化正文。
5. `jyotish_api_server.py` 不增长;全量前端测试与基线逐条一致、新增 0;Python 快速门与定向测试通过;改动断言三栏。
6. 真实浏览器(CDP 假数据 + 人为延迟)截图:发出后立刻出现进度句并随阶段变化。
## 任务分解
- T1 埋点(D4)。
- T2 分类移入流内 + 10 秒超时(D2、D3 前半)。
- T3 阶段进度句(D3)+ VOICE / DESIGN。
- T4 服务端无口吻优化(D5)+ A/B 证明。
- T5 记录:BUG-1047(每轮等待过长 / 开流前无反馈),关联 BUG-721~726、BUG-722;CHANGELOG;PROGRESS(各段耗时改前 / 改后估计,部署后用新埋点复核);`docs/testing/` 真机清单(打字回答后立刻出现「收到,正在对照你的档案…」并逐段变化;总耗时记录)。
## BUG 编号
本单 **BUG-1047**(1045 / 1046 由重复问题单预留),开工时核对。