Pusimos a prueba 5 RAG frameworks: LangChain, LangGraph, LlamaIndex, Haystack y DSPy, construyendo el mismo flujo de trabajo agente de RAG con componentes estandarizados: modelos idénticos (GPT-4.1-mini), embeddings (BGE-small), recuperador (Qdrant) y herramientas (búsqueda web Tavily). Esto aísla la sobrecarga real y la eficiencia de tokens de cada framework.
Resultados del benchmark de frameworks RAG
El benchmark consistió en 100 consultas, ejecutando cada framework el conjunto completo 100 veces para proporcionar promedios estables.
- Promedio de Tokens: Total de tokens consumidos en todas las llamadas de LLM (enrutador, calificador de documentos, calificador de respuestas y generador), incluye tanto prompts (con contexto recuperado) como completaciones. Menor = menor costo de API.
- Sobrecarga del Framework: Tiempo puro de orquestación (ms), el procesamiento interno del framework (lógica de enrutamiento, gestión de estado, etc.), excluyendo llamadas de LLM API y herramientas. Menor = framework más ligero.
Todas las implementaciones lograron un 100% de precisión en el conjunto de pruebas. Se utilizaron los mismos modelos, temperaturas, proveedor de recuperación, herramienta de búsqueda web y un límite compartido de tokens de contexto.
Hallazgos clave
- Nos enfocamos en controlar lo que es controlable: Misma familia de modelos y temperaturas, max_tokens a nivel de nodo, recuperador (Qdrant + BGE-small, k=5, normalización activada), proveedor web (solo Tavily), política de enrutador (heurística + modelo), retorno temprano de calculadora, límite compartido de tokens de contexto, rúbrica de calificación idéntica, instrumentación unificada. Esto reduce sustancialmente los principales factores de confusión en nuestras mediciones.
- La sobrecarga del framework es medible pero pequeña: Observamos ~3–14 ms por consulta derivadas de la lógica de orquestación. Estas diferencias son reales, pero no la principal fuente de las brechas de latencia de >1 s; la mayor parte del tiempo se gasta en E/S con modelos/herramientas externos.
- El rendimiento sigue a los tokens (bajo estas restricciones): DSPy muestra la menor sobrecarga del framework (~3.53 ms). Haystack (~5.9 ms) y LlamaIndex (~6 ms) siguen, mientras que LangChain (~10 ms) y LangGraph (~14 ms) son más altos. El uso de tokens es más bajo para Haystack (~1.57k), luego LlamaIndex (~1.60k); DSPy y LangGraph son ~2.03k, y LangChain ~2.40k.
- La ruta de enrutamiento/herramienta importa: Pequeños cambios en el enrutamiento inicial (recuperador vs. web vs. calculadora) y el comportamiento de respaldo afectan tanto los tokens como el tiempo, incluso cuando los prompts y presupuestos están alineados.
¿Por qué persisten las diferencias? El "ADN del Framework"
A pesar de la estandarización, permanecen pequeñas variaciones en la cantidad de tokens y la latencia. Estas son atribuibles a los comportamientos inherentes y de bajo nivel de cada framework, su "ADN".
- Serialización de prompts y mensajes: Cada framework envuelve el mismo contenido lógico con un formato ligeramente diferente antes de enviarlo al LLM, creando deltas de tokens pequeños pero consistentes.
- Ensamblaje de contexto: El orden preciso y la inclusión de metadatos dentro del contexto concatenado pueden diferir ligeramente según el framework, afectando la cantidad final de tokens.
- Desempates de enrutamiento: En casos limítrofes, las sutiles diferencias en cómo un framework analiza la salida JSON del enrutador pueden llevar a una elección de herramienta inicial diferente.
En esta configuración, la huella de tokens parece ser el principal impulsor, más que el tiempo de ejecución del framework.
La arquitectura agente compartida de RAG
Para lograr una comparación justa, las cinco implementaciones se construyeron sobre el mismo flujo de control:
- Enrutador: Un nodo híbrido de modelo y heurística que elige recuperador, web_search o calculadora.
- Recuperar Documentos: Obtiene los 5 documentos principales de Qdrant utilizando embeddings BGE-small normalizados.
- Calificar Documentos: Un juez LLM evalúa la relevancia del documento. Si es irrelevante, activa un respaldo de búsqueda web.
- Generar Respuesta: Utiliza un LLM con temperatura=0.0 y un límite compartido de tokens de contexto para generar un borrador de respuesta.
- Calificar Respuesta: Un segundo juez LLM evalúa el borrador en cuanto a fundamentación, contradicciones (alucinaciones) y completitud.
- Respaldo y Retorno Temprano: Se activa una búsqueda web si la calificación de la respuesta es insuficiente. Sin embargo, los resultados de la calculadora se devuelven directamente, omitiendo los pasos de generación y calificación.
Ejemplos de flujo de trabajo
Escenario A — Impacto directo desde la base de datos:
Escenario B — Evento reciente activa la herramienta web:
Escenario C — La calculadora proporciona un retorno temprano:
Escenario D — La BD de vectores es insuficiente, recurre a la búsqueda web:
Metodología de frameworks RAG
Todas las cinco implementaciones lograron un 100% de precisión en nuestro conjunto de pruebas de 100 consultas, coincidiendo con las respuestas de verdad fundamental. Este fue el requisito fundamental, asegurando que cada framework pudiera ejecutar exitosamente el mismo flujo de trabajo agente de RAG antes de medir las diferencias de rendimiento.
1. Componentes principales y configuración
Las herramientas fundamentales se estandarizaron para eliminar variables de rendimiento en la fuente.
- LLMs:
- Modelo: Todos los nodos (enrutador, generador, calificador) utilizaron el modelo openai/gpt-4.1-mini a través de la OpenRouter API.
- Determinismo: La temperatura se estableció en 0.0 para todas las llamadas de LLM para garantizar la máxima consistencia en el enrutamiento, la generación y la calificación.
- Límites de tokens: Se aplicaron límites estrictos de max_tokens: 256 para el enrutador y calificadores, y 512 para el generador. Esto evita diferencias de latencia causadas por un framework que genera respuestas excesivamente largas.
- Modelo de embedding y recuperación:
- Modelo: Todos los frameworks utilizaron BAAI/bge-small-en-v1.5 de HuggingFace.
- Normalización: Un paso crítico para el rendimiento, normalize_embeddings se estableció en True en los cinco frameworks. (LangChain/LangGraph vía encode_kwargs; LlamaIndex vía normalize=True; Haystack vía normalize_embeddings; recuperador DSPy normalizado.)
- Recuperación: El almacén vectorial Qdrant se consultó para un k=5 (5 documentos principales) en todas las implementaciones.
- Herramientas:
- Búsqueda web: El benchmark se restringió a solo Tavily (max_results=3).
- Calculadora: Las cinco implementaciones utilizaron la biblioteca sympy para el análisis y evaluación de expresiones matemáticas, asegurando capacidades idénticas.
2. Flujo de control y política de RAG
El proceso de "toma de decisiones" del agente se reflejó explícitamente en todas partes.
- Lógica de enrutamiento: Se implementó una estrategia de enrutamiento híbrida en los cinco scripts para equilibrar la inteligencia del modelo con reglas deterministas:
- Una heurística basada en regex (heuristic_route) verifica primero patrones obvios de calculadora o búsqueda web (por ejemplo, símbolos matemáticos, años como "2024").
- Un nodo LLM router_node toma luego su propia decisión.
- La decisión final prioriza la heurística para calculadoras, de lo contrario, se remite a la elección del LLM.
- Presupuesto de contexto: Esta es una de las estandarizaciones más críticas. Antes de llamar al nodo generate_answer, todo el contexto de documentos recuperados y los resultados de búsqueda web se concatenan y luego se recortan a un límite compartido de 2000 tokens utilizando una utilidad común truncate_to_token_budget. Esto asegura que el LLM generador en cada framework reciba una entrada del mismo tamaño exacto, evitando que cualquier framework individual se vea favorecido o perjudicado por la verbosidad de su contexto recuperado.
- Política de calificación de respuestas:
- Rúbrica permisiva: El nodo grade_answer utiliza un prompt idéntico y permisivo en todos los frameworks, instruyendo al juez LLM a aceptar respuestas semánticamente similares y razonablemente completas.
- Manejo de fallos: La lógica para manejar un análisis JSON fallido del calificador se estandarizó. Si la salida del calificador no es JSON válido, el sistema predetermina a una calificación permisiva (grounded=True, complete=True), imitando un escenario del mundo real donde no querrías que un analizador frágil fallara una respuesta de lo contrario buena. Los campos estructurados de DSPy devuelven (sin análisis JSON), esto se registra como una diferencia de robustez, no como una ventaja de rendimiento.
- Retorno temprano de calculadora: Como se ve en el código, una llamada exitosa al calculadora_node establece directamente final_answer y termina el flujo de trabajo temprano. Esta es una optimización significativa que se aplica consistentemente, evitando que la ruta de la calculadora invoque innecesariamente los LLM de generación y grade_answer.
- Alineación de DSPy. Para mantener la equidad con las líneas base sin CoT, DSPy utiliza dspy.Predict (sin CoT) para Router y AnswerGenerator. Las firmas reflejan los contratos de nodo de otros frameworks; donde están disponibles, las cantidades de tokens utilizan el uso reportado por el modelo, de lo contrario, se utiliza el respaldo de tiktoken.
3. Instrumentación y métricas
El proceso de medición fue idéntico, utilizando utilidades y principios compartidos.
- Latencia: Se utilizó time.perf_counter() de alta precisión para todas las mediciones de tiempo. La Sobrecarga del Framework se calcula consistentemente como Latencia Total – Latencia de Llamadas Externas.
- Tokenización: Todas las cantidades de tokens para prompts y completaciones se calcularon utilizando tiktoken, la codificación cl100k_base, asegurando una única fuente de verdad para las métricas de tokens. La métrica "Promedio de Tokens" reportada en los resultados representa la suma acumulada de todos los tokens de entrada (prompt) y salida (completación) para cada llamada de LLM (por ejemplo, enrutador, calificadores, generador) dentro de un solo flujo de trabajo de consulta.
- Gestión de estado: Aunque la sintaxis de implementación varía (TypedDict de LangGraph, clase de LlamaIndex, diccionario de LangChain), la estructura de estado es funcionalmente idéntica. Cada framework pasa el mismo conjunto de claves (pregunta, documentos, resultados_web, etc.) entre nodos, asegurando que la lógica de flujo de control opere sobre la misma información.
Al imponer estas estandarizaciones estrictas a nivel de código, este benchmark busca ir más allá de las comparaciones superficiales y ofrecer un análisis replicable del rendimiento del framework bajo una política de RAG fija.
Interpretación de los resultados:
- Puedes concluir: En esta configuración específica y altamente controlada, la sobrecarga de orquestación tiende a ser menor; las diferencias son impulsadas principalmente por las cantidades de tokens y las rutas de herramientas.
- En esta configuración específica y altamente controlada, la sobrecarga del framework es insignificante.
- Las diferencias de rendimiento fueron impulsadas por la cantidad de tokens y las variaciones en la ruta de herramientas.
- No puedes generalizar: Los resultados son específicos de esta arquitectura, modelos, prompts, recuperador y proveedor web; cambiar estos puede alterar las clasificaciones.
Experiencia del desarrollador: Una comparación cualitativa
El rendimiento no es el único factor; cómo se siente trabajar con un framework es igualmente importante.
- LangGraph: El gráfico declarativo
Utiliza un paradigma centrado en gráficos. Defines nodos y los conectas con bordes (incluyendo add_conditional_edges), por lo que el flujo de control es parte de la arquitectura. El estado está tipado a través de un TypedDict con actualizaciones estilo reductor (Annotated[…, add]).- Elige LangGraph para: flujos de trabajo complejos con múltiples ramas, reintentos y ciclos; su estructura escala en robustez y mantenibilidad a medida que los agentes crecen.
- LlamaIndex: Orquestación imperativa
Un script procedural donde el flujo de control es un if/else estándar de Python; el "gráfico" vive en tu código. El estado es una clase PipelineState dedicada, y el framework proporciona primitivas de recuperación limpias (VectorStoreIndex → .as_retriever(k=5)).- Elige LlamaIndex para: flujos de trabajo legibles en un solo archivo donde valoras la lógica procedural clara y la depuración fácil.
- LangChain: Imperativo con componentes declarativos
La orquestación sigue siendo un script de Python, pero las tareas individuales son cadenas pequeñas y composables usando el operador | (por ejemplo, prompt | llm | parser). El estado es un dict de Python flexible y no tipado.- Elige LangChain para: prototipado rápido o equipos que ya están en el ecosistema de LangChain y prefieren componer pequeñas unidades declarativas dentro de un controlador imperativo más grande.
- Haystack: Basado en componentes, orquestación manual Componentes tipados y reutilizables (@component) con E/S explícita, mientras que el flujo de control permanece en Python simple (if/else). Fácil de intercambiar backends de LLM/recuperador/web, más instrumentación de primer nivel por paso (tiempo externo vs. tiempo del framework).
- Elige Haystack para: pipelines listos para producción y probables con contratos claros y control fino.
- DSPy: Programas centrados en firmas (menos líneas de código)
Define una tarea a través de una firma (entradas/salidas + intención), luego impléntala con Módulos que encapsulan la solicitud y las llamadas de LLM. Centraliza el manejo de prompts/uso y elimina el código de pegamento; intercambiar internos (por ejemplo, Predict ↔ CoT) no cambia el contrato.- Elige DSPy para: boilerplate mínimo, flujos legibles en un solo archivo, desarrollo impulsado por contratos (con optimizadores opcionales).
Intercambiando el rendimiento óptimo por comparabilidad
- LangGraph podría destacar con sus optimizaciones nativas de gráficos cuando se le permite usar ejecución paralela, caché de estado y su sistema de bordes condicionales para lógica de ramificación compleja.
- DSPy podría mostrar resultados dramáticamente diferentes al usar sus optimizadores de firma (como MIPROv2) y la solicitud de Cadena de Pensamiento (Chain-of-Thought), lo que puede mejorar significativamente la calidad de la respuesta.
- Haystack podría aprovechar su caché listo para producción, características de agrupación y optimizaciones a nivel de componente que desactivamos por equidad.
- LlamaIndex podría beneficiarse de sus estrategias de indexación avanzadas, motores de consulta y capacidades multimodales que no se ejercitaron en este benchmark.
- LangChain podría brillar con su extenso ecosistema de herramientas y optimizaciones de LCEL (LangChain Expression Language) cuando no está restringido a nuestro conjunto de herramientas estandarizado.
El framework "mejor" depende de si optimizas para: velocidad de desarrollo, mantenibilidad, rendimiento o patrones arquitectónicos específicos.
Conclusión
En un pipeline agente de RAG estrechamente emparejado, la sobrecarga de orquestación suele ser una pequeña porción. Lo que mueve la aguja es cuántos tokens procesas y qué herramientas invocas, ambos moldeados por prompts, recuperación y enrutamiento. El framework "correcto" finalmente depende del estilo de orquestación preferido por tu equipo: gráficos declarativos (LangGraph), scripts imperativos (LlamaIndex), cadenas composables (LangChain), componentes modulares (Haystack) o programas centrados en firmas (DSPy) que minimizan el boilerplate.
Lectura adicional
Explora otros benchmarks de RAG, como:
- Modelos de Embedding: OpenAI vs Gemini vs Cohere
- Base de datos vectorial principal para RAG: Qdrant vs Weaviate vs Pinecone
- Benchmark de Agente RAG: enrutamiento de múltiples bases de datos y generación de consultas
- RAG Híbrido: Aumentando la precisión de RAG
Cita este benchmark
Elige el formato que se ajuste al lugar donde vas a publicar. Pegar la versión con enlace en tu CMS conserva el enlace de retroceso.
@misc{dilmegani2026,
author = {Dilmegani, Cem and Sarı, Ekrem},
title = {{RAG Frameworks: LangChain vs LangGraph vs LlamaIndex}},
year = {2026},
month = jun,
howpublished = {\url{https://aimultiple.com/rag-frameworks}},
note = {AIMultiple. Recuperado el 3 de Junio de 2026}
}
Sé el primero en comentar
Tu dirección de correo electrónico no será publicada. Todos los campos son obligatorios. Los comentarios se dejan en su idioma original.