diff --git a/.agents/notes/implemented/bug-fix/2026-10-21-subagent-end-turn-guidance.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-10-21-subagent-end-turn-guidance.i18n.yaml new file mode 100644 index 0000000000..8b8bba1309 --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-10-21-subagent-end-turn-guidance.i18n.yaml @@ -0,0 +1,22 @@ +# Bilingual-pair consistency record for 2026-10-21-subagent-end-turn-guidance.md (docs/i18n/README.md): per heading +# section, a hash of its English and Chinese blocks outside code blocks and generated regions. +# After editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-10-21-subagent-end-turn-guidance.md +/agent-note-subagent-end-turn-guidance-stays-in-the-delegation-paragraph: + en: bfafb6d348cf2d21 + zh: 191bedbfa12b6329 +/agent-note-subagent-end-turn-guidance-stays-in-the-delegation-paragraph/problem: + en: 36ff1fff46915956 + zh: 198c8ca7efaeb5b6 +/agent-note-subagent-end-turn-guidance-stays-in-the-delegation-paragraph/decision: + en: 47b44ed9313c2ccf + zh: 7ad254f8ef88351d +/agent-note-subagent-end-turn-guidance-stays-in-the-delegation-paragraph/alternatives-considered: + en: d52fa1af379dea5b + zh: 4e404994f7a607dc +/agent-note-subagent-end-turn-guidance-stays-in-the-delegation-paragraph/verification: + en: be076216381ea64d + zh: 2da8d9819c20e2fe +/agent-note-subagent-end-turn-guidance-stays-in-the-delegation-paragraph/consequences: + en: d7c144cbe750a873 + zh: 602c06d08572481c diff --git a/.agents/notes/implemented/bug-fix/2026-10-21-subagent-end-turn-guidance.md b/.agents/notes/implemented/bug-fix/2026-10-21-subagent-end-turn-guidance.md new file mode 100644 index 0000000000..cd800e94fe --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-10-21-subagent-end-turn-guidance.md @@ -0,0 +1,44 @@ +# Agent Note: Subagent end-turn guidance stays in the delegation paragraph + +Status: implemented + +English | [中文](2026-10-21-subagent-end-turn-guidance.zh.md) + +## Problem + +The delegation guidance paragraph ended with `When only waiting for their results remains, end your turn instead of sleeping or polling; the next result starts a new turn.` A later prompt revert removed that sentence together with unrelated prompt changes. + +Before the sentence existed, one long Session slept seven times for 150–240 seconds each (about 25 minutes) waiting for review subagents that finished in 2–9 minutes (#6057). A controlled probe on 2026-10-21 measured the sentence's effect on the model's next message after a child starts: `deepseek-v4-flash` and `deepseek-v4-pro`, 150 requests per arm per model, minimal system prompt, real `subagent` and `bash` schemas, history ending with `started subagent reviewer-1`. + +| Arm | Sleep call | Any bash call | Ended turn | +|---|---|---|---| +| With the sentence | 0/300 | 7/300 | 291/300 | +| Without the sentence | 29/300 | 120/300 | 179/300 | + +The per-model difference is `0/150` vs `6/150` for flash (p=0.030) and `0/150` vs `23/150` for pro (p=9.6e-8), two-sided Fisher exact. The two remaining samples in the with-sentence arm called `subagent` again instead of ending the turn. + +## Decision + +The delegation paragraph keeps the end-turn sentence, byte-identical to the text introduced for #6057. Ending the turn does not lose the result: a settled child delivers a user-role notice to its parent, and a notice that reaches an idle parent starts one independent model request ([`dsh-subagent`](../../../../packages/subagent/subagent/README.md)). Hosts that keep children progressing alternate `agent.whenIdle()` and `waitForChildren(agent)` ([ACP `session.ts`](../../../../packages/acp/acp/src/session.ts)), and `dsh-goal-round-driver` waits for running descendants before starting the next goal round. + +The sentence stays one literal line. Rewording `the next result starts a new turn` to `each result starts a new turn` would re-render 83 prompt sidecars without a measured behavior change. + +## Alternatives considered + +**Rely on the tool description.** The `subagent` tool description states that the runtime notifies the model when the child finishes. The probe measured 29/300 sleep calls without the paragraph sentence, so the tool description does not replace it. + +**Move the guidance into the tool description.** The paragraph is assembled from the set of visible delegation tools and lists their names; the tool description describes one tool. Moving the sentence changes ownership without changing the behavior it prevents. + +**Restore every prompt phrase reverted together with this sentence.** The read guidance and the `run_code` argument order are separate decisions with their own evidence; this note records only the delegation paragraph. + +## Verification + +- `packages/subagent/tool-subagent/tests/tool-subagent.spec.ts` asserts the rendered paragraph for each visible-tool combination, including the restored sentence (9 expectations). +- 83 `snapshots/**/system-prompt*.expected.md` sidecars carry the restored text and replay through the shipped headless profile in `test:snapshot`. +- The probe is a one-off controlled measurement and is not committed; its two arms differ only in the guidance sentence. + +## Consequences + +- Every request with a visible delegation tool carries one more sentence, about 30 tokens. +- The model ends its turn while only waiting for a delegated result instead of calling `bash sleep` or polling. +- A future prompt-slimming pass must treat this sentence as load-bearing; the probe table above is the evidence for keeping it. diff --git a/.agents/notes/implemented/bug-fix/2026-10-21-subagent-end-turn-guidance.zh.md b/.agents/notes/implemented/bug-fix/2026-10-21-subagent-end-turn-guidance.zh.md new file mode 100644 index 0000000000..b11656473a --- /dev/null +++ b/.agents/notes/implemented/bug-fix/2026-10-21-subagent-end-turn-guidance.zh.md @@ -0,0 +1,44 @@ +# Agent Note: 委派指导段保留结束本轮说明 + +Status: implemented + +[English](2026-10-21-subagent-end-turn-guidance.md) | 中文 + +## 问题 + +委派指导段以 `When only waiting for their results remains, end your turn instead of sleeping or polling; the next result starts a new turn.` 结尾。后来的一次提示词回退把这句和不相关的提示词改动一起删掉了。 + +这句出现之前,一个长 Session 为了等待 2–9 分钟就结束的 review 子代理,七次 `sleep` 150–240 秒,累计约 25 分钟(#6057)。2026-10-21 的受控探针测量了这句对「子代理启动后模型下一条消息」的影响:`deepseek-v4-flash` 与 `deepseek-v4-pro`,每臂每模型 150 次请求,最小 system prompt,真实 `subagent` 与 `bash` schema,历史以 `started subagent reviewer-1` 结束。 + +| 组 | sleep 调用 | 任何 bash 调用 | 结束本轮 | +|---|---|---|---| +| 有这句 | 0/300 | 7/300 | 291/300 | +| 无这句 | 29/300 | 120/300 | 179/300 | + +分模型差异:flash `0/150` vs `6/150`(p=0.030),pro `0/150` vs `23/150`(p=9.6e-8),双侧 Fisher 精确检验。有这句的一组里剩余 2 次是重新调用 `subagent`,而不是结束本轮。 + +## 决策 + +委派段保留结束本轮这句,文本与 #6057 引入的版本逐字一致。结束本轮不会丢失结果:子代理结束后会向父级投递 user-role 通知,通知到达空闲父级会起一次独立的模型请求([`dsh-subagent`](../../../../packages/subagent/subagent/README.zh.md))。在子代理继续推进期间,宿主交替等待 `agent.whenIdle()` 与 `waitForChildren(agent)`([ACP `session.ts`](../../../../packages/acp/acp/src/session.ts)),`dsh-goal-round-driver` 也会等运行中的后代结束再开下一轮 goal。 + +这句保持为一行字面文本。把 `the next result starts a new turn` 改成 `each result starts a new turn` 会重录 83 个提示词 sidecar,而测不到行为变化。 + +## 考虑过的替代方案 + +**只依赖工具描述。** `subagent` 工具描述写明运行时会在子代理结束时通知模型。探针测得没有这句时 sleep 为 29/300,说明工具描述替代不了它。 + +**把说明移进工具描述。** 这段指导按可见委派工具集合组装并列出工具名,工具描述只描述单个工具。移动这句会改变归属,但不改变它阻止的行为。 + +**把与这句一起被回退的所有提示词都恢复。** read 指导与 `run_code` 参数顺序是各自有证据的独立决定;本记录只覆盖委派段。 + +## 验证 + +- `packages/subagent/tool-subagent/tests/tool-subagent.spec.ts` 对每种可见工具组合断言渲染出的指导段,包含恢复后的这句(9 条断言)。 +- 83 个 `snapshots/**/system-prompt*.expected.md` sidecar 带有恢复后的文本,由 `test:snapshot` 通过随附 headless profile 回放。 +- 探针是一次性受控测量,未入库;两组只差这一句指导。 + +## 影响 + +- 只要存在可见委派工具,每个请求多一句,约 30 token。 +- 模型在只剩等待委派结果时结束本轮,不再调用 `bash sleep` 或轮询。 +- 后续的提示词精简必须把这句当作承重文本;上面的探针表是保留它的证据。 diff --git a/packages/subagent/tool-subagent/README.i18n.yaml b/packages/subagent/tool-subagent/README.i18n.yaml index 3b05b61f13..41253b1f1e 100644 --- a/packages/subagent/tool-subagent/README.i18n.yaml +++ b/packages/subagent/tool-subagent/README.i18n.yaml @@ -81,8 +81,8 @@ en: cf78b9dd5596495f zh: bd44560f8c2435e8 /deepseek-ai-dsh-tool-subagent/model-experience/system-prompt/what-the-model-sees: - en: 64a1c2edb455950c - zh: 15d280ff2c918672 + en: 571d1dcec395c549 + zh: 6e9b6bf1cfa7e915 /deepseek-ai-dsh-tool-subagent/model-experience/system-prompt/what-the-model-sees/tool-guidance-section: en: 82b3cd08b3961c98 zh: bdc2a34bcea16cac diff --git a/packages/subagent/tool-subagent/README.md b/packages/subagent/tool-subagent/README.md index b2bac655ae..0652050afc 100644 --- a/packages/subagent/tool-subagent/README.md +++ b/packages/subagent/tool-subagent/README.md @@ -167,7 +167,7 @@ The schema is prefix-stable across adapter registration and catalog changes. Eac #### What the model sees -Visible delegation tools share one guidance paragraph, listing tools in name order and instructing the model to start independent delegations together and keep working while they run, and to end its turn instead of sleeping or polling when only waiting for their results remains. Hidden or unavailable tools are omitted; no guidance appears when none are visible. With both `subagent` and `subagent_fork` visible, the text is: +Visible delegation tools share one guidance paragraph, listing tools in name order and instructing the model to start independent delegations together and keep working while they run, and to end its turn instead of sleeping or polling when only waiting for their results remains. Ending the turn works because a settled child notifies its parent and a notice that reaches an idle parent starts one independent model request; hosts that keep children progressing alternate `agent.whenIdle()` and `waitForChildren(agent)` ([`dsh-subagent`](../subagent/README.md), [`session.ts`](../../acp/acp/src/session.ts)). Hidden or unavailable tools are omitted; no guidance appears when none are visible. With both `subagent` and `subagent_fork` visible, the text is: ##### Tool-guidance section diff --git a/packages/subagent/tool-subagent/README.zh.md b/packages/subagent/tool-subagent/README.zh.md index d8d31e5a4e..6325975f63 100644 --- a/packages/subagent/tool-subagent/README.zh.md +++ b/packages/subagent/tool-subagent/README.zh.md @@ -167,7 +167,7 @@ kind: "package-reference" #### 模型看到什么 -可见的委派工具共享一段指导,列出按名称排序的工具,指示模型一起启动相互独立的委派,并在它们运行时继续工作;当只剩等待它们的结果时,结束本轮,而不是休眠或轮询。隐藏或不可用的工具不列入其中;没有可见工具时,不输出指导。`subagent` 和 `subagent_fork` 都可见时,文本为: +可见的委派工具共享一段指导,列出按名称排序的工具,指示模型一起启动相互独立的委派,并在它们运行时继续工作;当只剩等待它们的结果时,结束本轮,而不是休眠或轮询。结束本轮之所以可行,是因为子代理结束后会通知父级,而通知到达空闲父级会起一次独立的模型请求;在子代理继续推进期间,宿主交替等待 `agent.whenIdle()` 与 `waitForChildren(agent)`([`dsh-subagent`](../subagent/README.zh.md)、[`session.ts`](../../acp/acp/src/session.ts))。隐藏或不可用的工具不列入其中;没有可见工具时,不输出指导。`subagent` 和 `subagent_fork` 都可见时,文本为: ##### 工具指导 section