01. Visión general de la arquitectura
Refery está construido como un sistema de IA híbrido: los motores de reglas deterministas y la recuperación vectorial gestionan el trabajo de alto volumen, mientras que los paneles adversariales impulsados por LLM gestionan el pequeño conjunto de evaluaciones genuinamente ambiguas que quedan. Cada componente es observable, auditable e idempotente.
Diagrama de alto nivel del sistema
graph TB
subgraph Sources["Fuentes de datos"]
SCOUTS[300+ scouts operadores<br/>etiquetadores HITL]
GMAIL[Gmail<br/>comunicaciones de candidatos + clientes]
LINKEDIN[Señales de LinkedIn]
JDS[Descripciones de puestos<br/>públicas + privadas]
end
subgraph Ingest["Ingesta + normalización"]
JOB_INGEST[Ingesta de puestos<br/>preservación literal de la JD]
CAND_INGEST[Recepción de candidatos<br/>análisis de currículum + señales]
AUTO_DRAFT[Motor de reglas de autoborrador<br/>filtrado fuera del ICP]
end
subgraph Core["Inteligencia central"]
SIGNAL[Motor de señales<br/>nivel de logo, trayectoria,<br/>pedigrí, bonus de IA]
EMBED[Embedder multivectorial<br/>pgvector]
RETRIEVE[Recuperador Top-K<br/>vector + filtro]
PANEL[Panel de 5 personas<br/>evaluación adversarial]
BRACKET[Tramificación +<br/>matriz de ajuste por etapa]
end
subgraph State["Pipeline + estado"]
SM[Máquina de estados<br/>9 etapas de solo avance]
HISTORY[Historial de solo adición<br/>pipeline_stage_history]
RECON[Reconciliación de Gmail<br/>transiciones ligadas a evidencia]
end
subgraph Outreach["Contacto automatizado"]
WATERFALL[Cascada por niveles<br/>1차 → 5차]
VOICE[Motor de voz de Refery<br/>borradores de estilo consistente]
GMAIL_OUT[Redactor de borradores de Gmail]
end
subgraph Storage["Persistencia"]
SUPA[(Supabase Postgres<br/>candidatos, puestos, pipeline,<br/>historial, notas, embeddings)]
end
SCOUTS --> CAND_INGEST
GMAIL --> CAND_INGEST
LINKEDIN --> CAND_INGEST
JDS --> JOB_INGEST
JOB_INGEST --> AUTO_DRAFT
AUTO_DRAFT --> SUPA
CAND_INGEST --> SUPA
SUPA --> SIGNAL
SUPA --> EMBED
EMBED --> RETRIEVE
SIGNAL --> RETRIEVE
RETRIEVE --> PANEL
PANEL --> BRACKET
BRACKET --> SM
SM --> HISTORY
GMAIL --> RECON
RECON --> SM
BRACKET --> WATERFALL
WATERFALL --> VOICE
VOICE --> GMAIL_OUT
GMAIL_OUT --> GMAIL
Stack tecnológico
Refery se ejecuta sobre un stack deliberadamente minimalista, elegido por su eficiencia de costes, su baja sobrecarga operativa y sus sólidas primitivas para cargas de trabajo de IA.
| Capa | Tecnología | Por qué |
|---|---|---|
| Frontend | Next.js 14 (App Router), React, TypeScript | Los componentes de servidor reducen el bundle del cliente; las React Server Actions eliminan la fontanería de la API |
| Hosting | Vercel | Funciones edge para embeddings de baja latencia, entornos de previsualización automáticos |
| Base de datos | Supabase Postgres | Relacional sólido + JSON para registros híbridos, RLS para seguridad multiinquilino |
| Almacén de vectores | pgvector (en Supabase) | Coubicado con los datos relacionales, elimina una base de datos vectorial separada y un salto de red adicional |
| Auth | Supabase Auth | Las políticas de seguridad a nivel de fila imponen los límites de datos en la capa SQL |
| Orquestación de flujos de trabajo | Ejecutores basados en skills (deterministas) | Coste de ejecución acotado frente a bucles de agente ilimitados |
| Capa de LLM | API de Anthropic Claude + embeddings de OpenAI | Anthropic para el panel de personas; OpenAI para embeddings baratos y bien evaluados |
| Integración de correo | API de Gmail | Ingesta de datos de origen propio para las comunicaciones de candidatos/clientes |
| Búsqueda | Híbrido de full-text de Postgres + pgvector | Una sola base de datos para la búsqueda por palabra clave y semántica |
| Observabilidad | Logs de Vercel + logs de Supabase + rastros de auditoría personalizados | Todas las transiciones de estado se registran en pipeline_stage_history |
La decisión de coubicar los embeddings vectoriales con los datos relacionales en pgvector (en lugar de usar una base de datos vectorial dedicada como Pinecone o Weaviate) es una de las decisiones de ingeniería más trascendentales de Refery. Elimina toda una clase de errores de sincronización, reduce la complejidad operativa, suprime un salto de red de la ruta crítica de recuperación y es materialmente más barata al volumen de datos de Refery. El mismo SELECT puede unir los metadatos del candidato con la similitud vectorial en una única consulta.
Flujo de datos: de la recepción del candidato al pipeline
Un nuevo candidato entra en el sistema por una de tres vías: el envío de un scout, una referencia a través de Gmail o una recepción directa. El flujo que sigue es el mismo en todos los casos.
sequenceDiagram
participant Source as Scout / Gmail / Recepción
participant Ingest as Recepción de candidatos
participant Signal as Motor de señales
participant Embed as Embedder
participant Retrieve as Recuperador
participant Panel as Panel de 5 personas
participant DB as Supabase
participant Lily as Operadora (Lily)
Source->>Ingest: Currículum + contexto
Ingest->>DB: INSERT fila de candidates
Ingest->>Signal: Calcular señales deterministas
Signal->>Signal: Nivel de logo (raw → modificado)<br/>Trayectoria<br/>Indicador no-tech<br/>Perfil de ventas
Signal->>DB: UPDATE candidates con señales
Ingest->>Embed: Construir vector del candidato
Embed->>DB: INSERT en embeddings (pgvector)
Retrieve->>DB: Top-K puestos abiertos por vector + filtros
DB-->>Retrieve: 30 mejores pares candidato-puesto
Retrieve->>Panel: Top 30 → evaluación del panel
Panel->>Panel: 5 personas × puntuación adversarial<br/>Comprobación de veto absoluto<br/>Agregación + tramificación
Panel->>DB: UPDATE candidates.ai_analysis<br/>INSERT filas de pipeline<br/>INSERT filas de historial
Panel-->>Lily: Informe + tabla de emparejamiento + preguntas de screening
La arquitectura está dividida intencionadamente para que el paso costoso (el panel) solo se ejecute sobre un conjunto prefiltrado y clasificado por recuperación de 20-30 pares candidato-puesto, no sobre el producto cruzado completo de candidatos × puestos. Esta es la palanca de eficiencia central y se describe en detalle en escalabilidad y eficiencia.
Límites de los componentes
Cada componente tiene una única responsabilidad bien definida y una interfaz estable. Esto es lo que hace que el sistema sea extensible sin romper los flujos existentes.
- El motor de señales es puro: la misma entrada siempre produce la misma salida. Sin llamadas a API externas. Se ejecuta en milisegundos.
- El embedder es idempotente y cacheado. El vector de un candidato se recalcula solo cuando cambian las señales subyacentes.
- El recuperador es de solo lectura. Nunca muta el estado.
- El panel es el único componente intensivo en LLM. Se invoca con moderación y produce una salida estructurada que consumen los componentes posteriores.
- La máquina de estados es el único componente que escribe en
job_candidate_pipeline.stage. Cada transición emite una fila depipeline_stage_history. Ninguna otra ruta de código puede mutar la etapa directamente. - El motor de reconciliación es idempotente. Volver a ejecutarlo sin nueva evidencia produce cero escrituras.
Esta disciplina importa porque el sistema funciona con un pequeño equipo de operadores. Los límites estrictos entre componentes implican que una persona de ingeniería junior puede extender cualquier pieza sin entender el sistema completo, y los errores quedan localizados en lugar de propagarse en cascada.
Qué es novedoso aquí
Varias piezas de esta arquitectura son inusuales en el sector de la tecnología de reclutamiento y constituyen conocimiento técnico propietario:
- Arquitectura híbrida determinista + recuperación + LLM adversarial. La mayoría de las plataformas de "reclutamiento con IA" son o bien reglas puras (sin comprensión semántica) o bien LLM puro (caro, no determinista, sesgado). La arquitectura de tres niveles de Refery hereda las fortalezas de cada una.
- Datos vectoriales y relacionales coubicados mediante pgvector. Elimina una clase de errores de consistencia que los sistemas de base de datos única no tienen.
- Máquina de estados de solo adición con transiciones ligadas a evidencia. La integridad del pipeline la garantiza la base de datos, no el código de la aplicación.
- Límites de ejecución basados en skills. Cada automatización se ejecuta como un skill determinista y acotado en lugar de como un agente sin límites. Esta es la diferencia entre un coste predecible y un coste descontrolado.
- Señales estructuradas de grado de producción (nivel de logo, trayectoria, pedigrí, bonus de IA) que sustituyen el análisis de currículums en texto libre. Estas se codifican como estructuras de datos explícitas, no se extraen ad hoc por consulta.
Los siguientes capítulos describen cada una de estas en detalle.