Skip to content

[Design] Inline phase 重新設計:對稱 condense(入場摘要 + attempt_inline_completion 離場摘要) #19

Description

@easonLiangWorldedtech

[Design] Inline phase 重新設計:對稱 condense(入場摘要 + attempt_inline_completion 離場摘要)

關聯 issue #9(nesting depth / auto-flatten 設計)。本提案基於實際測試觀察(depth-2 task、qwen3.8-27b、workspace ai_test_project_4),重新定義 inline 模式的語義與 context 行為。

1. 現狀與問題

目前 inlineSubtask(auto-flatten,depth limit 觸發)只做四件事:

# 位置 作用
1 NewTaskTool.ts:126 flatten 時設 marker {message, todos}
2 NewTaskTool.ts:111 phase 中再呼叫 new_taskreject-nested(紅 banner)
3 AttemptCompletionTool.ts:85-89 phase 中 attempt_completion → 只清 marker、task 繼續
4 Task.ts:2332 abort 時清 marker

沒有:獨立 Task instance、獨立 context/history、獨立 todo list、completion routing。本質是一個 phase flag + prompt directive,不是 subtask。

實際測試觀察到的問題

  1. 沒有 clean context:inline「子任務」在同一對話流裡執行,看得到父對話全部 raw history(system prompt、environment_details、之前所有 tool results)。對 auto-workflow 而言,handoff 沒有隔離、沒有摘要。
  2. raw messages 永久累積:phase 期間的 list_files/update_todo_list 等雜訊留在對話裡,長 run 不斷膨脹(condense 只按 token threshold 觸發,不按邏輯邊界)。
  3. 無持久提示 → 重試迴圈風險environment_details 的 Task Context block 只有 Nesting depth / Parent task不告知模型 phase 進行中。唯一防線是反應式的 reject tool_result;弱模型可能 new_task → reject → new_task → reject 循環,每次多一個 API round-trip + 紅 banner。
  4. UX 誤導:紅色「巢狀子任務被拒絕」banner 是用來給 LLM 看的 guard,卻以錯誤樣式呈現給用戶;用戶看不到任何 tab 變化,只看到一個莫名其妙的紅字。
  5. attempt_completion 語義過載:phase 中 = 「結束階段、task 繼續」,phase 外 = 「完成 task」。同一個 key 兩個意圖,模型容易誤用(以為收尾其實只是繼續)。
  6. 命名不誠實:叫「inline subtask」但沒有任何 subtask 機制。

2. 提案:對稱 condense 的 inline phase

核心思想:入場和離場各做一次摘要,summary 當狀態通道——handoff contract 跟真實子任務同構(init prompt + 乾淨起點),物理承載仍是同一條對話流。

2.1 入場(現行 auto-flatten 觸發點,depth limit)

new_task → childDepth > maxNestingDepth → flatten
 ├─ guard: phase 未進行中(現有 marker check)
 ├─ ① CONDENSE:summarizeConversation() 把「至今全部」折成 summary S0
 │     → 舊訊息 tag condenseParent、建立 summary message
 │     → effective context = system + S0 + staged init prompt
 │     (= inline phase 跟真實子任務一樣,從乾淨的摘要+初始化提示開始)
 ├─ marker: task.inlinePhase = { prompt, todos }
 ├─ banner(黃色 info):「內聯階段開始(上下文已摘要)」+ staged prompt 可見
 └─ tool_result:[inline phase] context condensed. Staged instructions: <prompt>.

2.2 離場:新工具 attempt_inline_completion({ result })

獨立成工具,不重用 attempt_completion key:

情境 attempt_completion attempt_inline_completion
phase 中 ❌ 嚴格報錯:「內聯階段進行中,請改用 attempt_inline_completion」 ✅ 結束階段、摘要、task 繼續
phase 外 ✅ 正常完成 task(含委派路由) ❌ 報錯:「目前沒有進行中的內聯階段」
attempt_inline_completion({ result })
 ├─ guard: phase 必須進行中
 ├─ ② CONDENSE:summarizeConversation() —— 語義天然吻合:它摘要「自上次 summary 以來的訊息」,
 │     恰好 = 本階段產生的全部工作(含 result),零新機制
 │     → effective context = system + S0 + S1(S1 含 result)
 ├─ 清 marker
 ├─ banner(綠色 ✓):「內聯階段完成」+ summary snippet
 └─ tool_result:[inline phase completed] <summary>。父對話繼續。

2.3 為什麼幾乎免費(對接現有 condense 機制)

  1. summarizeConversationsrc/core/condense/index.ts)本來就是「摘要自上次 summary 以來的訊息」——入場做一次、離場再做一次,第二次恰好只覆蓋 phase 期間的工作。
  2. nested-condense 已驗證可疊加nested-condense.spec.ts):多次 phase = 多層 summary;rewind/delete 的 condenseParent 清理邏輯全部現成。
  3. raw messages 不刪除,只 tag + 過濾——rewind 可還原。「clean」是視角上的乾淨,不是銷毀。

3. Context view(模型在每個時刻看到什麼)

根任務工作 R...(raw messages 累積中)
│
├─[inline #1 入場] condense(R) → S0
│   模型看到: system + S0 + P1(staged prompt)        ← 乾淨起點,跟子任務同構
│   phase 1 工作 M1...(raw,即時可見)
├─[inline #1 離場 attempt_inline_completion] condense(M1) → S1
│   模型看到: system + S0 + S1                        ← M1 的 raw 全部隱藏
│
├─[inline #2 入場] S1 之後沒有新訊息 → 跳過 condense(no-op guard),只 stage P2
│   模型看到: system + S0 + S1 + P2                   ← 記得 #1 的「結果」(S1),不記得過程(raw)
│   phase 2 工作 M2...
├─[inline #2 離場] condense(M2) → S2
│   模型看到: system + S0 + S1 + S2

語義總結:inline = 一條共享對話流 + 每個 phase 一個 summary 封裝。 main task context 永遠在(以 S0 形式);每個 inline 離場後變成自己的 Si。執行期間沒有物理隔離(那是 inline 的本質),但起點是乾淨的。

邊界情況

  1. 入場 condense no-op guard:連續兩個 phase、中間無新訊息時,summarizeConversationcondensed_recently——入場邏輯要當成「跳過、只 stage」而非錯誤。
  2. summary 可再折疊:phase 很多時 S0+S1+... 本身可被下一次 condense 折成 meta-summary(多層疊加已驗證),context 永遠有界,不隨 phase 數線性膨脹。
  3. abort/resume:marker 非持久化(issue [ENHANCEMENT] Task Tree 統一子任務管理:詳細設計同 PR 拆分計劃(upstream #856) #9 決定);resume 後 summary 仍在、task 從 condensed context 繼續。需明確寫入設計文件。
  4. phase 中 new_task:維持現行 reject-nested guard,但 banner 降級為安靜 info(見 §4)。

4. 順帶修復的 UX / 模型行為問題

  1. 重試迴圈:phase 進行中時,environment_details Task Context block 追加:
    Inline phase in progress: <prompt>
    Do NOT call new_task or start another phase; finish with attempt_inline_completion.
    
    每個 request 重建 → 模型永遠知道狀態,不再依賴埋在 history 裡的 tool_result。
  2. 紅色 banner 降級:「巢狀子任務被拒絕」改為 info 樣式 + 白話文案(「已達巢狀上限,內聯階段進行中;再建子任務會被忽略」)——這是預期 guard,不是錯誤。
  3. attempt_completion 卸載過載語義:phase 中嚴格報錯並指向 attempt_inline_completion,一個工具一個意圖。
  4. 命名 sweepinlineSubtaskinlinePhase;banner「內聯階段開始/完成」;zh-TW 字串、settings deep-link 文字一併更新。

5. 對 auto-workflow 的價值

  • 模型可控的 context 管理:在邏輯邊界(phase)而非只按 token threshold 折疊。
  • 乾淨起點 + 有界累積:每個 phase 從 summary+init prompt 開始;長 run 累積的是摘要不是 raw 噪音。
  • 零新委派連結:不開 tab、不加 parent→child link → 沒有 orphaning 失敗面(PR Fix delegation link loss across interrupt/resume; type NewTaskTool provider call #18 Problem A/C 那一類問題)。
  • handoff contract 同構子任務:init prompt + todos,模型行為可預期。

6. 待決定

  1. 成本:每個 phase 兩次 summarization API call。phase 是低頻事件(depth limit 才觸發),傾向直接做;若要省可加 condense: true 參數讓淺層跳過。
  2. 入場是否也要顯式工具(如 start_inline_phase):建議本期只做 auto-flatten 觸發 + condense 語義,顯式工具留後續 PR——一次改一個面。
  3. abort/resume 的 marker 行為寫入 issue [ENHANCEMENT] Task Tree 統一子任務管理:詳細設計同 PR 拆分計劃(upstream #856) #9 設計文件。

7. PR 拆分建議

PR 內容
PR-1 入場 condense + marker payload 擴充({prompt, todos} → 加 entryCondenseId)+ banner 文案更新
PR-2 attempt_inline_completion 工具(離場 condense + guard + banner);phase 中 attempt_completion 改嚴格報錯
PR-3 命名/i18n sweep(inlineSubtaskinlinePhase、zh-TW、settings deep-link)+ environment_details「phase 進行中」提示 + 紅 banner 降級 info

每個 PR 獨立可測:PR-1/2 各帶 focused spec(condense mock + marker 狀態機),PR-3 純文案 + environment_details spec。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions