Phase 13.1 CI/CD Integration: - #76 workflow_run handler for CI failure diagnosis - #77 SignOz log query (query_logs, error_logs_summary MCP) - #78 CIAutoRepairService with risk-based execution decisions Phase 13.3 Smart Routing: - #85 Intent Classifier v2.0 (rule engine + LLM fallback) - #86 Complexity Scorer (9-dimension scoring) - #87 AI Router v3.0 (routing decision matrix) - #88 Token Counter (OTEL + Langfuse integration) New files: - services/ci_auto_repair.py (risk stratification) - services/model_registry.py (centralized model config) - services/token_counter.py (677 lines) - Skill 08: Model Router Expert - Skill 09: Strangler Pattern Expert - ADR-023: Smart Routing Architecture - ADR-024: API Layer Architecture Tests: - phase11-conversational.spec.ts (E2E tests) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
653 lines
28 KiB
Markdown
653 lines
28 KiB
Markdown
# ADR-023: Phase 13.3 智能路由架構
|
||
|
||
> **狀態**: 已接受
|
||
> **日期**: 2026-03-26
|
||
> **決策者**: CTO, CEO
|
||
> **相關**: ADR-006 (AI Fallback Strategy), ADR-016 (Smart Routing)
|
||
> **Phase**: 13.3
|
||
|
||
---
|
||
|
||
## 1. 背景與問題
|
||
|
||
### 問題描述
|
||
|
||
ADR-006 建立了固定順序的 AI 備援策略 (Ollama → Gemini → Claude),ADR-016 引入了智能路由概念。然而,隨著 AWOOOI 從「告警響應」升級為「全方位 AIOps 平台」(Phase 13),需要更完整的架構設計:
|
||
|
||
1. **意圖分類不夠精細**: 缺少針對 K8s 操作的專屬意圖類型
|
||
2. **複雜度評估不完整**: 缺少跨系統、有狀態資源的風險評估
|
||
3. **Token 用量無追蹤**: 無法掌握成本分佈與趨勢
|
||
4. **配置分散**: 模型選擇邏輯散落各處,難以維護
|
||
|
||
### 目標
|
||
|
||
- 建立完整的 **Intent → Complexity → Model** 決策流程
|
||
- 定義 K8s 專屬意圖 (RESTART/SCALE/CONFIG/DIAGNOSE)
|
||
- 建立 1-5 分複雜度評分系統
|
||
- 整合 Token 用量監控 (SignOz + Langfuse)
|
||
|
||
---
|
||
|
||
## 2. 決策: Intent Classifier + Complexity Scorer + AI Router
|
||
|
||
### 核心策略
|
||
|
||
```
|
||
Intent (意圖) + Complexity (複雜度) + Context (上下文) → Model Selection (模型選擇)
|
||
```
|
||
|
||
### 三元件架構
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────────┐
|
||
│ Phase 13.3 Smart Router │
|
||
├──────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Request / Alert / Webhook │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ Intent Classifier (意圖分類器) │ │
|
||
│ │ ├── 關鍵字匹配 (< 1ms) │ │
|
||
│ │ └── LLM 備援 (qwen2.5:1b, < 100ms) │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ Complexity Scorer (複雜度評分器) │ │
|
||
│ │ ├── 服務數量 / 指標數量 │ │
|
||
│ │ ├── 跨系統判斷 / 有狀態風險 │ │
|
||
│ │ └── 歷史案例匹配 │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ AI Router (智能路由器) │ │
|
||
│ │ ├── 意圖覆寫規則 │ │
|
||
│ │ ├── 複雜度 → 模型映射 │ │
|
||
│ │ └── Circuit Breaker + Fallback │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ┌────┴────────────────────┬───────────────────┐ │
|
||
│ ▼ ▼ ▼ │
|
||
│ ┌─────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||
│ │ Ollama │ │ Gemini │ │ Claude │ │
|
||
│ │ (Local) │ │ (Cloud) │ │ (Cloud) │ │
|
||
│ │ $0 │ │ $0.001/1K │ │ $0.008/1K │ │
|
||
│ └─────────┘ └─────────────┘ └─────────────┘ │
|
||
│ │
|
||
├──────────────────────────────────────────────────────────────────┤
|
||
│ Token Usage Monitor (SignOz + Langfuse) │
|
||
│ └── llm.tokens.* / llm.cost.* / trace.generation() │
|
||
└──────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 架構圖
|
||
|
||
### 完整請求流程
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ AWOOOI Phase 13.3 │
|
||
│ Smart Routing Architecture │
|
||
└─────────────────────────────────────────────────────────────────────────┘
|
||
|
||
┌────────────────────┐
|
||
│ Alert / Request │
|
||
│ (Telegram/API) │
|
||
└─────────┬──────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────┐
|
||
│ Intent Classifier │
|
||
│ 目標: < 100ms │
|
||
└─────────┬───────────┘
|
||
│
|
||
┌─────────────────────┼─────────────────────┐
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌─────────┐ ┌───────────┐ ┌────────────┐
|
||
│ RESTART │ │ SCALE │ │ CONFIG │
|
||
│ 重啟類 │ │ 擴縮容 │ │ 配置變更 │
|
||
└────┬────┘ └─────┬─────┘ └─────┬──────┘
|
||
│ │ │
|
||
└─────────┬──────────┴─────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────┐
|
||
│ Complexity Scorer │
|
||
│ 輸出: 1-5 分 │
|
||
└─────────┬───────────┘
|
||
│
|
||
┌─────────────┼─────────────┬─────────────┬─────────────┐
|
||
│ │ │ │ │
|
||
▼ ▼ ▼ ▼ ▼
|
||
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
|
||
│ 1 │ │ 2 │ │ 3 │ │ 4 │ │ 5 │
|
||
│簡單 │ │低風險│ │中等 │ │高複雜│ │極複雜│
|
||
└──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘
|
||
│ │ │ │ │
|
||
└────────────┴─────┬──────┴────────────┴────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────┐
|
||
│ AI Router │
|
||
│ 模型選擇 │
|
||
└────────┬────────┘
|
||
│
|
||
┌────────────────┼────────────────────┐
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌──────────┐ ┌──────────────┐ ┌──────────────┐
|
||
│ Ollama │ │ Gemini │ │ Claude │
|
||
│ llama3.2 │ │ gemini-1.5 │ │ claude-3.5 │
|
||
│ qwen2.5 │ │ │ │ │
|
||
└────┬─────┘ └──────┬───────┘ └──────┬───────┘
|
||
│ │ │
|
||
└─────────────────┼───────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────┐
|
||
│ Token Monitor │
|
||
│ SignOz/Langfuse│
|
||
└─────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 意圖分類 (Intent Classification)
|
||
|
||
### 四大核心意圖
|
||
|
||
| IntentType | 說明 | 典型場景 | 關鍵字 |
|
||
|------------|------|----------|--------|
|
||
| `RESTART` | 重啟 Pod/Deployment/StatefulSet | Pod CrashLoopBackOff、服務無回應 | restart, 重啟, 重新啟動, rollout restart |
|
||
| `SCALE` | 擴縮容、HPA 調整 | CPU 高負載、流量激增 | scale, 擴容, 縮容, replicas, hpa |
|
||
| `CONFIG` | ConfigMap/Secret/ENV 變更 | 配置錯誤、環境變數缺失 | config, 配置, configmap, secret, env |
|
||
| `DIAGNOSE` | 日誌查詢、健康檢查、RCA | 錯誤追蹤、根因分析 | diagnose, 診斷, log, describe, rca |
|
||
|
||
### 輔助意圖
|
||
|
||
| IntentType | 說明 | 典型場景 |
|
||
|------------|------|----------|
|
||
| `DEPLOY` | 部署操作 | kubectl apply, helm upgrade |
|
||
| `ROLLBACK` | 回滾操作 | rollout undo, 版本回滾 |
|
||
| `QUERY` | 資訊查詢 | 狀態查詢、資源列表 |
|
||
| `CODE_REVIEW` | 程式碼審查 | PR Review, Commit 分析 |
|
||
| `ALERT_TRIAGE` | 告警分流 | 高負載告警、OOM、服務 Down |
|
||
| `UNKNOWN` | 未知意圖 | 無法分類的請求 |
|
||
|
||
### 分類策略 (兩階段)
|
||
|
||
```python
|
||
class IntentClassifier:
|
||
"""
|
||
意圖分類器 - 兩階段策略
|
||
階段 1: 關鍵字匹配 (< 1ms)
|
||
階段 2: LLM 備援 (qwen2.5:1b, < 100ms)
|
||
"""
|
||
|
||
async def classify(self, text: str) -> IntentType:
|
||
# 階段 1: 關鍵字快速匹配
|
||
intent = self._keyword_match(text.lower())
|
||
if intent != IntentType.UNKNOWN:
|
||
return intent
|
||
|
||
# 階段 2: LLM 分類 (備援)
|
||
return await self._llm_classify(text)
|
||
|
||
def _keyword_match(self, text: str) -> IntentType:
|
||
"""
|
||
關鍵字映射 (優先級: 越上面越優先)
|
||
"""
|
||
INTENT_KEYWORDS = {
|
||
IntentType.RESTART: [
|
||
"restart", "重啟", "重新啟動", "rollout restart",
|
||
"kill", "recreate", "delete pod",
|
||
],
|
||
IntentType.SCALE: [
|
||
"scale", "擴容", "縮容", "replicas", "hpa",
|
||
"autoscale", "capacity", "節點",
|
||
],
|
||
IntentType.CONFIG: [
|
||
"config", "配置", "configmap", "secret", "env",
|
||
"環境變數", "yaml", "設定",
|
||
],
|
||
IntentType.DIAGNOSE: [
|
||
"diagnose", "診斷", "log", "describe", "rca",
|
||
"root cause", "根因", "排查", "debug", "trace",
|
||
],
|
||
# ... 其他意圖
|
||
}
|
||
for intent, keywords in INTENT_KEYWORDS.items():
|
||
if any(kw in text for kw in keywords):
|
||
return intent
|
||
return IntentType.UNKNOWN
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 複雜度評分 (Complexity Scoring)
|
||
|
||
### 評分維度與權重
|
||
|
||
| 維度 | 權重 | 說明 |
|
||
|------|------|------|
|
||
| `service_count` | +0.5/服務 | 每增加一個受影響服務 |
|
||
| `metric_count` | +0.3/指標 | 每增加一個相關指標 |
|
||
| `cross_namespace` | +1.0 | 跨命名空間操作 |
|
||
| `cross_cluster` | +2.0 | 跨叢集操作 |
|
||
| `stateful_resource` | +1.0 | 有狀態資源 (StatefulSet, PVC) |
|
||
| `database_operation` | +1.5 | 涉及資料庫操作 |
|
||
| `critical_severity` | +1.0 | CRITICAL 嚴重程度 |
|
||
| `has_playbook` | -0.5 | 有歷史 Playbook (降低複雜度) |
|
||
| `requires_multisig` | +1.0 | 需要 Multi-Sig 審核 |
|
||
|
||
### 複雜度等級定義
|
||
|
||
| 分數 | 等級 | 定義 | 範例 |
|
||
|------|------|------|------|
|
||
| **1** | 簡單 | 單一資源、無狀態、可立即回滾 | 重啟單一 Pod |
|
||
| **2** | 低風險 | 多資源但同命名空間、低風險 | 擴容 Deployment |
|
||
| **3** | 中等 | 跨命名空間、需要上下文收集 | 多服務診斷 |
|
||
| **4** | 高複雜 | 有狀態資源、需要 Multi-Sig | StatefulSet 操作 |
|
||
| **5** | 極複雜 | 跨叢集、資料庫操作、需要人工審核 | 資料庫 Schema 變更 |
|
||
|
||
### 評分邏輯
|
||
|
||
```python
|
||
class ComplexityScorer:
|
||
"""
|
||
複雜度評分器 - 純規則引擎 (< 10ms)
|
||
"""
|
||
|
||
def score(self, context: dict) -> ComplexityScore:
|
||
score = 1.0 # 基礎分
|
||
|
||
# 服務數量
|
||
service_count = len(context.get("affected_services", []))
|
||
score += service_count * 0.5
|
||
|
||
# 指標數量
|
||
metric_count = len(context.get("metrics", []))
|
||
score += metric_count * 0.3
|
||
|
||
# 跨命名空間
|
||
if context.get("cross_namespace"):
|
||
score += 1.0
|
||
|
||
# 跨叢集
|
||
if context.get("cross_cluster"):
|
||
score += 2.0
|
||
|
||
# 有狀態資源
|
||
if context.get("stateful_resource"):
|
||
score += 1.0
|
||
|
||
# 資料庫操作
|
||
if context.get("database_operation"):
|
||
score += 1.5
|
||
|
||
# CRITICAL 嚴重程度
|
||
if context.get("severity") == "CRITICAL":
|
||
score += 1.0
|
||
|
||
# 歷史 Playbook (降低)
|
||
if context.get("has_playbook"):
|
||
score -= 0.5
|
||
|
||
# Multi-Sig 需求
|
||
if context.get("requires_multisig"):
|
||
score += 1.0
|
||
|
||
# 限制範圍 1-5
|
||
final_score = min(5, max(1, round(score)))
|
||
|
||
return ComplexityScore(
|
||
score=final_score,
|
||
factors=self._extract_factors(context),
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Provider 選擇邏輯
|
||
|
||
### 複雜度 → 模型映射
|
||
|
||
| 複雜度 | 主要模型 | Fallback 順序 | 理由 |
|
||
|--------|----------|---------------|------|
|
||
| **1** | `llama3.2:3b` | qwen2.5:7b → gemini → claude | 快速回應,資源節省 |
|
||
| **2** | `qwen2.5:7b-instruct` | llama3.2:3b → gemini → claude | 平衡品質與延遲 |
|
||
| **3** | `qwen2.5:7b-instruct` | gemini → claude | 需要較強推理能力 |
|
||
| **4** | `gemini` | claude → qwen2.5:7b | 需要雲端能力 |
|
||
| **5** | `claude` | gemini → qwen2.5:7b | 最強模型處理 |
|
||
|
||
### 意圖強制覆寫
|
||
|
||
某些意圖無論複雜度如何,都強制使用特定模型:
|
||
|
||
| 意圖 | 強制模型 | 原因 |
|
||
|------|---------|------|
|
||
| `DIAGNOSE` | `qwen2.5:7b-instruct` (本地) | 日誌可能含敏感資料,禁止送雲端 |
|
||
| `CODE_REVIEW` | `qwen2.5:7b-instruct` | 程式碼分析需要較強能力 |
|
||
| `QUERY` | `llama3.2:3b` | 簡單查詢不需大模型 |
|
||
|
||
### 路由決策流程
|
||
|
||
```python
|
||
class AIRouter:
|
||
"""
|
||
智能路由器 - 動態模型選擇
|
||
"""
|
||
|
||
COMPLEXITY_ROUTING = {
|
||
1: "llama3.2:3b",
|
||
2: "qwen2.5:7b-instruct",
|
||
3: "qwen2.5:7b-instruct",
|
||
4: "gemini",
|
||
5: "claude",
|
||
}
|
||
|
||
INTENT_OVERRIDES = {
|
||
IntentType.DIAGNOSE: "qwen2.5:7b-instruct", # 隱私優先
|
||
IntentType.CODE_REVIEW: "qwen2.5:7b-instruct",
|
||
IntentType.QUERY: "llama3.2:3b",
|
||
}
|
||
|
||
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: 模型選擇 (考慮意圖覆寫)
|
||
if intent in self.INTENT_OVERRIDES:
|
||
model = self.INTENT_OVERRIDES[intent]
|
||
reason = f"意圖 {intent.value} 強制使用 {model}"
|
||
else:
|
||
model = self.COMPLEXITY_ROUTING[complexity.score]
|
||
reason = f"複雜度 {complexity.score} → {model}"
|
||
|
||
# Step 4: 建立 Fallback 列表
|
||
fallbacks = self._build_fallback_list(model)
|
||
|
||
return RoutingDecision(
|
||
model=model,
|
||
intent=intent,
|
||
complexity=complexity,
|
||
reason=reason,
|
||
fallback_models=fallbacks,
|
||
)
|
||
|
||
def _build_fallback_list(self, primary: str) -> list[str]:
|
||
"""
|
||
建立 Fallback 順序 (ADR-006)
|
||
"""
|
||
FALLBACK_ORDER = [
|
||
"qwen2.5:7b-instruct",
|
||
"llama3.2:3b",
|
||
"gemini",
|
||
"claude",
|
||
]
|
||
return [m for m in FALLBACK_ORDER if m != primary]
|
||
```
|
||
|
||
---
|
||
|
||
## 7. Token 用量監控
|
||
|
||
### 監控架構
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ Token Usage Monitoring │
|
||
├─────────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||
│ │ SignOz │ │ Langfuse │ │
|
||
│ │ (Infra 層) │ │ (LLMOps 層) │ │
|
||
│ └────────┬────────┘ └────────┬────────┘ │
|
||
│ │ │ │
|
||
│ ▼ ▼ │
|
||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||
│ │ OTEL Metrics │ │ Trace/Generation│ │
|
||
│ │ - llm.tokens.* │ │ - cost tracking │ │
|
||
│ │ - llm.latency.* │ │ - model compare │ │
|
||
│ └─────────────────┘ └─────────────────┘ │
|
||
│ │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 關鍵指標
|
||
|
||
| 指標 | 說明 | 類型 |
|
||
|------|------|------|
|
||
| `llm.tokens.input` | 輸入 Token 數 | Counter |
|
||
| `llm.tokens.output` | 輸出 Token 數 | Counter |
|
||
| `llm.cost.usd` | 估算成本 (雲端 Provider) | Counter |
|
||
| `llm.latency.p99` | 延遲 P99 | Histogram |
|
||
| `llm.requests.total` | 總請求數 | Counter |
|
||
| `llm.requests.failed` | 失敗請求數 | Counter |
|
||
|
||
### 成本警報閾值 (ADR-006 延伸)
|
||
|
||
| Provider | 每日上限 | 每月上限 | 告警閾值 |
|
||
|----------|---------|---------|---------|
|
||
| Gemini | 100K tokens | 2M tokens | 70% |
|
||
| Claude | 50K tokens | 500K tokens | 70% |
|
||
|
||
### Langfuse 追蹤整合
|
||
|
||
```python
|
||
from langfuse.decorators import langfuse_context, observe
|
||
|
||
class AIRouter:
|
||
@observe(name="smart_routing")
|
||
async def route(self, text: str, context: dict) -> RoutingDecision:
|
||
decision = await self._make_decision(text, context)
|
||
|
||
# 記錄路由決策
|
||
langfuse_context.update_current_trace(
|
||
metadata={
|
||
"intent": decision.intent.value,
|
||
"complexity": decision.complexity.score,
|
||
"model": decision.model,
|
||
"reason": decision.reason,
|
||
}
|
||
)
|
||
|
||
return decision
|
||
|
||
@observe(name="llm_generation")
|
||
async def generate(self, model: str, prompt: str) -> str:
|
||
result = await self._call_model(model, prompt)
|
||
|
||
# 記錄 Token 用量
|
||
langfuse_context.update_current_observation(
|
||
usage={
|
||
"input_tokens": result.input_tokens,
|
||
"output_tokens": result.output_tokens,
|
||
},
|
||
model=model,
|
||
)
|
||
|
||
return result.content
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 與 ADR-006 的關係
|
||
|
||
### 架構層次
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ ADR-023 (Phase 13.3) │
|
||
│ 智能路由架構 │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ Intent Classifier → Complexity Scorer → AI Router │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ ADR-016 (Smart Routing 基礎實作) │ │
|
||
│ │ - IntentClassifier / ComplexityScorer / AIRouter │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||
│ │ ADR-006 (AI Fallback Strategy) │ │
|
||
│ │ - Circuit Breaker / Token 配額 / 固定 Fallback 順序 │ │
|
||
│ └─────────────────────────────────────────────────────────┘ │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 協作關係
|
||
|
||
| 面向 | ADR-006 (基礎) | ADR-016 (實作) | ADR-023 (架構) |
|
||
|------|---------------|----------------|----------------|
|
||
| **範疇** | Fallback 策略 | 路由實作 | 完整架構 |
|
||
| **觸發時機** | 服務失敗時 | 每個請求 | 架構設計層面 |
|
||
| **選擇邏輯** | 固定順序 | 意圖 + 複雜度 | 三元件協作 |
|
||
| **目標** | 高可用性 | 資源最佳化 | 全方位 AIOps |
|
||
| **狀態** | 仍然有效 | 已實作 | 本文件 |
|
||
|
||
### 請求流程整合
|
||
|
||
```
|
||
Request
|
||
│
|
||
▼
|
||
[ADR-023: 三元件決策]
|
||
│
|
||
├── Intent Classifier
|
||
├── Complexity Scorer
|
||
└── AI Router → 選擇 Model A
|
||
│
|
||
失敗 ▼
|
||
[ADR-006: Fallback Chain]
|
||
│
|
||
├── Model B
|
||
├── Model C
|
||
└── Static Response
|
||
```
|
||
|
||
---
|
||
|
||
## 9. 後果分析
|
||
|
||
### 優點
|
||
|
||
| 面向 | 效益 |
|
||
|------|------|
|
||
| **資源優化** | 簡單任務用小模型 (3B),節省 GPU 資源 30%+ |
|
||
| **品質提升** | 複雜任務自動升級到強模型,減少人工介入 |
|
||
| **成本可控** | 只有真正需要時才使用雲端 API |
|
||
| **延遲改善** | 簡單查詢回應 < 5s (llama3.2:3b) |
|
||
| **可觀測性** | Token 用量透明,成本趨勢可預測 |
|
||
| **隱私保護** | DIAGNOSE 意圖強制本地,敏感日誌不送雲端 |
|
||
|
||
### 缺點
|
||
|
||
| 面向 | 風險 | 緩解措施 |
|
||
|------|------|---------|
|
||
| **分類錯誤** | 意圖分類可能有邊界情況 | 關鍵字優先 + LLM 備援 |
|
||
| **複雜度誤判** | 規則可能需要持續調優 | 收集數據 + 定期調整權重 |
|
||
| **延遲增加** | 分類 + 評分 增加約 100ms | 限制 LLM 分類僅作備援 |
|
||
| **維護成本** | 需維護關鍵字映射表 | 集中管理於 models.json |
|
||
|
||
### 風險
|
||
|
||
| 風險 | 等級 | 緩解策略 |
|
||
|------|------|---------|
|
||
| LLM 分類器 Timeout | 中 | 設定 100ms Timeout,fallback 到 UNKNOWN |
|
||
| 全部 Provider 失敗 | 低 | ADR-006 靜態回應兜底 |
|
||
| Token 預算超支 | 中 | 告警閾值 70%,超支自動切本地 |
|
||
| 意圖覆寫邏輯錯誤 | 低 | 嚴格測試 + 監控路由決策分佈 |
|
||
|
||
---
|
||
|
||
## 10. 實作位置
|
||
|
||
```
|
||
apps/api/src/services/
|
||
├── intent_classifier.py # IntentClassifier
|
||
├── complexity_scorer.py # ComplexityScorer
|
||
├── ai_router.py # AIRouter
|
||
└── token_tracker.py # TokenTracker (SignOz + Langfuse)
|
||
```
|
||
|
||
---
|
||
|
||
## 11. 配置集中管理
|
||
|
||
### 單一事實來源: `models.json`
|
||
|
||
```json
|
||
{
|
||
"providers": {
|
||
"ollama": {
|
||
"models": {
|
||
"default": "qwen2.5:7b-instruct",
|
||
"fast": "llama3.2:3b",
|
||
"intent": "qwen2.5:1b"
|
||
},
|
||
"circuit_breaker": {
|
||
"failure_threshold": 3,
|
||
"recovery_timeout": 60
|
||
}
|
||
},
|
||
"gemini": {
|
||
"model": "gemini-1.5-flash",
|
||
"daily_quota": 100000,
|
||
"monthly_quota": 2000000
|
||
},
|
||
"claude": {
|
||
"model": "claude-3-5-sonnet",
|
||
"daily_quota": 50000,
|
||
"monthly_quota": 500000
|
||
}
|
||
},
|
||
"complexity_routing": {
|
||
"1": "llama3.2:3b",
|
||
"2": "qwen2.5:7b-instruct",
|
||
"3": "qwen2.5:7b-instruct",
|
||
"4": "gemini",
|
||
"5": "claude"
|
||
},
|
||
"intent_overrides": {
|
||
"DIAGNOSE": "qwen2.5:7b-instruct",
|
||
"CODE_REVIEW": "qwen2.5:7b-instruct",
|
||
"QUERY": "llama3.2:3b"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 12. 變更記錄
|
||
|
||
| 日期 | 版本 | 變更 | 作者 |
|
||
|------|------|------|------|
|
||
| 2026-03-26 | v1.0 | 初版建立 (Phase 13.3 #85-88) | 首席架構師 |
|
||
|
||
---
|
||
|
||
## 參考
|
||
|
||
- [ADR-006: AI 降級備援策略](./ADR-006-ai-fallback-strategy.md)
|
||
- [ADR-016: 智能路由 (基礎實作)](./ADR-016-smart-routing.md)
|
||
- [Skill 08: Model Router Expert](../../.agents/skills/08-model-router-expert.md)
|
||
- [Phase 13.3 Smart Router 設計](~/.claude/projects/-Users-ogt-awoooi/memory/project_model_router_design.md)
|
||
- [Phase 13 Enterprise AIOps](~/.claude/projects/-Users-ogt-awoooi/memory/project_phase13_enterprise_aiops.md)
|
||
|
||
---
|
||
|
||
*此 ADR 記錄 Phase 13.3 智能路由架構的完整決策過程,整合 ADR-006 Fallback 策略與 ADR-016 路由實作。*
|