Navegación principal

¿Puede Postgres encargarse de tu flujo de RAG?

Probamos el enfoque de pgai centrado en la base de datos para ver dónde simplifica las operaciones de RAG y dónde las cargas complejas aún requieren más flexibilidad.

Resumen ejecutivo

  • Los LLM solo pueden “ver” una cantidad limitada de texto a la vez (la ventana de contexto). Esto funciona para tareas pequeñas, pero falla cuando una base de conocimientos abarca miles de páginas. Aunque la ventana de contexto sea suficiente, el rendimiento puede disminuir debido al problema de “encontrar una aguja en un pajar”.

  • La RAG (“generación aumentada por recuperación”) se ha convertido en un patrón muy común: se mantiene una base de conocimientos (documentos, wikis, políticas, transcripciones, etc.), se realiza una búsqueda semántica de la consulta del usuario para recuperar los fragmentos más relevantes mediante embeddings y, luego, se proporcionan esos fragmentos al LLM junto con la pregunta. Esto limita el contexto del modelo y, si se hace correctamente, puede mejorar la calidad de las respuestas y reducir las alucinaciones.

  • pgai es una extensión de código abierto para Postgres, con herramientas complementarias, que permite crear flujos de trabajo de “recuperación con IA” sobre PostgreSQL, la confiable base de datos de código abierto.

  • La idea principal es trasladar más etapas del flujo estándar de RAG a la capa de base de datos (ingesta → segmentación → creación de embeddings → sincronización de embeddings), en vez de tratar la base de datos como un “simple almacenamiento” de embeddings.

  • Nuestra impresión inicial es que resulta prometedor, pero deja de ser adecuado cuando el flujo de RAG adquiere incluso un poco de complejidad, sobre todo en los métodos de segmentación. Aun así, seguiremos este proyecto de cerca.

El patrón RAG

Hay muchas formas de crear una RAG. Para consultar un análisis más extenso de los distintos enfoques, lee Ejemplos prácticos de soluciones RAG personalizadas. Las posibilidades de diseño se vuelven sorprendentemente amplias cuando importa la calidad, y el enfoque “predeterminado” habitual suele ser el siguiente:

  1. Reúne un conjunto de documentos.

  2. Divídelos en fragmentos. Hay muchos métodos para hacerlo (p. ej., por párrafos o agrupaciones semánticas).

  3. Convierte cada fragmento en un embedding.

  4. Almacena los embeddings en una base de datos vectorial (Pinecone, Milvus, etc.) o en Postgres mediante pgvector.

  5. Al recibir una consulta, busca los fragmentos más cercanos `y pásalos al LLM (de nuevo... también hay muchas formas de hacerlo).

En muchas arquitecturas, los pasos (1)–(3) se realizan fuera de la base de datos, en el código de la aplicación o en un flujo de datos, y la base de datos se usa principalmente para:

  • almacenar embeddings

  • buscar embeddings

Propósito de pgai

pgai es una extensión de código abierto para Postgres, desarrollada por Timescale, que intenta borrar esa distinción.

En lugar de tratar los embeddings como algo que la aplicación administra manualmente, pgai los convierte en una función de la base de datos:

  • Defines qué tabla o documentos quieres convertir en embeddings.

  • Especificas el modelo de embeddings y una estrategia de segmentación.

  • pgai se encarga del resto, incluida la actualización de los embeddings cuando cambian los datos de origen.

La propuesta es atractiva:

  • Menos código de integración personalizado que mantener.

  • Debería ser más fácil mantener “actualizados” los embeddings cuando cambien los documentos de origen.

  • Postgres/pgai administra los reintentos, límites de frecuencia, trabajos fallidos, etc.

Nota para el lector: pgai incluye pgvector, otra extensión muy popular de RAG para Postgres. pgvector incorpora almacenamiento vectorial y búsqueda por similitud en Postgres, mientras que pgai aprovecha esas funciones para automatizar etapas del flujo de RAG, como la segmentación, la creación de embeddings y su actualización.

Primeras impresiones sobre pgai

Lo que nos gustó

1) Es fácil ponerlo en funcionamiento.

El proceso ideal es bastante sencillo:

  • Descarga las imágenes de Docker de Timescale (base de datos + worker).

  • Proporciona la clave de API de tu proveedor de embeddings.

  • Ejecuta unas pocas instrucciones SQL para declarar el vectorizador (en esencia: qué convertir en embeddings, cómo segmentarlo y qué modelo usar).

Después, pgai configura un worker de vectorización para que se ejecute como proceso independiente y genere embeddings de forma asíncrona (p. ej., cada 5 minutos o con la frecuencia que quieras).

2) Es práctico ejecutar todo el flujo “cerca” de la base de datos.

pgai puede ingerir contenido de tablas y cargar documentos desde lugares como S3 para luego analizarlos, segmentarlos y convertirlos en embeddings. También admite distintos formatos de documentos de texto, como PDF, Markdown, etc.

Lo que nos pareció limitado

1) Se pierde mucho control (y la RAG a veces lo necesita).

Los sistemas RAG de alto rendimiento, medido según la calidad de las respuestas, suelen requerir flujos personalizados, como:

  • reglas de segmentación personalizadas (por encabezados, páginas, turnos de cada interlocutor, etc.)

  • segmentación basada en metadatos (conservar títulos de secciones, marcas de tiempo, autores y tipo de documento)

  • distintas estrategias de embeddings para cada tipo de documento

pgai ofrece menos flexibilidad para lo anterior.

Actualmente hay dos estrategias principales de segmentación: un divisor de texto por caracteres y uno recursivo, además de la opción de no segmentar. Eso podría bastar para algunos casos de uso, pero muchos sistemas RAG en producción requieren más personalización.

Sería excelente que Timescale incorporara algunas de las estrategias de segmentación más sofisticadas presentes en bibliotecas como Chonkie y que también admitiera diseños avanzados como la recuperación contextual de Anthropic.

2) Prioriza el texto, no la multimodalidad.

Muchos problemas interesantes de RAG ya no se limitan al texto:

  • archivos PDF con diagramas

  • capturas de pantalla e imágenes

  • grabaciones de audio

  • clips de video

Aunque puedas “extraer texto” de estas fuentes, eso no equivale a un verdadero flujo de embeddings multimodales.

Si pgai llega a admitir modelos multimodales de extremo a extremo (cargar → segmentar → crear embeddings para imágenes grandes, audio o video almacenados en S3, con una sincronización sólida), sería una propuesta atractiva. Sin embargo, hoy es un flujo de embeddings de texto.

3) Si solo necesitas embeddings, quizá no necesites pgai.

Si tu flujo de ingesta ya es personalizado, o debe serlo, “crear embeddings de fragmentos de texto” no es la parte más difícil de la RAG. En ese contexto, pgai resuelve la parte más sencilla del problema.

Además, si tu base de conocimientos se actualiza con poca frecuencia, la sincronización automática de embeddings aporta menos valor.

Capa de texto a SQL

Una forma especialmente útil de aprovechar pgai sería implementar una interfaz de texto a SQL sobre tus bases de datos. Esto puede lograrse con facilidad mediante el módulo semantic_catalog que ofrece pgai. Solo tienes que configurarlo así:

Bash

OPENAI_API_KEY="your-OpenAPI-key-goes-here"TARGET_DB="postgres://user:password@host:port/database"CATALOG_DB="postgres://user:password@host:port/database"

y hacer que el catálogo semántico examine tus diccionarios de datos con pgai semantic-catalog create. Esto genera contexto a partir de tu almacén de datos con un aspecto similar al siguiente:

Plain Text

---schema: postgres_airname: aircrafttype: tabledescription: Lists aircraft models with performance characteristics and unique codes.columns:- name: model  description: Commercial name of the aircraft model.- name: range  description: Maximum flight range in kilometers.- name: class  description: Airframe class category or configuration indicator.- name: velocity  description: Cruising speed of the aircraft.- name: code  description: Three-character aircraft code serving as the primary key....

Este contexto ya está disponible para pgai de varias formas:

Mediante búsqueda semántica:

Esta consulta devolverá las tablas, funciones y otros objetos que podrían ser relevantes para tu consulta en lenguaje natural:

Bash

pgai semantic-catalog search -p "Your natural language question goes here!"

Obtener el contexto sin procesar:

Esto mostrará el contexto YAML sin procesar relacionado con tu consulta en lenguaje natural:

Bash

pgai semantic-catalog search -p "Your natural language question goes here!" --render

Generar SQL:

También puedes generar directamente el SQL sin procesar necesario para responder la consulta. El contexto del paso anterior se envía a un LLM, que genera la respuesta:

Bash

pgai semantic-catalog generate-sql -p "Your natural language question goes here!"

Cómo puedes usar pgai ahora mismo

Si estás creando un sistema RAG relativamente sencillo, vale la pena probar pgai si quieres:

  • usar Postgres como sistema de registro,

  • usar un mínimo de código de integración,

  • mantener los embeddings sincronizados automáticamente,

  • aplicar rápidamente una solución de texto a SQL a tus bases de datos,

  • experimentar con nuevas herramientas de RAG y extensiones de Postgres.

Cuándo actuaríamos con cautela

Probablemente convenga esperar antes de usar pgai si tu flujo de RAG necesita cualquiera de estas características:

  • lógica de ingesta o segmentación muy personalizada

  • muchos tipos de documentos con distintos requisitos de análisis

  • embeddings multimodales

Por último, aunque está claro que pgvector ha logrado una gran adopción, no sabemos si pgai despertará el mismo interés y, por tanto, recibirá un nivel de soporte similar (si bien apenas existe desde hace unos 18 meses).

Gráfica del historial de estrellas en GitHub que muestra la adopción de pgai de Timescale a lo largo del tiempo.

Resumen

pgai ofrece un enfoque interesante de RAG que permite a las bases de datos asumir más tareas operativas rutinarias para simplificar el código de la aplicación.

Por ahora, es:

  • útil y realmente agradable para configuraciones sencillas de RAG

  • poco flexible para flujos más personalizados, sobre todo multimodales

Es prometedor y definitivamente vale la pena seguir su evolución.

Autor

Andrew Liubinas