大多數人把 Agent 設計成「一問一答」的延伸版本——輸入一個任務,等待一個輸出。 長時程任務打破了這個假設:任務可能跨越數小時、數天、數十個 LLM 呼叫。 短時程 Agent 的容錯率是 5%,長時程 Agent 的錯誤會複利累積,五十步後完成率可能跌到 5%。 真正的長時程 Agent 工程,是在不確定性中建立可恢復、可審計、可協作的執行系統。
面試情境
你的團隊正在建構一個自動化程式碼審查 Agent,需要在 72 小時內分析一個大型 monorepo 的 3000 個 PR,並針對每個 PR 產出安全性報告、效能建議與合規性評估。這個 Agent 在執行到第 800 個 PR 時崩潰重啟,你如何設計系統確保任務能從斷點繼續、不重複分析已完成的 PR、且最終報告的品質不會因為長時間執行而漂移?
一、核心問題:為什麼長時程任務對 Agent 是質的挑戰
1.1 短時程 vs 長時程的根本差異
大多數 LLM Agent 的設計假設是「無狀態、單輪、短暫」:使用者提問,Agent 在一個 context window 內完成推理,回傳答案,會話結束。這個模型在 RAG 問答、程式碼補全、單步工具呼叫等場景運作良好。
長時程任務打破了所有這些假設:
- 時間跨度:任務可能需要 2 小時、2 天、甚至 2 週才能完成
- 狀態複雜度:中間狀態數量可達數千個節點,無法全部放入 context window
- 錯誤複利:每一步有 2% 的錯誤率,50 步後完成率僅剩 36%(0.98^50 ≈ 0.364)
- 外部世界變化:任務執行期間,外部環境可能發生變化(程式碼庫更新、API 回應格式改變)
- 人工干預需求:某些決策點需要人類確認,無法全程自動化
1.2 錯誤複利的數學現實
假設每個子任務的成功率為 p,執行 n 個子任務,整體成功率為 p^n:
子任務成功率 10步任務 50步任務 100步任務
────────────────────────────────────────────────
99.0% 90.4% 60.5% 36.6%
95.0% 59.9% 7.7% 0.6%
90.0% 34.9% 0.5% 0.003%
這意味著:一個「看起來不錯」的 Agent,在長任務中可能完全不可用。提升長時程 Agent 可靠性的唯一方法是:Checkpoint、回滾、人工確認點,以及漂移偵測。
1.3 長時程任務失敗的四大根本原因
- 記憶喪失:每次 LLM 呼叫後,上下文在 context window 外的部分消失
- 目標漂移:隨著任務進行,Agent 對原始目標的理解逐漸偏離
- 狀態不一致:崩潰重啟後,已完成的步驟與待完成步驟的邊界不清
- 無法恢復的副作用:某些操作(發送郵件、寫入資料庫)不可逆,重試會造成重複
二、三個演進階段(POC/MVP/Scale)
╔══════════════════════════════════════╗
║ Phase 1:POC / < 10K 任務 / 單機 ║
╚══════════════════════════════════════╝
核心假設:任務數量少,可以接受失敗後手動重跑,不需要分散式協調。
┌─────────────────────────────────────────────────────────┐
│ Phase 1 Architecture │
│ │
│ 使用者請求 │
│ │ │
│ ▼ │
│ ┌──────────┐ ┌──────────────────┐ │
│ │ Agent │───▶│ LLM API (GPT-4) │ │
│ │ Loop │◀───│ │ │
│ └────┬─────┘ └──────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ 本地 JSON 檔案 (task_state.json)│ │
│ │ - 已完成步驟清單 │ │
│ │ - 當前中間結果 │ │
│ └──────────────────────────────────┘ │
│ │
│ 恢復方式:手動檢查 JSON,刪除失敗步驟,重新執行 │
└─────────────────────────────────────────────────────────┘
Phase 1 特點:
- 狀態儲存:本地 JSON 檔案,單機運行
- 恢復機制:手動,人工檢查並重新啟動
- Checkpoint 粒度:整個任務,不是子任務
- 成本:~$0.02/任務(GPT-4 API 費用),$0 基礎架構
- 適用場景:實驗驗證、個人工作流程自動化
- 可接受的缺陷:崩潰後需手動介入,不支援並發,無審計日誌
╔══════════════════════════════════════════════╗
║ Phase 2:MVP / 10K–200K 任務 / 微服務 ║
╚══════════════════════════════════════════════╝
核心升級:引入持久化狀態儲存、自動 Checkpoint、基本的人工確認點。
┌──────────────────────────────────────────────────────────────┐
│ Phase 2 Architecture │
│ │
│ ┌──────────┐ ┌─────────────────┐ ┌────────────────┐ │
│ │ Task │───▶│ Orchestrator │───▶│ Worker Pool │ │
│ │ Queue │ │ (stateful) │ │ (3-5 workers) │ │
│ │ (Redis) │ └────────┬────────┘ └───────┬────────┘ │
│ └──────────┘ │ │ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌────────────────┐ │
│ │ Checkpoint DB │ │ LLM API Pool │ │
│ │ (PostgreSQL) │ │ (rate limited)│ │
│ │ - task_id │ └────────────────┘ │
│ │ - step_index │ │
│ │ - state_blob │ ┌────────────────┐ │
│ │ - completed_at │ │ Human Review │ │
│ └─────────────────┘ │ Queue (Slack) │ │
│ └────────────────┘ │
│ │
│ 監控:Prometheus + Grafana,任務完成率 Dashboard │
└──────────────────────────────────────────────────────────────┘
Phase 2 特點:
- 狀態儲存:PostgreSQL,每個子任務完成後 Checkpoint
- 恢復機制:自動,Worker 崩潰後由 Orchestrator 重新分配
- Checkpoint 粒度:每個子任務(平均 30 秒一個 Checkpoint)
- 成本:~$50/月基礎架構 + $0.02/任務 LLM 費用
- 人工確認:高風險決策(刪除操作、外部 API 寫入)通過 Slack webhook 觸發
- 可接受的缺陷:無跨資料中心容錯,漂移偵測靠人工觀察
╔══════════════════════════════════════════════════════╗
║ Phase 3:Scale / 200K–1M+ 任務 / 分散式系統 ║
╚══════════════════════════════════════════════════════╝
核心升級:分散式 Checkpoint、自動漂移偵測、細粒度人工確認工作流程、多 LLM 後端。
┌──────────────────────────────────────────────────────────────────┐
│ Phase 3 Architecture │
│ │
│ ┌───────────┐ ┌─────────────────────────────────────────┐ │
│ │ API GW │──▶│ Orchestration Layer │ │
│ └───────────┘ │ ┌──────────┐ ┌────────────────────┐ │ │
│ │ │ Planner │ │ Drift Detector │ │ │
│ │ │ (DAG gen)│ │ (embedding-based) │ │ │
│ │ └─────┬────┘ └──────────┬─────────┘ │ │
│ └────────┼─────────────────┼─────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────────────┐ ┌─────────────────┐ │
│ │ Worker Fleet │ │ Alert Engine │ │
│ │ (auto-scaling) │ │ (PagerDuty / │ │
│ │ 10–100 workers │ │ Slack / Email)│ │
│ └────────┬───────────┘ └─────────────────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌────────┐ ┌──────────────┐ │
│ │ Checkpoint │ │ Vector │ │ Audit Log │ │
│ │ Store │ │ Memory │ │ (immutable) │ │
│ │ (Redis + │ │ (Pinecone│ │ (S3 / │ │
│ │ Postgres) │ │ / pgvec) │ │ BigQuery) │ │
│ └──────────────┘ └────────┘ └──────────────┘ │
│ │
│ SLA:99.5% 任務完成率,P99 恢復時間 < 30 秒 │
└──────────────────────────────────────────────────────────────────┘
Phase 3 特點:
- 狀態儲存:Redis(熱態)+ PostgreSQL(冷態)雙層 Checkpoint
- 恢復機制:< 30 秒自動恢復,跨資料中心容錯
- 漂移偵測:Embedding 相似度監控,目標向量與當前行為向量持續比對
- 成本:~$2,000/月基礎架構,但每任務單位成本從 Phase 1 的 $0.02 降至 $0.008(批次 + 快取)
- 審計:所有 Agent 決策不可變地記錄到 S3,支援事後分析
三、跨會話記憶:持久化設計與版本管理
3.1 記憶的四個層次
長時程 Agent 需要在不同時間尺度上管理記憶:
┌─────────────────────────────────────────────────────────────┐
│ 記憶層次架構 │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ L1:工作記憶 (Working Memory) │ │
│ │ ├── Context Window (128K tokens) │ │
│ │ ├── 當前任務狀態、最近 N 個工具呼叫結果 │ │
│ │ └── 生命週期:單次 LLM 呼叫 │ │
│ └────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ L2:會話記憶 (Session Memory) │ │
│ │ ├── 當前子任務的完整執行歷史 │ │
│ │ ├── 儲存:Redis,TTL = 24 小時 │ │
│ │ └── 生命週期:單一任務執行期間 │ │
│ └────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ L3:長期記憶 (Long-term Memory) │ │
│ │ ├── 已完成任務的摘要、學到的事實 │ │
│ │ ├── 儲存:Vector DB(語義搜尋)+ SQL(精確查詢) │ │
│ │ └── 生命週期:永久(帶版本控制) │ │
│ └────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ L4:外部知識 (External Knowledge) │ │
│ │ ├── 文件庫、程式碼庫、資料庫 │ │
│ │ ├── 存取方式:工具呼叫(不存入 context) │ │
│ │ └── 生命週期:獨立於 Agent │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
3.2 持久化記憶的版本管理
長時程任務中,記憶會隨時間演化。必須對記憶進行版本控制,原因有三:
- 回滾需求:任務失敗後需要恢復到某個良好狀態
- 稽核追蹤:需要了解 Agent 在某時間點「知道什麼」
- 一致性保障:避免部分更新造成的記憶不一致
記憶版本控制 Schema(PostgreSQL):
1CREATE TABLE agent_memory (
2 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
3 task_id UUID NOT NULL,
4 memory_key TEXT NOT NULL,
5 memory_value JSONB NOT NULL,
6 version INTEGER NOT NULL DEFAULT 1,
7 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
8 superseded_at TIMESTAMPTZ, -- NULL = 當前版本
9 checksum TEXT NOT NULL -- SHA-256,防止靜默損壞
10);
11
12-- 取得某任務的當前記憶快照
13CREATE VIEW agent_memory_current AS
14SELECT * FROM agent_memory
15WHERE superseded_at IS NULL;
3.3 記憶壓縮策略
當長期記憶累積過多時,需要進行摘要壓縮,避免每次查詢都必須處理數千個向量:
- 滾動摘要:每 20 個步驟,將舊步驟的詳細記錄壓縮為摘要(成本節省 ~80%)
- 重要性加權:錯誤記錄的保留權重 > 成功記錄(失敗提供更多學習信號)
- TTL 策略:> 30 天的任務摘要降級到冷儲存(S3),保持 Vector DB 精簡
四、長任務分解:里程碑 / 子目標 / 依賴圖
4.1 三層任務結構
長時程任務需要層次化分解,避免單層扁平結構帶來的複雜度爆炸:
任務(Task)
├── 里程碑 1:完成資料收集
│ ├── 子目標 1.1:API 資料抓取(獨立,可並行)
│ ├── 子目標 1.2:資料庫查詢(獨立,可並行)
│ └── 子目標 1.3:資料清洗(依賴 1.1、1.2)
├── 里程碑 2:分析處理
│ ├── 子目標 2.1:特徵工程(依賴里程碑 1)
│ └── 子目標 2.2:模型推理(依賴 2.1)
└── 里程碑 3:報告產出
└── 子目標 3.1:報告生成(依賴里程碑 2)
4.2 依賴圖的 DAG 表示
使用有向無環圖(DAG)表示子任務依賴關係,支援:
- 拓撲排序:確定執行順序
- 關鍵路徑分析:找出影響整體完成時間的瓶頸
- 並行化機會:識別可以同時執行的子任務
DAG 資料結構(Python):
1@dataclass
2class SubTask:
3 task_id: str
4 description: str
5 dependencies: List[str] # task_id 清單
6 status: Literal["pending", "running", "completed", "failed"]
7 checkpoint_data: Optional[dict] = None
8 retry_count: int = 0
9 max_retries: int = 3
10
11class TaskDAG:
12 def get_ready_tasks(self) -> List[SubTask]:
13 """返回所有依賴已完成且尚未執行的任務"""
14 return [
15 t for t in self.tasks.values()
16 if t.status == "pending"
17 and all(
18 self.tasks[dep].status == "completed"
19 for dep in t.dependencies
20 )
21 ]
4.3 里程碑的人工確認設計
不是每個里程碑都需要人工確認,需要根據風險等級決定:
| 風險等級 | 典型操作 | 確認方式 | 超時策略 |
|---|---|---|---|
| 高 | 資料庫寫入、外部 API 呼叫、資金操作 | 同步等待人工批准 | 超過 1 小時自動暫停 |
| 中 | 檔案系統修改、設定變更 | 非同步通知,可選審核 | 超過 4 小時自動繼續 |
| 低 | 唯讀查詢、內部計算 | 僅記錄日誌 | 無超時 |
五、斷點恢復:Checkpoint 設計與狀態一致性
5.1 Checkpoint 的核心原則
Checkpoint 設計有三個核心原則,違反任何一個都會導致恢復失敗:
- 冪等性(Idempotency):重複執行同一步驟的結果必須相同
- 原子性(Atomicity):Checkpoint 要麼完整寫入,要麼完全不寫入
- 先寫後執行(Write-Ahead):在執行副作用之前,先持久化 Checkpoint
5.2 Checkpoint 狀態機
┌─────────────────────────────────────────────────────────────┐
│ Checkpoint 狀態機 │
│ │
│ ┌──────────┐ │
│ │ PENDING │ ──── 開始執行 ────▶ ┌─────────────┐ │
│ └──────────┘ │ RUNNING │ │
│ └──────┬──────┘ │
│ │ │
│ ┌───────────────┼───────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌────────┐│
│ │ COMPLETED │ │ FAILED │ │TIMEOUT ││
│ └─────────────┘ └──────┬──────┘ └───┬────┘│
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────┐ │
│ │ RETRY_PENDING │ │
│ │ (max 3 retries) │ │
│ └──────────┬──────────┘ │
│ │ │
│ retry < max ───┴─── retry = max│
│ │ │ │
│ ▼ ▼ │
│ [回 RUNNING] [DEAD_LETTER│
│ 需人工介入] │
└─────────────────────────────────────────────────────────────┘
5.3 Write-Ahead Checkpoint 實作
1class CheckpointManager:
2 def execute_with_checkpoint(
3 self,
4 task_id: str,
5 step_id: str,
6 action: Callable,
7 *args, **kwargs
8 ):
9 # 1. 先檢查是否已有完成的 Checkpoint(冪等性保障)
10 existing = self.db.get_checkpoint(task_id, step_id)
11 if existing and existing.status == "completed":
12 return existing.result # 直接返回快取結果,跳過執行
13
14 # 2. Write-Ahead:在執行前記錄「開始」狀態
15 self.db.upsert_checkpoint(task_id, step_id, status="running")
16
17 try:
18 result = action(*args, **kwargs)
19
20 # 3. 執行成功後,原子性地更新為「完成」
21 self.db.upsert_checkpoint(
22 task_id, step_id,
23 status="completed",
24 result=result,
25 completed_at=datetime.utcnow()
26 )
27 return result
28
29 except Exception as e:
30 self.db.upsert_checkpoint(
31 task_id, step_id,
32 status="failed",
33 error=str(e)
34 )
35 raise
5.4 恢復時的狀態一致性問題
最危險的崩潰時機是「Checkpoint 已寫入,但副作用尚未發生」或「副作用已發生,但 Checkpoint 尚未寫入」。
解決方案:兩階段提交模式(Two-Phase Commit)
- Phase 1(Prepare):寫入 Checkpoint,狀態為
PREPARE,不執行副作用 - Phase 2(Commit):執行副作用,成功後更新 Checkpoint 為
COMMITTED - 恢復邏輯:找到
PREPARE狀態的步驟,從 Phase 2 重試(副作用必須冪等)
這個設計保障了:即使在任何時間點崩潰,恢復後都能達到一致狀態,且不會重複執行副作用超過一次。
六、人機協作:何時需要人工確認的決策框架
6.1 自動化 vs 人工確認的決策樹
並非所有決策都需要人工確認。過度要求人工確認會讓 Agent 失去自動化價值,不足則帶來風險。以下是決策框架:
需要人工確認的條件(滿足任一即觸發):
- 操作的不可逆程度 > 閾值(刪除資料、金融交易、發送通訊)
- Agent 信心分數 < 0.75(LLM 自我評估的不確定性)
- 操作涉及的資源規模超過預設上限(例如:刪除 > 100 筆記錄)
- 漂移偵測器發出警告(當前行為與原始目標偏差 > 15%)
- 連續失敗次數 > 2(可能遇到未知情況)
不需要人工確認的條件(必須全部滿足):
- 操作完全可逆
- Agent 信心分數 > 0.85
- 操作規模在預設閾值內
- 無漂移警告
- 同類操作在過去 24 小時內成功率 > 95%
6.2 人工確認的非同步設計
同步等待人工確認會阻塞整個任務管線。正確設計是非同步模式:
Agent 遇到確認點
│
▼
建立 HumanReviewRequest(記錄到 DB)
│
▼
通知人工審查員(Slack / Email / 前端 UI)
│
▼
Agent 暫停此子任務,繼續執行其他獨立子任務
│
▼ (審查員回應後)
Webhook 觸發,恢復子任務執行
關鍵細節:
- 審查請求必須包含完整的決策上下文(為何需要確認、可能的影響、建議選項)
- 提供「一鍵批准」和「一鍵拒絕 + 重新規劃」兩個選項
- 超時策略:高風險操作超時後暫停(保守),中風險操作超時後繼續(積極)
- 批次確認:將同類確認請求合併,避免審查員疲勞
6.3 人工確認的工作量預算
根據任務規模設定人工確認的預期工作量上限:
| 任務規模 | 最大確認次數 | 每次確認時間 | 總人工時間 |
|---|---|---|---|
| 小型(< 100 步) | 5 次 | 2 分鐘 | < 10 分鐘 |
| 中型(100–1000 步) | 15 次 | 3 分鐘 | < 45 分鐘 |
| 大型(1000+ 步) | 30 次 | 5 分鐘 | < 2.5 小時 |
超過預算時,系統需要自動調整確認閾值,或通知任務設計者重新評估自動化程度。
七、漂移偵測:長時程任務中的目標偏移診斷
7.1 什麼是目標漂移
目標漂移(Goal Drift)是指 Agent 在長時間執行過程中,其行為逐漸偏離原始任務目標的現象。漂移的三種形態:
- 語義漂移:Agent 對任務目標的理解偏移(例如:「分析安全性問題」變成「優化程式碼品質」)
- 範疇漂移:任務範圍悄悄擴大(例如:開始分析原本不需要處理的模組)
- 品質漂移:輸出品質隨時間下降(例如:前 100 個報告很詳細,後 100 個越來越簡略)
7.2 漂移偵測的實作方法
方法 A:Embedding 相似度監控
在任務開始時,對原始目標進行 Embedding:
1original_goal_embedding = embed("分析每個 PR 的安全性問題")
每隔 N 個步驟,對 Agent 最近 K 個動作進行摘要並 Embedding,計算與原始目標的 cosine 相似度。若相似度 < 0.75,觸發漂移警告。
方法 B:輸出品質指標監控
對於結構化輸出(例如安全報告),監控以下指標的時序趨勢:
- 報告長度(字數)
- 關鍵欄位填寫率(是否有遺漏項目)
- 嚴重問題識別率(與前期樣本比較)
若任何指標出現顯著下降趨勢(> 20% 下降),觸發品質漂移警告。
方法 C:行為熵增監控
追蹤 Agent 工具使用的多樣性(Shannon Entropy)。若熵值異常升高(Agent 開始呼叫不應該呼叫的工具),代表行為發生漂移。
7.3 漂移響應策略
| 漂移嚴重程度 | 偵測條件 | 自動響應 | 人工響應 |
|---|---|---|---|
| 輕微(黃色) | 相似度 0.65–0.75 | 強制重新注入原始目標到 context | 通知,可選審查 |
| 中度(橙色) | 相似度 0.50–0.65 | 暫停,重新規劃後續步驟 | 需確認繼續 |
| 嚴重(紅色) | 相似度 < 0.50 | 完全暫停,保存當前狀態 | 需人工分析根因 |
八、為什麼選 X 不選 Y
決策 1:Checkpoint 儲存 — PostgreSQL vs Redis
選擇 選 PostgreSQL 的理由 不選純 Redis 的理由
────────────────────────────────────────────────────────────────────────
PostgreSQL ACID 保障,不怕崩潰丟失 Redis 重啟可能丟失 AOF 未刷盤資料
vs Redis 原生 JSONB,複雜查詢支援 Redis 無法做 JOIN 查詢歷史 Checkpoint
(主儲存) 自動備份、PITR 支援 Redis 記憶體成本高,不適合長期儲存
SQL 讓稽核查詢非常直觀
Flip condition:當 Checkpoint 的讀寫延遲成為瓶頸(>5ms P99),改用 Redis 作為熱層快取,PostgreSQL 作為冷層持久化的雙層架構(Phase 3 的選擇)。
決策 2:任務佇列 — Redis Streams vs RabbitMQ vs Kafka
選擇 選 Redis Streams 的理由 不選的理由
────────────────────────────────────────────────────────────────────
Redis Streams 已有 Redis 基礎架構,零額外服務 RabbitMQ:需額外維護,資料不持久
vs RabbitMQ/ Consumer Group 原生支援重複消費 Kafka:過度設計,維運複雜度高
Kafka < 1ms 推送延遲 Kafka:需要 ZooKeeper/KRaft 叢集
(任務佇列) JSON 消息格式,與 Agent 代碼一致
Flip condition:每日任務量 > 1M 且需要消息保留 > 7 天時,切換到 Kafka(需要流式回放能力)。
決策 3:長期記憶 — Vector DB vs 純 SQL 全文檢索
選擇 選 Vector DB 的理由 不選純 SQL 的理由
────────────────────────────────────────────────────────────────────
Vector DB 語義搜尋:找「相似概念」不只「相同詞」 SQL LIKE 只能精確匹配
(pgvector/ < 10ms 近似最近鄰(ANN)查詢 SQL 全文檢索延遲 50–200ms
Pinecone) 自然語言記憶注入無需格式化 SQL 無法做 embedding 相似度排序
vs SQL FTS 支援 top-k 語義排序
Flip condition:記憶內容是高度結構化的資料(如時序指標、財務數字),SQL 精確查詢反而更合適。混合架構:Vector DB 做語義查詢,SQL 做精確查詢,各司其職。
決策 4:漂移偵測 — Embedding 餘弦相似度 vs 規則型檢查
選擇 選 Embedding 的理由 不選純規則的理由
────────────────────────────────────────────────────────────────────
Embedding 捕捉語義層面的偏移,不只關鍵字 規則無法覆蓋所有漂移模式
相似度 自適應:不需要為每個任務類型寫規則 規則維護成本高,容易遺漏邊緣情況
vs 規則型 可以量化偏移程度(0–1 的數值) 規則是二元判斷,無法做漸進式警告
Flip condition:任務目標是高度結構化且可量化的(例如:「分析 PR 必須包含這 5 個欄位」),規則型檢查更精準且成本更低($0 vs 每次 Embedding 呼叫 $0.0001)。
決策 5:人工確認通道 — Slack Webhook vs 專用審查 UI
選擇 選 Slack Webhook 的理由 不選專用 UI(初期)的理由
────────────────────────────────────────────────────────────────────
Slack Webhook 零開發成本,審查員已在用 Slack 專用 UI 需要 2–4 週開發時間
(Phase 1/2) Interactive Components 支援按鈕批准 初期任務量少,UI 投資報酬率低
行動裝置友好,隨時隨地可審查 Slack 支援附件、摘要、操作按鈕
審查歷史自動留存於 Slack 頻道
Flip condition:每日確認請求 > 50 個,或需要複雜的比較視覺化(如 diff 顯示),則專用 UI 的使用者體驗優勢超過開發成本。
決策 6:子任務重試策略 — 指數退避 vs 固定間隔
選擇 選指數退避的理由 不選固定間隔的理由
────────────────────────────────────────────────────────────────────
指數退避 防止下游服務雪崩:失敗往往是暫時性過載 固定間隔:多個 Worker 同時重試,
+ Jitter Jitter 避免驚群效應(Thundering Herd) 可能造成下游更大壓力
vs 固定間隔 符合 AWS / GCP 等主流雲端服務的 SLA 固定間隔:無法區分「短暫故障」
第 1 次重試:1s,第 2 次:4s,第 3 次:16s 和「永久故障」
Flip condition:當失敗的原因是 Agent 自身邏輯錯誤(例如提示詞問題)而非外部服務問題時,立即重試無意義,應直接觸發人工確認而非重試。
九、系統效應:短時程 vs 長時程 Agent 改善前後對比
Before(使用短時程 Agent 模式處理長任務)vs After(完整長時程 Agent 架構)
| 指標 | Before(短時程模式) | After(長時程架構) | 改善幅度 |
|---|---|---|---|
| 50 步任務完成率 | 36%(0.98^50) | 94%(含 Checkpoint 恢復) | +161% |
| 崩潰後恢復時間 | 需手動重啟,2–8 小時 | 自動恢復,< 30 秒 | -99.9% |
| 重複執行浪費 | 崩潰後從頭重跑,100% 浪費 | 從 Checkpoint 繼續,< 5% 浪費 | -95% |
| LLM API 費用(1000 個 PR 分析) | $45(重跑浪費 ~60%) | $18(Checkpoint 避免重複呼叫) | -60% |
| 目標漂移發生率 | 無偵測,~30% 任務靜默漂移 | < 5%(漂移偵測 + 自動糾正) | -83% |
| 人工介入次數 | 高(任何問題都要重跑) | 低(僅高風險決策點) | -70% |
| 可審計性 | 無日誌,無法事後分析 | 完整 Audit Log,100% 可追溯 | N/A → 100% |
| P99 單任務延遲 | 不穩定,5–20 分鐘 | 穩定,6–8 分鐘(Checkpoint 開銷 ~3%) | -60% (P99) |
| 3000 PR 任務端對端時間 | 無法完成(中途失敗) | 72 小時內完成,SLA 達成 | 0% → 100% |
關鍵洞察
最大的改善點是「可恢復性」而非「速度」。長時程 Agent 的工程挑戰本質上是可靠性工程,而非效能工程。在不增加 LLM 能力的情況下,純粹通過工程手段(Checkpoint、冪等設計、漂移偵測),可以將 50 步任務完成率從 36% 提升到 94%。
十、面試答題要點
「面對 72 小時、3000 個 PR 的長時程分析任務,我會從三個演進階段思考系統設計。Phase 1 是 POC:使用本地 JSON 作為 Checkpoint 儲存,手動恢復,驗證 Agent 的核心分析能力;關鍵是先確認單個 PR 分析的品質,再考慮規模化。Phase 2 是生產化:引入 PostgreSQL 儲存每個 PR 分析結果的 Checkpoint,加上 Write-Ahead 模式確保崩潰後自動恢復——這直接把 50 步任務的完成率從 36% 提升到 94%,並將 LLM API 成本降低 60%(不重複分析已完成的 PR)。關鍵設計決策是為什麼選 PostgreSQL 而非 Redis:ACID 保障讓 Checkpoint 在任何崩潰時機都不會丟失,而純 Redis 的 AOF 未刷盤風險在 3000 任務規模下不可接受。Phase 3 加入 Embedding 相似度漂移偵測,每 50 個 PR 後比對當前分析行為與原始目標的 cosine 相似度,低於 0.75 觸發警告、低於 0.50 暫停任務——這解決了長時程任務中報告品質靜默下降的問題,確保第 3000 個 PR 的報告品質不低於第 1 個。」
十一、系列導航
← Phase 14 Part 4:多模態 Agent 的工具選擇策略 | Phase 15 Part 2:長時程 Agent 的成本控制與 Token 預算管理 →
本文屬於「AI 工程從零開始」系列的 Phase 15 Part 1。系列完整索引請見 系列總覽。
