File size: 2,380 Bytes
d7f258e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
"""Conclusiones narrativas generadas por LLM (opcional).

Decisión de privacidad importante: al LLM se le envía SOLO el resumen
estadístico agregado (medias, porcentajes, alertas) — jamás filas del
dataset. Un dataset puede contener datos personales; sus estadísticas
agregadas, normalmente no.
"""

from __future__ import annotations

import json
import os

import requests

GROQ_URL = "https://api.groq.com/openai/v1/chat/completions"
GROQ_MODEL = "llama-3.3-70b-versatile"

SYSTEM_PROMPT = """Eres un analista de datos senior. Te paso el resumen estadístico \
agregado de un dataset (no tienes acceso a las filas) y escribes conclusiones útiles \
en español, en Markdown, con esta estructura:

## Lectura general
(2-3 frases: qué pinta tiene el dataset, tamaño, calidad global.)

## Lo más relevante
(4-6 viñetas con los hallazgos que un analista destacaría: variables problemáticas, \
correlaciones interesantes, rarezas. Cita números concretos del resumen.)

## Próximos pasos sugeridos
(3-5 viñetas accionables y ordenadas: qué limpiar primero, qué explorar después, \
qué precauciones tomar si se va a modelar.)

Reglas: no inventes nada que no esté en el resumen; si algo no se puede saber sin \
ver los datos, dilo. Sé concreto y directo, sin relleno."""


def llm_available() -> bool:
    return bool(os.environ.get("GROQ_API_KEY"))


def generate_insights(summary: dict) -> str:
    """Genera conclusiones a partir del resumen compacto. Lanza RuntimeError si falla."""
    if not llm_available():
        raise RuntimeError(
            "No hay GROQ_API_KEY configurada. Las conclusiones narrativas son "
            "opcionales: el resto del análisis no la necesita."
        )

    payload = json.dumps(summary, ensure_ascii=False, default=str)
    response = requests.post(
        GROQ_URL,
        headers={"Authorization": f"Bearer {os.environ['GROQ_API_KEY']}"},
        json={
            "model": GROQ_MODEL,
            "temperature": 0.3,
            "messages": [
                {"role": "system", "content": SYSTEM_PROMPT},
                {"role": "user", "content": payload[:20000]},
            ],
        },
        timeout=90,
    )
    if response.status_code != 200:
        raise RuntimeError(f"Groq devolvió {response.status_code}: {response.text[:200]}")
    return response.json()["choices"][0]["message"]["content"]