讀完能做到:為同時湧入的 AI 任務建立 Admission Control、優先佇列、分層併發限制與資源調度規則,避免高優先任務被塞住、下游 API 被打爆,或多個 Agent 同時改寫同一筆企業資料。
假設這是一個虛構的企業情境:客服信箱一次進來 30 件詢價,主管要求 4 份風險摘要,採購系統還有 2 筆正式報價等待處理。
最直覺的作法,是收到任務就建立 Agent,然後全部 asyncio.gather()。Demo 很快,真正執行時卻可能出現三種塞車:模型配額先被低優先摘要用完、ERP API 回傳 429、多個 Agent 同時更新同一個客戶紀錄。系統看似很忙,最重要的任務反而排在最後。
Gemini Spark 官方文件目前說明,同一時間最多可有 15 個執行中的 Task;達到上限時,新的排程不會啟動,尖峰流量也可能造成延遲。[1] 這個數字未來可能調整,但它提醒我們一件事:Agent 數量不是無限,模型、工具、網路與人工核准者也都有容量上限。
所以,多代理併發的第一個原則不是「多開 worker」,而是先決定哪些工作現在可以進場。
Spark Task/Schedule/企業事件
↓
Admission Control:驗證、去重、估算成本、檢查租戶配額
↓
┌──────────── Task Queues ────────────┐
│ urgent │ standard │ batch │ approval│
└────────────────┬────────────────────┘
↓
Scheduler:期限、優先級、aging、依賴與公平性
↓
Resource Gates
model slots/Gmail slots/ERP slots/tenant slots
↓
Supervisor → Intel/Analysis/Reviewer Agents
↓
State Store/Checkpoint/Approval/ActionResult
Task Queue 負責吸收尖峰,Scheduler 決定下一個可執行工作,Resource Gate 則保護真正稀缺的資源。三者不能混成一個「最大同時任務數」,否則增加模型併發時,很可能先把 ERP 或資料庫壓垮。
每個觸發事件先轉成結構化 Task,不要立刻建立 Agent。
{
"task_id": "inquiry-20260905-031",
"tenant_id": "sales-tw",
"task_type": "customer_inquiry",
"business_priority": "high",
"deadline": "2026-09-05T10:00:00+08:00",
"estimated_tokens": 12000,
"required_tools": ["gmail_read", "crm_read", "crm_write"],
"partition_key": "customer-042",
"idempotency_key": "mail-msg-031",
"status": "queued"
}
Admission Control 至少完成四件事:
優先級不能只靠 Agent 自己說「這很急」。可以先由程式計算:
effective_score
= business_priority
+ deadline_urgency
+ waiting_time_aging
- estimated_cost_penalty
aging 讓等待過久的普通任務逐步提升,避免永遠被高優先任務餓死。分數相同時,再依 deadline 與建立時間排序。涉及安全、付款或重大客戶的任務,仍應由既定政策標記,而不是讓郵件裡的一句「URGENT」改變系統權限。
一個詢價任務可能依序使用 Gemini 模型、Gmail、CRM 與 OCR。這些資源的容量不同,併發也應分開控制。
以下僅是示例配置,不是產品建議值:
resource_limits:
global_tasks: 8
gemini_reasoning: 4
gmail_read: 6
crm_read: 4
crm_write: 1
document_ocr: 2
tenant_sales_tw: 3
如果 Task 目前只在等待 Gmail,就不該先占住 Gemini slot;進入 awaiting_approval 後,也必須釋放 worker 與模型資源,等 Approval 事件到來再重新排隊。
Cloud Tasks 的官方文件把 dispatch rate、最大同時派送數與 retry 設定分開,並以 token bucket 控制突發流量。[2] Pub/Sub 的訂閱端 Flow Control 也用未完成訊息數與資料量限制,避免流量尖峰壓垮 consumer。[3] 企業 AI Scheduler 可以沿用相同思路:限制進入速度、同時執行量與在途資料量,而不是只看 worker 數量。
還有一個容易漏掉的資源:企業資料本身。兩個 Agent 可以平行讀取不同客戶,但若同時更新 customer-042,就應以 partition key、租約或版本號序列化寫入。否則兩次看似成功的 CRM 更新,可能互相覆蓋。
公平性也要被設計。若同一部門大量提交批次摘要,不能吃掉全公司的模型 slots。可以為 tenant 保留最低容量,再以 Weighted Fair Queueing 分配剩餘資源;高成本批次工作則移到離峰 Queue。
Worker 取得 Task 時,不是把狀態直接改成 running 就結束。它應取得有期限的 lease,並定期更新 heartbeat。Worker 崩潰後,lease 到期,Task 才能由另一個 worker 從最新 Checkpoint 接手。
queued → leased → collecting → analyzing → reviewing
→ awaiting_approval → executing → completed
↘ retrying/blocked/dead_letter/cancelled
外部寄信、建單或 CRM 寫入都必須使用冪等鍵。若 API 已成功但回應遺失,恢復程序先查 ActionResult,不可直接重送。資料衝突、權限不足或疑似 Prompt Injection 則進入 blocked,交由人員確認;系統不能把政策失敗當成暫時性錯誤無限重試。
Backpressure 是系統主動說「目前不要再餵」。當 Queue 深度、P95 等待時間、429 比例或 Token 預算超過門檻時,可以:
Cloud Tasks 也提醒,佇列從閒置狀態恢復或大量任務同時可用時,流量會逐步 ramp up;錯誤的 burst 設定可能讓下游收到大量 429 或 503。[4] 所以 autoscaling 不是瞬間救援,Queue 與 Backpressure 仍然不可少。
回到開場的虛構情境。系統不會同時啟動 36 個 Agent,而是這樣處理:
36 個事件進入 Admission Control
├── 重複郵件 → deduplicated
├── 4 份主管風險摘要 → urgent queue
├── 30 件詢價 → standard queue,依 deadline 與 aging 排序
└── 2 筆正式報價 → high-risk queue
↓
產生草稿後釋放 worker
↓
awaiting_approval
↓
人工核准事件重新加入 urgent queue
風險摘要可以先取得 Gemini slot;詢價任務在 Gmail 與 CRM 的各自限流下穩定前進;正式報價等待人工時不占資源。核准後的外部動作獲得保留容量,但仍要通過 Tool Gate 與冪等檢查。
這才是資源調度:不是平均分配,而是讓業務期限、風險與下游容量共同決定順序。
負載測試至少要包含正常流量、瞬間十倍 burst、慢速 ERP、模型 429、毒性任務反覆失敗、同一客戶並發更新、人工核准積壓與 Prompt Injection。
建議追蹤:
期限達成率
= deadline 前完成的任務數 ÷ 已完成任務總數
重複副作用率
= 重複寄信或寫入次數 ÷ 外部動作總數
飢餓率
= 等待時間超過內部上限且未執行的任務數 ÷ 入隊任務總數
資源利用率
= 資源實際忙碌時間 ÷ 可用時間
再搭配 Queue depth、P50/P95/P99 等待時間、吞吐量、各資源飽和度、429/503 比例、平均重試次數、每任務 Token/成本、人工核准等待時間與不同 tenant 的服務差距。
別只看吞吐量。把每秒完成數拉高,卻讓高風險任務跳過 Reviewer,或讓普通任務永遠沒機會執行,都不能算成功。
多任務湧入時,AI 虛擬員工不塞車的關鍵不是建立更多 Agent,而是先用 Admission Control 擋住重複、越界與超額任務,再以優先 Queue 安排工作,最後用分層 Resource Gate 保護模型、工具、租戶與企業資料。
Lease、Checkpoint、冪等與 Backpressure 則確保系統在 worker 崩潰、API 限流或人工等待時仍能恢復,不會重複外部動作。Spark 可以作為 Task 與 Schedule 的入口;企業級併發控制仍需要可查詢的 Queue、State 與 Audit Log。