# ADR-030: Frontier 多供應商策略 — Anthropic + Google + OpenRouter

- **Status**: Accepted
- **Date**: 2026-05-03
- **Decision Maker**: 統帥
- **Author**: Operation Ollama-First v5.0（Phase 7 落地後追認）
- **Supersedes**: 無
- **Related**: ADR-028（LLM 路由統一準則）、ADR-029（Hermes-First 雙塔分工）、ADR-027（Primary Ollama on GCP）

---

## Context

戰役 v5.0 Wave 1 完成後（commits 4648673~943de84），momo-pro 的 LLM 治理已具備：
- 三主機 Ollama 級聯（Primary/Secondary/Fallback）
- 13 caller 接入 ai_call_logger
- 7 場景鎖定 Gemini（不可走 Ollama）
- ADR-029 Hermes-First 雙塔分工

但 **Phase 7 升級（Claude Opus 4.7 接 Code Review）** 引入了第二家 Frontier 供應商（Anthropic），戰役需要明確的多供應商治理準則：

1. **何時用 Anthropic vs Google？** — 兩家都是 Frontier，但能力分布不同
2. **Prompt cache 戰術** — Anthropic 5min ephemeral / Google 隱式，省成本邏輯不同
3. **配額 / 帳單 / 失敗鏈** — 多家供應商需獨立 budget 與 fallback 順序
4. **OpenRouter 角色** — 既有 PPT deepseek-v3.2 鏈為何不丟掉？

**單一供應商風險**（戰役 v3.0 起的核心觀察）：Gemini 月用量 50M tokens，若 Google 端配額爆 / 政策變更 / API key 撤銷 → 全系統癱瘓。多供應商提供工程級 fault tolerance。

---

## Decision

### 1. 三家 Frontier 供應商角色定位

| 供應商 | 模型 | 適用場景 | 計費模式 |
|---|---|---|---|
| **Anthropic Claude** | Opus 4.7 / Sonnet 4.6 / Haiku 4.5 | **程式碼推理** + agentic 工具 + 長 context (200K) | metered / **prompt cache 5min ephemeral** |
| **Google Gemini** | 2.5 Flash / 2.5 Pro | **Search Grounding** + 繁中商業文體 + 多模態 | metered |
| **OpenRouter** | DeepSeek V3.2 / 其他 | **PPT 簡報降級** + 實驗性多供應商 | passthrough metered |

### 2. 場景對應決策矩陣（與 ADR-028 鎖定 7 場景對齊）

| ADR-028 場景 | 主供應商 | 備援供應商 | 依據 |
|---|---|---|---|
| #1 MCP 即時情報 | Gemini 2.5 Pro Grounding | Gemini 1.5 Flash Grounding | 唯一聯網 grounding（Phase 10 將補 mcp-omnisearch） |
| #2/3/4 OpenClaw 週/月/年報 | Gemini 2.5 Flash | NIM llama-3.3-70b | 長 context + 繁中商業文體 |
| #5 Code Review ⭐ | **Claude Opus 4.7** | Gemini 2.5 Flash → ElephantAlpha 49B | Arena code Elo 1548（程式碼 #1）+ 200K context |
| #6 EA HITL | Gemini 2.0 Flash | Hermes Ollama 預跑 | 統帥決策時效 |
| #7 PPT 簡報 | Gemini 2.0 Flash | Ollama qwen2.5-coder:7b → DeepSeek V3.2 | 5K rows 長 context |

⭐ **#5 Code Review 是 Phase 7 主要升級點**：
- **Claude Opus 4.7 程式碼能力 Arena Elo 1548 vs Gemini 2.5 Flash ~1450**（+7%）
- **200K context** 支援全 repo diff（Gemini Flash 限 1M 但實測響應品質下降）
- **Prompt cache** 對 Code Review 的「固定 system_prompt + 變動 diff」場景命中率預估 80%+，省 ~90% 成本
- 預估月成本：Opus 4.7 $25 vs Gemini 2.5 Flash $5（差 $20，但 +7% 品質 + 主權冗餘值得）

### 3. Prompt Cache 戰術

#### Anthropic（5 分鐘 ephemeral）
```python
# services/anthropic_service.py 已實作
kwargs["system"] = [
    {"type": "text", "text": system_prompt,
     "cache_control": {"type": "ephemeral"}}
]
```
**適用場景**：Code Review（system_prompt 固定、diff 變動）、相同 caller 5 分鐘內多次調用。

**省成本估算**：
- 第一次調用：input_tokens 全價 + cache_creation 收費（同 input）
- 第 2-N 次（5min 內）：cache_read 0.1× input 價格 → 省 90%

#### Google Gemini（隱式 server-side cache）
- 無顯式 API，依靠 Google 內部優化
- 不可預測，不納入成本估算

### 4. Budget 與告警（與 migration 025 種子對齊）

| Provider | 月預算 | 種子位置 | 告警閾值 |
|---|---|---|---|
| `claude` | $10 | `ai_call_budgets` | 80% |
| `gemini` | $8 | 同上 | 80% |
| `nim` | $5 | 同上 | 80% |
| `nim_via_elephant` | $5 | 同上 | 80% |
| `openrouter` | $3 | 同上 | 80% |
| `gcp_ollama` | $0.01 | 同上（異常激增告警） | 100% |
| `ollama_111` | $0.01 | 同上 | 100% |

**戰役 v5.0 月成本上限**：~$32 USD（vs 戰前估算 ~$25 + Phase 7 升級增量 $20 - Hermes-first 攔截 -$13）

### 5. Fallback 鏈規範

**Code Review** (Phase 7 落地)：
```
L0: Claude Opus 4.7 (CODE_REVIEW_USE_CLAUDE=true)
   ↓ 失敗 / SDK 不可用
L1: Gemini 2.5 Flash (REVIEW_MODEL)
   ↓ 失敗
L2: ElephantAlpha NIM 49B (services/elephant_service.py)
```

**EA HITL**（依 ADR-029 雙塔分工）：
```
L0: Gemini 2.0 Flash (orchestrator)
   ↓ 信心度不足
L1: Hermes Ollama 預跑（5s timeout，免費）
   ↓ 0 threats
L2: short-circuit 不送（避免空泛訊息）⭐ commit 56504ed 修補
```

**新增供應商規則**：
- 任何新 Frontier 供應商引入需獨立 ADR（如 Phase 7 引入 Claude）
- service wrapper 必加 feature flag + `is_available()` 檢查
- 必加 cost budget 種子 + ai_calls.provider 白名單
- 必有對應 unit test（fallback 鏈 + cache hit/miss）

---

## Alternatives Considered

| 方案 | 否決理由 |
|---|---|
| **A. 單一 Frontier (只用 Gemini)** | 單供應商風險：API 撤銷 / 配額爆 / 政策變更全系統癱瘓 |
| **B. 全 Frontier 多家互通（all-providers fallback）** | 模型輸出格式差異大（tool_calls schema、temperature 行為），統一介面工程量 > ROI |
| **C. 自建 Code Review 用 Ollama（DeepSeek-V3）** | A2 web research 紅燈：Ollama deepseek-r1 chat template tools 假支援（GitHub Issue #10935） |
| **D. 等 Gemini 3.0 Pro GA 再升級** | Anthropic Claude Opus 4.7 已驗 Arena Elo 1548 程式碼 #1，等待無價值 |
| **E. 用 OpenRouter 統一接入所有家** | 增加中間層延遲 + 失去 Anthropic prompt cache 優勢 |

---

## Consequences

### 正面（5）
1. **單供應商風險解除**：Code Review 從 Gemini 唯一改 Claude L0，戰時可一鍵切回 Gemini L1
2. **Code Review 品質 +7%**（Arena Elo 1548 vs ~1450）
3. **Prompt cache 隱性節省**：Code Review 重跑命中率 80%+，省 ~90% Claude 成本
4. **Frontier 配額分散**：Claude $10 + Gemini $8 + 其他 = 不會卡單一家配額
5. **未來新增供應商 SOP 化**：feature flag + budget + ADR 三件套

### 負面（3）
1. **月成本 +$20**（Claude Opus 4.7 對 Code Review 升級）
2. **依賴 Anthropic SDK**：版本升級需追蹤（requirements.txt anthropic>=0.40.0）
3. **多供應商除錯複雜度↑**：故障時要追三家失敗鏈

### 風險（4）
1. **Anthropic API key 洩漏**：與 Gemini 同等保護（.env + Gitea Secret） 
2. **Claude Opus 4.7 模型下架**：CLAUDE_MODEL env 可即時切 sonnet-4-6 不需改 code
3. **Cache hit 不如預期**：監控 `ai_calls.cache_read_tokens` 比例，<40% 觸發 INFO 告警
4. **多家帳單分散觀測**：token 日報 Section 4「成本拆解」需明確分家統計（已就位）

---

## Verification

### V1：service wrapper 可用性
```python
from services.anthropic_service import anthropic_service
print(anthropic_service.is_available())  # True if ANTHROPIC_API_KEY set
print(anthropic_service.check_connection())  # True if Claude API responds
```

### V2：Code Review 切換驗證
```bash
# 戰前（CODE_REVIEW_USE_CLAUDE=false）
# ai_calls 應只有 provider='gemini' for code_review_openclaw

# 戰後（CODE_REVIEW_USE_CLAUDE=true）
# ai_calls 應有 provider='claude' + cache_read_tokens > 0（5min 內第二次）
```

### V3：Prompt cache 命中率
```sql
SELECT
  AVG(CASE WHEN cache_hit THEN 1.0 ELSE 0.0 END) * 100 AS cache_hit_pct
FROM ai_calls
WHERE provider = 'claude'
  AND called_at > NOW() - INTERVAL '7 days';
-- 期望 ≥ 60% （首次 + 5min 內後續）
```

### V4：月成本對齊預算
```sql
SELECT provider, SUM(cost_usd) AS month_cost
FROM ai_calls
WHERE called_at > date_trunc('month', NOW())
GROUP BY provider
ORDER BY month_cost DESC;
-- 期望: claude < $10, gemini < $8, total < $32
```

---

## Migration Plan

| Phase | 工作 | 狀態 |
|---|---|---|
| 7.1 | Anthropic SDK 包裝 + COST_TABLE | ✅ commit 943de84 |
| 7.2 | code_review_pipeline 加 L0 Claude 路由 | ✅ commit 943de84 |
| 7.3 | feature flag CODE_REVIEW_USE_CLAUDE 預設 OFF | ✅ commit 943de84 |
| 7.4 | requirements.txt + .env.example | ✅ commit 943de84 |
| 7.5 | 統帥手動：`.env` 加 ANTHROPIC_API_KEY + 翻 ON | ⏳ 待 |
| 7.6 | 觀察 1-2 週 cache hit rate + 成本 | ⏳ 待 |
| 7.7 | 達標後寫 ADR-031（同類 SOP 用於其他升級） | ⏳ 後續 |

---

## References

- [Anthropic Prompt Caching](https://docs.anthropic.com/en/docs/prompt-caching)
- [Arena Code LLM Leaderboard](https://arena.ai/leaderboard) — Claude Opus 4.7 Elo 1548
- ADR-028（LLM 路由統一準則）
- ADR-029（Hermes-First 雙塔分工）
- migration 024/025（ai_calls + budgets schema）
- services/anthropic_service.py（Phase 7 落地）
- services/code_review_pipeline_service.py:46-58（feature flag）
