Volver al portfolio
LangGraph Multi-agent Automation

Agente Autónomo de
Búsqueda de Empleo en LinkedIn

Pipeline multi-agente construido con LangGraph que busca automáticamente ofertas de AI Engineer en LinkedIn, las valida y filtra con Gemini y las almacena en PostgreSQL. Un agente que trabaja de forma autónoma con lógica de reintento condicional.

PythonLangGraphLangChainGoogle Gemini 2.5 Flash LiteTavily SearchPostgreSQLpsycopg2
Ver en GitHub

¿Qué problema resuelve?

Buscar trabajo como AI Engineer implica revisar LinkedIn diariamente para encontrar ofertas recientes antes de que caduquen o se llenen de candidatos. Es un proceso manual y repetitivo.

Este agente automatiza toda la búsqueda: lanza queries de búsqueda específicas en LinkedIn (filtradas por fecha reciente y tecnología), extrae los datos de cada oferta con IA, elimina duplicados y los guarda en base de datos en la nube para consulta posterior. Todo ello en un pipeline autónomo que decide cuándo detenerse.

¿Qué es LangGraph?

LangGraph es un framework para construir agentes con estado como grafos dirigidos. A diferencia de una cadena lineal de LangChain, LangGraph permite definir nodos (funciones que procesan el estado) y aristas condicionales (decisiones de flujo basadas en el estado actual). Esto permite bucles, reintentos y lógica de agente real.

¿Cómo funciona? Los nodos del grafo

🔍

Nodo "buscar" — Tavily Search

Ejecuta queries de búsqueda en LinkedIn con filtro de fecha reciente (últimas 48h). Rota entre 4 queries distintas en cada ciclo para maximizar cobertura. Los resultados crudos de Tavily se guardan en el estado.

🤖

Nodo "validar" — Gemini extrae y filtra

Gemini 2.5 Flash Lite procesa el texto bruto de Tavily y extrae en JSON estructurado: empresa, puesto, link, ciudad, modalidad y fecha de publicación. Reglas estrictas: solo URLs de linkedin.com, de-duplicación por link, y reconstrucción del Job ID para generar URLs estables.

Arista condicional — ¿Seguir o guardar?

Tras cada ciclo de validación, el grafo decide: si hay ≥ 10 ofertas acumuladas o se han completado ≥ 5 ciclos → ir a "guardar". Si no → volver a "buscar" con la siguiente query. Esto crea un bucle autónomo que no para hasta tener suficientes resultados.

💾

Nodo "guardar" — PostgreSQL en la nube

Normaliza el link de LinkedIn extrayendo el Job ID con regex para construir URLs canónicas estables. Inserta cada oferta en PostgreSQL usando ON CONFLICT (link) DO NOTHING para evitar duplicados en ejecuciones repetidas.

Grafo de estados (LangGraph)

START
🔍 search
Tavily Search
🤖 validate
Gemini → JSON
≥10 offers or ≥5 cycles
💾 save
PostgreSQL
END
else →
↑ loop

Estado compartido del agente

El estado (EstadoAgente) persiste entre nodos y contiene:

messages Historial de mensajes del grafo (add_messages annotation)
ofertas_encontradas Lista acumulada de ofertas validadas entre ciclos
intentos Contador de ciclos para la condición de salida
max_ofertas Objetivo configurable (por defecto 10 ofertas)

Proyecto personal · Python · LangGraph · 2025

Ver código en GitHub