NovedadIA

Cómo usar Jev y Codex con routing por tarea en lugar de por mensaje

Guia

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

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.