{"schemaVersion":1,"id":"https://lucioduran.com/es/projects/rag-evaluation-workbench","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench","title":"RAG Evaluation Workbench","description":"Evaluación reproducible de RAG con BM25, recuperación densa e híbrida, inferencia local en CPU y métricas separadas de recuperación y respuesta.","language":"es","datePublished":"2026-10-21","dateModified":"2026-10-21","contentFormat":"text/markdown","content":"[Proyectos](<https://lucioduran.com/es/projects>) / RAG Evaluation Workbench\n\n# RAG Evaluation Workbench\n\nEvaluación reproducible de RAG con BM25, recuperación densa e híbrida, inferencia local en CPU y métricas separadas de recuperación y respuesta.\n\nAutor: [Lucio Durán](<https://lucioduran.com/es>) · Python 3.11.13 · Licencia: [MIT](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/LICENSE>)\n\nFicha publicada: 2026-10-21 · Ficha actualizada: 2026-10-21\n\n[Repositorio](<https://github.com/lucioduran/rag-evaluation-workbench>) · [Informe crudo de evaluación](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/report.json>)\n\n## Problema y utilidad para agentes\n\nRecuperar el documento correcto no garantiza una respuesta correcta. RAG Evaluation Workbench compara tres métodos de recuperación manteniendo fijos el modelo generador, el prompt, los presupuestos de contexto y la decodificación. Registra rankings, contexto incluido, respuestas y errores para evaluar cada etapa por separado.\n\nUn agente que recupera evidencia todavía puede confundir hechos o inventar una respuesta cuando debería abstenerse. Este proyecto permite inspeccionar esas fallas sin atribuir al retrieval un éxito que la respuesta final no tuvo.\n\n## Arquitectura\n\n1. **Corpus y partición.** 24 documentos ficticios originales con licencia MIT, 12 preguntas de desarrollo y 26 de evaluación. Desarrollo y evaluación usan grupos de documentos relevantes disjuntos; ambos consultan el mismo corpus. Dos preguntas de evaluación no tienen respuesta.\n2. **Recuperación comparable.** BM25, MiniLM con similitud coseno y fusión de rankings recíprocos con constante 60. Los tres recuperan hasta tres documentos. Cada documento es una unidad completa de recuperación; este experimento no compara estrategias de chunking ni rerankers.\n3. **Generación congelada.** FLAN-T5-small local en CPU, cuatro hilos, semilla 1729 y decodificación greedy. El presupuesto es de 256 tokens para embeddings, 384 tokens de entrada al generador y 32 de salida. Los documentos entran completos, en orden de ranking, hasta agotar el presupuesto. Las etiquetas y respuestas de referencia no entran en el prompt.\n4. **Evidencia y verificación.** Cada ejecución conserva hashes de entradas y modelos, revisiones, entorno, rankings, prompts, predicciones y tiempos. Un verificador con la biblioteca estándar reconstruye rankings y prompts y recalcula métricas e intervalos desde los datos guardados, sin volver a ejecutar los modelos.\n\n- [Metodología y límites de medición](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/methodology.md>)\n- [Configuración congelada](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/config/experiment.json>)\n\n## Qué demuestra\n\n- Diseño de una comparación controlada que separa calidad de recuperación, calidad de respuesta y abstención.\n- Implementación de Recall@3, NDCG@3, exact match y token F1, con bootstrap por grupos y diferencias pareadas entre métodos.\n- Trazabilidad de resultados hasta consultas, rankings, prompts y respuestas concretas, incluidos resultados desfavorables y límites del scoring.\n\n## Resultados publicados\n\nResultados publicados por el autor para la ejecución local en Intel Xeon W-3223 con Python 3.11.13 y cuatro hilos de CPU. Las métricas de recuperación usan 24 consultas con respuesta; exact match y token F1 usan las 26 consultas de evaluación, incluidas las dos sin respuesta.\n\nLos intervalos del 95% se calculan con 2.000 remuestreos bootstrap de grupos de origen. Las dos preguntas sobre un documento se mantienen juntas. Las diferencias entre métodos usan observaciones pareadas y el mismo remuestreo. Son 12 grupos con respuesta y dos grupos sin respuesta. Las tablas redondean los valores; los informes conservan su precisión.\n\n### Recuperación: 24 consultas con respuesta\n\nRecall@3 y NDCG@3 sobre 24 preguntas con respuesta, agrupadas en 12 fuentes. Las preguntas sin respuesta se excluyen de estas métricas. Los intervalos del 95% usan bootstrap por grupos.\n\n| Método | Recall@3 | Intervalo del 95% | NDCG@3 | Intervalo del 95% |\n| --- | --- | --- | --- | --- |\n| BM25 | 1.000 | \\[1.000, 1.000\\] | 0.969 | \\[0.923, 1.000\\] |\n| Densa | 1.000 | \\[1.000, 1.000\\] | 1.000 | \\[1.000, 1.000\\] |\n| Híbrida | 1.000 | \\[1.000, 1.000\\] | 1.000 | \\[1.000, 1.000\\] |\n\n### Respuestas: 26 consultas de evaluación\n\nExact match y token F1 sobre las 26 preguntas, en 14 grupos, incluidas las dos sin respuesta. Son métricas de coincidencia textual, no de factualidad. Los intervalos del 95% usan bootstrap por grupos.\n\n| Método | Exact match | Intervalo del 95% | Token F1 | Intervalo del 95% |\n| --- | --- | --- | --- | --- |\n| BM25 | 0.731 | \\[0.560, 0.885\\] | 0.756 | \\[0.583, 0.889\\] |\n| Densa | 0.769 | \\[0.600, 0.893\\] | 0.795 | \\[0.627, 0.926\\] |\n| Híbrida | 0.731 | \\[0.560, 0.885\\] | 0.767 | \\[0.605, 0.899\\] |\n\n### Diferencias pareadas en exact match\n\nDiferencias de exact match sobre las mismas 26 preguntas, con remuestreo pareado de 14 grupos. El intervalo de densa menos BM25 incluye cero; esta muestra no establece una mejora general.\n\n| Comparación | Diferencia media | Intervalo del 95% |\n| --- | --- | --- |\n| Densa menos BM25 | 0.038 | \\[0.000, 0.120\\] |\n| Híbrida menos BM25 | 0.000 | \\[0.000, 0.000\\] |\n\n### Latencia de solicitud y costo de API\n\nMilisegundos por solicitud en la ejecución publicada con Intel Xeon W-3223 y cuatro hilos. Una observación por consulta y método, 26 consultas por método. Carga de modelos, calentamiento e indexación quedan fuera. USD 0 corresponde solo a APIs pagas; electricidad y hardware no se midieron.\n\n| Método | P50 (ms) | P95 (ms) | API (USD) |\n| --- | --- | --- | --- |\n| BM25 | 93.7 | 133.4 | 0 |\n| Densa | 105.9 | 138.8 | 0 |\n| Híbrida | 105.9 | 144.4 | 0 |\n\nLos tres métodos alcanzan Recall@3 = 1 y conservan el contexto relevante en el prompt, pero ninguno responde correctamente todas las consultas. Dense obtiene un acierto exacto más que BM25: 20/26 frente a 19/26. Su diferencia pareada es 0,038 y el intervalo \\[0,000, 0,120\\] incluye cero. Este resultado no establece un ganador general.\n\nLos tres métodos fallan las dos preguntas de abstención: 0/2 por método. Entre las 78 respuestas hay 20 fallos de exact match: 14 con el contexto relevante presente y seis correspondientes a preguntas sin respuesta. [Análisis de errores](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/error-analysis.md>).\n\nAlgunos fallos son del scoring: «90 requests per minute» es una respuesta correcta excluida por los alias cortos fijados antes de evaluar. Otros son errores sustantivos, como confundir el código de acceso a una puerta con el código de registro de red. Los alias no se ampliaron después de ver las predicciones. [Errores por consulta](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/errors.json>).\n\nLa latencia de solicitud incluye recuperación, preparación del contexto y generación. Carga de modelos, calentamiento y construcción del índice se miden por separado. Hay una observación por consulta y método. Costo de API: USD 0; electricidad y hardware no están cuantificados. [Metodología y límites de medición](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/methodology.md>).\n\n## Reproducir\n\nLa verificación del informe usa únicamente la biblioteca estándar de Python. Reproducir la inferencia requiere instalar las dependencias y descargar explícitamente los dos modelos públicos. No requiere cuentas, APIs pagas ni GPU alquilada.\n\nCon Python 3.11.13, el primer bloque verifica la consistencia de la evidencia registrada. El segundo ejecuta los modelos y debe correrse desde el mismo repositorio. El lock corresponde al entorno medido, Intel macOS; otras plataformas pueden requerir paquetes PyTorch compatibles. Usá directorios de salida nuevos. La descarga requiere internet y varios cientos de MB; luego la inferencia se ejecuta offline. Una nueva ejecución registra su propio entorno, fecha y tiempos.\n\n### Verificar el informe guardado sin ejecutar modelos\n\n```\ngit clone https://github.com/lucioduran/rag-evaluation-workbench.git\ncd rag-evaluation-workbench\ngit checkout 60246831be5cf68768710e83d7b41614e49a8341\npython -m rag_workbench verify --report results/eval/report.json\n```\n\n### Repetir la inferencia local en el entorno de referencia\n\n```\npython -m venv .venv\n. .venv/bin/activate\npython -m pip install -r requirements-local.lock\npython -m rag_workbench download\nHF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 TOKENIZERS_PARALLELISM=false python -m rag_workbench run --split dev --output build/reproduced-dev\nHF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 TOKENIZERS_PARALLELISM=false python -m rag_workbench run --split eval --output build/reproduced-eval\npython -m rag_workbench verify --report build/reproduced-eval/report.json\n```\n\n## Alcance y límites\n\n- Corpus sintético pequeño y sencillo para retrieval. La partición está reservada contra el ajuste de parámetros, pero es conocida por el autor. No es una evaluación ciega externa ni demuestra generalización a producción.\n- Exact match y token F1 comparan formas de texto, no factualidad. Los alias congelados pueden penalizar paráfrasis válidas. El análisis manual no modifica las puntuaciones.\n- El modelo generador pequeño falla en abstención en esta muestra. Un recall perfecto no equivale a un sistema que responde correctamente.\n- Los intervalos provienen de pocos grupos. Un intervalo degenerado no prueba certeza fuera del corpus. Las latencias describen una ejecución local, no una prueba de carga ni un SLA.\n- La verificación offline comprueba consistencia interna. No autentica las mediciones, repite la inferencia neuronal ni recuenta tokens con el tokenizer. Los cambios de hardware o backend pueden alterar tiempos y predicciones.\n- La CLI procesa archivos locales confiables y carga entradas y resultados en memoria. No es un servicio de subida de archivos. Código, corpus y resultados usan MIT; los modelos descargados usan Apache-2.0 y no se redistribuyen en el repositorio.\n\n- [Artículo: arquitectura, recuperación y evaluación de pipelines RAG](<https://lucioduran.com/es/blog/rag-pipeline-architecture-chunking-reranking-evaluation>)\n\n## Fuentes y revisión\n\nLos valores de esta ficha provienen del informe enlazado. No son una medición en vivo. El informe conserva la revisión ejecutada; la revisión consultada incluye la publicación posterior de ese informe.\n\n- Revisión consultada: [` 60246831be5cf68768710e83d7b41614e49a8341 `](<https://github.com/lucioduran/rag-evaluation-workbench/commit/60246831be5cf68768710e83d7b41614e49a8341>)\n- Revisión registrada por el experimento: [` 1087f9b0b7985ce719204595c7a90b45e1e186b2 `](<https://github.com/lucioduran/rag-evaluation-workbench/commit/1087f9b0b7985ce719204595c7a90b45e1e186b2>)\n- Fecha del informe (UTC): 2026-10-21T21:08:41.652766+00:00\n- SHA-256 del corpus: ` ecf0e3d23dbee38f61aad545e67d7ad3e81195e39659a4619b7035babb5938e6 `\n\n- [README](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/README.md>)\n- [Metodología y límites de medición](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/methodology.md>)\n- [Configuración congelada](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/config/experiment.json>)\n- [Procedencia y partición del corpus](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/README.md>)\n- [Corpus original](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/corpus.json>)\n- [Consultas y etiquetas](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/queries.json>)\n- [Informe crudo de evaluación](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/report.json>)\n- [Resumen de métricas](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/summary.json>)\n- [Errores por consulta](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/errors.json>)\n- [Análisis de errores](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/error-analysis.md>)\n- [Informe crudo de desarrollo](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/dev/report.json>)\n- [Dependencias del entorno de referencia](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/requirements-local.lock>)\n- [Licencias de los modelos](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/model-notices.md>)\n- [Licencia MIT](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/LICENSE>)","headings":[{"level":1,"text":"RAG Evaluation Workbench","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#title"},{"level":2,"text":"Problema y utilidad para agentes","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#problem"},{"level":2,"text":"Arquitectura","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#architecture"},{"level":2,"text":"Qué demuestra","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#demonstrates"},{"level":2,"text":"Resultados publicados","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#results"},{"level":3,"text":"Recuperación: 24 consultas con respuesta","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#results-retrieval"},{"level":3,"text":"Respuestas: 26 consultas de evaluación","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#results-answers"},{"level":3,"text":"Diferencias pareadas en exact match","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#results-paired"},{"level":3,"text":"Latencia de solicitud y costo de API","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#results-latency"},{"level":2,"text":"Reproducir","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#reproduce"},{"level":3,"text":"Verificar el informe guardado sin ejecutar modelos","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#reproduce-verification"},{"level":3,"text":"Repetir la inferencia local en el entorno de referencia","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#reproduce-inference"},{"level":2,"text":"Alcance y límites","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#scope"},{"level":2,"text":"Fuentes y revisión","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#sources"}],"sections":[{"heading":"RAG Evaluation Workbench","level":1,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench","content":"[Proyectos](<https://lucioduran.com/es/projects>) / RAG Evaluation Workbench"},{"heading":"RAG Evaluation Workbench","level":1,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#title","content":"Evaluación reproducible de RAG con BM25, recuperación densa e híbrida, inferencia local en CPU y métricas separadas de recuperación y respuesta.\n\nAutor: [Lucio Durán](<https://lucioduran.com/es>) · Python 3.11.13 · Licencia: [MIT](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/LICENSE>)\n\nFicha publicada: 2026-10-21 · Ficha actualizada: 2026-10-21\n\n[Repositorio](<https://github.com/lucioduran/rag-evaluation-workbench>) · [Informe crudo de evaluación](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/report.json>)"},{"heading":"Problema y utilidad para agentes","level":2,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#problem","content":"Recuperar el documento correcto no garantiza una respuesta correcta. RAG Evaluation Workbench compara tres métodos de recuperación manteniendo fijos el modelo generador, el prompt, los presupuestos de contexto y la decodificación. Registra rankings, contexto incluido, respuestas y errores para evaluar cada etapa por separado.\n\nUn agente que recupera evidencia todavía puede confundir hechos o inventar una respuesta cuando debería abstenerse. Este proyecto permite inspeccionar esas fallas sin atribuir al retrieval un éxito que la respuesta final no tuvo."},{"heading":"Arquitectura","level":2,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#architecture","content":"1. **Corpus y partición.** 24 documentos ficticios originales con licencia MIT, 12 preguntas de desarrollo y 26 de evaluación. Desarrollo y evaluación usan grupos de documentos relevantes disjuntos; ambos consultan el mismo corpus. Dos preguntas de evaluación no tienen respuesta.\n2. **Recuperación comparable.** BM25, MiniLM con similitud coseno y fusión de rankings recíprocos con constante 60. Los tres recuperan hasta tres documentos. Cada documento es una unidad completa de recuperación; este experimento no compara estrategias de chunking ni rerankers.\n3. **Generación congelada.** FLAN-T5-small local en CPU, cuatro hilos, semilla 1729 y decodificación greedy. El presupuesto es de 256 tokens para embeddings, 384 tokens de entrada al generador y 32 de salida. Los documentos entran completos, en orden de ranking, hasta agotar el presupuesto. Las etiquetas y respuestas de referencia no entran en el prompt.\n4. **Evidencia y verificación.** Cada ejecución conserva hashes de entradas y modelos, revisiones, entorno, rankings, prompts, predicciones y tiempos. Un verificador con la biblioteca estándar reconstruye rankings y prompts y recalcula métricas e intervalos desde los datos guardados, sin volver a ejecutar los modelos.\n\n- [Metodología y límites de medición](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/methodology.md>)\n- [Configuración congelada](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/config/experiment.json>)"},{"heading":"Qué demuestra","level":2,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#demonstrates","content":"- Diseño de una comparación controlada que separa calidad de recuperación, calidad de respuesta y abstención.\n- Implementación de Recall@3, NDCG@3, exact match y token F1, con bootstrap por grupos y diferencias pareadas entre métodos.\n- Trazabilidad de resultados hasta consultas, rankings, prompts y respuestas concretas, incluidos resultados desfavorables y límites del scoring."},{"heading":"Resultados publicados","level":2,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#results","content":"Resultados publicados por el autor para la ejecución local en Intel Xeon W-3223 con Python 3.11.13 y cuatro hilos de CPU. Las métricas de recuperación usan 24 consultas con respuesta; exact match y token F1 usan las 26 consultas de evaluación, incluidas las dos sin respuesta.\n\nLos intervalos del 95% se calculan con 2.000 remuestreos bootstrap de grupos de origen. Las dos preguntas sobre un documento se mantienen juntas. Las diferencias entre métodos usan observaciones pareadas y el mismo remuestreo. Son 12 grupos con respuesta y dos grupos sin respuesta. Las tablas redondean los valores; los informes conservan su precisión."},{"heading":"Recuperación: 24 consultas con respuesta","level":3,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#results-retrieval","content":"Recall@3 y NDCG@3 sobre 24 preguntas con respuesta, agrupadas en 12 fuentes. Las preguntas sin respuesta se excluyen de estas métricas. Los intervalos del 95% usan bootstrap por grupos.\n\n| Método | Recall@3 | Intervalo del 95% | NDCG@3 | Intervalo del 95% |\n| --- | --- | --- | --- | --- |\n| BM25 | 1.000 | \\[1.000, 1.000\\] | 0.969 | \\[0.923, 1.000\\] |\n| Densa | 1.000 | \\[1.000, 1.000\\] | 1.000 | \\[1.000, 1.000\\] |\n| Híbrida | 1.000 | \\[1.000, 1.000\\] | 1.000 | \\[1.000, 1.000\\] |"},{"heading":"Respuestas: 26 consultas de evaluación","level":3,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#results-answers","content":"Exact match y token F1 sobre las 26 preguntas, en 14 grupos, incluidas las dos sin respuesta. Son métricas de coincidencia textual, no de factualidad. Los intervalos del 95% usan bootstrap por grupos.\n\n| Método | Exact match | Intervalo del 95% | Token F1 | Intervalo del 95% |\n| --- | --- | --- | --- | --- |\n| BM25 | 0.731 | \\[0.560, 0.885\\] | 0.756 | \\[0.583, 0.889\\] |\n| Densa | 0.769 | \\[0.600, 0.893\\] | 0.795 | \\[0.627, 0.926\\] |\n| Híbrida | 0.731 | \\[0.560, 0.885\\] | 0.767 | \\[0.605, 0.899\\] |"},{"heading":"Diferencias pareadas en exact match","level":3,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#results-paired","content":"Diferencias de exact match sobre las mismas 26 preguntas, con remuestreo pareado de 14 grupos. El intervalo de densa menos BM25 incluye cero; esta muestra no establece una mejora general.\n\n| Comparación | Diferencia media | Intervalo del 95% |\n| --- | --- | --- |\n| Densa menos BM25 | 0.038 | \\[0.000, 0.120\\] |\n| Híbrida menos BM25 | 0.000 | \\[0.000, 0.000\\] |"},{"heading":"Latencia de solicitud y costo de API","level":3,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#results-latency","content":"Milisegundos por solicitud en la ejecución publicada con Intel Xeon W-3223 y cuatro hilos. Una observación por consulta y método, 26 consultas por método. Carga de modelos, calentamiento e indexación quedan fuera. USD 0 corresponde solo a APIs pagas; electricidad y hardware no se midieron.\n\n| Método | P50 (ms) | P95 (ms) | API (USD) |\n| --- | --- | --- | --- |\n| BM25 | 93.7 | 133.4 | 0 |\n| Densa | 105.9 | 138.8 | 0 |\n| Híbrida | 105.9 | 144.4 | 0 |\n\nLos tres métodos alcanzan Recall@3 = 1 y conservan el contexto relevante en el prompt, pero ninguno responde correctamente todas las consultas. Dense obtiene un acierto exacto más que BM25: 20/26 frente a 19/26. Su diferencia pareada es 0,038 y el intervalo \\[0,000, 0,120\\] incluye cero. Este resultado no establece un ganador general.\n\nLos tres métodos fallan las dos preguntas de abstención: 0/2 por método. Entre las 78 respuestas hay 20 fallos de exact match: 14 con el contexto relevante presente y seis correspondientes a preguntas sin respuesta. [Análisis de errores](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/error-analysis.md>).\n\nAlgunos fallos son del scoring: «90 requests per minute» es una respuesta correcta excluida por los alias cortos fijados antes de evaluar. Otros son errores sustantivos, como confundir el código de acceso a una puerta con el código de registro de red. Los alias no se ampliaron después de ver las predicciones. [Errores por consulta](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/errors.json>).\n\nLa latencia de solicitud incluye recuperación, preparación del contexto y generación. Carga de modelos, calentamiento y construcción del índice se miden por separado. Hay una observación por consulta y método. Costo de API: USD 0; electricidad y hardware no están cuantificados. [Metodología y límites de medición](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/methodology.md>)."},{"heading":"Reproducir","level":2,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#reproduce","content":"La verificación del informe usa únicamente la biblioteca estándar de Python. Reproducir la inferencia requiere instalar las dependencias y descargar explícitamente los dos modelos públicos. No requiere cuentas, APIs pagas ni GPU alquilada.\n\nCon Python 3.11.13, el primer bloque verifica la consistencia de la evidencia registrada. El segundo ejecuta los modelos y debe correrse desde el mismo repositorio. El lock corresponde al entorno medido, Intel macOS; otras plataformas pueden requerir paquetes PyTorch compatibles. Usá directorios de salida nuevos. La descarga requiere internet y varios cientos de MB; luego la inferencia se ejecuta offline. Una nueva ejecución registra su propio entorno, fecha y tiempos."},{"heading":"Verificar el informe guardado sin ejecutar modelos","level":3,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#reproduce-verification","content":"```\ngit clone https://github.com/lucioduran/rag-evaluation-workbench.git\ncd rag-evaluation-workbench\ngit checkout 60246831be5cf68768710e83d7b41614e49a8341\npython -m rag_workbench verify --report results/eval/report.json\n```"},{"heading":"Repetir la inferencia local en el entorno de referencia","level":3,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#reproduce-inference","content":"```\npython -m venv .venv\n. .venv/bin/activate\npython -m pip install -r requirements-local.lock\npython -m rag_workbench download\nHF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 TOKENIZERS_PARALLELISM=false python -m rag_workbench run --split dev --output build/reproduced-dev\nHF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 TOKENIZERS_PARALLELISM=false python -m rag_workbench run --split eval --output build/reproduced-eval\npython -m rag_workbench verify --report build/reproduced-eval/report.json\n```"},{"heading":"Alcance y límites","level":2,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#scope","content":"- Corpus sintético pequeño y sencillo para retrieval. La partición está reservada contra el ajuste de parámetros, pero es conocida por el autor. No es una evaluación ciega externa ni demuestra generalización a producción.\n- Exact match y token F1 comparan formas de texto, no factualidad. Los alias congelados pueden penalizar paráfrasis válidas. El análisis manual no modifica las puntuaciones.\n- El modelo generador pequeño falla en abstención en esta muestra. Un recall perfecto no equivale a un sistema que responde correctamente.\n- Los intervalos provienen de pocos grupos. Un intervalo degenerado no prueba certeza fuera del corpus. Las latencias describen una ejecución local, no una prueba de carga ni un SLA.\n- La verificación offline comprueba consistencia interna. No autentica las mediciones, repite la inferencia neuronal ni recuenta tokens con el tokenizer. Los cambios de hardware o backend pueden alterar tiempos y predicciones.\n- La CLI procesa archivos locales confiables y carga entradas y resultados en memoria. No es un servicio de subida de archivos. Código, corpus y resultados usan MIT; los modelos descargados usan Apache-2.0 y no se redistribuyen en el repositorio.\n\n- [Artículo: arquitectura, recuperación y evaluación de pipelines RAG](<https://lucioduran.com/es/blog/rag-pipeline-architecture-chunking-reranking-evaluation>)"},{"heading":"Fuentes y revisión","level":2,"url":"https://lucioduran.com/es/projects/rag-evaluation-workbench#sources","content":"Los valores de esta ficha provienen del informe enlazado. No son una medición en vivo. El informe conserva la revisión ejecutada; la revisión consultada incluye la publicación posterior de ese informe.\n\n- Revisión consultada: [` 60246831be5cf68768710e83d7b41614e49a8341 `](<https://github.com/lucioduran/rag-evaluation-workbench/commit/60246831be5cf68768710e83d7b41614e49a8341>)\n- Revisión registrada por el experimento: [` 1087f9b0b7985ce719204595c7a90b45e1e186b2 `](<https://github.com/lucioduran/rag-evaluation-workbench/commit/1087f9b0b7985ce719204595c7a90b45e1e186b2>)\n- Fecha del informe (UTC): 2026-10-21T21:08:41.652766+00:00\n- SHA-256 del corpus: ` ecf0e3d23dbee38f61aad545e67d7ad3e81195e39659a4619b7035babb5938e6 `\n\n- [README](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/README.md>)\n- [Metodología y límites de medición](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/methodology.md>)\n- [Configuración congelada](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/config/experiment.json>)\n- [Procedencia y partición del corpus](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/README.md>)\n- [Corpus original](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/corpus.json>)\n- [Consultas y etiquetas](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/queries.json>)\n- [Informe crudo de evaluación](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/report.json>)\n- [Resumen de métricas](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/summary.json>)\n- [Errores por consulta](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/errors.json>)\n- [Análisis de errores](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/error-analysis.md>)\n- [Informe crudo de desarrollo](<https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/dev/report.json>)\n- [Dependencias del entorno de referencia](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/requirements-local.lock>)\n- [Licencias de los modelos](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/model-notices.md>)\n- [Licencia MIT](<https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/LICENSE>)"}],"links":[{"text":"Proyectos","url":"https://lucioduran.com/es/projects"},{"text":"Lucio Durán","url":"https://lucioduran.com/es"},{"text":"MIT","url":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/LICENSE"},{"text":"Repositorio","url":"https://github.com/lucioduran/rag-evaluation-workbench"},{"text":"Informe crudo de evaluación","url":"https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/report.json"},{"text":"Metodología y límites de medición","url":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/methodology.md"},{"text":"Configuración congelada","url":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/config/experiment.json"},{"text":"Resumen de métricas","url":"https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/summary.json"},{"text":"Análisis de errores","url":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/error-analysis.md"},{"text":"Errores por consulta","url":"https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/errors.json"},{"text":"Artículo: arquitectura, recuperación y evaluación de pipelines RAG","url":"https://lucioduran.com/es/blog/rag-pipeline-architecture-chunking-reranking-evaluation"},{"text":"60246831be5cf68768710e83d7b41614e49a8341","url":"https://github.com/lucioduran/rag-evaluation-workbench/commit/60246831be5cf68768710e83d7b41614e49a8341"},{"text":"1087f9b0b7985ce719204595c7a90b45e1e186b2","url":"https://github.com/lucioduran/rag-evaluation-workbench/commit/1087f9b0b7985ce719204595c7a90b45e1e186b2"},{"text":"README","url":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/README.md"},{"text":"Procedencia y partición del corpus","url":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/README.md"},{"text":"Corpus original","url":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/corpus.json"},{"text":"Consultas y etiquetas","url":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/queries.json"},{"text":"Informe crudo de desarrollo","url":"https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/dev/report.json"},{"text":"Dependencias del entorno de referencia","url":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/requirements-local.lock"},{"text":"Licencias de los modelos","url":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/model-notices.md"},{"text":"Licencia MIT","url":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/LICENSE"}],"structuredData":[{"@context":"https://schema.org","@graph":[{"@type":"WebPage","@id":"https://lucioduran.com/es/projects/rag-evaluation-workbench#page","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench","name":"RAG Evaluation Workbench","description":"Evaluación reproducible de RAG con BM25, recuperación densa e híbrida, inferencia local en CPU y métricas separadas de recuperación y respuesta.","inLanguage":"es","datePublished":"2026-10-21","dateModified":"2026-10-21","author":{"@id":"https://lucioduran.com/#person"},"mainEntity":{"@id":"https://lucioduran.com/projects/rag-evaluation-workbench#software"}},{"@type":"SoftwareSourceCode","@id":"https://lucioduran.com/projects/rag-evaluation-workbench#software","name":"RAG Evaluation Workbench","description":"Evaluación reproducible de RAG con BM25, recuperación densa e híbrida, inferencia local en CPU y métricas separadas de recuperación y respuesta.","url":"https://lucioduran.com/es/projects/rag-evaluation-workbench","codeRepository":"https://github.com/lucioduran/rag-evaluation-workbench","programmingLanguage":"Python","runtimePlatform":"Python 3.11.13","license":"https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/LICENSE","version":"60246831be5cf68768710e83d7b41614e49a8341","author":{"@type":"Person","@id":"https://lucioduran.com/#person","name":"Lucio Durán","url":"https://lucioduran.com"},"isAccessibleForFree":true,"citation":["https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/README.md","https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/methodology.md","https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/config/experiment.json","https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/README.md","https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/corpus.json","https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/data/queries.json","https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/report.json","https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/summary.json","https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/eval/errors.json","https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/error-analysis.md","https://raw.githubusercontent.com/lucioduran/rag-evaluation-workbench/60246831be5cf68768710e83d7b41614e49a8341/results/dev/report.json","https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/requirements-local.lock","https://github.com/lucioduran/rag-evaluation-workbench/blob/60246831be5cf68768710e83d7b41614e49a8341/docs/model-notices.md"]},{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Proyectos","item":"https://lucioduran.com/es/projects"},{"@type":"ListItem","position":2,"name":"RAG Evaluation Workbench","item":"https://lucioduran.com/es/projects/rag-evaluation-workbench"}]}]}],"contentHash":"cbea2cb588183183a42e176fb40e34bad252b9f5ce346045d7ae8f502e1f278c","provenance":{"method":"Deterministic serialization of the server-rendered main element","source":"https://lucioduran.com/es/projects/rag-evaluation-workbench","hashAlgorithm":"sha256","hashScope":"JSON document fields before contentHash and provenance","sourceHTMLBytes":58343,"contentBytes":13562}}
