How GPT-4o-mini selects up to 10 deals from the Layer 1 candidate set and what the model actually contributes to the final output.
Layer 2 is the AI curation step. It receives only the games that passed the deterministic rules filter and decides which ones are worth recommending based on community recognition, studio reputation, and cultural relevance in the gaming space.
Only identification and rating data is sent to the model — not prices, not deal URLs. This is intentional: the model cannot influence financial or navigational data in the output.
Eres un experto curador de videojuegos. Los juegos que recibes YA pasaron un filtrode calidad (buen Metacritic o Steam Rating, buen descuento). Tu trabajo es seleccionarhasta 10 juegos con reconocimiento o señales claras de calidad en la comunidad gamer.Prioriza devolver entre 8 y 10 si hay suficientes candidatos buenos que realmentevalga la pena recomendar.SELECCIONA si cumple al menos uno:1. Juegos AAA de grandes estudios (EA, Ubisoft, CD Projekt, Rockstar, Bethesda, etc.)2. Juegos AA de estudios medianos con buena reputación o trayectoria reconocible3. Indies muy reconocidos o premiados (Hades, Hollow Knight, Celeste, Stardew Valley, etc.)4. Indies menos conocidos pero con reseñas extremadamente positivas (por ejemplo "Overwhelmingly Positive") o reputación muy sólida5. Juegos que fueron trending o virales en los últimos 5 años6. Franquicias conocidas aunque sea una entrega menor7. Juegos de nicho con comunidades fieles y reputación fuerte en espacios gaming (Reddit, YouTube, Twitch, foros especializados, etc.)DESCARTA:- Juegos totalmente desconocidos sin señales claras de reconocimiento o comunidad- Asset flips o simuladores genéricos sin comunidad- DLCs de juegos no reconocidosResponde ÚNICAMENTE con JSON, sin texto adicional:{ "selectedIds": ["steamAppID_1", "steamAppID_2"], "reasons": { "steamAppID_1": "razón breve en español, máx 12 palabras", "steamAppID_2": "razón breve en español, máx 12 palabras" }}Si ninguno tiene reconocimiento, retorna { "selectedIds": [], "reasons": {} }.
GPT must respond with a single JSON object — no prose, no markdown fences:
{ "selectedIds": ["440", "570", "730"], "reasons": { "440": "Team Fortress 2: shooter clásico de Valve con millones de jugadores", "570": "Dota 2: MOBA de referencia con comunidad activa enorme", "730": "CS2: shooter táctico más jugado en Steam" }}
The reasons field is the only content GPT contributes to the final FilteredDeal output. All other fields — title, price, discount, deal URL — are taken from the original CheapShark response.
The buildFilteredDeals function reconstructs deals from the original candidates using only GPT’s selected IDs:
openaiFilter.ts
/** * Reconstructs FilteredDeal[] from the original candidates using GPT's selection. * Price/URL data comes from CheapShark, not the model. * The `reason` (the only free-form GPT field) is truncated to config.ai.maxReasonLength. */export function buildFilteredDeals( candidates: Deal[], selection: { selectedIds: string[]; reasons: Record<string, string> },): FilteredDeal[] { const dealMap = new Map(candidates.map((d) => [d.steamAppID, d])); return selection.selectedIds .map((id) => { const d = dealMap.get(id); if (!d) return null; const rawReason = typeof selection.reasons[id] === 'string' ? selection.reasons[id] : ''; const reason = rawReason.slice(0, config.ai.maxReasonLength); return { title: d.title, steamAppID: d.steamAppID, salePrice: d.salePrice, normalPrice: d.normalPrice, savingsPercent: Math.round(parseFloat(d.savings)), metacriticScore: parseInt(d.metacriticScore) || 0, steamRatingText: d.steamRatingText, dealUrl: `https://www.cheapshark.com/redirect?dealID=${encodeURIComponent(d.dealID)}`, reason, } satisfies FilteredDeal; }) .filter((d): d is FilteredDeal => d !== null);}
GPT cannot invent steamAppID values. Every ID in selectedIds is validated against the original candidate set before buildFilteredDeals is called. Any ID not present in candidates is silently dropped.
The model is called with temperature: 0. With a fixed temperature and identical input, GPT-4o-mini produces the same output on every call. This is what makes the candidate hash cache reliable: if the hash matches, the model would return exactly the same selection anyway, so the call is safely skipped.