diff --git a/backend/app/regenerate_ai.py b/backend/app/regenerate_ai.py index 7f71cfc..0f887cd 100644 --- a/backend/app/regenerate_ai.py +++ b/backend/app/regenerate_ai.py @@ -40,7 +40,8 @@ async def main() -> None: ).scalar_one() log.info("재생성 대상(미종료) 경기: %d", targets) - await generate_ai_predictions() # GPT/Claude/Gemini 실 API 호출 → 덮어쓰기 + # 수동 트리거 = 전부 강제 재생성(덮어쓰기). 프롬프트 수정 후 갱신 등에 사용. + await generate_ai_predictions(only_missing=False) async with SessionLocal() as db: rows = ( diff --git a/backend/app/worker.py b/backend/app/worker.py index b44ac47..e3823f2 100644 --- a/backend/app/worker.py +++ b/backend/app/worker.py @@ -75,7 +75,13 @@ async def tick_status() -> None: # ── 2) AI 예측 생성 (실연동) ──────────────────────────────── -async def generate_ai_predictions() -> None: +async def generate_ai_predictions(only_missing: bool = True) -> None: + """미종료 경기의 AI 예측 생성. + + only_missing=True(기본): 이미 있는 (경기×모델) 예측은 보존하고 **비어 있는 것만** + 생성한다(직전에 실패/누락된 모델만 채워짐 — API 비용↓, 예측 안정). + only_missing=False: 전부 재생성(덮어쓰기) — 수동 재생성 스크립트용. + """ async with SessionLocal() as db: matches = ( await db.execute( @@ -93,6 +99,9 @@ async def generate_ai_predictions() -> None: kickoff=m.kickoff_at.isoformat(), ) for model, fn in PROVIDERS.items(): + pred = next((p for p in m.predictions if p.model == model), None) + if only_missing and pred is not None: + continue # 이미 작성됨 — 보존, API 호출 안 함 try: data = await fn(ctx) except ProviderUnavailable as e: @@ -102,8 +111,7 @@ async def generate_ai_predictions() -> None: log.error("AI %s failed for %s: %s", model, m.match_id, e) continue - pred = next((p for p in m.predictions if p.model == model), None) - if pred is None: + if pred is None: # 신규 — 위에서 못 찾았으면 생성 pred = AIPrediction(match_id=m.match_id, model=model) db.add(pred) m.predictions.append(pred)