# ADR-016: 智能路由 (Smart Routing) > **狀態**: 已接受 > **日期**: 2026-03-26 > **決策者**: CTO, CEO > **相關**: ADR-006 (AI Fallback Strategy) --- ## 背景 ### 問題描述 ADR-006 建立了 AI 降級備援策略,採用固定順序 (Ollama → Gemini → Claude) 進行 Fallback。然而,這種「一刀切」的方式存在以下問題: 1. **資源浪費**: 簡單查詢(如「Pod 狀態如何?」)使用 7B 模型,過度消耗本地資源 2. **回應延遲**: 複雜告警分析卻只用本地模型,品質不足需人工介入 3. **成本失控**: 無法根據任務價值動態選擇模型,高價值任務與低價值任務同等對待 ### 解決方向 需要一個**智能路由機制**,根據請求的**意圖**和**複雜度**自動選擇最適合的模型,而非固定備援順序。 --- ## 決策 ### 核心策略 ``` Intent (意圖) + Complexity (複雜度) → Model Selection (模型選擇) ``` ### 架構圖 ``` User Request / Alert │ ▼ ┌─────────────────────┐ │ Intent Classifier │ ← 關鍵字優先 (0ms) + Qwen 1B 備援 (< 100ms) │ (意圖分類器) │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ Complexity Scorer │ ← 純規則引擎 (< 10ms) │ (複雜度評分器) │ └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ AI Router │ ← 動態模型選擇 │ (智能路由器) │ └──────────┬──────────┘ │ ┌─────┴─────┐ │ │ ▼ ▼ ┌─────────┐ ┌─────────┐ │ Local │ │ Cloud │ │ Ollama │ │ Gemini │ │ 3B/7B │ │ Claude │ └─────────┘ └─────────┘ ``` --- ## 技術實作 ### 1. IntentClassifier (意圖分類器) **檔案**: `apps/api/src/services/intent_classifier.py` #### 意圖類型 | IntentType | 說明 | 典型場景 | |------------|------|----------| | `ALERT_TRIAGE` | 告警分流 | 高負載告警、OOM、服務 Down | | `DEPLOYMENT` | 部署操作 | kubectl apply、helm upgrade | | `QUERY` | 資訊查詢 | 狀態查詢、日誌查看 | | `MAINTENANCE` | 維運操作 | 重啟、擴容、回滾 | | `CODE_REVIEW` | 程式碼審查 | PR Review、Commit 分析 | | `UNKNOWN` | 未知 | 無法分類的請求 | #### 分類策略 (兩階段) ```python async def classify(self, text: str) -> IntentType: # 階段 1: 關鍵字快速匹配 (0ms) intent = self._keyword_match(text.lower()) if intent != IntentType.UNKNOWN: return intent # 階段 2: LLM 分類 (< 100ms) - 備援 # 使用 Qwen 2.5 1B 小模型 return IntentType.UNKNOWN ``` #### 關鍵字映射 ```python INTENT_KEYWORDS = { IntentType.ALERT_TRIAGE: [ "alert", "告警", "警報", "異常", "error", "critical", "high cpu", "memory", "oom", "crash", "down", ], IntentType.DEPLOYMENT: [ "deploy", "部署", "rollout", "kubectl apply", "helm", "版本", "upgrade", "更新", "上線", ], IntentType.QUERY: [ "查詢", "狀態", "status", "describe", "get", "list", "日誌", "log", "哪個", "什麼", "how many", "多少", ], # ... } ``` --- ### 2. ComplexityScorer (複雜度評分器) **檔案**: `apps/api/src/services/complexity_scorer.py` #### 評分維度與權重 | 特徵 | 權重 | 說明 | |------|------|------| | `service_count` | +0.5/服務 | 每增加一個受影響服務 | | `metric_count` | +0.3/指標 | 每增加一個相關指標 | | `code_analysis` | +1.5 | 需要程式碼分析 | | `cross_system` | +1.0 | 跨系統問題 | | `has_history` | -0.5 | 有歷史案例 (降低複雜度) | | `critical_severity` | +1.0 | CRITICAL 嚴重程度 | #### 複雜度 → 模型映射 | 分數 | 複雜度等級 | 推薦模型 | 理由 | |------|-----------|----------|------| | 1 | 簡單 | `llama3.2:3b` | 快速回應,資源節省 | | 2 | 中等 | `qwen2.5:7b-instruct` | 平衡品質與延遲 | | 3 | 複雜 | `qwen2.5:7b-instruct` | 需要較強推理能力 | | 4 | 高複雜 | `gemini` | 需要雲端能力 | | 5 | 極複雜 | `claude` | 最強模型處理 | --- ### 3. AIRouter (智能路由器) **檔案**: `apps/api/src/services/ai_router.py` #### 路由決策流程 ```python async def route(self, text: str, context: dict | None = None) -> RoutingDecision: # Step 1: 意圖分類 intent = await self._intent_classifier.classify(text) # Step 2: 複雜度評分 complexity = self._complexity_scorer.score(context or {}) # Step 3: 模型選擇 (考慮意圖覆寫) model, reason = self._select_model(intent, complexity) # Step 4: 建立 Fallback 列表 fallbacks = self._build_fallback_list(model) return RoutingDecision( model=model, intent=intent, complexity=complexity, reason=reason, fallback_models=fallbacks, ) ``` #### 意圖強制覆寫 某些意圖無論複雜度如何,都強制使用特定模型: ```python INTENT_OVERRIDES = { IntentType.CODE_REVIEW: "qwen2.5:7b-instruct", # 程式碼審查需要強模型 IntentType.QUERY: "llama3.2:3b", # 查詢用快速模型 # 其他依複雜度選擇 } ``` #### Fallback 順序 當選定模型失敗時,依序嘗試: ```python FALLBACK_ORDER = [ "qwen2.5:7b-instruct", # 本地主力 "llama3.2:3b", # 本地備援 "gemini", # 雲端備援 "claude", # 最終備援 ] ``` --- ## 與 ADR-006 的關係 | 面向 | ADR-006 (固定備援) | ADR-016 (智能路由) | |------|-------------------|-------------------| | **觸發時機** | 服務失敗時 | 每個請求 | | **選擇邏輯** | 固定順序 | 意圖 + 複雜度 | | **目標** | 高可用性 | 資源最佳化 | | **狀態** | 仍然有效 | 補充 ADR-006 | **協作關係**: - ADR-016 先根據請求特性選擇「最適模型」 - 若該模型失敗,ADR-006 的 Fallback 機制接手 - Circuit Breaker 與 Token 配額監控仍依 ADR-006 執行 ``` Request → [ADR-016: 智能選擇] → Model A │ 失敗 ▼ [ADR-006: Fallback] → Model B → Model C → Static Response ``` --- ## 使用範例 ### 範例 1: 簡單查詢 ```python from src.services.ai_router import get_ai_router router = get_ai_router() decision = await router.route( text="awoooi-api Pod 狀態如何?", context={"affected_services": ["awoooi-api"]} ) # 結果: # decision.model = "llama3.2:3b" # decision.intent = IntentType.QUERY # decision.complexity.score = 1 # decision.reason = "意圖 query 強制使用 llama3.2:3b" ``` ### 範例 2: 複雜告警 ```python decision = await router.route( text="CRITICAL: awoooi-api OOM Killed,worker 也連不上 Redis", context={ "affected_services": ["awoooi-api", "awoooi-worker", "redis"], "metrics": ["memory_usage", "connection_errors", "restart_count"], "severity": "CRITICAL", "cross_system": True, } ) # 結果: # decision.model = "gemini" # decision.intent = IntentType.ALERT_TRIAGE # decision.complexity.score = 4 # decision.reason = "高複雜度告警 (score=4) → 使用雲端模型" # decision.fallback_models = ["qwen2.5:7b-instruct", "llama3.2:3b", "claude"] ``` ### 範例 3: 程式碼審查 ```python decision = await router.route( text="請審查這個 PR 的變更", context={"requires_code_analysis": True} ) # 結果: # decision.model = "qwen2.5:7b-instruct" # decision.intent = IntentType.CODE_REVIEW # decision.complexity.score = 3 # decision.reason = "意圖 code_review 強制使用 qwen2.5:7b-instruct" ``` --- ## 監控指標 | 指標 | 說明 | 目標 | |------|------|------| | `intent_classification_latency` | 意圖分類延遲 | < 100ms | | `complexity_scoring_latency` | 複雜度評分延遲 | < 10ms | | `model_selection_distribution` | 模型選擇分佈 | 監控 | | `routing_decision_reason` | 路由決策原因統計 | 監控 | --- ## 影響 ### 正面 - **資源優化**: 簡單任務用小模型,節省 GPU 資源 - **品質提升**: 複雜任務自動升級到強模型 - **成本可控**: 只有真正需要時才使用雲端 API - **延遲改善**: 簡單查詢回應更快 ### 需要注意 - **分類準確度**: 關鍵字匹配可能有邊界情況 - **複雜度評估**: 規則可能需要持續調優 - **模型可用性**: 需配合 ADR-006 的 Circuit Breaker ### 風險 - 錯誤分類可能導致品質不如預期 - 需持續收集數據優化分類規則 --- ## 變更記錄 | 日期 | 版本 | 變更 | 作者 | |------|------|------|------| | 2026-03-26 | v1.0 | 初版建立 (Phase 13.3 #85-87) | CTO | --- ## 參考 - [ADR-006: AI 降級備援策略](./ADR-006-ai-fallback-strategy.md) - [Phase 13.3 Smart Router 設計](../../.claude/projects/-Users-ogt-awoooi/memory/project_phase13_3_smart_router.md) - `apps/api/src/services/intent_classifier.py` - `apps/api/src/services/complexity_scorer.py` - `apps/api/src/services/ai_router.py` --- *此 ADR 記錄智能路由機制的決策過程與實作規範,作為 ADR-006 的補充。*