SKILL.md — Agha Actor 模型:並行代理系統設計
決策點
根據任務類型選擇 Actor 建立策略
如果任務有順序相依性:
├─ 使用顧客模式:建立帶有回覆位址的子 Actor
├─ 將顧客位址作為參數傳遞給子 Actor
└─ 子 Actor 直接將結果發送給顧客(非父 Actor)
如果任務需要長時間運算:
├─ 為運算建立不敏感 Actor
├─ 將傳入訊息轉發到緩衝 Actor
└─ 運算完成後從緩衝區恢復處理
如果任務需要動態資源配置:
├─ 按需建立資源管理 Actor
├─ 將能力(位址)作為訊息資料傳遞
└─ 無中央註冊表 - 位址在系統中流通
如果任務有故障隔離需求:
├─ 為高風險操作生成受監督的子 Actor
├─ 監督者透過遺失的回覆來偵測故障
└─ 替換失敗的 Actor,不影響其他
如果正在組合現有代理系統:
├─ 驗證介面是否保留因果結構
├─ 測試組合下的行為(不僅是隔離狀態)
└─ 使用訊息協定作為邊界(非共享狀態)
訊息發送 vs. 狀態替換決策樹
如果需要與其他代理協調:
├─ 發送訊息(不要先修改本地狀態)
├─ 如果需要回應,則包含回覆位址
└─ 永遠不要假設訊息順序
如果只需要本地計算:
├─ 指定替換行為
├─ 封裝新狀態(不要暴露內部細節)
└─ 確保一次只處理一個訊息
如果需要動態擴展:
├─ 建立具有特定行為的新 Actor
├─ 將必要的位址傳遞給新 Actor
└─ 無共享初始化狀態
失敗模式
1. 中央編排器反模式
檢測:如果看到一個 Actor 路由所有訊息或持有所有系統狀態 症狀:單點故障、負載瓶頸、無限遞歸問題 修復:分解為 Actor 社群,每個只了解本地上下文,使用能力路由
2. 同步阻塞謬誤
檢測:如果 Actor 等待/阻塞回應,而不是指定替換行為 症狀:負載下的死結、隱藏的時序假設、並行性降低 修復:建模為請求-回覆訊息對,對依賴項使用顧客模式,應用不敏感 Actor 模式
3. 共享狀態污染
檢測:如果多個 Actor 讀寫相同的資料結構(即使有鎖) 症狀:競態條件、順序瓶頸、隱藏的全局狀態 修復:將狀態封裝在單一 Actor 中,使用訊息傳遞進行協調,互斥是免費的
4. 僅輸出驗證
檢測:如果測試僅比較最終輸出,而不檢查互動模式 症狀:Brock-Ackerman 異常 - 輸出相同但組合行為不同 修復:驗證因果結構保留、測試組合下的行為、使用觀察等價
5. 靜態拓撲假設
檢測:如果通訊圖在啟動時固定,沒有執行時重新配置 症狀:無法處理開放系統、無動態資源管理、面對變化時脆弱 修復:將位址視為第一級資料、實作能力路由、支援執行時拓撲變更
實例
範例 1:使用顧客模式進行任務分解
情境:代理需要處理一個複雜請求,該請求需要順序子任務 A → B → C,但必須保持對其他訊息的回應能力。
新手方法:
收到請求 →
在呼叫子任務 A 時阻塞
在呼叫子任務 B 時阻塞
在呼叫子任務 C 時阻塞
發送最終結果
專家對 Actor 模型的應用:
收到請求 →
建立包含 B、C 和最終接收者位址的 customer_BC Actor
將子任務 A 請求發送給 A_processor,並將 customer_BC 作為回覆位址
指定替換行為:準備好處理下一個請求
customer_BC 收到 A 結果 →
將結果發送給 B_processor,並將 customer_C 作為回覆位址
customer_C 收到 B 結果 →
將結果發送給 C_processor,並將 final_recipient 作為回覆位址
做出的關鍵決策:
- 使用顧客模式來避免阻塞
- 每一步都在鏈中建立下一個顧客
- 原始代理在整個過程中保持回應能力
- 任何子任務中的失敗僅影響該鏈
範例 2:透過監督進行故障恢復
情境:系統需要處理代理故障,而不會擴散到整個系統。
新手方法:在代理呼叫周圍使用 try-catch,在故障時重新啟動所有內容。
專家應用:
監督者建立 worker_actor →
發送任務給 worker,並設定回覆超時
指定替換:"等待回覆"
如果在超時內收到回覆 →
將結果轉發給客戶端
指定替換:"準備就緒"
如果超時到期 →
建立新的 worker_actor(舊的失敗了)
將任務重新發送給新的 worker
指定替換:"等待回覆"
處理過的權衡:
- 監督是與業務邏輯分離的關注點
- 失敗的 Actor 被隔離和替換,而不是修復
- 超時檢測與保證交付之間的平衡
- 監督者和 worker 之間無共享狀態
品質關卡
- 沒有 Actor 阻塞其訊息處理迴圈(在需要處應用了不敏感 Actor 模式)
- 所有協調都使用訊息傳遞(Actor 之間無共享可變狀態)
- 訊息傳遞是有保證的,但不假設順序
- 位址被視為第一級資料以進行能力路由
- 每個 Actor 為每種訊息類型指定替換行為
- Actor 的建立是根據計算需求動態發生的
- 故障隔離防止故障在 Actor 邊界間級聯
- 系統拓撲可以在沒有中央註冊表的情況下於執行時重新配置
- 組合行為經過驗證,而不僅僅是隔離的元件行為
- 同步操作建模為請求-回覆訊息對
不適用邊界
此技能不應用於:
- 簡單的順序計算 → 改用函數式程式設計
- 系統在物理上需要共享記憶體 → 使用基於鎖的並行程式模式
- 具有嚴格時序限制的即時系統 → 使用具有正式時序分析的非同步訊息傳遞
- 不需要協調的數學計算 → 使用純函數式方法
當以下情況時,委派給其他技能:
- 實作特定 Actor 框架 → 使用平台特定的實作指南
- 對 Actor 系統進行效能調校 → 使用 [performance-optimization] 技能
- 對 Actor 屬性進行正式驗證 → 使用 [formal-methods] 技能
- 針對 Actor 持久化的資料庫設計 → 使用 [data-architecture] 技能
關於範圍的常見誤解:
- Actor 不僅僅是「帶有非同步方法的物件」——它們需要完整的 3 元組回應
- Actor 模型不僅僅適用於分散式系統——它適用於任何並行計算
- 這主要不是一個效能最佳化——它是一個正確性和可組合性框架