Cómo usar Jev y Codex con routing por tarea en lugar de por mensaje
Este artículo explica cómo combinar Jev y Codex mediante un sistema de routing por tarea, manteniendo el mismo modelo durante todo el trabajo y activando un nuevo routing solo cuando la complejidad aumenta. También muestra cómo implementar Task Binding, escalado y control de costes.
Herramientas relacionadas
OpenAI Codex
FreemiumAgente de programación cloud-native de OpenAI integrado en ChatGPT, capaz de ejecutar tareas en paralelo en sandboxes y trabajar con objetivos de larga duración.
TypeSafe AI Jev
De pagoJev es el primer System One Model de TypeSafe AI, una capa de decision para AI Agents que, en lugar de generar texto, responde preguntas tipadas con Choice, Score o Noul y devuelve decisiones + probabilidad. Disenado para que el software use la IA directamente, sin parsear strings.
Si utilizas Codex con frecuencia para desarrollar proyectos, es fácil encontrarse con un problema.
Por ejemplo, le pides a Codex:
Añade inicio de sesión mediante GitHub OAuth a mi proyecto de Next.js.
Después dices:
Cambia la URL de callback.
Y luego:
Añade un mensaje de error cuando falle el inicio de sesión.
Finalmente:
Ejecuta también las pruebas.
Desde el punto de vista del usuario, todo esto forma parte de la misma tarea de desarrollo.
Sin embargo, si el Router vuelve a evaluar el modelo cada vez que recibe un mensaje, el flujo puede terminar siendo algo así:
Mensaje 1 → Jev → Modelo A
Mensaje 2 → Jev → Modelo B
Mensaje 3 → Jev → Modelo A
Mensaje 4 → Jev → Modelo C
Este es el típico message-level routing.
El problema es que cambiar constantemente de modelo dentro de una misma tarea de Coding puede aumentar el coste del routing, dificultar la continuidad del contexto y reducir las oportunidades de reutilizar caché. Más importante aún, puede hacer que el estado de trabajo del Agent sea menos estable.
Un enfoque más razonable sería:
El usuario plantea una tarea completa
↓
Jev
↓
Evalúa la dificultad
↓
Vincula Agent de Codex + modelo
↓
Ejecuta toda la tarea
↓
Prueba / valida
↓
¿La tarea se ha vuelto claramente más compleja?
↓ ↓
No Sí
↓ ↓
Seguir ejecutando Jev vuelve a evaluar
↓
Escalar el modelo
En otras palabras:
El routing debería ocurrir al comenzar una tarea, no después de cada mensaje del usuario.
Hay que hacer una precisión importante. A septiembre de 2026, los proyectos públicos de routing entre Jev y Codex implementan principalmente un modelo de selección por cada fresh turn. Por ejemplo, jev-codex-router describe explícitamente un sistema de per-turn routing, mientras que otra implementación utiliza la expresión “each fresh user turn”.
Por tanto, el enfoque que se propone aquí debe entenderse como una capa adicional de Task Binding + escalation sobre las capacidades actuales de Codex + Jev, y no como una afirmación de que Codex ya ofrezca de forma nativa este modelo completo.
¿Qué función cumplen ChatGPT, Codex y Jev?
La arquitectura es bastante sencilla.
ChatGPT es la interfaz de interacción con el usuario.
Codex es el Agent que realmente ejecuta el trabajo de Coding: puede leer el proyecto, buscar archivos, modificar código, ejecutar comandos, lanzar pruebas y continuar trabajando en función de los resultados.
La arquitectura actual de Codex / Agents de OpenAI también permite la colaboración entre varios Agents, contextos independientes y delegación de tareas. La documentación oficial incluye la exploración de repositorios, la implementación de módulos independientes y las pruebas entre los escenarios adecuados para Subagents.
Por su parte, Jev no se encarga de desarrollar el proyecto completo.
Su función es responder a una pregunta mucho más concreta:
¿Qué nivel de modelo necesita esta tarea en este momento?
El sistema completo puede representarse así:
ChatGPT / User
↓
Jev
↓
Task Router
↓
Codex Agent
↓
Selected Model
Jev está diseñado precisamente para este tipo de decisiones estructuradas: puede convertir el estado de una aplicación en una decisión que el programa pueda utilizar directamente.
Preparar primero un proyecto real de Codex
No conviene probar este sistema con un simple Hello World.
Es mejor utilizar un proyecto Next.js + TypeScript que ya esté funcionando, por ejemplo:
my-next-app/
├── app/
├── components/
├── lib/
├── api/
├── tests/
├── package.json
└── AGENTS.md
Primero puedes pedirle a Codex una tarea de solo lectura:
Lee primero este proyecto sin modificar ningún archivo. Explícame su estructura, los módulos principales y dónde se encuentra el código relacionado con la autenticación de usuarios.
De esta manera, Codex puede buscar archivos, leer el código y construir su propio contexto del proyecto.
AGENTS.md también resulta especialmente útil. Codex CLI busca automáticamente archivos AGENTS.md dentro del directorio del proyecto e incorpora sus instrucciones a la conversación. Esto permite establecer de forma permanente los comandos de prueba, convenciones de código, restricciones de directorios y otras reglas.
Por ejemplo:
# AGENTS.md
- Utilizar TypeScript
- Ejecutar las pruebas correspondientes después de modificar código
- No añadir dependencias innecesarias
- Los cambios en la API deben incluir pruebas
- Antes de terminar una tarea, ejecutar lint y typecheck
Preparar tres niveles de capacidad para Codex
No es necesario crear realmente tres Agents independientes.
Una forma más práctica de plantearlo es preparar tres niveles de modelo:
Scout
↓
Modelo de bajo coste
Developer
↓
Modelo intermedio
Expert
↓
Modelo de alta capacidad
Scout puede utilizarse para:
Buscar código
Leer archivos
Encontrar relaciones entre dependencias
Realizar modificaciones sencillas
Actualizar documentación
Developer es adecuado para:
Desarrollo de funcionalidades normales
Modificaciones de API
Corrección de bugs
Pruebas
Cambios en varios archivos
Expert puede reservarse para:
Diseño de arquitectura
Bugs complejos
Refactorizaciones de bases de datos
Problemas de seguridad
Optimización de rendimiento
Refactorizaciones a gran escala
Codex se encarga de ejecutar el trabajo y Jev decide desde qué nivel debería comenzar.
Ejemplo práctico 1: una tarea sencilla
Crea una nueva tarea:
Encuentra todo el código relacionado con los avatares de usuario y explícame el flujo completo de los datos del avatar desde el frontend hasta la base de datos. No modifiques el código.
Jev podría producir una decisión como:
Task: Simple
Tier: Scout
Reasoning: Low
A continuación, Codex ejecuta la tarea.
Después, el usuario dice:
Cambia el texto del botón de avatar de Upload Avatar a Change Avatar.
Aquí hay un punto fundamental:
No hay que volver a pedir a Jev que seleccione un modelo.
La modificación sigue formando parte de la misma tarea.
El flujo debería mantenerse así:
Task Session #1024
↓
Scout
↓
Low Model
↓
Continuar ejecutando
Después el usuario puede decir:
Ejecuta también las pruebas relacionadas.
Sigue siendo la misma tarea.
El Agent actual continúa ejecutándola.
Esta es la diferencia más directa entre task-level routing y message-level routing.
Ejemplo práctico 2: una tarea de desarrollo intermedia
Ahora empieza una tarea diferente:
Añade una función para eliminar la cuenta del usuario en la página de configuración. Utiliza la UI, la API y la estructura de base de datos existentes, no añadas nuevas dependencias y agrega pruebas.
Jev podría determinar:
Task: Medium
Tier: Developer
Model: Mid
Entonces Codex comienza:
Analizar el proyecto
↓
Encontrar User Model
↓
Encontrar API
↓
Analizar UI
↓
Modificar código
↓
Añadir pruebas
↓
Ejecutar pruebas
Si las pruebas fallan, Codex debería continuar analizando y corrigiendo el problema.
Si durante el proceso el usuario dice:
Añade un cuadro de confirmación antes de eliminar la cuenta.
Esto tampoco constituye una tarea nueva.
La forma correcta de continuar sería:
Developer Agent
+
Mid Model
+
Contexto de la tarea original
Y seguir trabajando.
No:
Nuevo mensaje
↓
Jev
↓
Seleccionar de nuevo el modelo
Ejemplo práctico 3: una tarea compleja
Ahora empieza otra tarea:
Analiza el sistema de autenticación actual, diseña una estrategia más fiable para gestionar las sesiones y evalúa los problemas de base de datos, caché, seguridad y rendimiento. Primero analiza el sistema; no modifiques el código.
Jev podría determinar:
Task: Complex
Tier: Expert
Model: High
A continuación, Codex Expert analiza:
Authentication
↓
Session
↓
Database
↓
Cache
↓
API
↓
Security
↓
Performance
Y finalmente propone una arquitectura.
El usuario confirma:
Implementa esta solución y añade las pruebas.
Aquí tampoco debería producirse un nuevo routing.
El diseño de la solución y su implementación forman parte del mismo ciclo de vida de la tarea.
Lo realmente interesante: escalar el modelo durante la tarea
Esta es probablemente la parte más interesante del enfoque de task-level routing.
Por ejemplo, el usuario comienza con:
Optimiza el tiempo de respuesta de esta API.
Jev inicialmente determina:
Medium
↓
Developer
↓
Mid Model
Codex empieza a revisar el código.
Y descubre:
API
↓
Varias consultas a la base de datos
↓
Data Layer compartida
↓
Redis Cache
↓
Compartida por varias APIs
En ese momento, el problema ya no consiste simplemente en “optimizar una API”. Se ha convertido en un posible rediseño de parte de la arquitectura de acceso a datos.
Aquí debería activarse una:
Escalation
Y volver a consultar a Jev:
Estado actual de la tarea:
- El alcance de los cambios ha aumentado
- Hay dependencias con la base de datos
- Hay dependencias con la caché
- Varios módulos importantes están afectados
- El modelo actual ha intentado resolver el problema dos veces sin éxito
Jev puede entonces determinar:
Difficulty:
Complex
New Tier:
Expert
Y realizar el escalado:
Developer
↓
Escalation
↓
Jev
↓
Expert
Aquí existe una diferencia fundamental:
El routing vuelve a ejecutarse porque ha cambiado el estado de la tarea, no porque el usuario haya enviado un nuevo mensaje.
Esta es, en mi opinión, una arquitectura de Agent Routing más coherente.
¿Cuándo debería producirse un escalado?
Las condiciones de escalado pueden convertirse en reglas explícitas:
Dos fallos consecutivos de las pruebas
↓
Candidato a escalado
No se puede localizar el bug
↓
Candidato a escalado
El alcance de las modificaciones aumenta claramente
↓
Candidato a escalado
Afecta a la arquitectura de la base de datos
↓
Candidato a escalado
Afecta a autenticación / pagos / seguridad
↓
Candidato a escalado
Requiere refactorizar varios módulos principales
↓
Candidato a escalado
También puede incorporarse una autoevaluación del Agent:
I cannot confidently complete this task
Esto puede activar una nueva evaluación.
El flujo completo sería:
Task Start
↓
Jev
↓
Model Binding
↓
Codex
↓
Code → Test → Fix
↓
¿Ha cambiado la complejidad?
├── No → Continue
└── Sí
↓
Jev
↓
Escalate
¿Cómo conectar Jev con Codex?
Aquí es importante no mezclar las configuraciones de diferentes proyectos disponibles públicamente.
Actualmente existen varias implementaciones open source que pueden colocar Jev delante de Codex.
Por ejemplo, jev-codex-router utiliza un proxy local para que Codex CLI siga encargándose de la autenticación, las herramientas y la ejecución, mientras Jev selecciona el modelo.
Otra implementación, jev-model-router, ofrece directamente un sistema de instalación como plugin para Codex.
Uno de los métodos de instalación publicados actualmente tiene un aspecto similar a:
codex plugin marketplace add Mandrilsquad1441/jev-model-router
codex plugin add jev-model-router@jev-model-router
Este proyecto requiere configurar OPENROUTER_API_KEY o TYPESAFE_API_KEY, después de lo cual el plugin utiliza Jev para seleccionar el modelo.
También existe un wrapper más directo, jev-codex:
npm install -g jev-router
Y posteriormente:
jev-codex
Este sistema inicia el Codex CLI real y utiliza un proxy local para permitir que Jev participe en la selección del modelo. El inicio de sesión, las herramientas, los permisos y el mecanismo de sesión de Codex siguen funcionando.
Sin embargo, hay que destacar algo importante:
Estos proyectos existentes implementan principalmente per-turn routing.
Por ejemplo, jev-codex-router utiliza explícitamente la expresión:
For each fresh turn
Es decir, cada nuevo turno del usuario puede provocar una nueva selección de modelo.
Por eso, si el objetivo es conseguir estrictamente:
Una tarea
↓
Un routing inicial
↓
Modelo fijo
↓
Ejecución continua
↓
Nuevo routing solo cuando la tarea escala
es necesario añadir una sencilla capa de Task Binding al Router.
¿Cómo implementar Task Binding?
La idea fundamental es guardar el vínculo entre una tarea y el modelo seleccionado:
task_id
selected_tier
selected_model
created_at
status
escalation_count
Por ejemplo:
{
"task_id": "task_1024",
"tier": "developer",
"model": "mid-model",
"status": "running",
"escalation_count": 0
}
Cuando llega una tarea por primera vez:
task_1024
↓
Jev
↓
Developer
↓
Binding
Después, el usuario puede enviar:
Continúa
o:
Cambia el mensaje de error
El Router primero consulta:
task_1024 → Developer
y utiliza directamente el modelo asociado.
Solo cuando se recibe una señal como:
ESCALATE
se vuelve a llamar a Jev.
Así, el sistema pasa de:
Message → Jev → Model
a:
Task → Jev → Model
↓
múltiples Messages
↓
mismo Model
¿Qué ocurre con el contexto y la caché?
Tampoco sería correcto afirmar simplemente que “cambiar de modelo provoca la pérdida de caché”.
Hay que distinguir dos cuestiones.
En términos de continuidad del contexto, mantener el mismo Agent trabajando de forma continua resulta claramente más sencillo.
Puede conservar:
Los archivos que ya ha leído
El plan actual
Los resultados de las llamadas a herramientas
El historial de modificaciones
Los resultados de las pruebas
El estado actual de la tarea
En cuanto a Prompt Caching, su comportamiento concreto depende del modelo subyacente, la API y el contexto de cada solicitud.
Cambiar de modelo con frecuencia puede reducir parte de la reutilización de caché, ya que distintos modelos o rutas de solicitud pueden utilizar mecanismos de caché diferentes.
Por eso, dentro de una tarea continua de Coding, mantener estable el modelo suele ser más razonable que volver a seleccionarlo después de cada mensaje.
La documentación actual de modelos de OpenAI también destaca Prompt Caching y, en determinados modelos, la posibilidad de reutilizar persisted reasoning entre distintos turnos. Esto refuerza la idea de que mantener la continuidad del contexto puede tener un valor práctico.
También hay que incluir el coste del Router
Supongamos que en un día tenemos:
60 tareas sencillas
30 tareas intermedias
10 tareas complejas
Si todas utilizan High:
100%
→ High Model
Con task-level routing:
60%
→ Low
30%
→ Mid
10%
→ High
En teoría, esto puede reducir considerablemente el consumo de modelos de alta capacidad.
Pero el coste total sería realmente:
Coste total =
Coste del Jev Router
+
Low Model
+
Mid Model
+
High Model
+
Coste adicional de contexto
Por tanto, no basta con observar cuántas veces se utiliza un modelo barato.
La comparación correcta sería:
Ahorro obtenido al bajar de modelo
>
Coste de Jev
+
Coste adicional del routing
+
Coste de reprocesar contexto
Además, los propios Subagents pueden aumentar el consumo de tokens. La documentación actual de OpenAI señala que utilizar múltiples Agents no implica automáticamente un coste menor, por lo que es necesario medir la calidad, latencia y coste de extremo a extremo.
¿Cuándo no conviene utilizar Jev?
Si solo utilizas Codex unas pocas veces al día y todas las tareas son complejas:
Todas las tareas
↓
High Model
puede resultar más sencillo.
Si todas las tareas son extremadamente mecánicas:
Formatear
Cambiar nombres de variables
Modificar textos
tampoco tiene mucho sentido construir un Router complejo.
Existe además otro escenario: cuando la diferencia de precio entre modelos es muy pequeña.
Si:
Coste del Router
+
Coste de contexto
se aproxima al ahorro obtenido al utilizar un modelo inferior, el beneficio económico del routing se vuelve limitado.
Por eso Jev tiene más sentido en flujos de Coding donde:
hay muchas tareas, la dificultad varía considerablemente y existe una diferencia significativa de precio entre modelos.
Arquitectura final
Podemos resumir todo el sistema en un único esquema:
User
↓
New Task
↓
Jev
↓
Task Classification
↓
┌───────────┼───────────┐
↓ ↓ ↓
Simple Medium Complex
↓ ↓ ↓
Scout Developer Expert
↓ ↓ ↓
Low Mid High
└───────────┼───────────┘
↓
Codex Agent
↓
Analyze → Code → Test
↓
Task still stable?
↓ ↓
Yes No
↓ ↓
Continue Jev
↓
Escalate
↓
New Model
Lo más importante de esta arquitectura no es conseguir que Jev seleccione un modelo cada vez.
Es exactamente lo contrario.
Un Router bien diseñado debería hacer routing con la menor frecuencia posible.
Al comenzar una tarea, debería responder a una pregunta:
¿Qué nivel de capacidad necesita esta tarea?
Después, un Agent de Codex adecuado debería encargarse de completarla de forma continua.
Solo cuando la tarea pase realmente de:
Simple
↓
Medium
↓
Complex
debería volver a ejecutarse el Router.
Por eso, todo el diseño puede resumirse en tres principios:
Primero, Jev debe enrutar tareas, no mensajes.
Segundo, una tarea continua de Coding debería mantener, siempre que sea posible, el mismo Agent y modelo.
Tercero, el escalado del modelo debería activarse por cambios en el estado de la tarea, no por cada nuevo mensaje del usuario.
Este enfoque va un paso más allá de la idea básica de “utilizar un modelo barato para problemas sencillos y uno avanzado para problemas difíciles”. Tiene en cuenta el estado del Agent, la continuidad del contexto, la caché, el coste de tokens y el ciclo de vida completo de la tarea.
Las herramientas públicas actuales de Codex + Jev ya permiten establecer el flujo básico de “Jev decide → Codex ejecuta”.
El siguiente paso interesante no es conseguir que el Router seleccione modelos con mayor frecuencia, sino transformar el per-turn routing en task-bound routing y añadir un escalation loop verificable.