HN presenta: FastGraphRAG – Técnica RAG mejorada que aprovecha el PageRank tradicional
(github.com/circlemind-ai)- Fast GraphRAG es un framework GraphRAG simplificado para flujos de trabajo de búsqueda basados en agentes, interpretables y de alta precisión, enfocado en incorporar RAG avanzado a pipelines de búsqueda sin tener que construir directamente flujos de trabajo de agentes complejos
- Convierte los grafos de conocimiento en una forma explorable por humanos, permite consultarlos, visualizarlos y actualizarlos, y genera y refina grafos automáticamente según los requisitos del dominio y la ontología
- Para responder consultas, usa exploración de grafos basada en personalized PageRank para encontrar información relevante; el README enlaza el paper de HippoRAG como panorama general de este enfoque
- En el ejemplo de costos, con The Wizard of Oz,
fast-graphragcuesta $0.08 ygraphragcuesta $0.48; se afirma que el ahorro de costos de 6 veces mejora aún más a medida que aumentan el tamaño de los datos y la cantidad de inserciones - Funciona con Python 3.10.1 o superior, admite instalación desde el código fuente y desde PyPI, y, tras configurar la clave de la API de OpenAI, permite insertar documentos y hacer consultas, manteniendo automáticamente el conocimiento en el mismo directorio de trabajo
El framework de búsqueda que ofrece Fast GraphRAG
- Fast GraphRAG es un framework GraphRAG orientado a conocimiento interpretable y depurable
- El grafo ofrece el conocimiento en una forma que las personas pueden explorar y admite las siguientes operaciones:
- Consultas
- Visualización
- Actualizaciones
- Se enfoca en ofrecer capacidades RAG avanzadas mientras reduce la carga de construir y diseñar directamente flujos de trabajo de agentes
Funciones principales
- Está diseñado para ejecutarse a gran escala de forma rápida y de bajo costo, reduciendo requisitos pesados de recursos o costos
- Admite datos dinámicos, generando y refinando grafos automáticamente según los requisitos del dominio y la ontología
- Cuando los datos cambian, admite actualizaciones incrementales, lo que permite actualizaciones en tiempo real
- Ofrece exploración inteligente que aprovecha la exploración de grafos basada en PageRank para mejorar la precisión y la confiabilidad
- En general es asíncrono y apunta a flujos de trabajo robustos y predecibles mediante soporte completo de tipos
Ejemplo de costos
- En el ejemplo que usa The Wizard of Oz, el costo de
fast-graphragse presenta como $0.08 y el degraphragcomo $0.48 - El README lo describe como un ahorro de costos de 6 veces, y afirma que el efecto de ahorro mejora aún más a medida que aumentan el tamaño de los datos y la cantidad de inserciones
Instalación y flujo de ejecución
- Las formas de instalación recomendadas se dividen en instalación desde el código fuente para rendimiento e instalación desde PyPI para estabilidad
- Instalación desde el código fuente: clonar el repositorio y luego ejecutar
poetry install - Instalación desde PyPI:
pip install fast-graphrag
- Instalación desde el código fuente: clonar el repositorio y luego ejecutar
- El ejemplo de inicio rápido primero configura la variable de entorno
OPENAI_API_KEY - Después de descargar el texto de A Christmas Carol, se inicializa
GraphRAGdesde código Python - La inicialización de ejemplo incluye los siguientes valores:
working_dir="./book_example"- un
domainque analiza los personajes, interacciones, lugares y relaciones de la historia - una lista de consultas de ejemplo
- tipos de entidades
["Character", "Animal", "Place", "Object", "Activity", "Event"]
- Se inserta el documento con
grag.insert(f.read())y se imprime el resultado de la consulta congrag.query("Who is Scrooge?").response - Si se inicializa de nuevo en el mismo directorio de trabajo, el conocimiento se conserva automáticamente
- Para controlar la cantidad de tareas LLM concurrentes en casos como el uso de modelos locales, se puede configurar opcionalmente una variable de entorno como
CONCURRENT_TASK_LIMIT=8
Ejemplos y opciones de configuración
- La carpeta
examplesofrece tutoriales de casos de uso comunes de la biblioteca custom_llm.pyes un ejemplo simple para configurar de manera distinta un modelo de lenguaje compatible con la API de OpenAI y un embeddercheckpointing.ipynbcubre el uso de checkpoints para evitar daños irreversibles en los datosquery_parameters.ipynbcubre distintos parámetros de consulta y muestra cómo incluir referencias de la información usada en las respuestas conwith_references=True
Filosofía de diseño y método de exploración
- El objetivo es aumentar la cantidad de aplicaciones GenAI exitosas; para ello, se afirma que crean herramientas de memoria y datos que permiten a las apps LLM aprovechar pipelines de búsqueda especializados sin configurar ni mantener flujos de trabajo de agentes complejos
- Fast GraphRAG explora el grafo con el algoritmo personalized PageRank para encontrar la información más relevante para responder la consulta actual
- Como panorama general de por qué funciona este enfoque, presenta como referencia el paper de HippoRAG
Código abierto y servicio administrado
- El repositorio se ofrece bajo MIT License, y los detalles están en LICENSE.txt
- Ofrece un servicio administrado como forma de empezar de manera rápida y confiable
- El servicio administrado incluye las primeras 100 solicitudes gratis cada mes; después, se cobra según el uso
- Para saber más sobre el servicio administrado, se puede reservar una demo o consultar la documentación
- La guía para contribuir está en CONTRIBUTING.md, y las preguntas se pueden hacer en Discord
1 comentarios
Opiniones en Hacker News
Además de PageRank, hay varias métricas de centralidad interesantes que pueden influir en RAG sobre datos estructurados.
Entre ellas, Triangle Centrality calcula la centralidad contando los triángulos alrededor de un nodo, basándose en la idea de que los triángulos cierran fuertemente las relaciones, mientras que las conexiones abiertas le quitan peso al centro y diluyen la centralidad.
https://arxiv.org/abs/2105.00110
En el paper dicen que es más eficiente que otras centralidades como PageRank, pero en un estudio que usó GraphBLAS, TC fue más lento que nuestra implementación dispersa de PageRank en varios grafos dispersos de hasta 1.800 millones de aristas.
Aun así, parece que TC escala mejor a medida que el grafo crece, y es muy posible que sea más eficiente en el rango de billones de aristas.
https://fossies.org/linux/SuiteSparse/GraphBLAS/Doc/The_Grap...
De todos modos, el cuello de botella en la generación de respuestas será la parte que parsea el LLM.
PageRank es el primer paso, pero también me gustaría probar alternativas más precisas.
Aquí se usa PageRank personalizado, así que se asignan pesos iniciales a un conjunto específico de nodos; me pregunto si Triangle Centrality también admite eso.
Además, también se consideran pesos en las aristas, así que quisiera saber si eso también es posible.
https://link.springer.com/content/pdf/10.1007/978-3-030-6097...
He trabajado bastante en esta área y aprendí algunas cosas.
Combiné estas tres cosas para crear una etapa similar de descomposición/extracción de conocimiento, y le agregué un metaprompter para que generara prácticamente de forma automática el dominio/tipo de entidad.
Por defecto, los LLM no aciertan bien el nivel correcto de granularidad del conocimiento descompuesto.
Un truco es pedirle al LLM que emita un mapa mental en mermaid.js, que divida la entrada en un árbol jerárquico y que al final indique qué nivel es la raíz adecuada para los nodos de conocimiento.
Luego se generan preguntas que puedan responderse con el conocimiento dentro de ese nodo, y se indexa y también se embebe el texto de esas preguntas.
Hacer matching directo de la consulta del usuario contra esas preguntas con BM25 puro ya da buenos resultados, y un enfoque híbrido es mejor, aunque la diferencia no es enorme.
Si no se usa un LLM en el momento de la consulta, también se puede descender jerárquicamente desde la raíz hacia nodos más profundos usando la similitud de embeddings como función de costo de recorrido.
Al final decidí pasar a un grafo como generalización del árbol.
Considero que el concepto central es usar la similitud de embeddings para “caminar” el grafo, y en FastGraphRAG también lo estamos integrando activamente mediante pesos en las aristas según la consulta.
Es interesante ver cómo varias soluciones convergen hacia diseños parecidos.
La idea de generar una respuesta hipotética a partir de la consulta y luego hacer búsqueda de embeddings con esa respuesta es interesante, y voy a agregarla a la lista de experimentos.
Ahora me pregunto si generar la respuesta hipotética con un LLM ajustado finamente al corpus funcionaría aún mejor.
También quisiera saber si, al crear la respuesta hipotética, se le pide al modelo una respuesta ajustada al “tamaño de chunk”.
Usar PageRank para una mejor centralidad suena bien, pero sigue sin resolver el defecto probablemente irresoluble de RAG, es decir, la razón por la que RAG es fundamentalmente difícil de hacer funcionar.
La razón por la que todas las bases de datos RAG rinden por debajo de lo esperado es que RAG, en esencia, no logra encontrar las relaciones entre palabras necesarias para hallar la información que el usuario quiere.
Sonará extraño, y uno pensaría que el mecanismo original de “atención” debería ser bueno para esto, pero en la práctica no alcanza.
Por ejemplo, supongamos que en un texto se dice que una persona llamada ‘Sharon’ asistió a varias conferencias de fisicoquímica, pero no se menciona explícitamente su profesión.
Si buscas “¿cuál es la profesión de Sharon?”, es muy probable que casi todos los enfoques RAG no logren conectar ‘profesión’, asistencia a conferencias y el tipo de conferencias para inferir ‘química’.
Este tipo de error aparece en muchos tipos de información al recuperar datos con RAG.
En última instancia, soluciones como la anterior parecen reinventar, con más pasos, otros métodos de consulta como SQL o PageRank, y en ese punto la vectorización ya no tiene mucho sentido.
El componente RAG solo tiene que encontrar en un gran dataset el artículo relacionado con Sharon y pasárselo completo al LLM como contexto.
Si miras el paper de HippoRAG citado en el post original, el ejemplo motivador es casi idéntico, y la evaluación también está orientada principalmente a preguntas y respuestas multihop de este tipo.
Se obtiene la entidad Sharon y, como contexto adicional, se reciben los nodos y aristas cercanos a Sharon.
Después, el resto es tarea del LLM, y si en el contexto dado no está la profesión, debería decir: “No se puede encontrar la profesión de Sharon en el contexto proporcionado”.
Me pareció interesante, así que me registré y subí algunos documentos PDF al dashboard.
Nuestro caso de uso es analizar documentos de cumplimiento relacionados con manufactura en una startup de IA, y para que esto nos sea útil necesitamos entender hasta qué escala funciona y cuál es el modelo de costos.
Tenemos alrededor de 300 mil PDF por cliente, y esperamos que cerca del 10% del conjunto de documentos cambie cada mes.
Cualquier sistema GraphRAG tendría que procesar documentos a gran escala; podríamos usar S3 como mecanismo de ingesta, pero necesitamos saber el costo y el tiempo de procesamiento hasta que el sistema quede utilizable en estos momentos:
Me gustaría hablarlo con más detalle; escríbeme a antonio [at] circlemind.co
Interesante; me pregunto qué tan grande debe ser un corpus de texto específico de dominio para obtener un grafo de conocimiento útil.
Aider lleva tiempo aplicando PageRank al grafo de llamadas de repositorios de código.
Cualquier código no trivial tiene mucha estructura de grafo para sustentar PageRank, y funciona muy bien para encontrar el contexto más relevante dentro del proyecto relacionado con la tarea actual.
https://aider.chat/docs/repomap.html#optimizing-the-map
Cuando más gente empiece a usarlo, nos gustaría escuchar sus comentarios.
Me pregunto si hay planes para permitir forzar la generación del repo map e inspeccionarlo.
Genial.
Me da curiosidad cómo se almacena y se consulta el grafo.
Estoy familiarizado con las bases de datos de grafos, pero no parece que sean una dependencia.
También me pregunto si probaron el modelo sciphi triplex para la extracción.
Cuando hice extracciones antes, si extraía el mismo chunk varias veces seguidas, los resultados no eran consistentes.
El codebase está diseñado para que sea fácil integrar cualquier base de datos de grafos escribiendo un wrapper ligero, y tenemos previsto dar soporte a cosas como neo4j en un futuro cercano.
Todavía no hemos probado triplex, porque gpt4o-mini por ahora ha sido lo suficientemente rápido y preciso.
Usamos gpt4o-mini no solo para la extracción de entidades y relaciones, sino también para generar descripciones y resolver conflictos.
Con fine-tuning, los resultados seguramente mejorarían.
La consulta del grafo funciona encontrando primero un conjunto inicial de nodos relevantes para la consulta dada y luego ejecutando PageRank personalizado desde esos nodos para encontrar otros pasajes relacionados.
Actualmente elegimos los nodos iniciales con búsqueda semántica tanto sobre la consulta completa como sobre las entidades extraídas de la consulta, pero también tenemos planeadas algunas extensiones interesantes para este enfoque.
Buena idea.
Personalmente, creo que la recuperación de información tradicional es el camino a seguir para RAG.
La búsqueda vectorial es buena, pero lenta y cara, y la gente tiende a usarla como si fuera polvo mágico.
Funciona bien con datos no estructurados, pero no necesariamente encaja tan bien con datos estructurados.
A menos que esté muy bien ajustada, la búsqueda vectorial tampoco es mucho mejor que una consulta tradicional bien ajustada.
He visto en la práctica intentos de convertir datos estructurados en datos no estructurados para luego hacer búsqueda vectorial o prompt engineering, y en general se siente un poco al revés.
Puede funcionar hasta cierto punto, pero probablemente haya una forma más inteligente de obtener el mismo resultado.
La esencia de Graph RAG es aprovechar la estructura de los datos.
No importa demasiado si eso es un join de SQL o una consulta a una base de datos de grafos.
También habría valor en enseñarle al LLM cómo consultar, o en hacerlo interactuar con APIs existentes de búsqueda/consulta.
Los rankings deficientes se pueden compensar con tamaños de contexto más grandes y trayendo cientos o más resultados mediante varias consultas.
Escalar de esa forma sería mucho más rápido y barato que la búsqueda vectorial.
Se ve bien, pero me preocupa la sobresimplificación porque ya me quemé con otras capas de abstracción como LangChain.
Me pregunto cómo planean evitar repetir los mismos errores.
Me pregunto si tienen puntajes de métricas de evaluación para recuperación y generación.
Por ejemplo, con datasets como KILT o NQ.
Los datasets de benchmark no lo son todo, pero mostrar puntajes razonablemente buenos y tiempos de inferencia ayudaría mucho a convencer sobre el framework o a que los ingenieros lo elijan.
Como ingeniero freelance de procesamiento de lenguaje natural he construido muchos pipelines RAG, y pienso probar esto directamente.
Actualmente estoy construyendo un chatbot de Q&A y me está costando manejar el siguiente escenario:
cuando el usuario pregunta “¿qué quisiste decir con la oración anterior que acabas de mencionar?”, me pregunto cómo este framework puede recuperar el subconjunto pequeño correcto de conocimiento bruto e integrarlo en el LLM para producir una respuesta relevante.
Me resultó difícil resolver este problema sin depender de frameworks externos.
https://www.reddit.com/r/LocalLLaMA/comments/1gtzdid/d_optim...
Quisiera saber cómo este framework puede resolver este problema y simplificar el proceso.
Sin esto, fallaba con frecuencia cuando el usuario preguntaba cosas como “explícame más el punto 2” o “dame un ejemplo detallado de lo anterior”.
La implementación actual tiene tres índices; se le proporciona la consulta y los mensajes anteriores al LLM y se le pide descomponerlo en:
solicitud completa, pregunta optimizada para BM25, palabras clave y pregunta optimizada para búsqueda semántica.
Después se hace RAG y reranking, y se pasan los N pasajes principales junto con la solicitud completa a una segunda llamada al LLM.
Hay que concentrarse en la etapa de orquestación.
Puedes buscar agentes ReAct; se pueden construir con LangGraph o Bedrock Agents.