diff --git a/run_scheduler.py b/run_scheduler.py index 57680ad..3b6dd4e 100644 --- a/run_scheduler.py +++ b/run_scheduler.py @@ -50,6 +50,7 @@ def main(): run_backup_monitor_task, run_dedup_batch_task, run_quality_rescore_task, + run_openclaw_meta_analysis_task, ) logger.info("✅ 排程任務模組載入成功") except ImportError as e: @@ -99,6 +100,9 @@ def main(): schedule.every().day.at("04:00").do(run_quality_rescore_task) logger.info("📅 已設定:每日 04:00 執行 ai_insights 品質分數時間衰減重算") + schedule.every().sunday.at("02:00").do(run_openclaw_meta_analysis_task) + logger.info("📅 已設定:每週日 02:00 執行 OpenClaw Meta-Analysis(AI 系統效能自審)") + logger.info("=" * 60) logger.info("✅ 排程器已啟動,等待任務執行...") logger.info("=" * 60) diff --git a/scheduler.py b/scheduler.py index a66e026..753a86e 100644 --- a/scheduler.py +++ b/scheduler.py @@ -1805,6 +1805,18 @@ def run_backup_monitor_task(): _save_stats('backup_monitor', {"status": "Error", "error": str(e)}) +def run_openclaw_meta_analysis_task(): + """每週日 02:00 — OpenClaw 週報 Meta-Analysis(AI 系統學習效能自我審視)""" + try: + from services.openclaw_strategist_service import generate_meta_analysis_report + report = generate_meta_analysis_report() + logging.info(f"[Scheduler] [MetaAnalysis] 完成 | 長度={len(report)} 字元") + _save_stats('meta_analysis', {"status": "OK", "length": len(report)}) + except Exception as e: + logging.error(f"[Scheduler] [MetaAnalysis] Meta-Analysis 任務異常: {e}") + _save_stats('meta_analysis', {"status": "Error", "error": str(e)}) + + def run_dedup_batch_task(): """每日 03:00 — ai_insights 去重批次(同 SKU 同 type 同 period 保留最高品質)""" try: diff --git a/services/openclaw_strategist_service.py b/services/openclaw_strategist_service.py index a4bc1bc..45991f4 100644 --- a/services/openclaw_strategist_service.py +++ b/services/openclaw_strategist_service.py @@ -227,6 +227,115 @@ def _notify_telegram_group(report_md: str, period_str: str): except Exception as e: sys_log.error(f"[OCStrategist] Telegram 週報推送失敗: {e}") +def generate_meta_analysis_report() -> str: + """ + 週日 02:00 OpenClaw 綜合 Meta-Analysis。 + 分析本週 AI 系統的「學習模式」與「告警效能」: + - 哪些 SKU 反覆觸發告警(高頻威脅) + - relearn 事件集中在哪些商品類型 + - 各 Agent 分工占比(Hermes/NemoTron/OpenClaw 貢獻度) + - 對下週 AI 排程策略的建議 + 輸出雙寫 ai_insights(insight_type='meta_analysis')並推送 Telegram。 + """ + sys_log.info("[OCStrategist] 開始產生週日 Meta-Analysis...") + + now = datetime.now() + end_dt = now - timedelta(days=1) # 昨天 + start_dt = end_dt - timedelta(days=6) + start_str = start_dt.strftime("%Y-%m-%d") + end_str = end_dt.strftime("%Y-%m-%d") + period_str = f"{now.year}-W{now.isocalendar()[1]}-meta" + + # 從 DB 抽取本週 ai_insights 統計摘要 + session = get_session() + stats_text = "" + try: + rows = session.execute(text(""" + SELECT insight_type, product_sku, COUNT(*) AS cnt, AVG(avg_quality) AS avg_q + FROM ai_insights + WHERE DATE(created_at) BETWEEN :s AND :e + GROUP BY insight_type, product_sku + ORDER BY cnt DESC + LIMIT 30 + """), {"s": start_str, "e": end_str}).fetchall() + + relearn_count = session.execute(text(""" + SELECT COUNT(*) FROM ai_insights + WHERE status = 'relearn' + AND DATE(updated_at) BETWEEN :s AND :e + """), {"s": start_str, "e": end_str}).scalar() or 0 + + archived_count = session.execute(text(""" + SELECT COUNT(*) FROM ai_insights + WHERE status = 'archived' + AND DATE(updated_at) BETWEEN :s AND :e + """), {"s": start_str, "e": end_str}).scalar() or 0 + + total_insights = session.execute(text(""" + SELECT COUNT(*) FROM ai_insights + WHERE DATE(created_at) BETWEEN :s AND :e + """), {"s": start_str, "e": end_str}).scalar() or 0 + + lines = [f"總洞察數:{total_insights} 筆 | relearn 標記:{relearn_count} 筆 | 本週歸檔:{archived_count} 筆"] + for itype, sku, cnt, avg_q in rows: + sku_str = f"SKU={sku}" if sku else "(無 SKU)" + lines.append(f"• {itype} / {sku_str}:{cnt} 次 (avg_quality={avg_q:.2f})") + stats_text = "\n".join(lines) + except Exception as e: + stats_text = f"(DB 統計查詢失敗:{e})" + finally: + session.close() + + prompt = f""" +你是 OpenClaw Gemini — EwoooC 三層 AI 競情系統的元分析師。 +每週日凌晨,你負責審視本週 AI 系統自身的「學習效能」與「告警品質」, +並對下週的 AI 排程策略提出建議。 + +### 本週資料區間 +{start_str} ~ {end_str} ({period_str}) + +### 本週 ai_insights 統計摘要(系統自動產生): +{stats_text} + +### 請依以下格式產出 Meta-Analysis 報告(繁體中文): +# 【EwoooC AI 系統週報 Meta-Analysis】 ({period_str}) +## 一、本週 AI 告警效能總覽 +(總洞察量、各類型占比、品質分布概述) + +## 二、高頻威脅 SKU 分析 +(哪些 SKU 反覆觸發告警,是否已超出正常競價範圍) + +## 三、relearn 事件洞察 +(哪些商品類型的洞察被推翻,代表什麼市場信號) + +## 四、AI 系統調優建議(下週) +(根據本週數據,建議調整 Hermes 閾值、NIM 配額分配、或 relearn 觸發條件) + +語氣:分析師視角,精準、客觀,不誇大。 +""" + + report_md = _call_gemini_flash(prompt) + citation_footer = _build_citation_footer(start_str, end_str) + if citation_footer: + report_md = report_md + citation_footer + + if not report_md.startswith("⚠️ 呼叫 Gemini 失敗"): + store_insight( + insight_type="meta_analysis", + content=report_md, + period=period_str, + metadata={ + "start_date": start_str, "end_date": end_str, + "generated_by": "Gemini-2.0-Flash", + "total_insights": total_insights if 'total_insights' in dir() else 0, + }, + ) + _notify_telegram_group(report_md, period_str) + sys_log.info("[OCStrategist] Meta-Analysis 完成並推送 Telegram") + + return report_md + + if __name__ == "__main__": # 手動測試用 print(generate_weekly_strategy_report(force_tg_alert=False))