docs(hard-rules): Prompt-Model 同步鐵律 — LLM Schema Drift 禁令

血的教訓 (2026-04-17): SuggestedAction enum prompt/model 不同步
→ NemoTron 輸出 investigate → Pydantic 爆炸 → 全系統 fallback 待分析

新增強制鐵律:
- 修改 prompts.py 必須同步更新 models/ai.py
- 接收 LLM JSON 的 Model 必須有 validator + fallback
- 禁止靜默死亡(必須 log 具體失敗欄位)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-17 21:48:49 +08:00
parent 8e43d52afb
commit e4bc3ec0ee

View File

@@ -520,6 +520,51 @@ grep -rn "target_function_name" apps/ packages/ --include="*.py"
---
## 🔴🔴🔴 Prompt-Model 同步鐵律 — LLM Schema Drift 禁令
> 血的教訓 (2026-04-17): `prompts.py` 列了 6 個 `suggested_action` 值,`models/ai.py` 只有 4 個。
> NemoTron 輸出 `"investigate"` → Pydantic ValidationError → `analysis_result = None`
> → 全系統 fallback所有 Telegram 卡片顯示「待分析」,持續數週未被察覺。
### 強制鐵律
| 情境 | 必做動作 |
|------|---------|
| **修改 `prompts.py` 的 Enum/格式/欄位** | 同步檢查並更新 `models/ai.py` Pydantic Schema確保兩者完全一致 |
| **新增 LLM 輸出欄位** | 先在 Pydantic 加上 `field_validator``fallback`,再改 Prompt |
| **任何接收 LLM JSON 的 Model** | 必須有 `mode="before"` validator 處理:大小寫/別名/未知值 fallback |
### 三層防護缺一不可
```python
@field_validator("suggested_action", mode="before")
@classmethod
def normalize_suggested_action(cls, v):
if isinstance(v, str):
normalized = v.upper().replace("-", "_")
# 1. 別名映射
alias_map = {"DIAGNOSE": "INVESTIGATE", "MONITOR": "OBSERVE", ...}
normalized = alias_map.get(normalized, normalized)
# 2. 未知值 fallback — 絕不讓 Pydantic 爆炸導致 analysis_result = None
try:
MyEnum(normalized)
return normalized
except ValueError:
return "NO_ACTION" # 安全預設值
return v
```
### 禁止靜默死亡
Pydantic `ValidationError`log 必須明確印出:
- 哪個欄位失敗
- LLM 實際輸出了什麼值
- `pydantic_validation_failed` event已實作於 `openclaw.py`
違反此鐵律 = 破壞生產環境,必須立即 revert。
---
## 🔴🔴 Proactive Execution & Circuit Breaker — 主動執行與熔斷機制
> 整合 `feedback_proactive_execution.md`主動執行2026-04-05與孤島開發停問規則。