Lección 16 · 04 Python con IA
Proyecto final: tu bandeja de entrada inteligente
Juntamos todo: limpiar, anonimizar, reglas baratas primero, modelo para lo dudoso, validar la respuesta y un informe final. Es el esqueleto de una automatización real.
El plan
Tienes la bandeja de entrada de soporte de una pequeña empresa. Quieres, para cada mensaje:
- Quitar datos personales antes de que el texto vaya a ningún modelo.
- Resolver con reglas lo evidente (gratis e instantáneo).
- Preguntar al modelo solo lo que las reglas no saben decidir.
- Validar la respuesta y apartar lo raro para revisión humana.
- Sacar un informe: cuántos de cada tipo y cuáles son urgentes.
Reglas primero, modelo después
REGLAS = {"factura": "facturación", "contraseña": "incidencia", "presupuesto": "ventas"}
def por_reglas(texto):
t = texto.lower()
for palabra, categoria in REGLAS.items():
if palabra in t:
return categoria
return None # las reglas no saben
for m in ["La factura llega sin IVA", "Algo raro pasa con la web"]:
print(m, "→", por_reglas(m) or "pregunto al modelo: " + modelo(f"Clasifica. Texto: {m}"))Cada mensaje resuelto por reglas es una llamada que no pagas y un resultado que no tienes que validar.
Construye el proyecto
Los tres retos siguientes forman el programa completo. Cada uno reutiliza el anterior: el editor de cada reto ya trae lo que necesitas de los pasos previos.
Paso 1: limpiar y anonimizar
Define preparar(texto) que quite espacios sobrantes (también los repetidos en medio), sustituya emails por [EMAIL] y teléfonos de 9 cifras por [TELEFONO].
¿Atascado? Ver pista
Tres pasos: re.sub(r"[\w.+-]+@[\w-]+\.[\w.]+", "[EMAIL]", texto), después re.sub(r"\b\d{9}\b", "[TELEFONO]", ...) y al final re.sub(r"\s+", " ", ...).strip().
Paso 2: reglas y modelo
Define clasificar(texto) que devuelva un diccionario {"categoria": ..., "origen": ...}. Si por_reglas decide, origen es "reglas". Si no, pide JSON al modelo (Responde en JSON. Texto: <texto>), extrae la categoría y origen es "modelo". Si la categoría del modelo no es válida, devuelve {"categoria": "revisar", "origen": "modelo"}.
¿Atascado? Ver pista
categoria = por_reglas(texto)
if categoria:
return {"categoria": categoria, "origen": "reglas"}
datos = json.loads(modelo(f"Responde en JSON. Texto: {texto}"))
if datos.get("categoria") not in VALIDAS:
return {"categoria": "revisar", "origen": "modelo"}
return {"categoria": datos["categoria"], "origen": "modelo"}Paso 3: el informe
Procesa toda la bandeja: prepara cada texto, clasifícalo y cuenta en informe cuántos hay de cada categoría. Guarda en de_modelo cuántos necesitaron al modelo. Imprime el informe ordenado de más a menos.
¿Atascado? Ver pista
for texto in bandeja:
r = clasificar(preparar(texto))
informe[r["categoria"]] = informe.get(r["categoria"], 0) + 1
if r["origen"] == "modelo":
de_modelo += 1
for categoria, n in sorted(informe.items(), key=lambda par: par[1], reverse=True):
print(categoria, n)Y ahora, con un modelo de verdad
Has construido el patrón completo. Para usarlo con un LLM real solo cambia modelo() por la llamada a tu proveedor. Antes de hacerlo con datos de clientes, recuerda:
- Anonimiza siempre, como en el paso 1, o usa un modelo que se ejecute en tus propios servidores.
- Valida cada respuesta: los modelos reales se equivocan de formas que las reglas no.
- Pon un tope de gasto y registra qué se procesó, como en la lección anterior.
Si quieres seguir aprendiendo a usar la IA en tu trabajo, el Curso 0 de IAcademy es gratuito.