docs: ADR-105 推翻 A2 + LOGBOOK 2026-04-29 LLM 飛輪復活戰

ADR-105 完整記錄推翻 A2 鐵律的決策:
- Context: A2 歷史背景 + 2 個月後事實基礎變化(GPU + qwen2.5:7b)
- Decision: 4 處修改(IntentType.DIAGNOSE override / chain / openclaw.py task_type / 6 regression test)
- Consequences: 正面(飛輪復活)+ 負面(Ollama 單點)+ 已知債(ADR-106-109 後續)
- Validation: 部署前 1635 tests 全綠,部署後 5 項驗證指標
- Rollback: env 切換 / git revert

LOGBOOK 加 2026-04-29 條目:
- 真根因:4 provider 全死 + A2 鐵律排除 Ollama
- CD 連環血淚:5 個 commit 全 failure(setup_test_schema.sql 缺欄)
- 已落地(不依賴 CD):Prometheus 17 條 rule + Gemini sanitize
- Memory 索引同步更新(指向 project_revert_a2_ollama_primary.md)

注意:docs/ 不在 cd.yaml paths trigger,此 commit 不影響 CD。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-04-29 20:59:53 +08:00
parent 4115ddde48
commit f5f41543c9
2 changed files with 233 additions and 0 deletions

View File

@@ -6,6 +6,62 @@
---
## 🔴 2026-04-29 | LLM 飛輪復活戰 — 推翻 A2 + CD blocker 連環解
統帥訊息「2 個月在原地打轉」「Claude Code 浪費我兩個月訂閱費」+「主要優先用 111 主機的 Ollama」。
### 真根因debugger SSH 121 揪出)
- LLM 飛輪 100% `llm_failed`4 個 provider 全死
- openclaw_nemo 188:8088 → 500 Internal Server Error
- gemini → 429 Too Many Requests + **API key 在 prod log 明文洩漏**
- claude → 404 Not Foundmodel `claude-3-haiku-20240307` 過期)
- ollama → A2 鐵律下 DIAGNOSE chain **永久排除**(基於 INC-20260425 deepseek-r1:14b CPU 238s 過期事實)
- 配套盲區webhooks alert_context 未注入 `task_type` → Ollama timeout 走 30s 不是 200s
### 推翻 A2ADR-105
- `_intent_provider_overrides[DIAGNOSE]`: OPENCLAW_NEMO → **OLLAMA**
- `_diagnose_fallback_chain`: Ollama 第一順位OLLAMA → NEMO → GEMINI → CLAUDE
- openclaw.py 注入 `task_type="diagnose"`(讓 Ollama 用 200s timeout
- 6 個 regression test 同步更新reflectng new 鐵律)
- 1635 unit tests 全綠
### CD pipeline 連環血淚5 個 commit 全 failure
- 真根因:`tests/integration/setup_test_schema.sql` `knowledge_entries`
`related_approval_id` + `path_type` 欄位M4 ORM 加但 sql 沒同步)
- 修法commit `4115ddde` 補欄位 → 解 #1114-1118 全 backlog
### 已落地(不依賴 CD
- ✅ Prometheus 110 載入 17 條新 rule19 個 group`ai_autonomous_slo` 18 條 + `ollama_health` 4 條)
- ✅ Gemini API key sanitize防新 leakcommit `7b471e7a`
- ⚠️ 舊 log 中 leaked key 仍存(需手動輪換)
### 已 push 待 CD 部署
1. `715dc3cb` P0 觀測層止血 + drift 治理工具
2. `c22e5f33` KMWriter 統一契約 + M4 反查鏈
3. `dc18b0eb` PROMETHEUS_URL drift 修
4. `c5753e1c` KMWriter critic 5 修
5. `6878e62a` W1 PR-P1 + ADR-091 T1
6. `681b5ac9` W1 PR-R1 + PR-K1已部署 ✅)
7. `8d24f151` PR-R1 critic 4 修
8. **`fb0c72db` 推翻 A2 — DIAGNOSE Ollama primary**
9. `3668d49f` W2 三件 + KMWriter critic 修
10. `7b471e7a` Gemini sanitize
11. `c5b18101` cd-blocker修錯地方
12. **`4115ddde` cd-blocker-2真修— setup_test_schema 補欄**
### Memory 更新
- `feedback_ai_autonomous_direction.md` 對齊度提升
- 新增記錄 `project_revert_a2_ollama_primary.md`
- ADR-105 完整記錄推翻 A2 決策
### 已知債(後續 ADR
- ADR-106 `models.json` 對齊 prod 實載 model
- ADR-107 `complexity_map` 4/5 寫死雲端 改動態
- ADR-108 OpenClaw 188 服務 500 根因
- ADR-109 Claude API endpoint 過期升級
---
## ✅ 2026-04-28 | T0 12-Agent 全景驗證
承接前段 session 完成的 wave2commit `143c15f0`+ DB cleanup + Gitea HMAC + ArgoCD/Sentry MCP派四位專家並行驗證critic / db-expert / debugger / tool-expert

View File

@@ -0,0 +1,177 @@
# ADR-105: 推翻 A2 鐵律 — DIAGNOSE primary 改 Ollama 本地優先
**Status**: Accepted (2026-04-29)
**Deciders**: ogt首席架構師+ Claude Code
**Date**: 2026-04-29
**Supersedes**: A2 (2026-04-27 INC-20260425) DIAGNOSE 永久排除 Ollama
---
## Context
### A2 鐵律的歷史背景2026-04-27 INC-20260425
INC-20260425 事件NIM timeout 後 fallback 到 Ollama deepseek-r1:14b造成二次 timeout 238sCPU-only
統帥批准 A2 補丁:
- `_intent_provider_overrides[DIAGNOSE] = OPENCLAW_NEMO`(強制走 188 NIM
- `_diagnose_fallback_chain` = `[OPENCLAW_NEMO, GEMINI, CLAUDE]`**永久排除 Ollama**
- 6 個 regression test 守門「Ollama 不在 DIAGNOSE chain」
### 2 個月後的事實基礎變化
#### 新事實 1Ollama 111 已升級為 GPU
**舊A2 假設)**CPU-only deepseek-r1:14b @ 238s 不可用
**新2026-04-29 實測)**M1 Pro Apple Silicon GPU + qwen2.5:7b-instruct
- VRAM 8.2GB 全載入ctx 32k
- `curl /api/generate` hi prompt → **0.54s 完成**
- prod 已實際 load 此 model驗證自 `curl http://192.168.0.111:11434/api/ps`
#### 新事實 2A2 的雲端 fallback 全死
**2026-04-29 prod log 證據**
```
openclaw_nemo → 500 Internal Server Errorhttp://192.168.0.188:8088/api/v1/analyze/incident
gemini → 429 Too Many Requests每日配額 1000 用爆)
claude → 404 Not Found/v1/messagesmodel claude-3-haiku-20240307 過期)
```
A2 chain `[NEMO, GEMINI, CLAUDE]` 三條全部不可用 → 100% incident `llm_failed` → AI 自動修復永遠不啟動。
#### 新事實 3統帥鐵律明確衝突
- `feedback_ai_autonomous_direction.md`: 以本地免費 LLM 為主
- `feedback_ollama_111_only.md`: Ollama 唯一主機 = 111
- 統帥 2026-04-29 親口:「主要優先用 111 主機的 Ollama」+「就算 Ollama 慢還是可以等」
A2 鐵律與「本地優先」鐵律衝突。後者優先(範圍更廣、來源更高)。
---
## Decision
**推翻 A2 鐵律**DIAGNOSE primary 從 OPENCLAW_NEMO 改為 OLLAMA。
### 配套修改4 處)
#### 1. `ai_router.py:_intent_provider_overrides`
```python
IntentType.DIAGNOSE: AIProviderEnum.OLLAMA, # 推翻 A2
```
#### 2. `ai_router.py:_diagnose_fallback_chain`
```python
self._diagnose_fallback_chain = [
(AIProviderEnum.OLLAMA, self._ollama_default), # 主:本地免費(推翻 A2
(AIProviderEnum.OPENCLAW_NEMO, self._openclaw_nemo_default), # fallback 1
(AIProviderEnum.GEMINI, self._gemini_default), # fallback 2
(AIProviderEnum.CLAUDE, self._claude_default), # fallback 3
]
```
#### 3. `openclaw.py` 注入 `task_type="diagnose"`
critic 揭示的真根因webhooks alert_context 沒注入 `task_type`
`ai_providers/ollama.py:77` 讀不到 → 走 `OPENCLAW_TIMEOUT=30s`(不夠 qwen2.5:7b 推理)。
修法:
```python
exec_context = dict(alert_context) if alert_context else {}
if decision.intent == IntentType.DIAGNOSE:
exec_context["task_type"] = "diagnose"
```
讓 Ollama 用 `OLLAMA_DIAGNOSE_TIMEOUT_SECONDS=200s`
#### 4. 6 個 regression test 同步更新
| Test 檔案 | 舊斷言 | 新斷言 |
|----------|-------|-------|
| `test_p0_diagnose_routing.py::test_diagnose_override_is_openclaw_nemo` | DIAGNOSE = OPENCLAW_NEMO | `test_diagnose_override_is_ollama` → DIAGNOSE = OLLAMA |
| `test_ai_router_diagnose_fallback.py::test_diagnose_fallback_chain_no_ollama` | OLLAMA 不在 chain | `test_diagnose_fallback_chain_ollama_primary` → OLLAMA chain[0] |
| 其他 4 個守門 test | (排除 Ollama 系列) | (Ollama primary 系列) |
每個 test docstring 記載歷史脈絡 + 推翻原因,便於後續維護者理解。
### 不動的部分(避免 blast radius
- `_full_fallback_chain`: 不動(避免影響 RESTART/SCALE/CONFIG/DELETE
- `_tool_calling_fallback_chain`: 不動NEMOTRON 仍主推理 tool_call
- `_intent_provider_overrides[DELETE]`: 仍是 CLAUDECRITICAL 風險強制最強模型)
- `complexity_map`: 4/5 寫死 gemini/claudecritic M2 留待後續 ADR
---
## Consequences
### 正面
1. **AI 自動修復鏈路恢復** — DIAGNOSE 主推理走本地 Ollama雲端只當 fallback100% `llm_failed` 應降至 < 30%
2. **遵守統帥本地優先鐵律** — 對齊 `feedback_ai_autonomous_direction.md` + `feedback_ollama_111_only.md`
3. **節省雲端成本** — Gemini/Claude 配額不再被頻繁觸發燒光
4. **隱私加強** — incident evidence 不再頻繁送雲端
### 負面
1. **DIAGNOSE 延遲變長** — 真實 incident prompt 含 evidence + RAG context估 5-30svs OPENCLAW_NEMO 2-27s
- 緩解:`OLLAMA_DIAGNOSE_TIMEOUT_SECONDS=200s` 足夠等
- 統帥指令「即使慢也可以等」
2. **Ollama 健康度成單點** — 主推理掛掉 → fallback 雲端死亡 chain
- 緩解:`ollama_failover_manager` 偵測 111 不健康自動切 188 CPU 備援
- 監控:`OllamaInstanceDown` PrometheusRule 已部署(鐵證 3
3. **INC-20260425 教訓再現風險** — 若 prod model 不知為何切回 deepseek-r1:14bCPU 跑) → 238s timeout 重演
- 緩解:`models.json:21` 暫保留 deepseek-r1:14bcritic C1 警示,留待 ADR-106 處理)
- 防線CBcircuit breaker對 Ollama 失敗 5 次後 OPEN 60s
### 已知債(後續 ADR
- **ADR-106 (待寫)**`models.json` 對齊 prod 實際 load modelqwen2.5:7b-instruct
- **ADR-107 (待寫)**`complexity_map` 4/5 寫死 gemini/claude 改為動態路由
- **ADR-108 (待寫)**OpenClaw 188 服務 500 根因 + 修復策略
- **ADR-109 (待寫)**Claude API endpoint 過期model `claude-3-haiku-20240307``claude-haiku-4-5`
---
## Validation
### 部署前
- ✅ 1635 unit tests 全綠
- ✅ 6 個 regression test 反映新鐵律
- ✅ critic + onboarder 兩位 agent 全景審查通過
### 部署後(等 CD #1119 4115ddde 通過)
- [ ] prod pod image tag 更新到 fb0c72db
- [ ] 新 incident 路由 log `provider=ollama` 而非 `provider=openclaw_nemo`
- [ ] `llm_failed` 比率從 100% 降至 < 30%
- [ ] Ollama 真實 latency p95含 evidence + RAG< 60s
- [ ] `ollama_failover_manager` 對 OLLAMA primary 行為正確(不誤切 188 CPU
---
## Rollback
env 切換(不需 redeploy
```bash
# 暫時關閉本地優先,回到 A2 鐵律
kubectl -n awoooi-prod set env deployment/awoooi-api \
AI_FALLBACK_ORDER='["openclaw_nemo","gemini","claude"]'
```
或修改 commit `fb0c72db` 推 revert
```bash
git revert fb0c72db
git push gitea main
```
---
## References
- A2 原 commit: 2026-04-27 ai_router v4.4
- INC-20260425 教訓記錄: `feedback_auto_execute_pattern_bug.md`
- 推翻 commit: `fb0c72db` (2026-04-29)
- CD 阻塞修復: `4115ddde` (setup_test_schema.sql 補欄位)
- 統帥鐵律: `feedback_ai_autonomous_direction.md` / `feedback_ollama_111_only.md`
- critic PR review: 已驗證實測 0.54s + complexity_map 4/5 留債
- onboarder LLM 路徑全景審查: 確認 7 處違反本地優先鐵律