跳至主要內容
模組 2:多 Agent 2 / 6
中階 Session 8 Background Tasks Async

背景任務

了解長時間執行背景操作的守護線程與通知佇列。

2026年3月20日 16 分鐘閱讀

你將學到什麼

有些操作需要時間。執行完整測試套件可能需要 30 秒。建構 Docker 映像可能需要 2 分鐘。部署到預備環境可能需要 5 分鐘。沒有背景任務的話,Claude Code 會閒置等待,消耗上下文和你的耐心。

完成後,你將了解:

  • 為什麼某些任務應該在背景執行
  • 背景任務的生命週期:啟動、監控、通知
  • 通知佇列如何回報完成狀態
  • 何時使用前景 vs. 背景執行
  • 如何在等待時持續進行有用的工作

問題是什麼

考慮這個情境:

User: "Run the full test suite, then fix any failing tests."

Without background tasks:
  AI: Runs test suite...
      ████████░░░░░░░░░░░░ 45%
      ... (you wait 90 seconds) ...
      ████████████████████ 100%
  AI: "3 tests failed. Let me fix them."

這 90 秒被浪費了。AI 本可以在讀取測試檔案、分析可能的失敗模式,或準備修復方案。相反,它阻塞在同步呼叫上,什麼都沒做。

這就是閒置等待問題。同步執行意味著 AI 一次只能做一件事,即使當前操作不需要它的關注。

如何運作

前景 vs. 背景

Claude Code 支援兩種執行模式:

Foreground (blocking):
  ┌──────────┐     ┌──────────┐     ┌──────────┐
  │  Start   │────►│  Wait... │────►│  Result  │
  │  command │     │  (idle)  │     │  ready   │
  └──────────┘     └──────────┘     └──────────┘
  Time: ============================|

Background (non-blocking):
  ┌──────────┐     ┌──────────────────────────────┐
  │  Start   │────►│  Continue working...          │
  │  command │     │  Write code, read files, plan │
  └──────────┘     │  ...                          │
                   │  ◄── Notification: "Done!"    │
                   └──────────────────────────────────┘
  Time: ====|  (productive work fills the gap)

關鍵區別:在背景模式下,AI 立即取回控制權,可以在操作執行時做其他工作。

背景任務生命週期

每個背景任務遵循三個階段:

┌─────────────────────────────────────────────────────┐
│              Background Task Lifecycle               │
│                                                      │
│  Phase 1: LAUNCH                                     │
│  ┌────────────────────────────────────────┐          │
│  │  Tool call with run_in_background=true │          │
│  │  → Process starts in daemon thread     │          │
│  │  → AI receives confirmation instantly  │          │
│  │  → AI continues with next action       │          │
│  └────────────────────────────────────────┘          │
│                                                      │
│  Phase 2: MONITOR                                    │
│  ┌────────────────────────────────────────┐          │
│  │  Background process runs independently │          │
│  │  → stdout/stderr captured              │          │
│  │  → Exit code tracked                   │          │
│  │  → No AI attention required            │          │
│  └────────────────────────────────────────┘          │
│                                                      │
│  Phase 3: NOTIFY                                     │
│  ┌────────────────────────────────────────┐          │
│  │  Process completes (success or failure) │          │
│  │  → Result placed in notification queue │          │
│  │  → AI receives notification in next    │          │
│  │    turn's context                      │          │
│  │  → AI can act on the result            │          │
│  └────────────────────────────────────────┘          │
│                                                      │
└─────────────────────────────────────────────────────┘

啟動背景任務

run_in_background 參數可在 Bash 工具中使用:

{
  "type": "tool_use",
  "name": "Bash",
  "input": {
    "command": "npm test",
    "description": "Run full test suite",
    "run_in_background": true
  }
}

當這個執行時:

  1. 測試套件在獨立的程序中開始執行
  2. AI 立即收到確認:「Background task started」
  3. AI 的下一個動作可以是任何事 — 它不必等待

與前景呼叫(預設)比較:

{
  "type": "tool_use",
  "name": "Bash",
  "input": {
    "command": "npm test",
    "description": "Run full test suite"
  }
}

這會阻塞直到 npm test 完成。AI 在執行期間無法做任何其他事情。

通知佇列

當背景任務完成時,其結果會進入通知佇列。AI 在隨後的輪次中看到它:

Turn N:
  AI launches background task: "npm test"
  AI continues: reads files, writes code...

Turn N+1:
  [System notification]
  Background task completed:
    Command: npm test
    Exit code: 1
    Output: "47 passed, 3 failed
      FAIL: src/auth/login.test.ts
      FAIL: src/auth/session.test.ts
      FAIL: src/api/users.test.ts"

  AI: "The test suite found 3 failures. Let me fix them."

通知自然地出現在對話流程中。AI 不需要輪詢或檢查 — 當背景任務完成時它會自動被通知。

什麼適合在背景執行

不是每個命令都適合放在背景。以下是決策框架:

Need the result to decide your next action?
  ├── YES → Foreground (blocking)
  │   Examples:
  │   - "cat package.json" (need to read contents now)
  │   - "git status" (need to know state before committing)
  │   - "ls src/" (need to know what files exist)

  └── NO → Background (non-blocking)
      Examples:
      - "npm test" (can write code while tests run)
      - "docker build ." (can prepare deployment config while building)
      - "pnpm build" (can write documentation while building)
操作耗時背景執行?原因
cat file.txt< 1s立即需要結果
git diff< 1s現在就需要看到變更
npm test10-120s測試執行時可以繼續工作
docker build30-300s長時間建構,不立即需要結果
npm install5-30s視情況取決於是否立即需要套件
pnpm build5-60s可以同時準備部署設定
eslint .5-30s可以在 linting 時繼續寫程式

交錯背景和前景工作

真正的威力在於將背景任務與有效的前景工作結合起來:

Timeline:
  ├── Launch: npm test (background)
  ├── Read: src/auth/login.ts (foreground, instant)
  ├── Read: src/auth/session.ts (foreground, instant)
  ├── Edit: fix suspected bug in login.ts (foreground)
  ├── [Notification: npm test completed, 3 failures]
  ├── Analyze: compare failures with the fix just made
  ├── Edit: fix remaining 2 test failures
  └── Launch: npm test (background, verify fixes)

AI 利用測試套件的執行時間做了有用的工作:它讀取了可能出錯的檔案,並在測試結果返回之前就開始修復最明顯的問題。

關鍵洞見

背景任務讓你避免閒置等待 — AI 可以在長時間操作執行時做有用的工作。 這不僅僅是一種優化;它從根本上改變了 AI 處理複雜任務的方式。

沒有背景執行的話,每個長時間操作都會在對話中創造一個空白區。AI 啟動一個建構,閒等 60 秒什麼都不做,然後繼續。這 60 秒本可以用來閱讀文件、撰寫程式碼或規劃下一步。

洞見更深層:背景任務改變了 AI 的規劃策略。當 AI 知道它可以在背景執行測試時,它更願意提早啟動測試(以獲得快速回饋),而不是等到它認為一切都完美了才執行。這導致更迭代、更回饋驅動的工作流程 — 更接近經驗豐富的開發者實際的工作方式。

把它想像成做菜。好的廚師不會站在烤箱前面看烤肉。他們開始烤,然後切蔬菜、準備醬汁、擺餐桌。烤箱會在完成時通知他們。背景任務給了 AI 同樣的交錯操作能力。

實作範例

邊測試邊寫程式

以下是一個利用背景任務的實際工作流程:

User: "Fix the failing tests in the auth module"

AI Plan:
  1. Run test suite in background to identify failures
  2. While tests run, read the auth module source code
  3. When test results arrive, cross-reference with source
  4. Fix each failure
  5. Re-run tests in background to verify

Execution:

Step 1: Launch tests in background
  → Bash(command="npm test -- --reporter json", run_in_background=true)
  → "Background task started"

Step 2: Read source files (while tests run)
  → Read("src/auth/middleware.ts")
  → Read("src/auth/routes.ts")
  → Read("src/auth/session.ts")
  → (AI now understands the auth module's structure)

Step 3: Test results arrive
  → Notification: 3 tests failed
     - login.test.ts: "Expected 200, got 401"
     - session.test.ts: "Token expired error"
     - users.test.ts: "Missing required field"

Step 4: Fix with full context
  → AI already read the source files, can immediately
     correlate failures with code
  → Edit middleware.ts: fix token validation
  → Edit routes.ts: add missing field

Step 5: Verify in background
  → Bash(command="npm test", run_in_background=true)
  → Continue documenting the changes while tests run

背景任務與逾時

長時間執行的任務可以指定逾時來防止失控的程序:

{
  "type": "tool_use",
  "name": "Bash",
  "input": {
    "command": "npm run e2e-test",
    "description": "Run end-to-end test suite",
    "run_in_background": true,
    "timeout": 300000
  }
}

timeout 參數(以毫秒為單位)確保背景任務不會無限期執行。如果程序超過逾時,它會被終止,AI 收到逾時通知。

應避免的反模式

Bad: Running a quick command in background
  → Bash(command="cat README.md", run_in_background=true)
  → Overhead of notification queue isn't worth it for <1s operations

Bad: Launching many background tasks that compete for resources
  → 5 parallel "npm test" runs will slow each other down
  → Better: one background test run + foreground analysis

Bad: Launching a background task then immediately waiting for it
  → Bash(command="npm test", run_in_background=true)
  → Bash(command="sleep 30")  ← defeats the purpose!
  → Instead: do useful work, let the notification come naturally

前後對比

僅前景執行有背景任務
AI 在長時間操作時閒置AI 在等待時持續有效工作
一次一個操作交錯前景和背景工作
測試只在「準備好」時才執行測試提早執行以獲得快速回饋
循序工作流程重疊的執行階段
90 秒測試 = 90 秒什麼都不做90 秒測試 = 90 秒有效寫程式
建構後部署要等兩次建構在背景執行,同時準備部署設定

下一堂課

第 9 堂課介紹 Agent Teams 與通訊 — 多個 Claude Code 實例如何以獨立的上下文視窗協作,通過 JSONL 訊息匯流排進行通訊,處理單一代理無法應付的問題。