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

5.5 KiB
Raw Blame History

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 由重复问题单预留),开工时核对。