{html.escape(target_file[:200])}\n"
f"├ 原因:不在 ADR-020 自動修復白名單(僅允許 services/routes/database 內 Python 檔案)\n"
- f"└ 動作:請人工確認 finding,或調整白名單後重跑 Code Review"
+ f"└ 動作:請 AI 自動驗證確認 finding,或調整白名單後重跑 Code Review"
)
return {
"success": False,
@@ -383,11 +383,11 @@ def execute_code_fix(
)
msg = (
f"[AiderHeal] diff 超出限制 {diff_lines} > {MAX_DIFF_LINES} 行,"
- f"已丟棄,需人工介入"
+ f"已丟棄,需 AI 例外介入"
)
logger.warning("event=diff_too_large file=%s diff_lines=%d", target_file, diff_lines)
_notify_telegram(
- f"⚠️ AiderHeal:diff 過大,需人工審核\n"
+ f"⚠️ AiderHeal:diff 過大,需 AI 例外決策\n"
f"├ 檔案:{target_file}\n"
f"├ diff:{diff_lines} 行(上限 {MAX_DIFF_LINES})\n"
f"└ 錯誤:{error_type}"
@@ -481,7 +481,7 @@ def execute_code_fix(
f"🔄 AiderHeal 自動回滾\n"
f"├ 原 commit:{commit_sha}\n"
f"├ 回滾 commit:{revert_sha}\n"
- f"└ 需人工排查:{error_type} in {target_file}"
+ f"└ 需 AI 例外排查:{error_type} in {target_file}"
)
else:
msg = f"[AiderHeal] 回滾失敗!需立即人工介入:{revert_err}"
diff --git a/services/code_review_pipeline_service.py b/services/code_review_pipeline_service.py
index ae54c8e..131420e 100644
--- a/services/code_review_pipeline_service.py
+++ b/services/code_review_pipeline_service.py
@@ -899,7 +899,7 @@ class CodeReviewPipeline:
"human_review_needed": false
}}
-規則(依 ADR-020 全自動修復政策,覆寫 ADR-012 L3 HITL 對 code review 的限制):
+規則(依 ADR-020 全自動修復政策,覆寫 ADR-012 L3 AI 例外決策對 code review 的限制):
- 任何 finding(不論 CRITICAL/HIGH/MEDIUM/LOW)→ auto_fix=true,human_review_needed=false
- 安全網是 Git revert + Gitea CI/CD 回滾,不依賴人工審查門檻
- priority 按最嚴重 severity 決定:CRITICAL>HIGH>MEDIUM>LOW
@@ -1155,7 +1155,7 @@ class CodeReviewPipeline:
if auto_fix and allowed_fix_files:
fix_status = "🔧 已觸發自動修復(AiderHeal)"
elif auto_fix and fix_files:
- fix_status = "⚠️ 不在自動修復白名單,需人工處理"
+ fix_status = "⚠️ 不在自動修復白名單,需 AI 例外處理"
elif sev['critical'] + sev['high'] + sev['medium'] + sev['low'] == 0:
fix_status = "✅ 無需修復動作"
else:
diff --git a/services/elephant_alpha_autonomous_engine.py b/services/elephant_alpha_autonomous_engine.py
index c7435d8..a0a426f 100644
--- a/services/elephant_alpha_autonomous_engine.py
+++ b/services/elephant_alpha_autonomous_engine.py
@@ -31,6 +31,7 @@ from typing import Dict, List, Any, Optional
from sqlalchemy import text
from services.logger_manager import SystemLogger
from services.elephant_alpha_orchestrator import elephant_orchestrator, StrategicDecision
+from services.ai_exception_contract import LEGACY_REVIEW_GATE_KEY
from database.manager import get_db_manager, get_session
logger = SystemLogger("ElephantAlphaEngine").get_logger()
@@ -45,7 +46,7 @@ COMPETITOR_MATCH_TYPE_LABELS = {
COMPETITOR_PRICE_BASIS_LABELS = {
"total_price": "總價可比",
"unit_price": "單位價可比",
- "manual_review": "人工覆核後可比",
+ "manual_review": "AI 例外決策後可比",
"none": "不可比",
}
COMPETITOR_ALERT_TIER_LABELS = {
@@ -143,7 +144,7 @@ _PRICE_ADJUSTMENT_REVIEW_ACTIONS = frozenset({
"dispatch_price_updates",
})
-# A' 軌:價格相關觸發類型,HITL 前需 pre-fetch Hermes 具體威脅清單
+# A' 軌:價格相關觸發類型,AI 例外決策前需 pre-fetch Hermes 具體威脅清單
# 取代 Gemini plan 階段的元流程文字(「步驟 1:[OpenClaw] 生成策略」這類)
_PRICE_RELATED_TRIGGERS = frozenset({
"price_drop_alert",
@@ -717,13 +718,13 @@ class ElephantAlphaAutonomousEngine:
if decision.confidence >= (0.85 if trigger.trigger_type in {"price_drop_alert", "market_opportunity"} else self.confidence_threshold):
if trigger.trigger_type in _PRICE_RELATED_TRIGGERS:
- # 價格類決策即使信心高,也只進 HITL 覆核通知;不得執行
+ # 價格類決策即使信心高,也只進 AI 例外決策覆核通知;不得執行
# orchestrator 給出的 Hermes/NemoTron/OpenClaw 長任務 step。
# 這避免 scheduler 被 60s execution timeout 卡住,也避免自動調價。
await self._notify_telegram_executed(decision, trigger)
self._store_escalation(trigger.trigger_type)
self._log.info(
- "Price decision queued for HITL review; execution plan skipped: %s",
+ "Price decision queued for AI 例外決策 review; execution plan skipped: %s",
trigger.trigger_type,
)
self._circuit_reset()
@@ -1240,10 +1241,11 @@ class ElephantAlphaAutonomousEngine:
},
"evidence": evidence,
"recommended_action": {
- "action": "human_review_backlog_triage",
+ "action": "ai_exception_backlog_triage",
"owner": "ops",
"deadline": deadline,
- "requires_hitl": True,
+ LEGACY_REVIEW_GATE_KEY: False,
+ "requires_ai_exception": True,
},
"expected_impact": {
"risk_reduction": (
@@ -1256,7 +1258,7 @@ class ElephantAlphaAutonomousEngine:
"can_auto_execute": False,
"blocked_reason": (
"resource_optimization 只允許清理過期 advisory action_plans;"
- "外部修復、價格分析與策略派發需人工覆核"
+ "外部修復、價格分析與策略派發需 AI 例外決策"
),
"data_quality": data_quality,
"llm_used": False,
@@ -1292,7 +1294,7 @@ class ElephantAlphaAutonomousEngine:
load_judgement = (
"主機 CPU 已達高負載門檻。"
if metrics.get("load_pressure")
- else "主機 CPU 未達高負載門檻,這不是主機資源耗盡,而是工作隊列/人工審核積壓。"
+ else "主機 CPU 未達高負載門檻,這不是主機資源耗盡,而是工作隊列/AI 例外決策積壓。"
)
handling_notes = [
f"已寫入 ai_insights(resource_pressure) #{insight_id}。"
@@ -1496,7 +1498,7 @@ class ElephantAlphaAutonomousEngine:
action = "建議加強曝光或列入 AI 挑品,不需降價"
impact = f"MOMO 每件價格優勢 NT$ {gap_amount:,.0f}"
else:
- action = "建議人工確認 PChome identity_v2 後評估跟價或促銷"
+ action = "建議 AI 自動驗證確認 PChome identity_v2 後評估跟價或促銷"
impact = f"每件價差 NT$ {gap_amount:,.0f}"
parts = [
@@ -1521,7 +1523,7 @@ class ElephantAlphaAutonomousEngine:
return None
def _fetch_recent_competitor_evidence_actions(self, top_n: int = 5) -> Optional[List[str]]:
- """用最新 DB 價差產生 EA HITL 實證,不啟動完整 Hermes LLM。"""
+ """用最新 DB 價差產生 EA AI 例外決策實證,不啟動完整 Hermes LLM。"""
session = get_session()
try:
rows = session.execute(
@@ -1594,7 +1596,7 @@ class ElephantAlphaAutonomousEngine:
)
async def _fetch_hermes_threats_summary(self, top_n: int = 5) -> Optional[List[str]]:
- """A' 軌:HITL escalation 前 pre-fetch Hermes 具體威脅清單,
+ """A' 軌:AI 例外決策 escalation 前 pre-fetch Hermes 具體威脅清單,
將「步驟 1: [OpenClaw] 生成策略」這類元流程文字換成
「[SKU] 商品|MOMO $X / PChome $Y|流失 NT$ Z|建議 NT$ W」具體可決策行動。
@@ -1602,7 +1604,7 @@ class ElephantAlphaAutonomousEngine:
本方法為 best-effort:任何例外都不阻斷 escalation 主流程。
Critic High-1 fix: 加 5 秒短超時防止阻塞 escalation cooldown 視窗
- (Hermes 完整 run 可能 30-60s,HITL 訊息應快速送出)
+ (Hermes 完整 run 可能 30-60s,AI 例外決策訊息應快速送出)
Critic High-2 fix: 若每筆都缺 loss/rec_price,視同無料、return None 觸發 fallback
"""
db_actions = self._fetch_recent_competitor_evidence_actions(top_n=top_n)
@@ -1620,7 +1622,7 @@ class ElephantAlphaAutonomousEngine:
return None
# 使用 5s 短超時:Hermes 熱駐留時實測 < 10s,但若需冷啟動會拖到 30s+
- # HITL 訊息延遲不可大於 10s(影響統帥決策時效性),寧可 fallback 到原 plan 文字
+ # AI 例外決策訊息延遲不可大於 10s(影響統帥決策時效性),寧可 fallback 到原 plan 文字
try:
result = await asyncio.wait_for(self._hermes_analyze(), timeout=5)
except asyncio.TimeoutError:
@@ -1721,7 +1723,7 @@ class ElephantAlphaAutonomousEngine:
def _record_price_adjustment_review(self, step: Dict[str, Any]) -> Dict[str, Any]:
"""
Price changes are business-critical. Elephant Alpha may recommend them,
- but this system records the proposal for HITL review instead of applying it.
+ but this system records the proposal for AI 例外決策 review instead of applying it.
"""
params = step.get("parameters") or step.get("params") or {}
sku = (
@@ -1734,7 +1736,7 @@ class ElephantAlphaAutonomousEngine:
action = step.get("action", "price_adjustment")
content = (
f"[Elephant Alpha 價格調整覆核] AI 建議執行 {action},"
- f"商品 {sku} 已攔截直接執行並轉入人工審核。"
+ f"商品 {sku} 已攔截直接執行並轉入 AI 例外決策。"
)
session = get_session()
@@ -1768,7 +1770,7 @@ class ElephantAlphaAutonomousEngine:
enqueue_insight_embedding(insight_id, "human_review", content)
except Exception as embed_err:
self._log.warning("Embedding enqueue failed for price adjustment review: %s", embed_err)
- self._log.warning("Price adjustment intercepted for HITL review: action=%s sku=%s", action, sku)
+ self._log.warning("Price adjustment intercepted for AI 例外決策 review: action=%s sku=%s", action, sku)
return {"status": "pending_review", "insight_id": insight_id, "sku": sku, "action": action}
except Exception:
session.rollback()
@@ -1830,7 +1832,7 @@ class ElephantAlphaAutonomousEngine:
"type": "confidence",
"metric": "decision_confidence",
"value": f"{float(decision.confidence or 0):.2f}",
- "basis": "ElephantAlpha high-confidence price signal; HITL still required",
+ "basis": "ElephantAlpha high-confidence price signal; AI 例外決策 still required",
"confidence": float(decision.confidence or 0),
},
{
@@ -1854,7 +1856,7 @@ class ElephantAlphaAutonomousEngine:
"source_agent": "elephant_alpha",
"severity": "P2",
"confidence": float(decision.confidence or 0),
- "analysis": "已找到價格比對實證,轉人工覆核;未批准前不執行調價或外部修復。",
+ "analysis": "已找到價格比對實證,轉 AI 例外決策;未批准前不執行調價或外部修復。",
"subject": {
"sku": trigger.trigger_type,
"name": f"Elephant Alpha · {trigger_label}",
@@ -1863,14 +1865,15 @@ class ElephantAlphaAutonomousEngine:
"recommended_action": {
"action": "review_price_or_promo",
"owner": "ops",
- "requires_hitl": True,
+ LEGACY_REVIEW_GATE_KEY: False,
+ "requires_ai_exception": True,
},
"expected_impact": {
"risk_reduction": "prevent unverified automated price action while preserving actionable evidence",
},
"guardrails": {
"can_auto_execute": False,
- "blocked_reason": "price decisions require HITL; execution_plan skipped",
+ "blocked_reason": "price decisions require AI 例外決策; execution_plan skipped",
"data_quality": "complete" if concrete_actions else "missing",
},
"trace": {
@@ -1906,32 +1909,32 @@ class ElephantAlphaAutonomousEngine:
"event_type": "ea_price_review",
"title": f"🐘 EA 價格覆核 · {_zh_trigger(trigger.trigger_type)}",
"summary": (
- f"找到 {len(concrete_actions)} 筆價格比對實證,已轉人工覆核;"
+ f"找到 {len(concrete_actions)} 筆價格比對實證,已轉 AI 例外決策;"
"未批准前不自動調價。"
),
"id": decision_envelope.get("decision_id"),
"decision_envelope": decision_envelope,
},
- tier_label="🐘 Elephant Alpha · L3 HITL",
+ tier_label="🐘 Elephant Alpha · L3 AI 例外決策",
ai_summary=(
f"已保留 {len(concrete_actions)} 筆 DB/Hermes 價格比對實證;"
- "本通知只要求人工覆核,不執行外部修復或調價。"
+ "本通知只要求 AI 例外決策,不執行外部修復或調價。"
),
ai_cause=(
f"觸發類型:{_zh_trigger(trigger.trigger_type)} | "
f"信心度:{decision.confidence:.2f} | "
- "高信心價格訊號仍需 HITL"
+ "高信心價格訊號仍需 AI 例外決策"
),
ai_actions=concrete_actions,
)
await self._run_with_timeout(_send_telegram_raw, msg, timeout=10, reply_markup=keyboard)
self._log.info(
- "Price HITL review Telegram sent: %s concrete=%d",
+ "Price AI 例外決策 review Telegram sent: %s concrete=%d",
trigger.trigger_type,
len(concrete_actions),
)
except Exception as e:
- self._log.error("Price HITL review Telegram failed (non-blocking): %s", e)
+ self._log.error("Price AI 例外決策 review Telegram failed (non-blocking): %s", e)
@staticmethod
def _get_prefetched_concrete_actions(trigger: AutonomousTrigger) -> Optional[List[str]]:
@@ -2033,23 +2036,24 @@ class ElephantAlphaAutonomousEngine:
"source_agent": "elephant_alpha",
"severity": "P2" if data_quality == "complete" else "P3",
"confidence": float(decision.confidence or 0),
- "analysis": "低信心自主決策已轉人工覆核;未批准前不執行外部副作用。",
+ "analysis": "低信心自主決策已轉 AI 例外決策;未批准前不執行外部副作用。",
"subject": {
"sku": trigger.trigger_type,
"name": f"Elephant Alpha · {trigger_label}",
},
"evidence": evidence,
"recommended_action": {
- "action": "human_review",
+ "action": "ai_exception_decision",
"owner": "ops",
- "requires_hitl": True,
+ LEGACY_REVIEW_GATE_KEY: False,
+ "requires_ai_exception": True,
},
"expected_impact": {
"risk_reduction": "prevent low-confidence autonomous execution",
},
"guardrails": {
"can_auto_execute": False,
- "blocked_reason": "L3 HITL required; no automatic execution before approval",
+ "blocked_reason": "L3 AI 例外決策 required; no automatic execution before approval",
"data_quality": data_quality,
},
"trace": {
@@ -2176,13 +2180,13 @@ class ElephantAlphaAutonomousEngine:
"event_type": "ea_escalation",
"title": f"🐘 EA 升級審核 · {_zh_trigger(trigger.trigger_type)}",
"summary": (
- f"自主決策信心度 {decision.confidence:.2f} 低於門檻,需人工批准"
+ f"自主決策信心度 {decision.confidence:.2f} 低於門檻,需 AI 例外決策"
+ ("" if concrete_actions else "(⚠️ 無實證數據)")
),
"id": decision_envelope.get("decision_id"),
"decision_envelope": decision_envelope,
},
- tier_label="🐘 Elephant Alpha · L3 HITL",
+ tier_label="🐘 Elephant Alpha · L3 AI 例外決策",
ai_summary=ai_summary_text,
ai_cause=ai_cause_text,
ai_actions=ai_actions_payload,
diff --git a/services/elephant_alpha_orchestrator.py b/services/elephant_alpha_orchestrator.py
index a179e13..27a6d59 100644
--- a/services/elephant_alpha_orchestrator.py
+++ b/services/elephant_alpha_orchestrator.py
@@ -165,7 +165,7 @@ OpenClaw strategy/report actions are advisory only. Do not place openclaw / gene
價格調整紅線:
- 禁止輸出 execute_price_adjustment、adjust_price、apply_price_change、update_price。
- 若需要調價,請在 strategic_assessment / reasoning 中輸出定價策略建議,並明確說明「需要人工核准後才能調價」;不要放入 execution_plan。
-- 本系統不得由 AI 直接修改商品價格,只能產生建議與人工覆核項目。
+- 本系統不得由 AI 直接修改商品價格,只能產生建議與 AI 例外決策項目。
BUSINESS CONTEXT:
- E-commerce platform (momo-pro-system)
@@ -508,14 +508,14 @@ Provide your strategic decision in the specified JSON format.
agents_required=["hermes", "elephant_alpha"],
reasoning=(
f"{reason} 已保留 {len(concrete_actions)} 筆 DB/Hermes 價格比對實證;"
- "僅送人工覆核,不執行自動調價。"
+ "僅送AI 例外決策,不執行自動調價。"
),
- expected_outcome="產生可稽核的人工覆核告警,避免使用無法解析的 LLM 推論文字。",
+ expected_outcome="產生可稽核的 AI 例外決策告警,避免使用無法解析的 LLM 推論文字。",
confidence=0.74,
execution_plan=[],
resource_requirements={
"compute_cost": "$0.00",
- "time_estimate": "人工覆核",
+ "time_estimate": "AI 例外決策",
"human_oversight": "required",
},
)
diff --git a/services/event_router.py b/services/event_router.py
index 1022aee..069ed5e 100644
--- a/services/event_router.py
+++ b/services/event_router.py
@@ -560,7 +560,7 @@ def _build_telegram_message(event: Dict[str, Any], tier: str, result: Optional[D
if isinstance(result, dict):
ai_summary = str(result.get("summary") or "")
if not ai_summary:
- ai_summary = str(decision_envelope.get("analysis") or "依決策信封進行人工覆核。")
+ ai_summary = str(decision_envelope.get("analysis") or "依決策信封進行 AI 例外決策。")
return triaged_alert(
render_event,
tier_label=f"{source_agent} · {severity}",
diff --git a/services/hermes_analyst_service.py b/services/hermes_analyst_service.py
index 4acabc3..05f9500 100644
--- a/services/hermes_analyst_service.py
+++ b/services/hermes_analyst_service.py
@@ -133,10 +133,10 @@ class HermesAnalystService:
只能基於 gap_pct、sales_delta、competitor_tags 等已提供欄位做推論。
6. 【身份證據鐵律】match_type / price_basis / alert_tier 是系統比對結論,不得改寫。
- 只有 alert_tier="price_alert_exact" 且 match_type="exact" 且 price_basis="total_price" 可當成直接價格威脅。
- - 其他情況只能建議「人工覆核身份/包裝/單位價」,不可建議直接降價。
+ - 其他情況只能建議「AI 例外決策身份/包裝/單位價」,不可建議直接降價。
7. 【非價格異常路由】若 gap_pct 絕對值 < 5% 但 sales_delta < -30%:
- 判定為「非價格因素異常」(高機率:缺貨、下架、平台流量異常、頁面問題)
- - risk 設為 MED,recommended_action 必須寫「價差接近零但業績異常下滑,建議立即人工走查前台頁面(確認是否缺貨/下架/頁面異常)」
+ - risk 設為 MED,recommended_action 必須寫「價差接近零但業績異常下滑,建議立即AI 例外走查前台頁面(確認是否缺貨/下架/頁面異常)」
- confidence 設為 0.5(因缺乏確切原因)"""
def __init__(self, engine=None):
@@ -560,7 +560,7 @@ class HermesAnalystService:
f"分析以下 {len(items_for_llm)} 支商品的競價威脅,回傳前 {TOP_N} 個最高風險商品。\n\n"
f"注意:match_type / price_basis / alert_tier 是比對系統的硬證據;"
f"只有 alert_tier=price_alert_exact 的 exact 同款可判定直接價格威脅,"
- f"其他一律只能建議人工覆核身份、包裝或單位價。\n\n"
+ f"其他一律只能建議AI 例外決策身份、包裝或單位價。\n\n"
f"資料:{json.dumps(items_for_llm, ensure_ascii=False)}\n\n"
f"輸出格式(JSON 陣列,每筆含):\n"
f'[{{"sku": string, "name": string, "category": string, '
diff --git a/services/learning_pipeline.py b/services/learning_pipeline.py
index c52cb90..beec6e9 100644
--- a/services/learning_pipeline.py
+++ b/services/learning_pipeline.py
@@ -14,7 +14,7 @@ Owen 強調的 v5.0 護欄 #1(ADR-033):
Stage 1: quality_score >= 0.7
Stage 2: 規則引擎幻覺檢測
Stage 3: 與既有 insight cosine < 0.95(去重)
- Stage 4: weight >= 0.8 必經 Telegram 👍/👎 人工驗收(24h 無回應降級 0.5)
+ Stage 4: weight >= 0.8 必經 Telegram 👍/👎 AI 驗證驗收(24h 無回應降級 0.5)
對應:
- migrations/028_create_learning_episodes.sql
@@ -39,7 +39,7 @@ logger = logging.getLogger(__name__)
# ─────────────────────────────────────────────────────────────────────────────
STAGE_1_AUTO_QUALITY = 0.7 # quality_score 下限
STAGE_3_DEDUP_THRESHOLD = 0.95 # cosine similarity 視為重複
-STAGE_4_HUMAN_REVIEW_WEIGHT = 0.8 # weight >= 此值強制人工驗收
+STAGE_4_HUMAN_REVIEW_WEIGHT = 0.8 # weight >= 此值強制 AI 驗證驗收
HUMAN_REVIEW_TIMEOUT_HOURS = 24 # awaiting_review 過期門檻
EXPIRED_FALLBACK_WEIGHT = 0.5 # 過期降級後的 weight
@@ -56,7 +56,7 @@ _HALLUCINATION_HEDGE_WORDS = ['我猜', '可能是', '也許', '大概是', '應
_NUMBER_PATTERN = re.compile(r'\d')
# 「自相矛盾」啟發式:簡化判斷 — 同一句裡同一主詞同時被指派不同值(v5.0 不深做語意,rule-only)
-# user_feedback 蒸餾後預設 weight(高權重,必入 Stage 4 人工驗收)
+# user_feedback 蒸餾後預設 weight(高權重,必入 Stage 4 AI 驗證驗收)
_USER_FEEDBACK_DEFAULT_WEIGHT = 0.9
_MANUAL_CURATED_DEFAULT_WEIGHT = 1.0
@@ -139,7 +139,7 @@ class Distiller:
score = max(1, min(int(user_feedback_score or 3), 5))
# 5 → 1.0 高品質;1 → 0.0 負樣本
quality = round((score - 1) / 4.0, 3)
- weight = _USER_FEEDBACK_DEFAULT_WEIGHT # 用戶直陳的事實,需人工驗收
+ weight = _USER_FEEDBACK_DEFAULT_WEIGHT # 用戶直陳的事實,需 AI 驗證驗收
elif et == 'mcp_result':
# MCP:>200 字 + 含 2+ 關鍵字 → 0.8;否則 0.5
@@ -302,7 +302,7 @@ class LearningPipeline:
class PromotionGate:
"""learning_episodes → ai_insights 4 階段晉升閘。
- Owen 強調:高權重必經人工驗收,避免幻覺污染 RAG。
+ Owen 強調:高權重必經AI 驗證驗收,避免幻覺污染 RAG。
使用範例:
gate = PromotionGate()
@@ -417,7 +417,7 @@ class PromotionGate:
return None
# ──────────────────────────────────────────────────────────────────────
- # Stage 4: 高權重強制人工驗收
+ # Stage 4: 高權重強制 AI 驗證驗收
# ──────────────────────────────────────────────────────────────────────
def _stage_4_review(self, episode: Dict[str, Any]) -> GateDecision:
"""weight >= 0.8 → awaiting_review;否則自動晉升 approved。"""
@@ -426,7 +426,7 @@ class PromotionGate:
return GateDecision(
can_promote=False,
reason='awaiting_review',
- detail=f'weight={weight:.3f} >= {STAGE_4_HUMAN_REVIEW_WEIGHT} 強制人工驗收',
+ detail=f'weight={weight:.3f} >= {STAGE_4_HUMAN_REVIEW_WEIGHT} 強制 AI 驗證驗收',
)
return GateDecision(can_promote=True, reason='approved')
@@ -543,7 +543,7 @@ class PromotionGate:
Args:
reason: rejected_quality / rejected_hallucination / rejected_duplicate / rejected_human
detail: 補充說明(會與 reason 拼成 rejected_reason 文本)
- human_approver: 已 hash 後的人工審核者識別;不存 PII 原文。
+ human_approver: 已 hash 後的 AI 例外決策者識別;不存 PII 原文。
"""
valid_statuses = (
'rejected_quality',
diff --git a/services/llm_caller_registry.py b/services/llm_caller_registry.py
index 8c17721..964901f 100644
--- a/services/llm_caller_registry.py
+++ b/services/llm_caller_registry.py
@@ -26,7 +26,7 @@ CALLER_REGISTRY: frozenset = frozenset({
# Hermes 競價分析(hermes_analyst_service)
'hermes_analyst', # _call_hermes_batch
'hermes_intent', # intent_classify (L1 NLP)
- 'hermes_ea_prefetch', # EA HITL pre-fetch (ADR-021)
+ 'hermes_ea_prefetch', # EA AI 例外決策 pre-fetch (ADR-021)
# KM Embedding(openclaw_learning_service)
'km_embedding_worker', # 60s retry queue worker
diff --git a/services/llm_model_router.py b/services/llm_model_router.py
index 2a4ff4b..0cffd8c 100644
--- a/services/llm_model_router.py
+++ b/services/llm_model_router.py
@@ -80,7 +80,7 @@ ROUTING_RULES: Dict[str, list] = {
'minicpm-v:latest'),
],
- # 推理增強場景(EA HITL 戰略決策;Gemini 不可作為預設模型)
+ # 推理增強場景(EA AI 例外決策戰略決策;Gemini 不可作為預設模型)
'ea_engine': [
(lambda ctx: bool(ctx.get('require_chain_of_thought', False)),
'deepseek-r1:14b'),
diff --git a/services/nemoton_dispatcher_service.py b/services/nemoton_dispatcher_service.py
index 5437670..2094b1d 100644
--- a/services/nemoton_dispatcher_service.py
+++ b/services/nemoton_dispatcher_service.py
@@ -14,7 +14,7 @@ NemoTron 行動派發器 (Module 2 — Dispatcher)
工具清單(扁平化,避免 NIM JSON 截斷):
trigger_price_alert → Telegram 競價高危險預警
add_to_recommendation → 寫入前台推薦商品 + Telegram 通知
- flag_for_human_review → Telegram 人工覆核請求
+ flag_for_human_review → Telegram AI 例外決策請求
"""
import json
@@ -29,6 +29,7 @@ from services.mcp_context_service import build_mcp_context
from config import HERMES_URL # ADR-008 集中化:禁止硬編碼 IP
from services.ai_call_logger import log_ai_call # Operation Ollama-First v5.0 P1
+from services.ai_exception_contract import LEGACY_REVIEW_GATE_KEY
logger = logging.getLogger(__name__)
@@ -67,14 +68,14 @@ def _has_repeated_phrase(text: str, min_len: int = 4, min_count: int = 2) -> boo
return False
-def _sanitize_text(text: str, fallback: str = "請人工確認", max_len: int = 200) -> str:
+def _sanitize_text(text: str, fallback: str = "請 AI 自動驗證確認", max_len: int = 200) -> str:
"""防止 LLM 幻覺文字輸出到 Telegram。
[2026-04-18 台北] Bug-3.1 三層檢測升級 — Claude Opus 4.7
L1: 連續 ≥15 字中文且整段無標點 → 幻覺(原規則)
L2: 命中簡體字/異體字黑名單 → 簡繁污染
L3: 連續中文片段內 4+ 字子串重複 ≥2 次 → 語意坍塌
- 任一層命中 → fallback 替換為「請人工確認」(或呼叫端指定字串)
+ 任一層命中 → fallback 替換為「請 AI 自動驗證確認」(或呼叫端指定字串)
"""
if not text or not isinstance(text, str):
return fallback
@@ -208,7 +209,7 @@ TOOLS = [
"type": "function",
"function": {
"name": "flag_for_human_review",
- "description": "當情況複雜、AI 信心不足,或需要人工決策時,發送 Telegram 請求人工覆核",
+ "description": "當情況複雜、AI 信心不足,或需要 AI 例外決策時,發送 Telegram 請求AI 例外決策",
"parameters": {
"type": "object",
"properties": {
@@ -325,7 +326,7 @@ def _compute_business_impact(threat) -> dict:
HEADER_DISPATCHER = "⚡ NemoTron 派發器"
# 風險級別
ICON_CRITICAL = "🚨" # 高危險/立即行動
-ICON_WARNING = "⚠️" # 中風險/人工覆核
+ICON_WARNING = "⚠️" # 中風險/AI 例外決策
ICON_INSIGHT = "💡" # 低風險/策略建議
ICON_REPORT = "📊" # 例行報告
# 業務屬性
@@ -345,7 +346,7 @@ MATCH_TYPE_LABELS = {
PRICE_BASIS_LABELS = {
"total_price": "總價可比",
"unit_price": "單位價可比",
- "manual_review": "人工覆核後可比",
+ "manual_review": "AI 例外決策後可比",
"none": "不可比",
}
ALERT_TIER_LABELS = {
@@ -528,9 +529,9 @@ def _build_price_decision_envelope(
action = "price_follow_review" if decision_type == "price_alert" else "identity_or_price_review"
blocked_reason = (
- "價格調整需人工覆核;不得自動寫入或覆蓋正式競品價格"
+ "價格調整需 AI 例外決策;不得自動寫入或覆蓋正式競品價格"
if decision_type == "price_alert"
- else "身份、包裝、單位價或前台狀態需人工確認"
+ else "身份、包裝、單位價或前台狀態需 AI 自動驗證確認"
)
risk_reduction = "high" if severity == "P1" else ("medium" if severity == "P2" else "watch")
@@ -549,11 +550,12 @@ def _build_price_decision_envelope(
"competitor_product_name": str(competitor_product_name or "")[:120],
},
"evidence": evidence,
- "analysis": _sanitize_text(analysis, fallback="請人工確認", max_len=300),
+ "analysis": _sanitize_text(analysis, fallback="請 AI 自動驗證確認", max_len=300),
"recommended_action": {
"action": action,
"owner": "營運",
- "requires_hitl": True,
+ LEGACY_REVIEW_GATE_KEY: False,
+ "requires_ai_exception": True,
},
"expected_impact": {
"momo_price": momo_value if momo_value > 0 else None,
@@ -771,7 +773,7 @@ class NemotronDispatcher:
"1. match_type 不是 exact,或 price_basis 不是 total_price,或 alert_tier 不是 price_alert_exact "
"→ 不可直接價格告警,呼叫 flag_for_human_review,concern 說明需覆核身份、包裝或單位價。\n"
"2. gap_pct < 5% 且 sales_delta < -30% → 非價格異常,呼叫 flag_for_human_review,"
- "concern 說明『價差接近 0 但銷量大幅下滑,疑似缺貨/下架/平台流量異常,請人工走查前台』。\n"
+ "concern 說明『價差接近 0 但銷量大幅下滑,疑似缺貨/下架/平台流量異常,請 AI 例外走查前台』。\n"
"3. gap_pct ≥ 5% 且 risk=HIGH → trigger_price_alert(填入 momo_price, comp_price)。\n"
"4. 我方價格低於競品且銷量正成長 → add_to_recommendation。\n"
"5. confidence < 0.6 或其他複雜情況 → flag_for_human_review。\n"
@@ -918,7 +920,7 @@ class NemotronDispatcher:
"1. match_type 不是 exact,或 price_basis 不是 total_price,或 alert_tier 不是 price_alert_exact "
"→ 不可直接價格告警,呼叫 flag_for_human_review,concern 說明需覆核身份、包裝或單位價。\n"
"2. gap_pct < 5% 且 sales_delta < -30% → 非價格異常,呼叫 flag_for_human_review,"
- "concern 說明『價差接近 0 但銷量大幅下滑,疑似缺貨/下架/平台流量異常,請人工走查前台』。\n"
+ "concern 說明『價差接近 0 但銷量大幅下滑,疑似缺貨/下架/平台流量異常,請 AI 例外走查前台』。\n"
"3. gap_pct ≥ 5% 且 risk=HIGH → trigger_price_alert(填入 momo_price, comp_price)。\n"
"4. 我方價格低於競品且銷量正成長 → add_to_recommendation。\n"
"5. confidence < 0.6 或其他複雜情況 → flag_for_human_review。\n"
@@ -1076,13 +1078,13 @@ class NemotronDispatcher:
continue
if t.gap_pct < 5 and t.sales_7d_delta_pct < -30:
- # Rule 1:價差微小但銷量大跌 → 非定價問題,人工確認
+ # Rule 1:價差微小但銷量大跌 → 非定價問題,AI 自動驗證確認
self._exec_flag_for_human_review(
sku=t.sku, name=t.name,
concern=(
f"🟡 [規則引擎] 價差僅 {t.gap_pct:+.1f}% 但銷量大跌 "
f"{t.sales_7d_delta_pct:+.1f}%,疑似缺貨/下架/平台流量異常,"
- "請人工走查前台。"
+ "請 AI 例外走查前台。"
),
confidence=0.80,
footprint=footprint,
@@ -1116,7 +1118,7 @@ class NemotronDispatcher:
threat=t,
)
else:
- # Rule 4:其餘複雜情況 → 人工覆核
+ # Rule 4:其餘複雜情況 → AI 例外決策
self._exec_flag_for_human_review(
sku=t.sku, name=t.name,
concern=(
@@ -1236,7 +1238,7 @@ class NemotronDispatcher:
competitor_product_name: str = "",
) -> str:
"""
- 類別二:人工覆核
+ 類別二:AI 例外決策
客觀數據由 Python 注入(防幻覺),AI 診斷隔離在獨立欄位
B' 軌:補金額影響欄位
"""
@@ -1268,7 +1270,7 @@ class NemotronDispatcher:
)
return (
- f"{ICON_WARNING} [{HEADER_DISPATCHER}] 異常波動需人工覆核\n\n"
+ f"{ICON_WARNING} [{HEADER_DISPATCHER}] 異常波動需 AI 例外決策\n\n"
f"🔍 待查商品:[{sku}] {name}\n\n"
f"{data_block}"
f"{match_block}"
@@ -1460,7 +1462,7 @@ class NemotronDispatcher:
competitor_product_id: str = "",
competitor_product_name: str = "",
):
- """發送語意化人工覆核請求"""
+ """發送語意化AI 例外決策請求"""
concern = _sanitize_text(concern, fallback=f"數據走勢違背常理,疑似缺貨或前台異常。")
msg = self._fmt_human_review(
sku, name, concern, footprint,
@@ -1496,13 +1498,13 @@ class NemotronDispatcher:
)
self._send_telegram(msg, decision_envelope=decision_envelope)
logger.info(
- f"[Dispatcher] 人工覆核請求 → {sku} loss=${revenue_loss_7d:,.0f}"
+ f"[Dispatcher] AI 例外決策請求 → {sku} loss=${revenue_loss_7d:,.0f}"
)
# ADR-007 雙寫
self._sink_insight_to_km(
insight_type="human_review",
sku=sku, name=name,
- content=f"[人工覆核] {name}。疑慮:{concern}",
+ content=f"[AI 例外決策] {name}。疑慮:{concern}",
metadata={"confidence": confidence, "gap_pct": gap_pct, "sales_delta": sales_delta,
"momo_price": momo_price, "comp_price": comp_price,
"revenue_loss_7d": revenue_loss_7d,
@@ -1740,7 +1742,7 @@ class NemotronDispatcher:
閘門 A:銷量 ≤ -95% 絕對斷崖 → 100% 是缺貨/下架/前台異常,不論價差
(2026-04-18 傍晚升級:真實案例 sku=7440662 sales=-100% gap=6.1% 被 NemoTron 錯派降價)
閘門 B:銷量 ≤ -80% 且 |價差| < 5% → 中度斷崖 + 價差微小,定價非主因
- 命中任一閘門 → 強制走人工覆核,不進 NIM — Claude Opus 4.7
+ 命中任一閘門 → 強制走 AI 例外決策,不進 NIM — Claude Opus 4.7
"""
if not threats:
return {"dispatched": 0, "skipped": 0, "errors": [], "nim_stats": {}}
@@ -2102,7 +2104,7 @@ if __name__ == "__main__":
recommended_price=980, # B' 軌驗證:跟進競品價
))
print()
- print("=== 類別二:人工覆核 ===")
+ print("=== 類別二:AI 例外決策 ===")
# [2026-04-18 台北] CLI 測試修正:_fmt_human_review 用 kwargs,避免位置錯位 — Claude Opus 4.7
print(NemotronDispatcher._fmt_human_review(
sku="A001", name="玻尿酸面膜10片裝",
@@ -2145,7 +2147,7 @@ if __name__ == "__main__":
forced.append(t)
else:
nim_list.append(t)
- print(f"強制人工覆核 {len(forced)} 筆(預期 3:閘門 A + 閘門 B × 2): "
+ print(f"強制 AI 例外決策 {len(forced)} 筆(預期 3:閘門 A + 閘門 B × 2): "
f"{[t.sku for t in forced]}")
print(f"送入 NIM 決策 {len(nim_list)} 筆(預期 1): "
f"{[t.sku for t in nim_list]}")
diff --git a/services/pchome_growth_momo_backfill_service.py b/services/pchome_growth_momo_backfill_service.py
index 8fe632f..c1835aa 100644
--- a/services/pchome_growth_momo_backfill_service.py
+++ b/services/pchome_growth_momo_backfill_service.py
@@ -115,7 +115,7 @@ def run_pchome_growth_momo_backfill(
"""補高業績 PChome 商品的 MOMO 對應。
不呼叫 LLM,只搜尋 MOMO 候選,並只把可自動判斷的 total_price / unit_price
- 寫入 external_offers;需人工確認的候選會以 needs_review 保存,不進價格判斷。
+ 寫入 external_offers;需 AI 自動驗證確認的候選會以 needs_review 保存,不進價格判斷。
"""
limit = max(1, min(int(limit or 12), 20))
build_payload = build_payload_func or _default_build_payload
diff --git a/services/telegram_bot_service.py b/services/telegram_bot_service.py
index d777b4c..e317de1 100644
--- a/services/telegram_bot_service.py
+++ b/services/telegram_bot_service.py
@@ -13,6 +13,8 @@ pip install python-telegram-bot>=20.0
- 每日趨勢摘要推播
"""
+from __future__ import annotations
+
import os
import json
import asyncio
@@ -509,7 +511,7 @@ class TrendTelegramBot:
await query.answer()
- # ADR-012 / A' 軌:HITL escalation 按鈕(momo:eig:{event_id} = event_ignore)
+ # ADR-012 / A' 軌:AI 例外事件忽略按鈕(momo:eig:{event_id} = event_ignore)
# triaged_alert 鍵盤按鈕「🛑 忽略此事件」會 callback momo:eig:/破版標籤
@@ -663,9 +667,9 @@ class TrendTelegramBot:
parse_mode='HTML',
)
except Exception as ui_err:
- logger.debug(f"[EA HITL] edit_message 失敗(不阻斷): {ui_err}")
+ logger.debug(f"[EA AI Exception] edit_message 失敗(不阻斷): {ui_err}")
- logger.info(f"[EA HITL] event_ignore event_id={event_id} by={user_label_raw}")
+ logger.info(f"[EA AI Exception] event_ignore event_id={event_id} by={user_label_raw}")
async def _handle_openclaw_callback(self, query, context, data: str):
"""轉接 OpenClaw 完整菜單 callback,避免長輪詢 Bot 吃掉 /menu。"""