Files
ewoooc/docs/adr/ADR-021-ea-hitl-prefetch-and-alert-impact.md
OoO 6788379d10
All checks were successful
CD Pipeline / deploy (push) Successful in 1m2s
抑制 EA 無實證空告警
2026-05-19 13:04:01 +08:00

10 KiB
Raw Permalink Blame History

ADR-021: EA HITL Pre-fetch + 競價告警必填金額影響量化

  • Status: Accepted
  • Date: 2026-05-03
  • Deciders: 統帥
  • Related: 補強 ADR-012Agent Action Ladder L3 HITL對 escalation 訊息內容的要求;不取代任何既有 ADR
  • Affects: services/elephant_alpha_autonomous_engine.pyservices/nemoton_dispatcher_service.pyservices/hermes_analyst_service.pyservices/telegram_bot_service.py

Context

2026-05-02 統帥收到一條 EA 升級審核 Telegram 告警commit b5a2b094 時段),內容為:

自主決策信心度 0.83 低於門檻,需人工批准 AI 摘要:競爭對手價格溢價 >5% 且有庫存充足… 步驟 1[OpenClaw] 基於市區拉貨區市場特性,生成包含動態定價模型與競爭對手分析的策略建議 步驟 2[Hermes] 識別具體競爭商品並量化價格差異(目標確認至少 20 個高價溢價 SKU 步驟 3[NemoTron] 將生成的定價策略與競爭分析結果同步至人工審核管道

統帥指出此告警毫無決策價值,原因:

  1. 沒有具體 SKU、沒有金額影響、沒有可批准/駁回的具體動作
  2. 三步驟「建議行動」實為「申請開始分析」的元流程描述OpenClaw 生成策略 → Hermes 識別 SKU → NemoTron 同步),人類審核者沒有判斷依據
  3. HITL 攔截點放錯位置:應在「具體動作出爐後、執行前」攔,而非「分析計畫產出但尚未跑」

程式碼層證據

根因 A — _escalate_to_human 的 ai_actions 來源是 plan 階段services/elephant_alpha_autonomous_engine.py:528-557_execute_autonomous_decisionelephant_orchestrator.analyze_and_coordinate 產出 StrategicDecision 後,信心度不足即 escalate——此時 decision.execution_plan 還只是 Gemini 寫的 plan 文字Hermes/NemoTron 從未實際跑過取得具體 SKU。_escalate_to_human 把 plan 的前 3 個 step description 直接灌進 triaged_alert.ai_actions 是空泛元流程的根源。

根因 B — Hermes/NemoTron 已有具體告警,但缺金額影響量化services/nemoton_dispatcher_service.py:683-700_exec_trigger_price_alert 已經能輸出「[SKU] 商品MOMO $X / PChome $Y價差 ±%|銷量 ±%」,但缺絕對金額影響——人類看到「價差 22.4%、銷量 -35%」仍需自己換算「我這週實際少賺多少」才能決策。

根因 C — momo:eig: callback 按鈕從未實作services/telegram_templates.py:466-467triaged_alert 鍵盤產出「🛑 忽略此事件」按鈕callback_data = momo:eig:{event_id}),但 services/telegram_bot_service.py:512handle_callback 只 dispatch menu:/cmd:/await: 三個 prefixmomo: prefix 完全沒處理——統帥點擊忽略按鈕後永遠沒反應HITL 流程閉環缺一環。

Decision

對 EA L3 HITL 升級審核訊息與 NemoTron 競價告警採取三項根治措施:

規則 1 — EA 升級審核 pre-fetch Hermes 具體威脅清單

_PRICE_RELATED_TRIGGERS = {price_drop_alert, market_opportunity, threat_escalation} 三類觸發,_escalate_to_human 送 Telegram 前先呼叫 Hermes 取得具體 SKU 清單,將前 5 筆格式化為:

[SKU] 商品名稱MOMO $X vs PChome $Y (±%)|近 7 日流失 NT$ Z建議跟進 NT$ W

蓋掉原本的 plan 元流程文字。強制配套限制

  • asyncio.wait_for(timeout=5) 短超時Hermes 熱駐留 < 10s但冷啟動會拖到 30s+HITL 訊息延遲不可大於 10s
  • Pre-fetch 失敗timeout / 0 threats / 全部缺金額)→ 不送 Telegram、不寫 pending human_review,只記錄 suppressed escalation telemetry 與 cooldown避免把無實證 plan 當成可審核告警
  • 「全部行皆缺金額」也視同無料 fallback避免「乾巴巴兩行 MOMO/PChome 比價」比 plan 文字更空泛

規則 1.1 — 非價格類低信心 escalation 必須有可審核內容

2026-05-19 補充:resource_optimization 不是 SKU/價格事件,不能套用 Hermes/SKU fallback 模板。當 EA 對 resource_optimization 只產出低信心決策且沒有具體可審核行動時,系統只記錄 telemetry 與 cooldown不發 Telegram也不建立 ai_insights.status='pending' 的人工審核。這避免「資源調配優化」告警顯示「Hermes 即時威脅清單不可用」這類錯誤診斷。

規則 2 — NemoTron 告警必填金額影響量化

新增模組級 helper _compute_business_impact(threat) -> {revenue_loss_7d, recommended_price}

  • revenue_loss_7d = max(0, sales_7d_prev_amount - sales_7d_curr_amount)僅在 gap_pct > 0 時計算
    • 語意:「我方比競品貴,且過去 7 日銷量金額下滑 → 推估價格因素導致的流失」
    • gap_pct ≤ 0(我方便宜或持平)即使銷量下滑亦歸 0避免把季節性/商品壽命終結等非價格因素誤標為「流失」誘導降價
  • recommended_price = round(pchome_price)gap_pct > 0;否則 None
    • 語意:「跟進競品的最低調價金額」;統帥可基於此再依毛利策略加溢價

_fmt_price_alert / _fmt_human_review 加入「📉 過去 7 日營收流失NT$ X」「🎯 跟進競品建議價NT$ Y毛利策略可再加溢價」區塊。dispatch() 主路徑、防線二強制覆核、_hermes_rule_fallback 三條路徑全部走 Python 獨裁注入(同 Bug-1 防線二原則:客觀數字不過 LLM

為支援此計算,PriceThreat dataclass 新增 sales_7d_curr_amount / sales_7d_prev_amount 兩個欄位,由 _batch_analyze 從 SQL 結果直接帶出(餵給 LLM 推理,避免 token 爆炸與 LLM 嘗試引用幻覺)。

規則 3 — 補實 momo:eig: callback handler

telegram_bot_service.py.handle_callback 在既有 menu:/cmd:/await: dispatch 之前加 momo:eig: 處理,呼叫 _handle_event_ignore_callback

  1. 解析 event_id空 id 立即拒絕(防 audit 污染)
  2. 寫入 ai_insightsstatus='ignored', insight_type='human_review', metadata_jsonevent_id / decided_by / decided_atADR-012 §③ audit trail
  3. 編輯原訊息加「🛑 已忽略 by <user> @ <ts>」尾註
  4. user_label / ts_label 寫入 HTML 前必須 html.escape()user-controlled Telegram username 透過 <a href>/<pre> 注入超連結與破版的 XSS 防線)
  5. 任何例外都 best-effort不阻斷 UI

Critic 審查(必修)

編號 嚴重度 內容 修復
Critical-1 CRITICAL user_label 直接 HTML 拼接 → username 注入 <a>/<pre> 破版 html.escape() 雙重 escape
High-1 HIGH Pre-fetch Hermes 同步阻塞 escalation cooldown 視窗30-60s asyncio.wait_for(timeout=5)
High-2 HIGH Hermes 有 threats 但全部缺金額時 → 兩行乾巴巴比價反而更空泛 any_concrete 判斷,全缺則 return None 觸發 plan fallback
Medium-2 MEDIUM event_id callback 寫入 'unknown' 污染 audit prefix 解析後即拒絕
Medium-3 MEDIUM gap_pct ≤ 0prev > curr 仍顯示「流失」誤導降價 revenue_loss_7d 條件改為 if gap_pct > 0

Alternatives Considered

方案 為何不選
A. 廢掉 market_opportunity 觸發類型,全交 NemoTron pipeline EA 同時負責 price_drop_alert / threat_escalation / resource_optimization / code_exception 多類觸發,不可單刪一類;且 EA orchestrator 是 SOT廢觸發類型需大改
B. 把 EA 信心度門檻降到 0.5讓「market_opportunity」全部自主執行 違反 ADR-012 L3 HITL 對「實際修改價格」的安全網;統帥未授權自動調價
C. Pre-fetch 改為背景 taskescalation 訊息分兩次發 兩次告警分裂語境,使用者體驗差;且 Hermes 結果晚到時 escalation 已 cooldown
D. 不 pre-fetch要求人類自己用 /menu 查 SKU 違反「告警必須 actionable」精神且增加人類認知負荷

Consequences

正面

  • EA 升級審核 Telegram 內容從元流程描述變為「具體 SKU + 價格 + 金額流失 + 建議調價」HITL 真正可決策
  • 無實證的價格類與資源調配低信心 escalation 不再打擾人工,避免 Telegram 出現不可批准、不可駁回、不可操作的空告警
  • NemoTron 既有告警再升級,每筆都帶可批准/駁回的金額判斷依據
  • momo:eig: 按鈕首次有對應 handlerHITL 流程閉環完整
  • pre-fetch 改用 5s 短超時 + fallback最壞情況退回原 plan 文字,不破壞既有行為

負面 / 風險

  • 每次價格類 escalation 多花 ≤ 5sHermes 熱駐留實測 < 10s 但有 timeout整體告警延遲略增
  • Hermes 在 5s 內若沒回應,價格類 escalation 會被壓制並記錄 telemetry若後續需要追查需從 ai_calls.meta.suppressed_escalation 與 scheduler log 觀察
  • gap_pct ≤ 0 案例的銷量下滑(非價格因素)將完全不顯示流失金額——若統帥需追蹤「非價格流失」需另開告警類型(待後續 ADR

監控指標

  • Telegram 「EA 升級審核」訊息含「📉 過去 7 日營收流失」比例(部署後應 → 每筆價格類觸發都有,除非 5s timeout
  • _handle_event_ignore_callback audit 寫入頻率(觀察人類實際使用 HITL 比例)
  • Hermes pre-fetch timeout rate>10% 代表 Ollama 冷啟動嚴重,需檢查 keep_alive

實作 checklist

  • services/hermes_analyst_service.py PriceThreat 新增絕對金額欄位
  • services/nemoton_dispatcher_service.py _compute_business_impact helper + 三條 dispatch 路徑注入
  • services/elephant_alpha_autonomous_engine.py _fetch_hermes_threats_summary + 5s timeout + fallback
  • services/telegram_bot_service.py _handle_event_ignore_callback + HTML escape + 空 id 拒絕
  • 2026-05-19無實證價格類 / resource_optimization 低信心 escalation 改為 suppressed telemetry不再送空泛 Telegram
  • Critic 審查通過Critical-1 / High-1 / High-2 / Medium-2 / Medium-3 全修)
  • Smoke test_compute_business_impact 對 gap≤0 / gap=0 / 銷量回升 / bogus type 四案例驗證
  • docs/adr/README.md 索引加 ADR-021
  • 部署到 188 + 觀察首日 EA escalation 內容(人工驗證)