From 56504ed7c1662e57e6590c5e0c50734c5c8df612 Mon Sep 17 00:00:00 2001 From: OoO Date: Sun, 3 May 2026 23:26:18 +0800 Subject: [PATCH] =?UTF-8?q?fix(ea):=20Hermes-first=20short-circuit=20+=20?= =?UTF-8?q?=E6=B6=88=E9=99=A4=20EA=20escalation=20LLM=20=E5=B9=BB=E8=A6=BA?= =?UTF-8?q?=E8=A8=8A=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 統帥 2026-05-03 23:30 反饋:「EA escalation 訊息空洞、浪費 Gemini API」 根因: 1. 燒錢:每個 trigger 先跑 Gemini orchestration,再 prefetch Hermes Hermes 0 threats 時 → Gemini 已燒,訊息卻空泛幻覺 2. 空泛:fallback 路徑灌 OpenClaw plan 文字 + decision.reasoning 全是「312 SKU / 23% / 14 項任務」LLM 自由發揮,無 DB 鉤住 修補: A. _execute_autonomous_decision 加 Hermes-first short-circuit - 價格類 trigger 先跑 Hermes (5s timeout, 免費 Ollama) - 0 threats → 直接 return,不燒 Gemini orchestration - 預期 >70% trigger 在此階段攔截,月省 ~3-5M Gemini tokens - prefetch 結果存入 trigger.conditions 給 orchestrator 用 (避免 orchestrator 又自己編 SKU 數字) - log_ai_call 記 short_circuit=true 供 token report 統計 B. _escalate_to_human fallback 路徑改極簡訊息 - concrete=Hermes 實證 vs concrete=None 兩條路徑徹底分離 - 有實證 → 完整訊息(含 SKU 流失金額) - 無實證 → 極簡訊息「⚠️ Hermes 即時數據不可用」+ SQL 查詢指引 不再灌 OpenClaw plan 文字 / decision.reasoning(幻覺源頭) Operation Ollama-First v5.0 / Phase 6.5 hotfix / ADR-021 遵循收尾 Co-Authored-By: Claude Opus 4.7 (1M context) --- services/elephant_alpha_autonomous_engine.py | 93 +++++++++++++++++--- 1 file changed, 83 insertions(+), 10 deletions(-) diff --git a/services/elephant_alpha_autonomous_engine.py b/services/elephant_alpha_autonomous_engine.py index d6300bf..6618c40 100644 --- a/services/elephant_alpha_autonomous_engine.py +++ b/services/elephant_alpha_autonomous_engine.py @@ -534,6 +534,49 @@ class ElephantAlphaAutonomousEngine: return default async def _execute_autonomous_decision(self, trigger: AutonomousTrigger) -> None: + # ─── Operation Ollama-First v5.0 修補(2026-05-03)─── + # 統帥反饋:每個 EA trigger 都先跑 Gemini orchestrate(燒錢)才 prefetch Hermes, + # 結果 Hermes 0 threats 時送出空泛幻覺訊息 + Gemini 帳單照付。 + # 修法:價格類 trigger Hermes-first short-circuit + # 1. 先跑 Hermes(5s timeout,免費 Ollama) + # 2. 0 threats → 直接 return(**不燒 Gemini**) + # 3. 有 threats → 才走原 Gemini orchestration + # 預期:>70% 的 trigger 在 Hermes 階段就被攔截,月省 Gemini ~3-5M tokens + if trigger.trigger_type in _PRICE_RELATED_TRIGGERS: + try: + hermes_threats = await self._fetch_hermes_threats_summary(top_n=5) + except Exception as e: + self._log.warning("Hermes pre-flight check 失敗 (non-blocking): %s", e) + hermes_threats = None + + if not hermes_threats: + # 0 threats 或 prefetch timeout → 直接 drop trigger,不燒 Gemini + self._log.info( + "EA short-circuit: trigger=%s 無 Hermes 實證 threats," + "跳過 Gemini orchestration 省成本", + trigger.trigger_type + ) + # 紀錄 short-circuit 事件供 token report 統計(不影響主流程) + try: + from services.ai_call_logger import log_ai_call + with log_ai_call( + caller='ea_engine', + provider='gcp_ollama', # 只跑了 Hermes,沒燒 Gemini + model='hermes3:latest', + meta={'short_circuit': True, 'trigger': trigger.trigger_type, + 'reason': 'no_hermes_threats'}, + ) as ctx: + ctx.set_tokens(input=0, output=0) # Hermes 已自己記 + ctx.status = 'cache_only' # 不算 ok 也不算 error + except Exception: + pass # logger 失敗不影響主流程 + return + + # Hermes 有實證 threats → 把它存進 trigger.conditions 給 orchestrator 用 + # 避免 orchestrator 又自己編 SKU 數字 + trigger.conditions = trigger.conditions or {} + trigger.conditions['_prefetched_hermes_threats'] = hermes_threats + context = await self._build_trigger_context(trigger) try: decision = await self._run_with_timeout( @@ -881,32 +924,62 @@ class ElephantAlphaAutonomousEngine: self._log.warning("Pre-fetch threats raised (non-blocking): %s", e) concrete_actions = None + # ─── Operation Ollama-First v5.0 修補:消除空泛幻覺訊息 ─── + # 統帥反饋(2026-05-03):fallback 路徑帶 OpenClaw Gemini plan 文字 + + # decision.reasoning 全是「312 SKU / 23% / 14 項任務」幻覺數字,無 DB 鉤住, + # 嚴重誤導決策。修法:concrete=Hermes 實證 vs concrete=None 兩條路徑徹底分離。 + # - 有實證 → 完整訊息(含 SKU 流失金額) + # - 無實證 → 極簡訊息「Hermes 即時數據不可用」+ 不再灌 LLM 幻覺 + + from services.telegram_templates import triaged_alert, _send_telegram_raw + if concrete_actions: + # 有實證數據路徑:保留完整訊息 ai_actions_payload = concrete_actions + ai_summary_text = (decision.reasoning or "")[:300] + ai_cause_text = ( + f"觸發類型:{_zh_trigger(trigger.trigger_type)} | " + f"信心度:{decision.confidence:.2f} | " + f"參與模組:{', '.join(_AGENT_LABEL.get(a.lower(), a) for a in decision.agents_required)}" + ) else: + # 無實證數據路徑:極簡訊息,明確標註無數據 + self._log.warning( + "EA escalation 落入 no-concrete-data fallback (trigger=%s);" + "送極簡訊息避免 LLM 幻覺數字誤導統帥", + trigger.trigger_type + ) ai_actions_payload = [ - f"步驟 {s.get('step', i+1)}:{_zh_step(s)}" - for i, s in enumerate(decision.execution_plan[:3]) - ] or ["無具體執行計畫"] + "⚠️ Hermes 即時威脅清單不可用(5s timeout 或無 SKU 命中)", + "📋 建議:手動下 SQL 查詢過去 24h competitor_price_history 確認狀況", + "🔧 或:SSH 188 跑 docker exec momo-pro-system python -c " + "'from services.hermes_analyst_service import HermesAnalystService;" + " print(HermesAnalystService().run().threats[:5])'", + ] + ai_summary_text = ( + f"⚠️ 本訊息為**無實證**告警:Hermes pre-fetch 失敗," + f"以下原始決策內容含 LLM 自由發揮數字(非 DB 數據),請審慎參考。" + ) + ai_cause_text = ( + f"觸發類型:{_zh_trigger(trigger.trigger_type)} | " + f"信心度:{decision.confidence:.2f} | " + f"⚠️ 無 Hermes SKU 數據(不顯示 LLM 幻覺 plan 文字)" + ) try: - from services.telegram_templates import triaged_alert, _send_telegram_raw msg, keyboard = triaged_alert( base_event={ "event_type": "ea_escalation", "title": f"🐘 EA 升級審核 · {_zh_trigger(trigger.trigger_type)}", "summary": ( f"自主決策信心度 {decision.confidence:.2f} 低於門檻,需人工批准" + + ("" if concrete_actions else "(⚠️ 無實證數據)") ), "id": f"ea_review_{int(datetime.now().timestamp())}", }, tier_label="🐘 Elephant Alpha · L3 HITL", - ai_summary=(decision.reasoning or "")[:300], - ai_cause=( - f"觸發類型:{_zh_trigger(trigger.trigger_type)} | " - f"信心度:{decision.confidence:.2f} | " - f"參與模組:{', '.join(_AGENT_LABEL.get(a.lower(), a) for a in decision.agents_required)}" - ), + ai_summary=ai_summary_text, + ai_cause=ai_cause_text, ai_actions=ai_actions_payload, ) await self._run_with_timeout(_send_telegram_raw, msg, timeout=10, reply_markup=keyboard)