Entornos de RL para LLM: cómo se construyen, puntúan y escalan

Entornos de RL para LLM: cómo se construyen, puntúan y escalan
6frameworks con el mismo entorno construido en todos
11piezas que forman un entorno
4formas de conectar la recompensa
128 → 16.384sesiones a la vez con dos nodos, tras ajustar el balanceador
Entornos de RL para LLMs: la guía definitiva para construirlos, puntuarlos y escalarlos
También lo cuento en este vídeo, en mi canal Articulator ES.

Por qué importan los entornosenlace

El aprendizaje por refuerzo (RL) se ha convertido en el gran motor de los modelos que razonan y de los agentes: es el punto en el que el ajuste fino supervisado se estanca y el refuerzo sigue subiendo el rendimiento. Y su pieza central es el entorno: el sitio donde el modelo practica, recibe una nota y aprende de la interacción durante muchos pasos.

Para conseguir más capacidades, el número de entornos se ha disparado:

  • Qwen3 entrenó con unas 20 tareas de dominio general.
  • Qwen3-Coder pasó a 20.000 entornos en paralelo en Alibaba Cloud.
  • Forge, de MiniMax, entrena M2.5 con cientos de miles de entornos sacados del mundo real.
  • Qwen3.5 habla ya de entornos con millones de agentes y distribuciones de tareas cada vez más complejas.
La escala de los entornos: de unas 20 tareas en Qwen3 a 20.000 entornos en paralelo en Qwen3-Coder, cientos de miles en Forge y millones de agentes en Qwen3.5.
De veinte tareas a millones de agentes.

El equipo de Qwen lo dice sin rodeos en las notas de Qwen3.5: casi toda la mejora sobre Qwen3 viene de «escalar prácticamente todas las tareas y entornos de RL que se nos ocurrieron», subiendo a propósito su dificultad y su generalidad en vez de optimizar para benchmarks concretos.

Así que el cuello de botella ya no es «¿sé montar un entorno?», sino «¿cómo ejecuto 100.000 a la vez, los mantengo honestos y los meto en el bucle de entrenamiento?». Para eso están saliendo frameworks que lo estandarizan y catálogos de entornos hechos: el mayor está en Hugging Face Spaces, con más de 4.000 entornos compatibles con MCP, y el Environments Hub de Prime Intellect y openreward.ai suman varios miles más.

La conclusión de los autores, por adelantado: cada framework hace lo mismo a su manera. Las diferencias están en cómo se conecta el entorno con el resto del entrenamiento, no en lo que puede hacer. El mismo entorno se puede replicar en los seis, así que no te pierdes nada fundamental eligiendo uno u otro: lo que cambia es la comodidad, y eso depende de lo que ya uses. Todo el código está en su repositorio RL_Envs_101.

Qué es un entorno de RL en la era de los LLMenlace

En el RL clásico (Atari, robótica), un entorno es pequeño y autocontenido. El ejemplo de manual es CartPole: un carrito sobre un raíl con un palo en equilibrio encima. El agente observa cuatro números (posición y velocidad del carro, ángulo y velocidad angular del palo), elige una de dos acciones (empujar a la izquierda o a la derecha) y el entorno avanza un paso de física. La recompensa es +1 por cada paso en que el palo sigue de pie. El entorno es el simulador de física más la regla de la recompensa.

CartPole: un carrito sobre un raíl con un palo en equilibrio, cuatro números de estado, dos acciones y un punto por paso.
CartPole: cuatro números, dos acciones y un punto por paso.

Con los modelos de lenguaje la imagen se complica y no hay una implementación canónica. Una forma habitual: el agente es el modelo; el entorno, un sandbox que ejecuta comandos o código; y el espacio de acciones, las herramientas que exponga el framework. Cada intento (rollout) es una conversación de varios turnos: el modelo escribe, ejecuta una herramienta, lee la salida, decide qué probar y al final entrega una respuesta. El entorno puntúa el intento completo y devuelve una recompensa, y cada paso de entrenamiento junta un grupo de intentos por tarea para aprender de ellos.

El bucle con un modelo de lenguaje: el modelo llama a una herramienta en el sandbox, lee la observación y al final recibe una recompensa.
Mismo esqueleto que CartPole, otra escala.

Hay muchas otras formas (razonamiento en un solo turno, tareas web, agentes sobre repositorios, varios agentes), pero todas son variaciones del mismo esqueleto. Cambian las herramientas, las observaciones y la regla de la recompensa.

Las cinco etapas y quién cubre quéenlace

Todo sistema de entrenamiento por refuerzo para LLM se apoya en la misma columna de cinco etapas: tareas que resolver, un arnés que deja al modelo interactuar, una recompensa que puntúa su comportamiento, un recolector que junta episodios completos y un entrenador que convierte esos episodios en una actualización de la política. Lo que cambia de un framework a otro es qué trozo de esa columna te dan hecho:

FrameworkTareasArnésRecompensaRecolecciónEntrenador
OpenEnv–✓✓––
ORS✓✓✓––
NeMo Gym✓✓✓✓–
Verifiers + Prime RL✓✓✓✓✓
SkyRL Gym–✓✓✓✓
GEM✓✓✓––
Las cinco etapas en fila (tareas, arnés, recompensa, recolección y entrenador) con corchetes de color que marcan el tramo que cubre cada framework.
Cada framework cubre un tramo distinto de la columna.

OpenEnv te da el arnés (las herramientas que puede llamar el modelo) y la recompensa, pero el entrenador lo escribes tú. Verifiers, por sí solo, describe la tarea, las herramientas, el arnés y la recompensa, y el entrenamiento lo hace Prime RL, con el que va emparejado. Por eso una comparación plana «X contra Y» es difícil: cada uno nació para encajar en un ecosistema y no viven al mismo nivel de la pila. Para otro corte complementario, el de entrenamiento síncrono frente a asíncrono, los autores remiten al panorama del entrenamiento RL asíncrono de Hugging Face.

Las once piezas de un entornoenlace

Tras pasar tiempo dentro de los seis frameworks, siempre aparecían las mismas piezas: las que de verdad tienes que pensar al construir o elegir un entorno para un agente. Cada una responde a una pregunta:

PiezaQué pregunta respondeEjemplos
Tareas / dataset¿Qué problemas debe resolver el modelo?Tareas de programación, problemas de matemáticas, partidas
Estado inicial¿Cómo se prepara el estado al empezar un episodio?reset(), ciclo setup(), endpoint seed_session, hook setup_state
Plantilla del prompt¿Cómo se le presenta la tarea al modelo?Prompt de sistema + instrucción + descripción de herramientas
Herramientas¿Qué puede hacer el modelo en el mundo?execute_code(), search(), submit_answer()
Formato de la observación¿Qué ve el modelo tras una acción?Texto, un ToolOutput con bloques, la tupla de cinco de Gymnasium
Dónde se ejecuta¿Dónde corren de verdad las acciones?Sandbox en la nube, contenedor Docker, eval() de Python, un simulador o nada (Python puro)
Estado entre turnos¿Cómo se sigue el estado de un turno a otro?Cookies de sesión, persistencia del sandbox, historial de la conversación
Recompensa / rúbrica¿Cómo se puntúa el comportamiento?Comparar cadenas, un LLM como juez, tests unitarios, endpoint verify()
Fin del episodio¿Cómo termina?finished en cada llamada, terminated/truncated, máximo de turnos, lo decide verify()
Control del episodio¿Quién lleva el bucle y decide cuándo parar?El entrenador (TRL), el entorno (Atropos) o el framework (Verifiers)
Transporte / protocolo¿Cómo habla el modelo con el entorno?HTTP REST, WebSockets, JSON-RPC (MCP), SSE, llamadas de Python en el mismo proceso
La caja del entorno abierta, con sus once piezas: tareas, estado inicial, prompt, herramientas, observación, ejecución, estado, recompensa, fin, control y transporte.
Once piezas, en los seis frameworks.

Para qué sirven los frameworks, y los seis elegidosenlace

¿Para qué hace falta un framework de entornos? Sobre todo, para estandarizar. Si hay un protocolo acordado para que un entrenador hable con un entorno, como MCP para las herramientas, cualquier bucle de entrenamiento puede usar cualquier entorno, investigadores de campos distintos siguen la misma forma, y los entornos de otros te sirven para tu entrenamiento en vez de ser scripts de un solo uso.

Todavía no hay un protocolo estándar, así que cada framework responde a su manera a cuatro preguntas:

  1. ¿Qué es un entorno? Para unos, solo una función de recompensa; para otros, también herramientas, estado y el bucle de varios turnos; otros meten además todo el entrenamiento.
  2. ¿Dónde corre? Como servidor HTTP (Docker, HF Spaces), que escala aparte del entrenamiento, o dentro del proceso de entrenamiento, sin saltos de red pero sin aislamiento.
  3. ¿Cuánto entrenador trae? Algunos traen el suyo (Prime RL, NeMo RL, SkyRL); otros necesitan adaptadores para enchufarse a bucles externos como TRL.
  4. ¿Cuándo llega la recompensa? En cada llamada a herramienta, en cada paso con una rúbrica, al verificar el episodio o en una función externa.

De los 16 que revisaron, eligieron seis para construir el mismo entorno y compararlos cara a cara:

FrameworkCreadorTipoPaquetePython
OpenEnvMeta PyTorchServidor HTTP (MCP)openenv-core≥3.11
ORSGeneral ReasoningServidor HTTP (REST + SSE)ors-sdk≥3.10
NeMo GymNVIDIAServidor HTTP (REST)nemo_gym (desde git)≥3.12
VerifiersPrimeIntellectEn el proceso (Python)verifiers≥3.11
SkyRL GymNovaSky-AI · BerkeleyEn el proceso (Gym)skyrl-gym≥3.10
GEMAxon-RLEn el proceso (Gymnasium)gem-llm≥3.10
Los seis frameworks: OpenEnv, ORS y NeMo Gym como servidores HTTP; Verifiers, SkyRL Gym y GEM dentro del proceso de entrenamiento.
Tres servidores y tres que viven dentro del entrenamiento.

Los 16 se reparten en tres niveles:

  • Nivel 1, bibliotecas de tareas puras: problemas y verificadores, sin transporte, herramientas ni estado (RLVE, Reasoning Gym).
  • Nivel 2, frameworks de entornos: definen cómo construir un entorno y te dejan el entrenador (OpenEnv, ORS, NeMo Gym, RL-Factory).
  • Nivel 3, entorno y entrenamiento juntos: definición del entorno, recolección y entrenamiento en un paquete (Verifiers, SkyRL Gym, GEM, Atropos, Harbor, RAGEN, rLLM, Open-Instruct, TextArena, LlamaGym).

Se centraron en los niveles 2 y 3, los que admiten entornos de varios turnos con herramientas. Los que quedaron fuera, y por qué:

FrameworkCreadorPor qué no entró
AtroposNous ResearchOtro paradigma: el entorno hace su propia inferencia y envía lotes puntuados a una API central. No encaja con las llamadas a herramientas turno a turno de TRL.
HarborLaude InstituteFramework de evaluación y generación de intentos, el arnés oficial de Terminal-Bench 2.0: ejecuta agentes completos (Claude Code, Codex CLI, OpenHands) en contenedores.
RLVEZhiyuan ZengBiblioteca de verificadores (445 tareas), generate() → verify(), sin transporte, herramientas ni estado.
Reasoning GymOpen ThoughtGeneradores de tareas y verificadores, sin estado ni varios turnos.
RAGENZihan WangPila completa (entorno + StarPO + veRL) muy acoplada a su propio bucle.
rLLMAgenticaPatrón de decorador que envuelve código de agente existente; no hay clase de entorno.
RL-FactorySimple-EfficientCualquier servidor MCP se vuelve entorno con una configuración; interesante, pero muy temprano.
Open-InstructAllen AIFramework de entrenamiento con ganchos de entorno; los entornos son funciones de recompensa, no agentes de varios turnos.
TextArenaLeon GuertlerJuegos multiagente, un dominio estrecho.
LlamaGymKhoomeiKEnvoltorio de Gymnasium para LLM, prototipo sin mantenimiento.

Qué trae cada uno de serieenlace

Esta es la tabla clave. Cada framework trae un subconjunto distinto de piezas: ✅ tiene una API propia para esa pieza; ⚙️ funciona, pero apoyándote en una convención o en un gancho del entrenador; 🔧 la pones tú (bring your own).

PiezaOpenEnvORSNeMo GymVerifiersSkyRL GymGEM
Tareas🔧✅ list_tasks(split)✅ JSONL + ng_prepare_data✅ Dataset de HF🔧 (JSONL)✅ 24+ entornos
Estado inicial✅ reset()✅ setup()✅ /seed_session✅ setup_state✅ init(prompt)✅ reset(seed)
Plantilla del prompt🔧✅ get_prompt()✅ en el JSONL✅ system_prompt🔧✅ instrucciones por entorno
Herramientas✅ @mcp.tool✅ @tool✅ endpoints POST✅ funciones de Python✅ ToolGroup✅ ToolEnvWrapper
Observación✅ str✅ ToolOutput✅ Response✅ str✅ BaseTextEnvStepOutput✅ tupla de 5
Dónde se ejecuta🔧🔧🔧🔧🔧🔧
Estado entre turnos✅ sesiones MCP✅ X-Session-ID✅ cookies⚙️ estado en el proceso✅ contador self.turns✅ reset()/step()
Recompensa✅ Rubric✅ ToolOutput.reward✅ /verify✅ Rubric + JudgeRubric✅ la devuelve step()✅ la devuelve step()
Fin del episodio✅ Observation.done✅ finished⚙️ lo decide verify()✅ @vf.stop / máx. turnos✅ step().done✅ terminated/truncated
Control del episodio⚙️ entrenador⚙️ entrenador✅ Agent Server✅ env.evaluate()⚙️ entrenador⚙️ entrenador
Transporte✅ HTTP + JSON-RPC✅ REST + SSE✅ REST + cookies⚙️ solo en el proceso⚙️ solo en el proceso⚙️ solo en el proceso
Despliegue✅ Docker / HF Spaces✅ Docker / Spaces / OpenReward✅ Docker / Ray⚙️ entorno de entrenamiento⚙️ entorno de entrenamiento⚙️ entorno de entrenamiento
Entrenamiento⚙️ con TRL⚙️ varios✅ Megatron / NeMo RL✅ Prime RL✅ SkyRL⚙️ varios
La tabla de qué trae cada framework, con la fila de dónde se ejecutan las acciones vacía en los seis.
Hay una fila que no rellena ninguno: dónde se ejecutan las acciones.
  • El más completo: Verifiers trae dataset, herramientas, rúbrica, arnés de recolección y entrenamiento. Defines el problema y él hace el resto, a cambio de vivir dentro de su API.
  • El más ligero: OpenEnv trae un protocolo (MCP), la gestión de sesiones y un sistema de rúbricas. Las tareas y la ejecución las pones tú: más trabajo, más control.
  • En medio: ORS y NeMo Gym traen protocolo de despliegue y recompensa, pero la ejecución y las tareas las pones tú. GEM trae entornos hechos y la API de Gymnasium, y el entrenador lo pones tú.

Y un detalle que se ve enseguida en la tabla: ninguno trae dónde se ejecutan las acciones. El sandbox siempre es cosa tuya.

Mismo concepto, seis nombresenlace

Leer la documentación de dos de estos frameworks seguidas parece leer dos APIs distintas para lo mismo, porque básicamente lo es. Una pequeña piedra de Rosetta:

ConceptoOpenEnvORSNeMo GymVerifiersSkyRL GymGEM
Función de recompensaRubriccampo reward de ToolOutputendpoint verify()Rubriclo que devuelve step()lo que devuelve step()
Fin del episodiodonefinished en cada llamadalo decide verify()@vf.stopdoneterminated / truncated
Una tarealo que tú traigasuna tarea de un splituna línea de JSONLuna fila de un Datasetlo que tú traigasuna instancia de un entorno incluido
La misma idea, la recompensa, con un nombre distinto en cada framework: Rubric, ToolOutput.reward, verify() y step().
La recompensa se llama distinto en casi cada framework.

Dos cosas llaman la atención con todo junto: todos tienen algo para el estado inicial y para definir herramientas, porque cualquier entorno de varios turnos lo necesita, pero las tareas solo las rellenan los que traen su propia fuente. Y en el estado del episodio, los de HTTP usan sesiones y los de dentro del proceso tiran de Python normal.

Dimensión 1: qué código escribesenlace

Lo primero con lo que te encuentras es la API: de qué heredas, cómo declaras una herramienta y cuánto andamiaje rodea a la lógica. El mismo entorno de juguete se escribe de seis formas:

OpenEnvORSNeMo GymVerifiersSkyRL GymGEM
Clase baseMCPEnvironmentors.EnvironmentSimpleResourcesServerninguna (funciones)BaseTextEnvgem.Env
Herramientas@mcp.tool@tool + Pydanticapp.post("/name")def func(arg: type)dentro de step()dentro de step()
DevuelvestrToolOutput(blocks, reward, finished)Response(output=str)strBaseTextEnvStepOutput(obs, reward, done, trunc, info)
Punto de entradacreate_app(Env)Server([Env]).run()Env.run_webserver()vf.ToolEnv(tools=[...])skyrl_gym.register(...)gem.register(...)

Para ver el contraste, el mismo entorno en OpenEnv, con sus herramientas MCP registradas dentro de la clase:

class MyEnv(MCPEnvironment):
    def __init__(self):
        mcp = FastMCP("my_env")

        @mcp.tool
        def do_action(input: str) -> str:
            """Execute an action. Returns observation."""
            return execute(input)

        super().__init__(mcp)

    def reset(self, **kwargs) -> Observation:
        self._state = fresh_state()
        return Observation(done=False, reward=None, metadata={"status": "ready"})

En Verifiers, en cambio, bastan funciones de Python normales y una rúbrica:

def do_action(input: str) -> str:
    """Execute an action. Returns observation."""
    return execute(input)

async def correctness(completion, answer, **kwargs) -> float:
    return 1.0 if answer in completion[-1]["content"] else 0.0

env = vf.ToolEnv(
    tools=[do_action],
    rubric=vf.Rubric(funcs=[correctness]),
    dataset=my_dataset,
)

Y en GEM todo pasa por reset() y step(), al estilo de Gymnasium, con spawn() para clonar el entorno en los intentos en paralelo de GRPO:

class MyGEM(gem.Env):
    def reset(self, seed=None):
        super().reset(seed)
        self._state = fresh_state()
        return "Your task: ...", {"suffix": "Begin."}

    def step(self, action):
        parsed = parse_action(action)
        result = execute(self._state, parsed)
        terminated = is_done()
        return result, score(result), terminated, False, {"suffix": "Continue."}

    def spawn(self, same_state=False, **kwargs):
        return MyGEM(...)
El entorno de juguete escrito en GEM, con reset() y step() al estilo de Gymnasium, y debajo su clase base, cómo declara las herramientas y qué devuelve.
Mismo entorno, seis API: aquí, el de GEM.

Dimensión 2: servidor HTTP o dentro del procesoenlace

La división más importante de todas: ¿el entorno corre como servidor HTTP aparte o dentro del proceso de entrenamiento? De esa elección sale casi todo lo demás. Se nota en tres cosas:

  • Dónde corre. Un servidor vive en su propia máquina, muchas veces una barata sin GPU, o en un Space de Hugging Face. El de dentro del proceso comparte el nodo de GPU del entrenamiento.
  • Qué instalas junto al entrenador. Con HTTP, solo un SDK o requests. Dentro del proceso, el paquete entero del framework.
  • Cómo escala. Con HTTP, añadiendo réplicas detrás de un balanceador. Dentro del proceso, añadiendo trabajadores de entrenamiento idénticos, cada uno con su copia del entorno.
OpenEnvORSNeMo GymVerifiersSkyRL GymGEM
Tiposervidor HTTPservidor HTTPservidor HTTPen el procesoen el procesoen el proceso
ProtocoloJSON-RPC 2.0 (MCP), WebSocketREST + SSEREST + cookiesllamadas de Pythonllamadas de Pythonllamadas de Python
Dockersísísínonono
Escala por separadosísísínonono
Junto al entrenadoropenenv-coresolo requestssolo requestsel paquete enteroel paquete enteroel paquete entero
AutenticaciónningunaX-API-Keycookies–––
¿Dónde corre el entorno? Dos ramas: como servidor HTTP aparte o dentro del proceso de entrenamiento; de esa elección sale casi todo.
Servidor aparte o dentro del entrenamiento: la decisión que ordena todo lo demás.

Un matiz importante: en la práctica casi ningún entorno hace el trabajo pesado él mismo. Lo delega en un proveedor de sandbox como E2B, Modal o un backend de contenedores propio. Eso cambia la historia del escalado en los dos casos: el servidor HTTP se queda en un enrutador fino que guarda sesiones y reenvía las llamadas al sandbox, así que añadir réplicas es barato; y la clase de dentro del proceso acaba siendo un cliente fino del sandbox, así que cada trabajador ocupa poco aunque lances cientos. La forma del despliegue sigue importando (HTTP aísla dependencias, en el proceso se comparten), pero el cómputo pesado vive en el sandbox que elijas.

Dimensión 3: herramientas y accionesenlace

Los seis acaban enseñándole al modelo lo mismo: una lista de herramientas con nombre, descripción y parámetros con tipo. Cambia dónde se define la herramienta y cómo la descubre el entrenador. Los de HTTP la definen en el servidor y ofrecen un endpoint para descubrirlas en tiempo de ejecución; los de dentro del proceso son funciones de Python que se registran al construir el entorno. Después, las dos formas son idénticas: mandas una llamada y recibes una observación.

Descubrimiento de herramientas: por HTTP se piden al servidor en tiempo de ejecución; en el proceso se registran al crear el entorno; después, llamada y observación.
Después del descubrimiento, todo es igual.
  • Portabilidad del esquema. Los de HTTP envían JSON Schema (MCP, ToolSpec de ORS, OpenAPI), que cualquier modelo compatible con OpenAI sabe llamar: la misma herramienta pasa de un modelo a otro sin tocarla. Los de dentro del proceso sacan el esquema de los tipos de Python: más rápido de escribir, más difícil de llevarse a otro framework o a un modelo que espera otro dialecto.
  • Coste de escribir cada herramienta. Un decorador @tool sobre una función es una línea; un endpoint de FastAPI con su modelo Pydantic se parece más a un archivo. Multiplícalo por tus herramientas.
  • El bucle de varios turnos es universal. Una vez conectadas las herramientas, para el modelo todo es igual: nombre y argumentos con tipo de entrada, observación de salida.

Dimensión 4: la recompensaenlace

¿Quién decide si el comportamiento del modelo fue bueno, y cuándo? Aquí es donde los frameworks más difieren en filosofía. Hay cuatro patrones:

PatrónCómo funcionaQuién lo usa
1. Recompensa externaDecide el script de entrenamiento: el entorno solo devuelve texto y una función que escribes tú compara el resultado con lo esperado.SkyRL Gym, GEM
2. Dentro del servidorCada respuesta de una herramienta lleva su recompensa; el servidor evalúa sobre la marcha y el entrenador solo lee env.reward.ORS
3. Verificación al finalTras el episodio se llama a un endpoint /verify aparte, que evalúa la trayectoria completa.NeMo Gym
4. Rúbrica dentro del entornoUn objeto Rubric componible (inspirado en nn.Module) calcula la recompensa desde acciones y observaciones; se llama solo en cada step().OpenEnv, Verifiers
Los cuatro patrones de recompensa sobre la misma trayectoria: externa, en cada llamada, al verificar al final y con una rúbrica en cada paso.
Cuatro momentos para poner la nota.

La rúbrica componible admite combinaciones (WeightedSum, Sequential, Gate), un LLM como juez (LLMJudge) y puntuar la trayectoria entera.

La rúbrica componible: varias funciones sumadas con pesos, encadenadas, con una puerta que corta la nota y un modelo que hace de juez.
Una rúbrica se compone como un módulo de PyTorch.

Qué va dentro de una recompensa

Los cuatro patrones hablan de cuándo se calcula y de quién es el código. Lo que va dentro es otra pregunta, con tres sabores:

  • Procedural o verificable. Comprobaciones deterministas: ¿la respuesta coincide?, ¿pasa el test?, ¿el JSON se puede leer?, ¿la cuenta da el número correcto? Es el patrón RLVR (reinforcement learning with verifiable rewards) que escaló DeepSeek-R1: el modelo solo gana si su salida supera un control programado, casi siempre un 0 o un 1. Escala, es difícil de engañar y encaja en matemáticas, código y lógica. La pega: necesita una respuesta correcta clara.
  • LLM como juez (a veces llamado RLAIF). Para lo que no se comprueba con código: escritura creativa, razonamiento abierto, la calidad de un resumen, la coherencia de un agente. Otro modelo lee la trayectoria y la puntúa, a menudo con una rúbrica («precisión de 1 a 5, claridad de 1 a 5, con pesos»). Es lo que hacen LLMJudge y JudgeRubric. La pega es el hackeo de la recompensa: la política aprende a producir lo que el juez premia de más, aunque un juez más estricto lo castigaría. Para frenarlo hay rúbricas descompuestas y «jueces que piensan» (al estilo de J1) que razonan antes de puntuar.
  • Densa frente a escasa. Es otro eje. La escasa llega solo al final (aprobado o suspenso, nota final); la densa, en cada paso, en cada token o en cada subobjetivo, y le da al entrenador mucha más información para repartir el mérito. La externa y la verificación al final son escasas por defecto; la del servidor y la rúbrica pueden ser cualquiera de las dos, y la rúbrica es el sitio más natural para hacerlas densas. Las densas entrenan más rápido y más estable; las escasas son más fáciles de definir y más difíciles de engañar.
El hackeo de la recompensa: el modelo aprende a darle al juez lo que le gusta en vez de hacer bien la tarea.
Con un juez blando, el modelo aprende a esconder el polvo debajo de la alfombra.

En la práctica casi siempre se mezclan: una parte procedural para lo que se puede verificar (el test pasa, el JSON es válido, la respuesta coincide) y un juez para lo que no (si la explicación es buena, si el agente no se desvió), combinadas con pesos en un solo número. Los frameworks solo cambian dónde escribes esa combinación y cuándo se dispara.

Dimensión 5: quién lleva el bucle y cuándo paraenlace

Un intento de varios turnos es un ciclo apretado: el modelo genera una acción, se llama a la herramienta, la observación vuelve al modelo, y otra vez. Hay que decidir quién mueve ese ciclo y cómo sabe que ha terminado.

En todos los que probaron, manda el entrenador: genera, interpreta las llamadas a herramientas, las ejecuta a través del adaptador y vuelve a generar. El entorno es pasivo: responde, pero no inicia nada. Así, el entrenador controla la longitud del episodio, cómo se leen las llamadas y los reintentos. Otros que no probaron le dan la vuelta: en Atropos, el entorno tiene su propia instancia de vLLM y genera los intentos solo; en el modo env.evaluate() de Verifiers, el framework lleva el bucle. Importa porque cambia cómo piensas el agrupado en lotes, el paralelismo y el reparto de recursos.

El entrenador genera, interpreta la llamada, la ejecuta en el entorno a través del adaptador y vuelve a generar; el entorno solo responde.
El entrenador manda; el entorno responde.

La otra mitad es la señal de parada:

FrameworkSeñal de finGranularidadQuién lleva el bucle
OpenEnvObservation.done · herramienta final_answerpor paso + longitud máxima del entrenadorentrenador
ORSToolOutput.finishedpor llamadaentrenador
NeMo Gymverify() tras el intentoal final del episodioentrenador
Verifiers@vf.stop · is_completed()por pasoentrenador o entorno
SkyRL Gymstep().donepor pasoentrenador
GEMterminated · truncatedterminado / truncadoentrenador

Dos ejemplos con un entorno de agente de programación con herramientas al estilo de Claude Code: archivos (read, write, edit, multi_edit, ls, glob, grep), terminal (bash(command, timeout=30)), planificación (todo_write(todos)) y una herramienta final, submit_solution().

  • Control por herramientas (manda el entrenador). El entorno solo expone las herramientas y el episodio acaba cuando el modelo llama a submit_solution() o cuando se agota max_completion_length. Lo admiten los seis tal cual y se porta casi idéntico entre ellos. Para la mayoría de entornos con herramientas, es el camino más sencillo.
  • Intento controlado por el arnés (manda el entorno). A veces no quieres que el entrenador lleve nada: quieres un arnés de programación real (OpenCode, OpenClaw, Aider, al estilo de Claude Code) corriendo en el sandbox y hablando con el modelo. El arnés lleva la conversación: gestiona los archivos, comprime el contexto, reintenta si falla una herramienta y sabe cuándo ha terminado; el entorno solo lo aloja y devuelve la trayectoria. Da una fidelidad de benchmark, pero sacar datos para entrenar se vuelve otro problema: el arnés tiene que guardar en cada turno la acción, la observación, la recompensa y los logprobs que necesite tu pérdida, y eso es trabajo específico de cada arnés.
Un agente de programación completo corriendo dentro del sandbox, que gestiona archivos, comprime el contexto y reintenta, y que tiene que registrar acción, observación, recompensa y probabilidades en cada turno.
Cuando manda el arnés, recoger datos de entrenamiento es otro trabajo.

Dimensión 6: tareas y datasetsenlace

Cada intento empieza con una tarea: el prompt, los datos con los que trabaja el modelo y, para puntuar, la respuesta esperada o el test que decide si salió bien. Es la dimensión más variada después de la recompensa:

  • Verifiers se integra con los Dataset de Hugging Face.
  • GEM tiene un registro de más de 24 entornos incluidos.
  • ORS guarda las tareas en el servidor (list_tasks(split)).
  • NeMo Gym preprocesa JSONL con una herramienta de línea de comandos (ng_prepare_data).
  • OpenEnv y SkyRL Gym te lo dejan a ti.

Los que traen una abstracción de dataset te dan además particiones y versiones gratis; en los demás, las montas tú.

Una tarea es más que una fila

Una fila es una entrada y una salida esperada. Una tarea, sobre todo en agentes y programación, es un paquete de archivos que tiene que llegar al sandbox antes de empezar. El ejemplo más limpio es SETA, de OpenReward: 1.376 tareas de agente de terminal sobre el Open Reward Standard, cada una con un task.yaml (prompt y metadatos), los archivos de datos, un tests/test_outputs.py que se ejecuta al entregar y un weights.json que convierte los resultados de los tests en una nota. Las filas de SWE-Bench van más allá: cada una lleva repo, base_commit, problem_statement y test_patch; el entorno clona el repositorio en ese commit, aplica los tests y evalúa el diff del agente con FAIL_TO_PASS y PASS_TO_PASS.

Una tarea de SETA como paquete: task.yaml, datos, tests y weights.json, que se copian al sandbox antes del intento.
La tarea viaja al sandbox con sus datos y sus tests.

Esos paquetes suelen vivir detrás de la fila (en S3, en un repositorio de datasets de Hugging Face o en un tarball): el entorno los baja al empezar el episodio, los deja en el sandbox, puntúa y lo desmonta.

Acoplado o libre: quién manda en el formato

  • Acoplados. Verifiers espera un Dataset con una columna prompt y, opcionalmente, answer o info; GEM trae sus cargadores; ORS y NeMo Gym fijan el esquema en el servidor. El Environments Hub y OpenReward van más allá y estandarizan el paquete entero (estructura, contrato de puntuación, incluso el empaquetado en wheels), así que cualquier tarea que cumpla la especificación corre en cualquier entorno que la siga.
  • Libres. OpenEnv y SkyRL Gym dejan el dataset en tus manos: los prompts vienen de donde sea, pero cada fuente nueva cuesta un poco de integración.

Acoplar significa que el entorno dicta el formato y tú transformas tus datos. Por ejemplo: pasar el JSONL de SWE-Bench a un Dataset de Verifiers con su columna prompt y el parche en info; repartir un volcado de preguntas de Kaggle en carpetas al estilo de OpenReward, una por fila, con task.yaml, data/ y tests/; o, con HumanEval o GSM8K, nada, porque el entorno ya trae su cargador. Lo escribes una vez y, a cambio, el mismo entorno corre sin cambios con todas las tareas que cumplan el formato. Si solo te importa una tarea, la especificación sobra; si entrenas con muchas o usas suites de benchmarks, es lo que lo hace posible.

Dimensión 7: ecosistema y madurezenlace

OpenEnvORSNeMo GymVerifiersSkyRL GymGEM
CreadorMeta PyTorchGeneral ReasoningNVIDIAPrimeIntellectNovaSky-AI · BerkeleyAxon-RL · ICLR 2026
Entornos incluidosejemplo en el repoejemplo en el repo50+ejemplo en el repopocos (búsqueda, SQL)24+ (juegos, matemáticas, código)
Hub de la comunidad4.000+ en HF Spaces330+ en openreward.ai–~1.000 en el Environments Hub––
En producciónMetaplataforma OpenRewardNVIDIA · NemotronPrimeIntellect · INTELLECT-3SkyRL-Agent · SWE-Benchinvestigación
Quién hay detrás de cada framework, cuántos entornos tiene su catálogo y dónde se usa en producción.
De la investigación a la producción.

Dimensión 8: cuánto cuesta un entorno nuevoenlace

¿Cuánto se tarda en pasar de «tengo una idea de entorno» a «está entrenando»? Importa tanto si lo escribes a mano como si lo escribe un agente.

OpenEnvORSNeMo GymVerifiersSkyRL GymGEM
Archivos4-6 (entorno, app, modelos, Dockerfile, pyproject)3-4 (servidor, Dockerfile, pyproject)4-5 (servidor, YAML, Dockerfile)1-21-21-2
ConceptosMCPEnvironment, create_app, Observation, Rubric, FastMCPEnvironment, @tool, ToolOutput, Server, SplitSimpleResourcesServer, setup_webserver, verify, sesionesToolEnv, RubricBaseTextEnv, init/step/closegem.Env, reset/step, spawn
Generador de esqueletoopenenv initorwd init–prime env init––
Primera prueba~30 min (Docker / servidor)~20 min (servidor + curl)~30 min (servidor + config)~5 min (pytest)~5 min (pytest)~5 min (pytest)
Archivos y conceptos de cada framework: los de dentro del proceso abajo a la izquierda, con uno o dos archivos y cinco minutos hasta la primera prueba; los de servidor arriba a la derecha.
Pocos archivos y tests inmediatos frente a Docker y despliegue.

Y lo probaron con un agente: Claude Code escribió un entorno completo de Wordle en los seis frameworks en una sola sesión. Los de dentro del proceso (Verifiers, SkyRL, GEM) estuvieron en minutos; los de HTTP (ORS, NeMo Gym, OpenEnv) necesitaron más vueltas para los Dockerfiles y la configuración del despliegue. Un solo archivo de Python, sin Docker ni servidor y con respuesta inmediata de pytest, es justo lo que mejor le va a un agente.

Dimensión 9: en local y en un clústerenlace

OpenEnvORSNeMo GymVerifiersSkyRL GymGEM
Necesita Dockeren producciónen producciónen producciónnonono
Instalaciónpip install openenv-core fastmcppip install ors-sdkpip install nemo_gym (desde git, trae Ray)pip install verifierspip install skyrl-gympip install gem-llm
Dependencias pesadasFastMCP, FastAPI, GradioFastAPI, uvicornRay, OmegaConf, aiohttppocaspocaspocas
Python≥3.11≥3.10≥3.12≥3.11≥3.10≥3.10
Riesgo de conflictosbajobajoalto (Ray fija muchas versiones)bajobajobajo

En un clúster con Slurm la pregunta es quién vive dónde. Los de HTTP ponen el entorno en su propio nodo, a menudo solo con CPU, y apuntan ahí cualquier número de nodos de entrenamiento con GPU, con un balanceador delante de un grupo de réplicas que puede crecer. Los de dentro del proceso ponen entrenador y entorno en el mismo entorno de Python y el mismo nodo de GPU: más fácil de operar, pero escalar el entorno es lo que permita tu framework de entrenamiento.

Frameworks HTTPFrameworks en el proceso
Despliegue del entornoEn HF Spaces o en otro nodo; el entrenamiento solo necesita requestsPaquete instalado en el entorno de entrenamiento
GPUEl servidor no usa GPUComparte el nodo de GPU con el entrenamiento
Aislamiento de dependenciasLimpio: Docker o entorno propioTiene que convivir con TRL, vLLM, DeepSpeed…
Varios nodosServidor en uno, entrenamiento en otrosUn solo nodo

Dimensión 10: escalarenlace

El RL genera varios intentos por prompt, a ser posible en paralelo, así que hay que hablar con muchos entornos a la vez. En GRPO son num_generations (normalmente entre 4 y 16) por prompt: con 64 prompts y num_generations=8, tienes 512 entornos vivos a la vez en cada paso.

Dentro del proceso

Verifiers, SkyRL Gym y GEM crean objetos de Python: arrancar uno cuesta menos de un milisegundo, así que 512, o 10.000, no son problema, y el paralelismo lo pone el framework de entrenamiento (cada trabajador con su instancia). El límite real es de orquestación, no de arquitectura: si el entorno hace su propio cómputo (parseo pesado, simulación), comparte CPU con el entrenamiento y escalarlo es escalar nodos de entrenamiento, pagando GPU para trabajo de CPU; si delega en un sandbox o un servicio remoto (E2B, Modal, un backend HTTP propio), la clase es un cliente fino y el entorno escala aparte, pero la orquestación es tuya: elegir proveedor, réplicas, recuperación de fallos, reparto de carga. Los frameworks HTTP lo traen hecho; los de dentro del proceso te lo dejan a ti. Y hay dos cosas que no cambian: las dependencias del entorno tienen que convivir con las del entrenamiento (un framework que fije otra versión de numpy o de torch puede romperlo), y un fallo en código de entorno puro dentro del proceso puede tumbar al trabajador de entrenamiento, mientras que la ejecución en un sandbox aísla los fallos sola.

Con servidor: el benchmark

El benchmark openenv-scaling desplegó un entorno como app de FastAPI dentro de un contenedor Docker (la misma imagen que usa HF Spaces) en cinco infraestructuras. OpenEnv, ORS y NeMo Gym siguen esa misma forma (una app con estado por sesión en un contenedor), así que las cifras valen para los tres. Máximo de entornos a la vez con al menos un 95 % de éxito:

InfraestructuraNúcleosMáximo a la vezPor núcleo
Slurm con 2 nodos + balanceador Envoy9616.384170,7
uvicorn en local (8 trabajadores)82.048256
Docker en local (misma imagen que HF Spaces)82.048256
Slurm con un nodo (48 trabajadores)4851210,7
Hugging Face Spaces (gratis, cpu-basic)212864
Sesiones a la vez por infraestructura: 128 en un Space gratuito, 2.048 en un portátil con o sin Docker y 16.384 con dos nodos y Envoy.
Del Space gratuito a dieciséis mil sesiones.

¿Y dónde se va el tiempo con la carga al máximo? La mediana de cada fase (conectar, reiniciar y dar un paso, con una espera simulada de 1 s en la herramienta) y el percentil 99 del total:

InfraestructuraConectarReiniciarPasop99 total
uvicorn en local0,58 s0,08 s1,05 s1,95 s
Docker en local1,38 s0,19 s1,05 s2,90 s
HF Spaces0,79 s0,10 s1,10 s2,48 s
Slurm, un nodo0,26 s0,04 s1,00 s1,33 s
Slurm, dos nodos (16.384 sesiones)17,50 s2,25 s2,42 s26,30 s
Barras apiladas con conectar, reiniciar y paso por infraestructura: el paso domina salvo con 16.384 sesiones, donde conectar sube a 17,5 s.
El paso, donde corre la herramienta, se lleva casi todo el tiempo.

El p99 de los dos nodos refleja las colas de conexión de 16.384 sesiones a través del proxy Envoy, aunque su rendimiento absoluto (518 peticiones por segundo) es el más alto de todos. Las cinco lecciones:

  1. Docker no añade nada apreciable: Docker y uvicorn en local llegan a las mismas 2.048.
  2. La configuración del balanceador importa: antes de arreglar Envoy, los dos nodos solo llegaban a 128; después, a 16.384, 128 veces más.
  3. HF Spaces se queda en unas 128 sesiones: suficiente para desarrollar y hacer demos, y cómodo porque es el mayor catálogo de entornos hechos.
  4. El servidor rara vez es el cuello de botella: hasta un portátil aguanta 2.048 sesiones. La ejecución (crear el sandbox, correr la herramienta) domina la latencia de cada paso, sea cual sea el framework.
  5. Escalar en horizontal es un problema de configurar el balanceador, no de protocolo: el salto de 128 a 16.384 salió de ajustar Envoy, no de cambiar el formato. Las sesiones fijas que impone WebSocket lo complican; para miles de entornos, peticiones sin estado con un identificador de sesión dan menos sustos.
Un peaje que abre todas sus cabinas: ×128 al ajustar el balanceador; lo que cambió fue la configuración, no el protocolo.
Más de cien veces más, cambiando solo la configuración.
OpenEnvORSNeMo GymVerifiersSkyRL GymGEM
Modelo de escaladoservidor WS multisesiónservidor SSE/HTTP multisesiónservidor multisesión + Rayinstancia por trabajadorinstancia por trabajadorinstancia por trabajador
Escalado horizontalEnvoy + más nodosEnvoy + más nodosautoescalado de Raymás trabajadores de GPUmás trabajadores de GPUAsyncVectorEnv
Aislamiento del estadodiccionario por sesiónpor sesión (X-Session-ID)por sesión (cookies)por instanciapor instanciapor instancia

La tabla globalenlace

Si juntas las diez dimensiones en una sola tabla, salen tres cosas:

  • Ninguno gana en todas las filas. Cada uno gana una columna o dos y pierde en otras. La elección se reduce a las dos o tres dimensiones que de verdad te importan: normalmente la forma del despliegue, quién lleva el bucle y lo estricta que es la especificación de las tareas.
  • La división más fuerte sigue siendo el despliegue. Servidor HTTP (OpenEnv, ORS, NeMo Gym) o dentro del proceso (Verifiers, SkyRL Gym, GEM) atraviesa casi todas las filas. Decide eso primero y la tabla se estrecha enseguida.
  • Las herramientas alrededor están desiguales. Generadores de esqueleto, registros de datasets y observabilidad son fuertes en unos y no existen en otros, aunque la API se parezca. Conviene mirarlo antes de comprometerse.

Los seis, uno a unoenlace

OpenEnv (Meta PyTorch)

Un contrato basado en MCP: protocolo, capa de sesiones y transporte (WebSocket) y un sistema de recompensas componible (LLMJudge, WeightedSum, rúbricas de trayectoria). Tareas, datasets y ejecución, tuyos. Para interfaces de entorno finas e intercambiables que tengan que seguir siendo compatibles con MCP.

ORS (General Reasoning)

Una API estándar para herramientas, tareas y recompensas: decoradores @tool, respuestas ToolOutput con la recompensa de cada paso y tareas en el servidor con list_tasks(split). openreward.ai aloja más de 330 entornos sobre la especificación. Para enchufarse a un catálogo grande de entornos hechos.

NeMo Gym (NVIDIA)

Servidores de herramientas con FastAPI y un endpoint /verify aparte para puntuar al final, con más de 50 entornos incluidos y muy integrado con NeMo y Megatron. Para puntuar trayectorias completas y para equipos que ya usan la pila de NVIDIA.

Verifiers (PrimeIntellect)

El que más trae: datasets, herramientas, rúbricas, arnés de recolección, entrenador y el comando prime env init. Su Environments Hub reparte entornos como wheels. Para pasar de cero a entrenar rápido con todo incluido.

SkyRL Gym (NovaSky · Berkeley)

Una API al estilo de Gym con BaseTextEnv y ToolGroup, pocas dependencias, y la misma biblioteca con la que se entrenó SkyRL-Agent para SWE-Bench. Para controlar todo el bucle con el modelo mental de Gym.

GEM (Axon-RL)

El más fiel a Gymnasium: reset() devuelve una observación, step() la tupla de cinco (obs, reward, terminated, truncated, info) y AsyncVectorEnv vectoriza. Trae más de 24 entornos de juegos, matemáticas y código. Para llevar el modelo mental de Gymnasium y Atari a agentes de texto.

Lo que más les llamó la atención, y cuál elegirenlace

  • Dónde acaba el entorno es una decisión de diseño, no un estándar. Unos (OpenEnv, SkyRL Gym) te dan una interfaz fina de herramientas y te dejan dataset, recompensa y entrenador; otros (Verifiers, GEM) lo juntan todo. Ninguno se equivoca: es control frente a tiempo hasta tenerlo funcionando.
  • HTTP o dentro del proceso es la bifurcación más fuerte. Lo que se ejecuta en un sandbox (código, terminal, navegador) pide HTTP, para escalar el cómputo del entorno aparte del entrenamiento. Lo puramente Python (juegos, matemáticas, razonamiento de texto) pide quedarse en el proceso: sin coste de red y sin infraestructura que vigilar.
  • Acoplar el dataset corta en las dos direcciones. Juntos (Verifiers, ORS), entorno y dataset vienen como una unidad y no cambias uno sin el otro. Separados (OpenEnv, SkyRL Gym), conectas tú los datos, pero cualquier tarea encaja en cualquier entorno.
  • Cuándo llega la recompensa importa más que lo que lleva dentro. Puntuar en cada llamada es limpio para dar señal paso a paso e incómodo cuando la nota solo tiene sentido al final; verificar al final es limpio para la trayectoria completa, pero no da señal durante el episodio.
  • La ejecución domina la latencia de cada paso, sea cual sea el framework.

Y si solo quieres una recomendación, su árbol de decisión tiene cuatro preguntas de sí o no:

  1. ¿Dónde corre el entorno? En su propio servidor (OpenEnv, ORS, NeMo Gym) o dentro del entrenador (Verifiers, SkyRL Gym, GEM).
  2. ¿Quieres un entrenador incluido? Sí (NeMo RL, Prime RL o SkyRL) o no, porque conectas el tuyo (TRL o propio).
  3. ¿Necesitas un catálogo grande de entornos hechos?
  4. ¿Te hace falta una API estricta al estilo de Gymnasium? La tupla de cinco de step(), compatible con código de RL clásico.

Por ejemplo: con servidor propio y tu entrenador quedan OpenEnv y ORS; con servidor y entrenador incluido, NeMo Gym; y si necesitas Gymnasium estricto, solo GEM.

El árbol de cuatro preguntas con el ejemplo de un servidor propio y tu entrenador: quedan dos frameworks, OpenEnv y ORS.
Cuatro preguntas para elegir.

Lo que les dio guerraenlace

FrameworkProblema
OpenEnvEl protocolo MCP aún evoluciona: los cambios de API entre versiones pueden obligar a actualizar adaptadores.
ORSEl manejo de base_url con aiohttp en el cliente del SDK obliga a usar HTTP a pelo.
NeMo GymExige Python 3.12, y la validación estricta de Pydantic en /verify devuelve 422 con trayectorias de forma inesperada.
VerifiersEl dataset es obligatorio al crear el entorno: entorno y dataset van acoplados.
SkyRL Gymstep() devuelve un diccionario, no una dataclass: hay que lidiar con esa inconsistencia de tipos.
GEMgem-llm puede no estar instalado: hacen falta imports condicionales.

Es una foto de mayo de 2026. Los seis salieron en 2025 y cambian deprisa: seis frameworks haciendo lo mismo con API distintas es lo normal en una etapa de exploración temprana. Los autores esperan que el año que viene todo converja en menos protocolos (MCP, ORS).

Dos detalles que no cuadranenlace

Comparando las figuras interactivas del artículo entre sí, hay dos cosas que no casan del todo:

  • GEM y el entrenador. El mapa de niveles coloca a GEM en el nivel 3 (entorno y entrenamiento juntos), pero el texto dice que GEM «trae entornos hechos y la API de Gymnasium, pero el entrenador lo pones tú», y la tabla de qué trae cada uno le da el entrenamiento como parcial («varios entrenadores»).
  • NeMo Gym y el entrenamiento. En el diagrama de las cinco etapas, NeMo Gym llega hasta la recolección, sin entrenador; en la tabla de qué trae, en cambio, tiene entrenamiento nativo (Megatron / NeMo RL), y el árbol de decisión también lo cuenta entre los que traen entrenador.

Nada de esto cambia las conclusiones, pero conviene saberlo si eliges por esa casilla.

En resumenenlace

Un entorno de RL para un LLM son tareas, herramientas, una recompensa y un bucle, repartidos en once piezas que los seis frameworks cubren de forma distinta. La decisión que ordena todo es si el entorno vive en su propio servidor o dentro del entrenamiento; después vienen cuándo llega la recompensa, quién lleva el bucle y lo estricto que es el formato de las tareas. Y al escalar, el servidor casi nunca es el cuello de botella: lo es el sandbox, y el balanceador bien configurado.

En una frase

Los seis frameworks son lo mismo con distinta ropa: el mismo entorno se lleva de uno a otro, así que elige el que encaje con lo que ya usas.

¿Qué entorno te gustaría entrenar tú?

Fuentesenlace

Seguir leyendo

Últimos posts -->

¿Has visto estos proyectos?

Gymnasia

Gymnasia Gymnasia
Expo
React Native
TypeScript
OpenAI
Anthropic

App de fitness con dos agentes que se ejecutan íntegramente en el dispositivo, sin backend, de forma que los datos del usuario nunca salen del móvil. Un coach conversacional BYOK con tools locales y system prompt remoto con fallback offline, y un estimador de comidas que saca los macronutrientes de una foto del plato, con lectura de códigos de barras contra OpenFoodFacts.

LangGraph Deep Researcher

LangGraph Deep Researcher LangGraph Deep Researcher
Python
LangGraph
FastAPI
React
TypeScript
Docker

Sistema multiagente de investigación construido con LangGraph. Un supervisor descompone tu pregunta en temas y lanza subagentes de búsqueda en paralelo; cada uno comprime sus hallazgos antes de pasarlos a un agente redactor que escribe el informe final en markdown con sus fuentes. Streaming en vivo por WebSockets, modelo configurable por rol y claves de API propias que nunca se guardan en el servidor.

Tau

Tau Tau
Python
LangChain

Sistema multiagente de tutoría para estudiantes de secundaria, con un agente por asignatura y material de curso elaborado y validado por un equipo de profesores. Llegó a usarse con alumnos reales en un colegio privado en España y en un instituto en Colombia.

Ver todos los proyectos -->
>_ Disponible para proyectos

¿Tienes un proyecto con IA?

Hablemos.

maximofn@gmail.com

Especialista en Machine Learning e Inteligencia Artificial. Desarrollo soluciones con IA generativa, agentes inteligentes y modelos personalizados.

¿Quieres ver alguna charla?

Últimas charlas -->

¿Quieres mejorar con estos tips?

Últimos tips -->

Usa esto en local

Los espacios de Hugging Face nos permite ejecutar modelos con demos muy sencillas, pero ¿qué pasa si la demo se rompe? O si el usuario la elimina? Por ello he creado contenedores docker con algunos espacios interesantes, para poder usarlos de manera local, pase lo que pase. De hecho, es posible que si pinchas en alún botón de ver proyecto te lleve a un espacio que no funciona.

Flow edit

Flow edit Flow edit

Edita imágenes con este modelo de Flow. Basándose en SD3 o FLUX puedes editar cualquier imagen y generar nuevas

FLUX.1-RealismLora

FLUX.1-RealismLora FLUX.1-RealismLora
Ver todos los contenedores -->
>_ Disponible para proyectos

¿Tienes un proyecto con IA?

Hablemos.

maximofn@gmail.com

Especialista en Machine Learning e Inteligencia Artificial. Desarrollo soluciones con IA generativa, agentes inteligentes y modelos personalizados.

¿Quieres entrenar tu modelo con estos datasets?

short-jokes-dataset

HuggingFace

Dataset de chistes en inglés

Uso: Fine-tuning de modelos de generación de texto humorístico

231K filas 2 columnas 45 MB
Ver en HuggingFace →

opus100

HuggingFace

Dataset con traducciones de inglés a español

Uso: Entrenamiento de modelos de traducción inglés-español

1M filas 2 columnas 210 MB
Ver en HuggingFace →

netflix_titles

HuggingFace

Dataset con películas y series de Netflix

Uso: Análisis de catálogo de Netflix y sistemas de recomendación

8.8K filas 12 columnas 3.5 MB
Ver en HuggingFace →
Ver más datasets -->