Diversify AI predictions via per-model analyst personas
GPT (data-driven), Claude (tactical/upset-aware), Gemini (attacking-minded) each get a distinct perspective so the 3 picks genuinely diverge instead of producing identical scorelines. Honest: still each model's own judgment. Finished matches are untouched (generation filters result_outcome IS NULL). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>develop
parent
0f055dace1
commit
1d406f6a4e
|
|
@ -32,10 +32,33 @@ class MatchContext:
|
|||
kickoff: str # ISO
|
||||
|
||||
|
||||
def _prompt(ctx: MatchContext) -> str:
|
||||
# 모델별 분석 관점(페르소나) — 동일 경기라도 서로 다른 시각으로 보게 해
|
||||
# 예측이 자연스럽게 갈리도록 한다(강제 분산이 아니라 진짜 판단의 다양화).
|
||||
PERSONA = {
|
||||
"GPT": (
|
||||
"You are a DATA-DRIVEN analyst. Base your call on recent form, head-to-head, "
|
||||
"FIFA ranking gaps and goals-scored/conceded trends. Be objective and "
|
||||
"evidence-led; pick the scoreline the numbers most support."
|
||||
),
|
||||
"Claude": (
|
||||
"You are a TACTICAL analyst. Focus on matchups, defensive organization, "
|
||||
"midfield control and game-state. Take low-scoring games, tight margins and "
|
||||
"genuine upset potential seriously — do not just rubber-stamp the favorite."
|
||||
),
|
||||
"Gemini": (
|
||||
"You are an ATTACKING-MINDED analyst. Weigh momentum, attacking quality, "
|
||||
"star players and scoring potential. Lean toward open, higher-scoring "
|
||||
"scenarios when the talent and tempo justify it."
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def _prompt(ctx: MatchContext, persona: str) -> str:
|
||||
return (
|
||||
f"You are a football match analyst. Predict the result of this "
|
||||
f"2026 FIFA World Cup match.\n"
|
||||
f"{persona}\n"
|
||||
f"Predict the result of this 2026 FIFA World Cup match using YOUR perspective "
|
||||
f"above. Judge independently — it is fine to differ from the obvious consensus "
|
||||
f"pick when your perspective warrants it.\n"
|
||||
f"Team A: {ctx.team_a}\nTeam B: {ctx.team_b}\n"
|
||||
f"Venue: {ctx.venue}\nKickoff: {ctx.kickoff}\n"
|
||||
f"Important: World Cup group-stage matches are played at NEUTRAL venues. "
|
||||
|
|
@ -96,7 +119,7 @@ async def predict_gpt(ctx: MatchContext) -> dict:
|
|||
model=settings.openai_model,
|
||||
messages=[
|
||||
{"role": "system", "content": "You output only valid JSON."},
|
||||
{"role": "user", "content": _prompt(ctx)},
|
||||
{"role": "user", "content": _prompt(ctx, PERSONA["GPT"])},
|
||||
],
|
||||
response_format={"type": "json_object"},
|
||||
)
|
||||
|
|
@ -116,7 +139,7 @@ async def predict_claude(ctx: MatchContext) -> dict:
|
|||
return await client.messages.create(
|
||||
model=settings.anthropic_model,
|
||||
max_tokens=1024,
|
||||
messages=[{"role": "user", "content": _prompt(ctx)}],
|
||||
messages=[{"role": "user", "content": _prompt(ctx, PERSONA["Claude"])}],
|
||||
**extra,
|
||||
)
|
||||
|
||||
|
|
@ -143,7 +166,7 @@ async def predict_gemini(ctx: MatchContext) -> dict:
|
|||
client = genai.Client(api_key=settings.google_api_key)
|
||||
resp = await client.aio.models.generate_content(
|
||||
model=settings.google_model,
|
||||
contents=_prompt(ctx),
|
||||
contents=_prompt(ctx, PERSONA["Gemini"]),
|
||||
config=types.GenerateContentConfig(response_mime_type="application/json"),
|
||||
)
|
||||
return _normalize(json.loads(resp.text or "{}"))
|
||||
|
|
|
|||
Loading…
Reference in New Issue