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:

  1. Quitar datos personales antes de que el texto vaya a ningún modelo.
  2. Resolver con reglas lo evidente (gratis e instantáneo).
  3. Preguntar al modelo solo lo que las reglas no saben decidir.
  4. Validar la respuesta y apartar lo raro para revisión humana.
  5. 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.

// reto 01

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].

main.py
Ctrl/⌘ + Enter
¿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().

$ python main.py
    // reto 02

    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"}.

    main.py
    Ctrl/⌘ + Enter
    ¿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"}
    $ python main.py
      // reto 03

      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.

      main.py
      Ctrl/⌘ + Enter
      ¿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)
      $ python main.py

        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.