Enterprise RAG Challenge 3: lecciones de las candidaturas públicas

Traducción automática

Este artículo se tradujo automáticamente a partir de la versión original en inglés.

Enterprise RAG Challenge 3 (ERC3) pidió a agentes completar tareas empresariales contra la API de una empresa simulada. La clasificación congelada de los premios es especialmente útil porque muchos participantes publicaron algo más que una puntuación: arquitectura, combinación de modelos, coste y notas sobre los fallos.

He revisado esas descripciones públicas para responder a una pregunta más concreta: ¿qué decisiones de diseño se repetían en las candidaturas más sólidas y cuáles sirven fuera de este benchmark?

Este artículo es para ingenieros que construyen agentes que llaman a APIs empresariales. Verás cinco diseños tomados de las descripciones públicas, los problemas que resolvió cada uno (permisos, paginación, enlaces ausentes, tamaño del contexto) y un orden para probarlos en tu propio agente.

¿Qué es Enterprise RAG Challenge?

Enterprise RAG Challenge 3 es un proyecto de investigación colaborativo y a gran escala que pone a prueba cómo gestionan los agentes autónomos tareas empresariales complejas. A diferencia de los benchmarks estáticos, ERC3 se ejecuta sobre la Agentic Enterprise Simulation (AGES), una simulación de eventos discretos que expone una API empresarial realista.

Qué evalúa el benchmark

A través de AGES, los agentes trabajan dentro de una empresa ficticia que cuenta con:

  • Perfiles de empleados con habilidades y departamentos concretos
  • Proyectos con asignaciones de equipo y relaciones con clientes
  • Wiki corporativa con reglas de negocio y jerarquías de permisos
  • Registro de tiempo y operaciones financieras

Cada tarea inicia una simulación aislada. La wiki de la empresa es común, pero los registros operativos varían de una tarea a otra, así que un agente no puede resolver el conjunto memorizando el estado de una sola empresa.

Interpreta las puntuaciones como una instantánea

ERC3 ofrece ahora una clasificación de competición congelada y un benchmark público que siguió recibiendo ejecuciones después del evento. Esas páginas responden a preguntas distintas. Las cifras siguientes describen la clasificación de premios en el corte de la competición, no las mejores sesiones posteriores:

MétricaInstantánea de la competición
Candidaturas al premio38
Conjunto de tareas103 tareas empresariales
Mayor puntuación del premio0,718
Corte del premio9 de diciembre de 2025, 13:40 CET

La página del benchmark en vivo puede mostrar puntuaciones más altas porque incluye ejecuciones posteriores. Por eso la clasificación congelada es la fuente adecuada para afirmar qué ganó la competición. La clasificación Ultimate toma la mejor ejecución de cada cuenta sin el corte de la competición, de modo que sus puntuaciones no son comparables con las del premio.

Tipos de tareas

Las tareas abarcan varias áreas de habilidad:

  • Razonamiento multisalto, como emparejar las habilidades de los empleados con las asignaciones de proyectos.
  • Validación de permisos, como bloquear cambios salariales o accesos a datos no autorizados.
  • Consultas ambiguas, incluidas peticiones multilingües y parafraseadas.
  • Cumplimiento estricto del formato de salida, incluidos los enlaces obligatorios a entidades en las respuestas.

Qué sugieren las candidaturas

Las descripciones públicas no respaldan un veredicto simple como “multi-agent supera a un solo agente”. La candidatura de MMzXeM, cuarta en la clasificación de premios, era un único agente con herramientas asignadas 1:1 a los endpoints de la API, una herramienta ask_wiki y un system prompt de 320 tokens. Las descripciones sí respaldan cuatro observaciones más acotadas:

  1. Los equipos separaban un componente cuando este se encargaba de un requisito que los agentes incumplían una y otra vez: una comprobación de permisos, la validación de pasos, la ejecución de código o los enlaces a entidades. No dividían por “roles de agente” arbitrarios.
  2. La validación se acercó a las acciones irreversibles. Varios sistemas comprobaban los permisos antes de ejecutar, revisaban pasos individuales o protegían la respuesta final.
  3. Las trazas fallidas guiaron los cambios. El ganador del premio convirtió las ejecuciones fallidas en revisiones del prompt mediante un bucle automatizado; otros equipos documentaron correcciones igual de concretas en herramientas y prompts.
  4. La política de contexto fue una decisión de arquitectura. Los equipos probaron la destilación, la precarga, la recuperación y la compresión del historial. Sus propios informes no coinciden en si la compresión ayudó, así que no hay una receta universal.

Cinco enfoques informativos

No son los cinco primeros por orden de clasificación. Los elegí porque sus descripciones públicas muestran cinco formas distintas de construir el sistema: revisión automática del prompt, etapas especializadas, validación por paso, guards de la respuesta y aislamiento entre planificación y ejecución.

EquipoContexto de la clasificaciónPuntuación publicada
VZS9FLPremio, 1.º0,718
LcnxuyPremio, 8.º0,505
NLN7DwPremio, 2.º0,621
J8GvbiPremio, 16.º0,437
5qsp7i (key_concept_parallel)Ultimate, 3.º0,670

1. Prompt engineering evolutivo (equipo VZS9FL / @aostrikov)

El enfoque con la puntuación más alta automatizó el prompt engineering mediante un bucle de automejora.

Versiones del prompt de v1 a v80 y una vuelta del bucle: el agente principal registra las tareas fallidas, el analizador propone causas y el versionador conserva algunas y escribe la versión siguienteVersiones del prompt de v1 a v80 y una vuelta del bucle: el agente principal registra las tareas fallidas, el analizador propone causas y el versionador conserva algunas y escribe la versión siguiente

En lugar de ajustar a mano el prompt de producción, el equipo montó un bucle de tres agentes que convertía las trazas fallidas en revisiones candidatas.

Pipeline de tres agentes:

AgenteFunción
Main AgentEjecuta el benchmark y registra todas las acciones y los fallos
Analyzer AgentRevisa las tareas fallidas y formula hipótesis sobre las causas de fondo
Versioner AgentGenera una nueva versión del prompt que incorpora lo aprendido

El prompt de producción fue la versión número 80 generada automáticamente. El equipo describe el bucle como el análisis de las tareas fallidas, la propuesta de causas y la decisión de qué sugerencias incorporar. La clasificación establece la puntuación final y el número de iteraciones. No aísla cuánta de la mejora se debió a la automatización y cuánta a los modelos, las herramientas o el feedback acumulado del benchmark.

Stack: claude-opus-4.5 con el SDK de Anthropic para Python y tool use nativo.


2. Pipeline secuencial multi-agent (equipo Lcnxuy / @andrey_aiweapps)

Esta candidatura construyó un flujo secuencial en el que componentes especializados se encargaban de las comprobaciones de seguridad, la extracción de contexto, la ejecución y el formato de los enlaces a entidades.

Cuatro etapas, desde la puerta de seguridad hasta la herramienta de respuesta, las cinco fases de ejecución y dos respuestas: una sin sus enlaces y otra con los enlaces construidos dentro de la herramienta de respuestaCuatro etapas, desde la puerta de seguridad hasta la herramienta de respuesta, las cinco fases de ejecución y dos respuestas: una sin sus enlaces y otra con los enlaces construidos dentro de la herramienta de respuesta

Los componentes documentados:

  1. Security Gate Agent: comprobación previa a la ejecución que valida los permisos contra las reglas de la wiki antes de que arranque el bucle principal.
  2. Context Extraction Agent: extrae las reglas críticas de system prompts de más de 500 líneas y precarga los datos de usuario, proyecto y cliente.
  3. Execution Agent: planificación al estilo ReAct con 5 fases internas (identidad → detección de amenazas → recopilación de información → validación de acceso → ejecución).
  4. LinkGeneratorAgent: integrado en la herramienta de respuesta, analiza el contexto para incluir los enlaces a entidades requeridos.

La descripción del equipo dice que el LinkGeneratorAgent estaba para evitar los fallos por enlaces ausentes: respuestas con el texto correcto pero sin los enlaces a entidades requeridos. Es la parte más transferible. Al integrarlo en la herramienta de respuesta, un requisito del benchmark (los enlaces obligatorios a entidades) pasa a ser una propiedad de la interfaz y deja de ser una instrucción más que el modelo de ejecución puede olvidar.

Stack: los frameworks atomic-agents e instructor con gpt-5.1-codex-max, gpt-4.1 y claude-sonnet-4.5.


3. Razonamiento guiado por esquema con validación de pasos (equipo NLN7Dw / Ilia Ris)

El razonamiento guiado por esquema (SGR) hace que el modelo rellene en cada paso un esquema de salida fijo, por ejemplo su razonamiento, un plan y la siguiente tool call, de modo que el programa pueda leer y comprobar cada campo. El artículo sobre SGR de este blog muestra cómo imponer un esquema así con vLLM. Este equipo combinó SGR con inferencia rápida y un validador en cada paso propuesto. El diseño abarata la revisión: rechaza un paso defectuoso antes de que se convierta en tool call y pide al flujo principal que lo rehaga con los comentarios del validador.

El modelo lee el plan, los registros y el historial comprimido, escribe un paso como esquema y el StepValidator devuelve un paso defectuoso antes de cualquier tool callEl modelo lee el plan, los registros y el historial comprimido, escribe un paso como esquema y el StepValidator devuelve un paso defectuoso antes de cualquier tool call

Componentes clave:

ComponenteFunción
StepValidatorInspecciona cada paso propuesto. Si algo falla, lo devuelve para que se rehaga, con comentarios.
Gestión del contextoPlan completo del turno anterior, más historial comprimido de los turnos más antiguos
Enriquecimiento dinámicoObtiene automáticamente perfil de usuario, proyectos y clientes; un LLM filtra para inyectar solo los datos relevantes para la tarea
Wrappers de paginación automáticaTodos los endpoints de listado devuelven resultados completos automáticamente

El equipo comunicó que ejecutaba gpt-oss-120b en Cerebras a hasta unos 3000 tokens por segundo. Combinó la validación con inferencia de alto rendimiento, lo que pudo reducir su coste en latencia. El resultado público no aísla ese efecto.

Stack: un agente NextStep modificado, el agente de ejemplo de SGR publicado para ERC3.


4. Sistema de enricher y guard (equipo J8Gvbi / @mishka)

Esta candidatura añadió a una base SGR pistas no bloqueantes y un sistema de guards por niveles. Cuando llegaban las respuestas de la API, los enrichers las inspeccionaban y añadían orientación operativa al contexto posterior. Los guards comprobaban la respuesta del agente antes de enviarla.

Dos enrichers convierten las respuestas de la API en pistas y luego tres modos de guard: el bloqueo duro rechaza, el bloqueo suave acepta una respuesta repetida y la pista suave acepta con orientaciónDos enrichers convierten las respuestas de la API en pistas y luego tres modos de guard: el bloqueo duro rechaza, el bloqueo suave acepta una respuesta repetida y la pista suave acepta con orientación

Más de 20 enrichers inspeccionaban las respuestas de la API e inyectaban pistas contextuales:

RoleEnricher: "You are LEAD of this project, proceed with update."
PaginationHintEnricher: "next_offset=5 means MORE results! MUST paginate."

Sistema de guards de tres modos:

ModoComportamiento
Hard blockSe rechaza una respuesta que los datos de la API muestran como imposible, por ejemplo una que nombra a un empleado ajeno al equipo del proyecto
Soft blockUna respuesta arriesgada se rechaza una vez con una advertencia y se acepta si el agente la vuelve a enviar tras esa advertencia
Soft hintSe añade orientación sin bloquear

Wiki con RAG híbrido: el equipo buscaba en una copia local de la wiki de la empresa de tres maneras: regex para patrones estructurados como salary|privacy, embeddings de sentence-transformer para coincidencias semánticas y solapamiento de tokens como alternativa por palabras clave. Mi lectura de por qué tres: la regex encuentra nombres de campo y términos exactos, y los embeddings encuentran reglas redactadas de otra forma que la pregunta.

Stack: qwen/qwen3-235b-a22b-2507 sobre el framework SGR de LangChain.


5. REPL de planificación y ejecución (equipo 5qsp7i / key_concept_parallel)

Esta arquitectura mantenía la planificación y la escritura de código en llamadas al modelo separadas. El Python generado se ejecuta en un REPL (read-eval-print loop): una sesión de Python que conserva sus variables entre pasos. Apareció en la clasificación Ultimate, más amplia, no entre los cinco primeros del premio congelado. Su descripción pública sigue siendo útil porque muestra otra forma de descomposición: aislamiento por fase de ejecución en lugar de por rol de negocio.

Planificador, modelo de código, REPL y modelo de decisión con sus resultados, y una traza de cuatro pasos en la que un nuevo plan reescribe los pasos 3 y 4 pero conserva las variables s1 y s2 del REPLPlanificador, modelo de código, REPL y modelo de decisión con sus resultados, y una traza de cuatro pasos en la que un nuevo plan reescribe los pasos 3 y 4 pero conserva las variables s1 y s2 del REPL

Distintos modelos se encargaban de distintas tareas: uno planificaba, otro escribía Python y un modelo de decisión aparte elegía qué hacer después de cada paso.

Configuración con varios modelos:

EtapaModelo
Planificaciónopenai/gpt-5.1
Generación de códigodeepseek/deepseek-v3.2
Decisión tras el pasoopenai/gpt-4.1
Respuesta finalopenai/gpt-4.1

El REPL de finalización de pasos:

  1. El planificador crea un paso de alto nivel.
  2. El modelo de generación de código trabaja con un contexto de modelo nuevo y escribe un script de Python para ese paso.
  3. El script se ejecuta en un REPL acotado a la tarea, cuyas variables persisten entre pasos.
  4. El modelo de decisión examina el resultado y elige uno de cuatro desenlaces: continuar con el siguiente paso, terminar porque la tarea está hecha, abortar porque ha fallado o replanificar.

La ruta de replanificación es la idea reutilizable. Cuando el resultado de un paso muestra que el plan ya no encaja, el modelo de decisión puede conservar el trabajo completado y reescribir solo los pasos restantes del plan. En el diagrama, hecho y fallido comparten una única salida hacia la respuesta final.


Patrones que se repetían en las candidaturas

Las implementaciones diferían, pero varias preocupaciones de ingeniería aparecían una y otra vez en las descripciones públicas.

La gestión del contexto era explícita

Ningún equipo pudo darle al modelo todas las reglas, registros y pasos anteriores sin tomar una decisión de política. Los sistemas diferían en dónde filtraban la información: antes de la ejecución, en la recuperación o en el historial. El diagrama divide el contexto del modelo en cuatro partes y muestra qué política controla cada una, cuándo se ejecuta y qué equipos la usaron.

El contexto dividido en reglas del wiki, registros, resultados de búsqueda e historial de turnos, cada uno con su política, cuándo se ejecuta y los equipos que la usaronEl contexto dividido en reglas del wiki, registros, resultados de búsqueda e historial de turnos, cada uno con su política, cuándo se ejecuta y los equipos que la usaron

EstrategiaEnfoqueIdeal para
Destilación de reglasPreprocesar las reglas de la wiki en instrucciones compactas conservando las restriccionesPrompts ligeros, arranque rápido
Precarga intensivaCargar los datos de usuario, proyecto y cliente antes de la ejecuciónMinimizar las tool calls
RAG híbridoFlujos de búsqueda por regex, semántica y palabras claveNecesidades de recuperación complejas
Compresión del historialMantener completos los turnos recientes y comprimir el historial antiguoConversaciones largas

Compromiso: NLN7Dw comprimió los turnos antiguos, mientras que f1Uixf comunicó que la compresión del historial perjudicó sus experimentos y mantuvo la conversación completa. Trata la compresión como una decisión que se mide, no como un valor por defecto. Las candidaturas sólidas también diferían en el tamaño del prompt. Kc7F2N (3.º del premio) mantuvo mínimas sus propias instrucciones, se apoyó en reglas de la wiki destiladas y construyó sus herramientas de búsqueda sobre embeddings. MMzXeM (4.º del premio) limitó el prompt principal a 320 tokens y puso toda la wiki tras su herramienta ask_wiki, que dependía del context caching para resultar barata.


Comprobaciones antes, durante y después del bucle principal

Varios equipos situaron comprobaciones antes, durante o después del bucle principal. Estas comprobaciones necesitan datos distintos en cada fase. Una implementación compartida puede realizarlas si recibe las entradas adecuadas en cada fase. Un crítico que solo se invoca para la respuesta final no puede impedir un tool call no autorizado anterior. El diagrama sitúa cada comprobación en una línea temporal desde la tarea hasta el evaluador y muestra qué ve y qué fallo evita.

Una línea temporal desde la tarea hasta el evaluador, con la puerta de seguridad antes del bucle, una comprobación de paso dentro y el guard de tres modos después, cada uno con lo que ve y lo que evitaUna línea temporal desde la tarea hasta el evaluador, con la puerta de seguridad antes del bucle, una comprobación de paso dentro y el guard de tres modos después, cada uno con lo que ve y lo que evita

Tipo de guardrailCuándoEjemplo
Comprobaciones previas a la ejecuciónAntes de que arranque el bucle principalSecurity Gate Agent valida los permisos contra las reglas de la wiki
Validadores dentro del bucleDurante el razonamientoStepValidator comprueba cada acción propuesta y provoca una revisión si es defectuosa
Guards posteriores a la ejecuciónAntes del envío finalEl Three-Mode Guard System comprueba la respuesta del agente contra los datos de la API y la política

Tool wrappers

Varios equipos cambiaron la capa de herramientas que ve el modelo en lugar de añadir instrucciones sobre la API en bruto:

  • Auto-paginación: NLN7Dw eliminó la paginación de todas las herramientas. Una función recorre todas las páginas y devuelve la lista completa.
  • Normalización difusa: los parsers de herramientas de J8Gvbi traducen el lenguaje humano a nombres de la API, de modo que “Willingness to travel” se convierte en el campo will_travel.
  • Limpieza de esquemas: f1Uixf eliminó los campos sin usar de los tool schemas y amplió las descripciones de los parámetros. NLN7Dw reconstruyó Req_LogTimeEntry, la única herramienta del SDK cuyos campos llegaban en otro orden, porque ese orden confundía al modelo.
  • Herramientas de razonamiento: xoDvsa (7.º del premio, 0,515) añadió las herramientas plan, think y critic a un agente ReAct sencillo. La herramienta critic devuelve structured output con campos de razonamiento específicos.

Un wrapper oculta la paginación al modelo: el agente pide una lista una sola vez y list_all sigue next_offset hasta que vale -1, el valor de fin utilizado en el ejemplo oficial de ERC3. El código siguiente es un esquema del paso 1 del orden de adopción al final de este artículo, no el código de ningún equipo. respond construye los enlaces a entidades a partir de los IDs que el agente ha obtenido y rechaza cualquier ID que nunca haya visto, de modo que cada enlace procede del código y un ID inventado falla antes de llegar al evaluador.

# Stand-in for the benchmark API: 12 projects, 5 per page.
PROJECTS = [{"id": f"proj_{i}", "name": f"Project {i}"} for i in range(12)]

def call_api(endpoint: str, offset: int = 0, limit: int = 5) -> dict:
    page = PROJECTS[offset : offset + limit]
    more = offset + limit < len(PROJECTS)
    return {"items": page, "next_offset": offset + limit if more else -1}

def list_all(endpoint: str) -> list[dict]:
    """Follow next_offset until the API returns the terminal value -1."""
    items, offset = [], 0
    while offset != -1:
        page = call_api(endpoint, offset=offset)
        items.extend(page["items"])
        offset = page["next_offset"]
    return items

def respond(text: str, entity_ids: list[str], fetched: list[dict]) -> dict:
    """Build required links from IDs; refuse IDs the agent never fetched."""
    known = {row["id"] for row in fetched}
    unknown = [i for i in entity_ids if i not in known]
    if unknown:
        raise ValueError(f"unknown entity ids: {unknown}")
    return {"message": text, "links": [{"id": i} for i in entity_ids]}

projects = list_all("/projects/list")
assert len(projects) == 12  # three pages, one list
print(respond("You lead two projects.", ["proj_3", "proj_11"], projects))

El agente nunca ve un límite de página, y proj_11, de la tercera página, es un enlace válido.


Modos de fallo y correcciones estructurales que comunicaron los equipos

Las descripciones mencionan repetidamente fallos en los que el agente llama a la API o aplica una política de la empresa. Las correcciones más reutilizables trasladaron el requisito al código o a un paso de validación específico:

Modo de falloDescripciónCorrección de arquitectura
Omisión de permisosEjecutar acciones restringidas sin verificar los permisos del usuarioSecurity Gate Agent previo a la ejecución; secuencia obligatoria identidad → permisos → ejecución
Enlaces a entidades ausentesRespuesta de texto correcta pero sin los enlaces de referencia requeridosLinkGeneratorAgent integrado en la herramienta de respuesta
Paginación incompletaProcesar solo la primera página de los resultados de un listadoWrappers de auto-paginación para todos los endpoints de listado
Bucles de tool callsLlamadas repetidas con variaciones menoresLímites de turnos; tool schemas más claros; elección del modelo probada en el flujo real
Sobrecarga del contextoLlenar el contexto con secciones irrelevantes de la wikiDestilación de reglas; filtrado dinámico del contexto

Dos informes añaden detalle a la fila de los bucles. f1Uixf observó bucles de tool calling con GPT-5, pero no con el modelo Qwen3, más pequeño. NLN7Dw fijó un límite de turnos demasiado bajo y 5 de las 103 tareas no terminaron, así que un límite de turnos necesita margen.


Un orden práctico de adopción

ERC3 es una sola empresa simulada, no un estudio general de ablación de agentes. Úsalo como fuente de hipótesis de diseño y después pruébalas con tus propias trazas. Un orden de adopción razonable es:

  1. Haz primero determinista la corrección de la API. Auto-pagina los endpoints de listado, normaliza los campos difusos, valida los esquemas y genera los enlaces requeridos dentro de la herramienta de respuesta.
  2. Añade comprobaciones donde un error sale caro. Verifica la identidad y el permiso antes de modificar datos; valida un paso antes de ejecutarlo solo cuando la llamada extra al modelo detecte fallos que compensen su coste.
  3. Escribe una política de contexto. Decide qué se precarga, qué se recupera, qué se comprime y qué se conserva literal. Mide la política por segmento de tareas y no solo por número de tokens.
  4. Convierte las trazas fallidas en casos de regresión. Clasifica el fallo, cambia un solo mecanismo y vuelve a ejecutar el segmento afectado. Automatiza la revisión del prompt solo cuando ese bucle sea fiable.
  5. Descompón cuando la responsabilidad se vuelva más clara. Un componente separado se justifica cuando puede encargarse de una restricción, usar un modelo o una herramienta distintos, o probarse de forma independiente, no solo porque “multi-agent” suene más capaz.

La figura siguiente esboza qué aspecto tiene cada fallo en una traza y señala la corrección que probar primero. Los números coinciden con los pasos anteriores.

Siete fallos esbozados tal como se ven en una traza, cada uno con la corrección que probar primero y su número de pasoSiete fallos esbozados tal como se ven en una traza, cada uno con la corrección que probar primero y su número de paso

Referencias