From 446645d0a0089c56bdfbfc374f596cf35e518d64 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Sun, 27 Sep 2026 11:27:53 +0800 Subject: [PATCH] =?UTF-8?q?docs(plan):=20=E9=98=B6=E6=AE=B5=202=20?= =?UTF-8?q?=E6=A0=87=E8=AE=B0=E5=AE=8C=E6=88=90=EF=BC=8C=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E8=A7=84=E5=88=99=E4=B8=8E=202c=20=E5=88=A4?= =?UTF-8?q?=E6=8D=AE=E9=97=AD=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/zh/toolcall-parallel-execution-plan.md | 32 +++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/docs/zh/toolcall-parallel-execution-plan.md b/docs/zh/toolcall-parallel-execution-plan.md index b71f55a..3f581f8 100644 --- a/docs/zh/toolcall-parallel-execution-plan.md +++ b/docs/zh/toolcall-parallel-execution-plan.md @@ -110,14 +110,14 @@ FAIL(`父的执行失败被误报为『工具不存在』`);修复后全 但 `stepPrepare` 对 `f.StageCtx` **无 nil 兜底**。本次不修(无生产触发路径), 记为潜在健壮性缺口。 -## 阶段 2 ⬜ 并行执行层(进行中:2a/2b/2c 已落地,2d 待做) +## 阶段 2 ✅ 并行执行层(已完成) | 子项 | 内容 | 状态 | | --- | --- | --- | -| **2a** | 消息落法:一条 assistant 带全部 tool_calls | ✅ 已提交 | -| **2b** | `ConsumeToolBlocks` 改 per-call 归档 | ✅ 已提交 | -| **2c** | `StageContext` 拆 per-tool | ✅ 已提交(**判据待 2d 补强**) | -| **2d** | 批次调度与保序(`ParallelSafe` + 同通道保序) | ⬜ 待做 | +| **2a** | 消息落法:一条 assistant 带全部 tool_calls | ✅ `28b42bc` | +| **2b** | `ConsumeToolBlocks` 改 per-call 归档 | ✅ `25f5c53` | +| **2c** | `StageContext` 拆 per-tool | ✅ `3d12e82`(判据由 2d 闭合) | +| **2d** | 批次调度与保序(`ParallelSafe` + 同通道保序) | ✅ `34c0df2` | **改动要点**(细节见设计文档 §6): @@ -130,6 +130,28 @@ FAIL(`父的执行失败被误报为『工具不存在』`);修复后全 - **2d** 全批 `ParallelSafe` 才并发,否则**整批**降级串行(不做部分并发—— 收益不抵不可预测性);同 `output_send__<通道>` 多次发送**保序**。 +**并发规则**(三条全满足才并发):批内 >1 个工具;**全部**声明 `ParallelSafe`; +不含需保序的同通道输出发送。 + +**结构**:`StepToolBatch` —— fan-out(每工具一 goroutine,各写自己的 +`toolCtxs[i]`)→ join → **按索引顺序**串行收尾。收尾必须串行且按索引: +`f.Msgs` 是共享切片,且按索引落才能让模型读到的上下文顺序与它自己发出的 +顺序一致。 + +⚠️ **修掉一个我自己引入的竞争**:`resolveTurnScenes` 会把结果记进**共享**的 +`f.sceneDone` / `f.turnScene`。最初在每个 goroutine 里各调一次 —— 既是数据 +竞争,又会各自触发一次 `EnterSceneWithHint`,**重复计入场景强度** +(正是 `sceneDone` 注释警告过的问题)。改为 fan-out **之前**解析一次。 + +### 2c 判据缺口:已由 2d 闭合 + +2c 落地时做过变体验证(`toolCtxFor` 退回单槽),**两条判据仍全绿** —— +因为串行路径下「单槽」与「per-tool」行为完全一致,差别只在并发下显现。 +当时据实记为「实现已就位、判据未闭合」。 + +2d 落地后补了**并发版**判据(`TestBatchConcurrentEachToolSeesOwnContext`): +退回单槽时触发 **6 处 DATA RACE 报告 + 串味断言失败**。缺口至此关闭。 + ### 遇到的一处**既有**测试竞态(非本次引入,但会污染回归信号) `TestResidualKeepReturnsTasksToParent` / `TestResidualDropNotifiesSyncCaller`