← Todo el material
Curso Avanzado 7 de septiembre de 2026

Capstone — Fase 3: el prototipo

Tercera fase del Capstone: el agente existe. El grafo de LangGraph que clasifica, decide y responde — flujo estructurado de pasos claros en vez del agente librepensador —, el retrieval sobre el corpus con filtro de vigencia, las citas obligatorias desde el primer commit, y la cascada económica de modelos que la Metodología ya diseñó. Con el código del grafo y la razón de cada arista.

☰ Índice del contenido

Fase 3 y por fin: el agente. Con criterios firmados y corpus limpios, el prototipo se construye rápido — que es exactamente el punto de haber hecho las fases 1-2 primero. La herramienta es LangGraph (el curso completo vive en el catálogo; aquí se aplica), y la decisión de arquitectura más importante ya la tomó la economía del caso: flujo estructurado, no agente librepensador.

La tesis de la fase

El triaje de correos es un flujo con forma conocida — clasificar, decidir por política, responder con fundamento o derivar con resumen — y esa forma se implementa como grafo de pasos explícitos, no como agente autónomo decidiendo su propio camino: menos tokens, menos varianza, y cada decisión auditable en una arista que se puede señalar. Las dos reglas no negociables nacen con el código: toda respuesta lleva cita al corpus, y la decisión responder-vs-derivar es una política declarada — no una opinión del modelo.

El grafo

   EL GRAFO DEL AGENTE DE FINANDES

START ──► ┌────────────┐     ┌─────────────┐
          │ clasificar │ ──► │ decidir     │
          │ (categoría │     │ (política:  │
          │ +confianza)│     │ ¿respondo?) │
          └────────────┘     └──┬──────┬───┘
                     responder  │      │ derivar
                                ▼      ▼
                      ┌───────────┐  ┌───────────┐
                      │ recuperar │  │ resumir   │
                      │ (RAG con  │  │ para el   │
                      │ vigencia) │  │ humano    │
                      └─────┬─────┘  └─────┬─────┘
                            ▼              │
                      ┌───────────┐        │
                      │ redactar  │        │
                      │ (con cita)│        │
                      └─────┬─────┘        │
                            ▼              ▼
                      ┌───────────┐  ┌───────────┐
                      │ validar   │  │ cola de   │
                      │ (¿citó?   │  │ agentes   │
                      │ ¿cuadra?) │  │ humanos   │
                      └─────┬─────┘  └───────────┘
              ok │          │ falla → derivar
                 ▼
               enviar borrador a revisión ──► END

El esqueleto en código — recortado a lo estructural; el estado, los prompts completos y los helpers viven en el repo del proyecto:

from langgraph.graph import StateGraph, START, END

def clasificar(state: Estado) -> Estado:
    """Categoría + confianza, con modelo de gama económica."""
    r = llm_economico.invoke(PROMPT_CLASIFICAR.format(
        correo=state["correo_enmascarado"]))   # PII ya enmascarada (fase 2)
    return {**state, "categoria": r.categoria, "confianza": r.confianza}

def decidir(state: Estado) -> str:
    """La POLÍTICA, no una opinión del modelo (fase 6 la endurece)."""
    if state["categoria"] in CATEGORIAS_SOLO_HUMANO:   # reclamos, fraude
        return "derivar"
    if state["confianza"] < UMBRAL_CONFIANZA:          # la duda deriva
        return "derivar"
    return "responder"

def recuperar(state: Estado) -> Estado:
    """RAG sobre corpus_rag, SIEMPRE filtrado por vigencia."""
    chunks = retriever.buscar(
        state["correo_enmascarado"],
        filtros={"vigente": hoy(), "producto": state.get("producto")})
    return {**state, "contexto": chunks}

def validar(state: Estado) -> str:
    """Sin cita válida no hay respuesta: se deriva, no se inventa."""
    if not state["respuesta"].citas:
        return "derivar"
    if not citas_existen_en(state["contexto"], state["respuesta"].citas):
        return "derivar"
    return "ok"

g = StateGraph(Estado)
g.add_node("clasificar", clasificar)
g.add_node("recuperar", recuperar)
g.add_node("redactar", redactar)        # gama media, con cita obligatoria
g.add_node("resumir_para_humano", resumir_para_humano)
g.add_edge(START, "clasificar")
g.add_conditional_edges("clasificar", decidir,
    {"responder": "recuperar", "derivar": "resumir_para_humano"})
g.add_edge("recuperar", "redactar")
g.add_conditional_edges("redactar", validar,
    {"ok": END, "derivar": "resumir_para_humano"})
g.add_edge("resumir_para_humano", END)
agente = g.compile()

Las decisiones dentro del código, argumentadas

  • La cascada de modelos, implementada. clasificar usa la gama económica; redactar, la media — la tabla costo-calidad del caso, ahora como dos variables de configuración. El routing por gama (nunca por marca — la lección del gateway) hará trivial el A/B de la fase 9.
  • decidir es política, no prompt. Las categorías que jamás se responden solas y el umbral de confianza son código declarado — legible, versionado, modificable sin tocar prompts. Es la gobernanza del Harness en miniatura, y la fase 6 la elevará a política formal con más dimensiones.
  • validar convierte el criterio en compuerta. El groundedness del 100% de la fase 1 no se espera del modelo: se verifica — la respuesta sin citas que existan en el contexto recuperado no sale: se deriva. El agente honesto no es el que nunca falla; es el que falla hacia el humano.
  • La derivación es un final digno, no un fracaso. resumir_para_humano produce el resumen con categoría, contexto encontrado y motivo de derivación — el correo derivado llega mejor que en el proceso viejo. El desvío del 80% que promete el caso en régimen incluye que el 20% restante también mejore.
  • El borrador, no el envío. El prototipo termina en “borrador a revisión” — la fase del piloto donde el 100% pasa por humanos. El envío directo de las categorías maduras es una decisión de la fase 8, con datos del holdout — no un default del código.

Ojo — resistir el agente librepensador: la tentación de darle al modelo el control del flujo (“decide tú si buscar, qué buscar, cuándo responder”) produce demos fascinantes y tres problemas de producción: costo multiplicado por turnos impredecibles, varianza donde el negocio pide consistencia, y decisiones de política tomadas por un modelo en vez de por Finandes. El grafo de pasos explícitos no es menos “IA” — es la IA puesta donde rinde (entender lenguaje, redactar con fundamento) y el control puesto donde corresponde (las aristas). El módulo de cómputo del agente dio la versión de infraestructura de este argumento; este es el de diseño.

El entregable: el agente corriendo en local contra dataset_eval — clasificando, respondiendo con citas, derivando con resumen. Sin números todavía: medir bien es la fase 5, y las primeras corridas informales existen solo para depurar lo obvio.

Errores comunes

  • El agente autónomo donde había un flujo. El control del camino entregado al modelo compra varianza y costo sin comprar calidad — el triaje tiene forma; el grafo la respeta.
  • La política escondida en el prompt. “No respondas reclamos” como instrucción en vez de arista es una sugerencia estadística donde Finandes necesita una regla. Lo que es política se escribe como código.
  • Citas opcionales “por ahora”. El groundedness agregado después exige re-cablear todo. La cita obligatoria y validada nace con el primer commit — es más barato así, además de más seguro.
  • Retrieval sin filtro de vigencia. El corpus tiene los metadatos (fase 2) para usarse: la búsqueda sin filtro responde con la política vieja el día que conviven dos versiones.
  • Optimizar prompts antes de medir. Las horas de ajuste fino contra tres ejemplos favoritos son la procrastinación del prototipo. Se depura lo obvio y se corre a la fase 5 — el ajuste con métricas es otro deporte.
  • Enviar directo desde el día uno. El prototipo que manda correos a clientes reales es el incidente de la semana dos. Borrador a revisión hasta que el holdout diga otra cosa — la escalera de confianza también aplica a los agentes propios.

La frase para llevarse

“El triaje tiene forma y el grafo la respeta: la IA donde rinde (clasificar, redactar con fundamento), el control donde corresponde (las aristas), la política como código y la cita como compuerta. Y el principio que gobierna todo el diseño: este agente no es el que nunca falla — es el que falla hacia el humano.”

Qué viene

Fase 4: herramientas y MCP. El agente responde con conocimiento general de Finandes, pero las mejores respuestas necesitan datos del caso concreto: el estado de cuenta del cliente, la fecha exacta de su próxima cuota, el certificado generado. Las herramientas — expuestas como servidor MCP, con permisos mínimos y la lección del confused deputy aplicada — le darán manos al agente sin darle las llaves de la caja.

Material relacionado

CapstoneLangGraphAgentesRAGPrototipo

Preguntas sobre este curso

Regístrate gratis para hacer preguntas y guardar tu progreso.

✉ Entérate de lo nuevo

Recibe un aviso cuando publique nuevos cursos, workshops o investigaciones. Sin spam.