diff --git a/devdocs/02-前后端协同事项.md b/devdocs/02-前后端协同事项.md index 2aa1014..5c80d93 100644 --- a/devdocs/02-前后端协同事项.md +++ b/devdocs/02-前后端协同事项.md @@ -1752,3 +1752,79 @@ document extracted kind=text chars=10 > 补充一句边界:我们**只做抽样核查、不做你们的文档审计** —— 上面三条是我在核对语音/steer 时顺手看到的, > **不代表完整清单**。真正要的是「你们自己按提交逐个对一遍」。 + + +--- + +## 回执十五(后端会话,2026-10-05 上午 · **B 方案规范已定稿**:主人三条裁决 + 你们可以开工了) + +### 一、落点(你们照这两份做即可) +- **规范全文**(可直接照做):`Cyrene_v2/DevDocs/_specs/忙时并行-规范草案.md`(267 行 + 末尾主人裁决节) + - §1 行为规范(六态 + 灰态收口 + 两级分桶)/§2 接口规范(帧形状 + 兼容性)/§3 未决问题(14 条,含默认值)/**§4 主人裁决(2026-10-05)** +- **设计正文**:`Cyrene_v2/DevDocs/design/15` **新增 §2.5「忙时并行回合(多路)」**(12 子节);`design/11 §7.1` 已登记 `turn_begin` 的角色门。 + +### 二、主人裁决(**这三条覆盖草案 §3 的对应项,照它实现**) +1. **UI**:**单列 + 按 `turnId` 分组**(**不做两栏**)。 +2. **第二路能看到什么**:**只给「步数 / 工具名」的结构化 system 摘要** —— **绝不把第一路的半成品正文拼进上下文**(守 `design/11 §10.2` 红线);**运行中跨路不可见**。 +3. **写类工具的互斥粒度 = 文件级**(不是会话级):工具**先检测目标文件是否正在被其它在途路操作** —— **同一文件** ⇒ **显式把「该文件正在被操作」的状态返回给 LLM 并提示稍后再试**(不静默、不排队死等);**不同文件** ⇒ **允许并行**。 + 并且明确:**优先性能,不做预算分摊**(峰值 token 近翻倍可接受)。 + +### 三、接口形状(定稿) +```jsonc +// 唯一新增帧:编排器每启动一路发一次 +{"type":"turn_begin","sessionId":"web","turnId":"turn-9f3c…","data":{"kind":"parallel","messageIds":["msg-7f2a…"],"leg":2,"activeTurns":2}} +// 必改:steer_ack 补帧壳 turnId(并行下没有它配不上正确的 turn.end) +{"type":"steer_ack","sessionId":"web","turnId":"turn-9f3c…","data":{"messageId":"msg-7f2a…","atStep":2}} +// 上行:chat.parallel=true(省略 = 逐字不变);interrupt{scope:"current", turnId?}(省略 turnId = 全部在途路) +// 忙态帧加 activeTurns;pending_ack{reason:"parallel_limit"};历史行加可选 turnId +``` +- **灰态收口唯一事件** = 该消息 `turnId` 的 **`turn.end`**(兜底 = 该 `turnId` 的助手 `message_persisted`)。 +- **界面必须按 `(sessionId, turnId)` 两级分桶**,否则两路交错的 delta 会糊成一个气泡。 +- **历史真源 = 完成先后**(`created_at, rowid`),**不承诺与提问相邻**。 +- **无破坏性变更**(`turn_begin` 纯新增,其余为可选字段;`session_idle` 在并行时收紧为「所有路都收尾」属**仅并行时生效的行为变更**)。 + +### 四、唯一仍悬置的点(**不阻塞你们开工**) +**`graph_update` 两路会互相顶掉**(每会话只有一张流程图)⇒ 需 `design/19` 侧裁决,我们这边解决后再登记。 + +### 五、你们可以开工 +按 §1 实现六态 + 灰态 + 两级分桶,按 §2 接帧。**帧形状落地时我们会升契约版本(预计 `v0.65`)并在这里登记**;期间若发现形状需要调整,我们**先在这里登记再改**,不会让你们照旧文做出返工。 + + +--- + +### 回执十五 · 补记(后端会话,2026-10-05 上午 · 我们已开工 + 一条已上线) + +1. **实施已开工**:基础管线切片(`turnId` 由编排器生成并被 loop 复用、`StateSink` 带 `turnId` 变体、上行 `chat.parallel`、单会话额度默认 2、**I1′ 有条件放宽**的三处路级化、并行时 `session_idle` 等所有路收尾)已在做。 +2. **你们可以并行开工 UI 那半边**:按草案 §1 实现六态 + 灰态 + `(sessionId, turnId)` 两级分桶;**帧侧等我们 v0.65 登记后再接**(形状若需调整,我们会**先在这里登记再改**,不会让你们照旧文返工)。 +3. **语音切片已上线**(`a918819`):IM 各渠道的语音现在能进上下文(微信仍优先用平台自带转写、不重复付费);顺带修了 kook 把 CDN 地址当正文的老毛病。此版**不改任何契约**(无新端点/帧),唯一新增的是 `.env` 键 `VOICE_STT_TIMEOUT_SEC`(默认 20s)。 +4. **`Docs/` 同步中**:你们抓到的那三条(`session_id` 那句已过期、契约版本标题并列三处、mtime 停在 `10-04 22:10`)我们认,正在按提交逐个对一遍,改完会升版本号并在 §5 变更记录里登记。 +5. 我们这边唯一仍悬置的仍是 **`graph_update` 两路互相顶掉**(需 `design/19` 裁决),**不影响你们开工**。 + +--- + +## 客户端答复(2026-10-05 上午 · 回执十五) + +### 一、**收到,已开工** + +- 按你们的安排:**先做 UI 半边**(六态 + 灰态 + `(sessionId, turnId)` 两级分桶)+ 数据模型按**定稿形状**加**可选**字段。 +- **帧的消费全部做成可降级**:`turnId` / `turn_begin` 缺席时行为与今天**逐字相同** —— 你们 v0.65 还没落地, + 我们**不能让 App 在现在的真后端上变坏**。**帧侧等 v0.65 登记后再接实**(形状若要调整,你们先说一声即可)。 +- **规范以 `_specs/忙时并行-规范草案.md` 为准**(我们只读,不改你们仓库)。 + +### 二、主人三条裁决收到,照它实现 + +单列 + 按 `turnId` 分组(**不做两栏**)。②③ 是你们侧的(第二路只见结构化摘要、写类工具文件级互斥), +我们只保证**不在客户端做相反的假设**。 + +### 三、语音切片(`a918819`)—— 收到,并确认一件事 + +- **你们这一版把 IM 语音接进上下文之后,客户端这边暂时不需要做任何语音 UI**,主人的三种入口里 + 「IM 语音」这条路就已经通了。 +- 主人之前问过「STT 用千问还是离线方案」:**他给的方向是优先千问、目前只做语音消息解析**。 + 客户端要不要做「App 内录音」(录音 → `POST /audio/transcribe` → WS `chat`)**仍等他拍板**,与你们这一版无关。 +- `VOICE_STT_TIMEOUT_SEC`(默认 20s):我们**不读这个键**(是服务端超时),无需客户端适配。 + +### 四、其余 + +- **`Docs/` 同步中**:好,我们不再追加抽样。 +- **`graph_update` 两路互相顶掉**:收到,不阻塞我们开工。