Files
ewoooc/docs/adr/ADR-004-nemotron-fallback-chain.md
ogt 1b4f3a7bbe
Some checks failed
CD Pipeline / deploy (push) Failing after 59s
feat: EwoooC 初始化 — 完整專案推版至 Gitea
- 建立 Gitea Actions CD pipeline (.gitea/workflows/cd.yaml)
- 部署模式: rsync Python 檔案至 188 → docker restart (volume mount)
- Dockerfile/requirements 變動時自動重建 Docker image
- 部署通知: Telegram (開始/成功/失敗)
- 健康檢查: https://mo.wooo.work/health (最多 5 次重試)
- 同步最新 CLAUDE.md / ADR-008 / memory (2026-04-19)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 01:21:13 +08:00

89 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-004NemoTron 配額耗盡 fallback 至 Hermes Rule-based
- **Status**: Accepted
- **Date**: 2026-04-18
- **Decision Maker**: 統帥(顧問補充建議第 2 條)
- **Author**: Claude
## Context
NemoTron 走 NVIDIA NIM每日 80 次免費配額(保留 20 給 AWOOOI實際可用 60 次)。風險場景:
- **雙 11 / 母親節 / 聖誕** 等大促時,告警暴增可能瞬間耗盡配額
- **PChome 突發降價戰** 觸發大量競價威脅分類
- **任何單日異常** 導致 webhook 大量被觸發
一旦 NemoTron 回 HTTP 429Too Many Requests現有代碼會直接報錯 → 告警靜默 → 業務風險。
## Decision
**NemoTron 必須有兩階 fallback 鏈**
```
告警觸發
NemoTron (NIM) ─── HTTP 200 ─→ 正常派發
└─ HTTP 429 / timeout / network error
Hermes (Ollama 本地) Rule-based 派發
├─ 已知告警類型 → 對應 template 派發 Telegram
└─ 未知類型 → 兜底 template + 標記「降級模式」
```
**降級模式特徵**
- 派發訊息開頭加 `🟡 降級派發` 標記
- 不嘗試做複雜決策(不調用 store_insight 等需要 reasoning 的 tool
- 純 if-else 分類 + template 渲染
## Alternatives Considered
| 方案 | 拒絕原因 |
|---|---|
| 直接 fallback 到 OpenClaw/Gemini | 大促時 OpenClaw 配額也很緊張;付費成本暴增 |
| 進入告警佇列等配額恢復 | 告警時效性最重要,等不起 |
| 不做 fallback直接 alert 統帥 | 告警靜默風險巨大 |
## Consequences
### Positive
- 告警永不中斷(即使 NemoTron 全掛)
- 大促日成本依然受控(不會意外切到 OpenClaw 燒錢)
- Hermes 本地 = 永遠可用兜底
### Negative / Trade-offs
- 降級期間決策品質下降rule-based 不如 LLM
- 需要維護一套 rule template增加代碼量
- Hermes 主機壓力會在降級時激增
## Implementation Notes
```python
# services/nemotron_dispatcher_service.py
class DispatchResult:
mode: Literal['normal', 'degraded']
text: str
def dispatch_alert(alert: Alert) -> DispatchResult:
try:
return _nemotron_dispatch(alert) # NIM tool calling
except (RateLimitError, TimeoutError, RequestException) as e:
sys_log.warning(f"[NemoTron] degraded: {e}")
return _hermes_rule_fallback(alert)
def _hermes_rule_fallback(alert: Alert) -> DispatchResult:
template = RULE_TEMPLATES.get(alert.type, RULE_TEMPLATES['default'])
text = template.render(alert=alert)
return DispatchResult(mode='degraded', text=f"🟡 降級派發\n{text}")
```
監控加上:
- Prometheus metric: `nemotron_fallback_total` counter
- Grafana 告警5 分鐘內 fallback > 10 次 → 通知統帥(系統級異常)
## Related ADRs
- ADR-001三 Agent 分工NemoTron 處理層、Hermes 採集層)