Inicio / Artículos

Tuberías Docling: Creación de tuberías de datos RAG de nivel empresarial

Cómo docling-pipelines reemplaza los frágiles scripts de enlace por operadores componibles y flujos JSON: ingestión, extracción, controles de calidad, embeddings y almacenamiento vectorial.

Editor: REACTAPP.TOP15 min de lectura3498 palabras

Fuentes: Introducing Docling Pipelines: Building Enterprise-Grade RAG Data Pipelines

Dónde falla el código de enlace

Imagínese una unidad de almacenamiento compartida con 10,000 PDFs, un sitio de SharePoint repleto de archivos de Word y una pila de llamadas de clientes grabadas. El equipo de producto quiere que todo esto se almacene en un repositorio vectorial, buscable y dividido en fragmentos, con los datos personales eliminados y las duplicadas removidas.

La solución típica de ingeniería es un script, y luego otro script más. Se incorporan algunas bibliotecas, una hoja de cálculo de Pandas las une, un trabajo programado con cron ejecuta todo esto cada noche, y listo. Funciona, al menos por un tiempo.

Tres meses después, alguien pregunta por qué faltan los nuevos documentos. La pista conduce a un cambio en el esquema de una columna posterior, y el script descartó silenciosamente esas filas. Nadie se dio cuenta, porque no había nada observable. Después de la corrección se vuelve a ejecutar el proceso, y entonces se comprende que no existe registro de qué documentos ya fueron procesados, por lo que los 10,000 se procesan de nuevo.

Esa es la vida típica de los componentes que conectan los pipelines de documentos. Comienzan de forma sencilla y se deterioran lentamente, para luego hacerlo de forma abrupta. Se añaden intentos repetidos, el filtrado de calidad llega como algo secundario, y no existe seguimiento de dependencias entre pasos, por lo que el éxito depende de que los scripts se ejecuten en el orden correcto. Las actualizaciones incrementales son problemáticas sin una identidad estable para los documentos. Lo que queda es un enredo que solo su autor puede depurar, y ni siquiera el autor está seguro ya.

Qué es docling-pipelines

Docling-pipelines es un marco modular basado en operadores para el procesamiento de documentos, diseñado para crear pipelines de datos RAG completos. Su alcance abarca todo el ciclo de vida, comenzando con la ingesta desde fuentes locales o en la nube, pasando por la extracción de texto y entidades, el filtrado de calidad, el fragmentado y el embebedo, y finalizando con la escritura en una base de datos vectorial. Ese es el camino estándar, y la mayoría de los pipelines en producción son una variante de él.

Se instala como un paquete Python ordinario:

bash
pip install docling-pipelines

Funciona en cualquier lugar donde funcione Python. Para un uso básico no necesita infraestructura externa: ni Kafka, ni clústeres de Spark, nada que configurar. Un pipeline se describe en un archivo JSON, la CLI apunta a ese archivo y comienza la ejecución.

Existen tres formas de utilizarlo. La CLI es adecuada para ejecuciones puntuales y desarrollo local. La biblioteca en Python, centrada en DocpipeFlowManager, sirve para activar pipelines desde código de aplicaciones o notebooks. La REST API está pensada para pipelines que se ejecutan como servicio compartido utilizado por varios equipos. Se tratarán los tres métodos a continuación.

El proyecto es de código abierto, y su primera versión, v0.1.0, se lanzó en julio de 2025.

La idea central: operadores y flujos

Quienes sean nuevos en este framework deberían dedicarle la mayor parte del tiempo aquí, ya que todo lo demás queda claro una vez esto se comprende.

El operador es la unidad básica. Un operador es una clase de Python que acepta una tabla de documentos y devuelve una tabla, posiblemente transformada. Cada funcionalidad del framework, ya sea la ingesta, la extracción, la detección de idioma, el fragmentado o los embeddings, es un operador.

Las obligaciones son pocas:

  • short_name: la cadena que JSON Flow utiliza para referirse al operador
  • transform(table): toma un pa.Table y devuelve una lista de tablas además de un diccionario de metadatos
  • get_metadata(): una @staticmethod que devuelve los metadatos del operador para que pueda ser descubierto
  • get_required_features(): indica qué columnas necesita el operador en la entrada
  • validate(): un gancho opcional que verifica la configuración al iniciar

Un esqueleto mínimo se ve así:

from docpipe.core.operators.abstract_operator import AbstractOperator, OperatorCategory
import pyarrow as pa

class MyOperator(AbstractOperator):
  short_name = "my_operator"
  category = OperatorCategory.Quality

  def __init__(self, config: dict) -> None:
    super().__init__(config)

  def transform(self, table: pa.Table) -> tuple[list[pa.Table], dict]:
    metadata = self.create_base_metadata(total_docs_count=len(table))
    # … process table …
    return [table], metadata

  @staticmethod
  def get_metadata() -> dict:
  return {"short_name": "my_operator", "description": "…"}

La implementación de esos métodos genera un componente de primera clase que se puede combinar con cualquier otro operador del ecosistema.

Las tablas de PyArrow almacenan los datos. Cada operador recibe un pa.Table y devuelve uno. Esta es una elección intencionada, ya que el formato columnar de PyArrow es eficiente y tipado, y permite transferir datos entre etapas sin realizar copias. Las cadenas sin formato y los diccionarios de Python nunca se transfieren entre pasos.

La consecuencia positiva es que las columnas se van acumulando a medida que avanza el procesamiento de los datos. La etapa de ingesta agrega id, name, path y source. La etapa de extracción agrega content. El procesador en bloques agrega chunked_content, y la etapa de embeddings agrega embeddings. Para cuando una fila llega al almacén de vectores, ya contiene un registro completo, con todas sus columnas y metadatos, listo para ser indexado.

Un operador solo interactúa con las columnas que le interesan, y todo lo demás pasa sin ser afectado. Por lo tanto, se puede insertar un nuevo operador en cualquier lugar sin cambiar a sus vecinos.

Un flujo es un DAG. La tubería de procesamiento se almacena en un archivo JSON. Cada nodo declara un type (el nombre abreviado del operador), un name único en el grafo, un bloque config y una lista depends_on. Al iniciar, el motor resuelve el grafo de dependencias y ejecuta los nodos en orden topológico, con ramas paralelas que se ejecutan al mismo tiempo.

Así, la estructura de la tubería de procesamiento es de datos y no de código. Puede versionarse, compararse, validarse estáticamente y reemplazarse sin tocar ningún código en Python. La opción --validate detecta violaciones de dependencias, columnas faltantes y errores de configuración antes incluso de procesar un solo documento.

Por qué funciona el modelo. En la práctica destacan dos ventajas.

Una es la composibilidad. Un operador puede seguir a cualquier otro siempre y cuando los operadores anteriores hayan generado las columnas que se enumeran en get_required_features(). El motor verifica esto al iniciar y indica la columna faltante exacta y el nodo que debería haberla proporcionado, todo antes de que comience la ejecución.

La otra ventaja es la posibilidad de pruebas. Cada operador se comporta como una función pura de una tabla a otra, por lo que se puede probar por separado: se crea una pa.Table con las columnas necesarias, se llama a transform() y se verifica el resultado. No se requieren simulaciones, efectos secundarios ni pipelines en tiempo real.

Un recorrido por los operadores

Existen 22 operadores integrados en cinco categorías. Esta es una breve descripción.

Ingestión. IngestSource es el único operador de ingestión, que abarca tanto fuentes locales como en la nube. Una ruta local utiliza el proveedor filesystem, y el mismo nodo puede pasar a cualquiera de los ocho proveedores en la nube (S3, IBM COS, SharePoint, OneDrive, Google Drive, Box, archivos CSV y páginas web) sin que nada más en el flujo cambie. Genera una fila por archivo con solo metadatos y sin contenido aún. El paso de extracción obtiene el contenido más tarde, lo que mantiene la ingestión rápida y con bajo consumo de memoria incluso a gran escala.

Extracción. Extract convierte los archivos en bruto en texto estructurado. PDF, DOCX, HTML, imágenes, audio y video se convierten todos en formato markdown a través de Docling, ya sea en modo biblioteca (local, sin llamadas de red) o mediante Docling Serve en modo API, lo cual permite transferir la pesada tarea de extracción a un servicio dedicado.

La extracción de entidades es opcional además de lo anterior, y existen tres proveedores: LiteLLM (que redirige a más de 100 proveedores de modelos), IBM watsonx.ai y la extracción basada en plantillas de Docling. La elección depende del acceso a los modelos y de los costos.

ACLOperator forma parte de la etapa de extracción. Extrae los metadatos de control de acceso de los documentos en una columna separada, de modo que los sistemas posteriores puedan aplicar medidas de seguridad a nivel de documento sin tener que acceder nuevamente al archivo de origen.

Funcional. Esta categoría contiene la lógica del pipeline: operadores que transforman, redirigen y reorganizan los datos en lugar de enriquecerlos.

ChunkerOperator divide el texto extraído en fragmentos utilizando una de tres estrategias: simple (tamaño de carácter fijo, solapamiento configurable), semántica (basada en el contenido) o híbrida (fragmentación nativa de Docling que mantiene la estructura del documento). También puede resumir cada fragmento con una LLM, lo que proporciona una representación más rica para la recuperación de información.

EmbeddingsOperator genera embeddings vectoriales para cada fragmento. Funciona con modelos de HuggingFace ejecutados localmente, LiteLLM (más de 100 proveedores en la nube) e IBM watsonx.ai, y cambiar el modelo de embeddings solo requiere una modificación en una línea del archivo JSON de flujo.

BranchingOperator es donde los flujos se vuelven interesantes. Divide los documentos en subprocesos separados según los valores de las columnas, las condiciones de estilo SQL o las etiquetas de clasificación. Cada ramificación se ejecuta por separado y se referencia por su nombre en depends_on mediante notación de puntos, por ejemplo "depends_on": ["branch_node.branch_name"].

MergeOperator reúne nuevamente las corrientes divididas, ya sea apilando filas o combinando columnas, según lo que esperen los operadores siguientes en el flujo.

DocIdHashOperator genera un ID de hash determinista y estable a partir del contenido de cada documento. Ese ID sirve de base para la eliminación de duplicados y el procesamiento incremental: el mismo documento siempre recibe el mismo ID, sin importar dónde o cuándo sea ingresado.

EntityCurationOperator y NOOPOperator completan el conjunto. El primero se encarga de limpiar las entidades después de su extracción, mientras que el segundo es un nodo de paso que ayuda a conectar la red DAG.

Calidad. Los operadores de este grupo marcan la diferencia entre simplemente contar con un pipeline y contar con uno en el que se pueda confiar.

LanguageDetect identifica el idioma de un documento mediante fastText y agrega una columna lang_name que permite realizar filtrados, enrutamientos o etiquetado.

ReadabilityOperator evalúa cada documento desde cinco perspectivas en cuanto a su legibilidad: facilidad de lectura según Flesch, nivel según Flesch-Kincaid, grado de oscuridad según Gunning Fog, escala Dale-Chall y un recuento de palabras difíciles. Generan señales útiles para el enrutamiento, por ejemplo, para distinguir entre documentación técnica y contenido general antes de elegir una estrategia de fragmentación.

PIIAndHAPAnnotator utiliza detección basada en LLM para encontrar y ocultar información personal (direcciones de correo electrónico, números de teléfono, números de seguro social, números de tarjetas, cuentas bancarias, direcciones IP), así como contenido de odio, abuso y vulgaridades, con umbrales establecidos por categoría.

RedactionOperator se encarga de la ocultación basada en patrones cuando se conocen los formatos, como IDs internos, códigos de producto o cualquier cosa que pueda coincidir con una expresión regular.

EdedupOperator elimina duplicados exactos en todo el conjunto de documentos, utilizando la columna doc_id_hash para hacerlo de manera determinista.

SQLFilterOperator es uno de los componentes más subestimados. Filtra filas utilizando una condición SQL WHERE basada en los valores de las columnas, por lo que "docq_total_words > 100 AND lang_name = 'en'" constituye una barrera de calidad completa sin necesidad de Python. Junto con las puntuaciones de legibilidad y la detección de idioma, permite un enrutamiento bastante complejo sin escribir código alguno.

DocumentClassifierOperator clasifica los documentos en categorías configurables. DocQuality calcula métricas de calidad para todo el corpus, y MLEnrichmentOperator agrega predicciones de aprendizaje automático como columnas adicionales. El punto más importante, que también se menciona en otras descripciones de pipelines, es que la calidad de los datos suele influir más en los resultados de RAG que la elección del modelo.

VectorDB y almacenamiento. VectorDBOperator escribe documentos embebidos y divididos en chunks en un almacén de vectores, con OpenSearch y Milvus como backends soportados. Las asignaciones de campos, los ajustes de índice y la normalización de metadatos se definen todos en el JSON del flujo.

DocumentSetOperator guarda la tabla procesada en un conjunto de documentos respaldado por DuckDB. Esto es útil cuando los documentos procesados deben poder consultarse sin un almacén de vectores, o cuando se desea un punto de control duradero en medio del proceso.

StorageOutputOperator escribe los documentos de vuelta a destinos externos (S3, SharePoint, Google Drive o el sistema de archivos local), ya sea en formato procesado o original, lo cual es adecuado para patrones de “procesar y archivar”.

Todos estos componentes pueden combinarse en cualquier orden siempre y cuando se cumplan las dependencias previas, de modo que el flujo no esté limitado a una estructura fija.

Un flujo real

Aquí se muestra el flujo canónico de inicio rápido, un pipeline completo de ingestión a almacenamiento de vectores que utiliza Ollama para las incrustaciones y OpenSearch para el almacenamiento:

{
  "flow_name": "complete-document-pipeline",
  "global_config": {
    "doc_column": "content",
    "storage": "in-memory"
  },
  "flow": [
    {
      "type": "ingest_source",
      "name": "ingest_local_folder",
      "config": {
        "provider": "filesystem",
        "connection_params": {
          "paths": [
            "./sample_documents"
          ]
        },
        "include_filter": "pdf,txt,docx"
      }
    },
    {
      "type": "extract_operator",
      "name": "extract_with_docling",
      "config": {
        "text_extraction": {
          "provider": "docling_library"
        },
        "entity_extraction": {
          "provider": "none"
        }
      },
      "depends_on": [
        "ingest_local_folder"
      ]
    },
    {
      "type": "chunker",
      "name": "simple_chunker",
      "config": {
        "chunk_type": "simple",
        "chunk_size": 512,
        "chunk_overlap": 50
      },
      "depends_on": [
        "extract_with_docling"
      ]
    },
    {
      "type": "embeddings",
      "name": "ollama_embeddings",
      "config": {
        "provider": "litellm",
        "provider_config": {
          "model_id": "openai/nomic-embed-text",
          "api_base": "http://localhost:11434/v1"
        },
        "embeddings_column": "embeddings"
      },
      "depends_on": [
        "simple_chunker"
      ]
    },
    {
      "type": "vectordb",
      "name": "opensearch_vector_store",
      "config": {
        "provider": "opensearch",
        "doc_id_column": "doc_id_hash",
        "embeddings_column": "embeddings",
        "provider_config": {
          "index_name": "sample-documents-index",
          "host": "localhost",
          "port": 9200
        }
      },
      "depends_on": [
        "ollama_embeddings"
      ]
    }
  ]
}

Analizando nodo por nodo:

  • ingest_local_folder escanea ./sample_documents en busca de archivos PDF, de texto y DOCX a través de ingest_source y su proveedor de sistema de archivos. Cada archivo se convierte en una fila que contiene el ID, el nombre, la ruta y el origen. En este momento no se leen los contenidos, por lo que el proceso es rápido: solo se localizan los archivos en lugar de cargarlos.
  • extract_with_docling toma esas filas de metadatos, lee cada archivo con Docling y agrega una columna content que alberga el texto extraído en formato Markdown. En este paso los archivos PDF se transforman en texto estructurado y susceptible de consultas. El proveedor docling_library funciona íntegramente dentro del proceso, por lo que no se necesita ningún servicio externo.
  • simple_chunker divide la columna de contenido en trozos de 512 caracteres, con 50 caracteres de solapamiento entre vecinos. Agrega chunked_content, una lista estructurada de objetos de fragmento que incluyen su texto y posición en el documento de origen.
  • ollama_embeddings envía cada fragmento al modelo nomic-embed-text ejecutado localmente y almacena los vectores resultantes en una nueva columna embeddings. Se trata simplemente de LiteLLM adaptado para Ollama; al cambiar model_id y api_base, se redirige a cualquiera de los más de 100 proveedores que soporta LiteLLM, sin que se modifique nada más.
  • opensearch_vector_store actualiza o inserta las filas fragmentadas e incrustadas en un índice de OpenSearch, utilizando doc_id_hash como clave primaria. Por lo tanto, ejecutarlo nuevamente nunca genera duplicados.

Algunos aspectos estructurales merecen atención. depends_on es el único enlace necesario: no hay transferencia explícita de datos, ni registro de callbacks ni estado compartido, ya que el motor resuelve el grafo y mueve los datos. El bloque global_config establece valores por defecto que hereda cada operador. doc_column indica qué columna contiene el texto principal, y storage: "in-memory" mantiene las tablas intermedias en RAM entre pasos, lo cual es adecuado para la mayoría de las ejecuciones y puede reemplazarse por almacenamiento en disco para conjuntos de datos grandes.

Toda la pipeline se ejecuta con una sola orden:

docling-pipelines - flow-file pipeline.json

Patrones avanzados

Los flujos no tienen por qué ser cadenas lineales. Tres patrones se repiten en las implementaciones reales.

División y fusión. La división envía documentos a diferentes subconductos según criterios configurables. Cada ramificación es una salida con nombre a la que los nodos siguientes hacen referencia mediante notación de puntos en depends_on. Una ramificación de enrutamiento basada en la puntuación de legibilidad se ve así:

{
  "name": "quality_branching",
  "type": "branching",
  "config": {
    "branches": {
      "high_quality_branch": {
        "link_name": "High Quality Documents",
        "criteria_json": {
          "criteria_list": [
            {
              "variable": "flesch_reading_ease",
              "operator": ">",
              "value": 60
            }
          ],
          "logical_operator": "AND"
        }
      },
      "low_quality_branch": {
        "link_name": "Low Quality Documents",
        "criteria_json": {
          "criteria_list": [
            {
              "variable": "flesch_reading_ease",
              "operator": "<=",
              "value": 60
            }
          ],
          "logical_operator": "AND"
        }
      }
    }
  },
  "depends_on": [
    "readability"
  ]
}

La rama de alta calidad puede pasar por un proceso de enriquecimiento con ML antes de ser incrustada, mientras que la rama de baja calidad atraviesa otro SQLFilterOperator que descarta los documentos con cero palabras antes de la incrustación. Ambas terminan en índices separados de OpenSearch, y MergeOperator puede volver a combinar las corrientes posteriormente cuando la lógica posterior requiera una única vista.

Enrutamiento basado en filtros de calidad. La idea es ejecutar primero operadores de calidad económicos y luego permitir que SQLFilterOperator descarte filas antes de cualquier paso costoso con LLM. Un filtro completo podría verse así:

lang_detect → ededup → doc_quality → readability → sql_filter → embeddings

La condición sql_filter es simplemente una cláusula SQL WHERE expresada como datos:

{
  "criteria_list": [
    {
      "variable": "docq_total_words",
      "operator": ">",
      "value": 100
    },
    {
      "variable": "lang_name",
      "operator": "=",
      "value": "en"
    }
  ],
  "logical_operator": "AND"
}

No existe Python ni operadores personalizados, solo una condición en JSON, y cada fila que no la cumple nunca llega a la llamada de incrustación.

Enriquecimiento en múltiples etapas. La secuencia clasificar, enrutar, extraer, enriquecer y almacenar aparece constantemente en entornos de producción. Los documentos pueden clasificarse primero: la documentación técnica se dirige a un extractor de entidades ajustado para contenido técnico, mientras que los documentos de políticas se envían a otro extractor distinto. Cada ramificación agrega columnas de enriquecimiento específicas para su tipo, y los flujos se fusionan antes del procesamiento en bloques e incrustación, de modo que el resto del pipeline se comparta.

Cada etapa agrega columnas, y los operadores posteriores reciben una tabla cada vez más enriquecida. Nada de esto depende de modos o flags especiales. Se trata de operadores ordinarios combinados entre sí, lo cual representa la ventaja del modelo de operadores.

Tres formas de ejecutarlo

El framework es más que una herramienta CLI y se adapta a varios contextos de ingeniería.

CLI. Este es el camino más rápido para activar un pipeline en ejecución:

docling-pipelines - flow-file pipeline.json
docling-pipelines - flow-file pipeline.json - validate # validate without running
docling-pipelines - list-operators - verbose # discover all registered operators

--validate es útil durante el desarrollo de un flujo: las violaciones de dependencias, las columnas requeridas ausentes y los errores en el tipo de configuración se detectan antes de que se lea o escriba cualquier cosa. Es una buena práctica ejecutarlo en CI antes de desplegar cambios en el flujo.

Biblioteca de Python. Cuando los pipelines necesitan ser activados desde código de aplicación:

from docpipe.lib.docpipe_flow_manager import DocpipeFlowManager
manager = DocpipeFlowManager(flow_file="pipeline.json")
manager.execute()

Esto es adecuado para código incrustado en una aplicación más grande, un cuaderno de notas o un script de orquestación que necesita gestionar el propio ciclo de vida de ejecución.

REST API. Para funcionar como un servicio de larga duración:

uvicorn docpipe.api.main:app - host 0.0.0.0 - port 8000

El servidor FastAPI expone tres grupos de rutas: /api/v1/flows para gestionar flujos, /api/v1/job_runs para controlar las ejecuciones de tareas, y /api/v1/operators para descubrir operadores. Los usuarios se autentican mediante LDAP o OAuth2/OIDC usando tokens JWT, y la documentación OpenAPI/Swagger se genera automáticamente en /docs. Esta es la interfaz de un servicio compartido que utilizan varios equipos, que se activa mediante eventos externos, y del cual otros consultan el estado y los resultados.

Ampliación con operadores personalizados

Para lograr una adopción duradera en organizaciones reales, esta es sin duda la parte más importante del diseño.

El contrato es lo suficientemente compacto como para que un operador ocupe aproximadamente 30 líneas. Una clase de Python cumple los requisitos si hereda de AbstractOperator e implementa transform(), get_metadata() y get_required_features(). Se combina con cada operador integrado, aparece en la salida de --list-operators, y el JSON de flujo hace referencia a ella mediante short_name al igual que a un operador integrado.

El registro funciona de tres maneras, según la fase de desarrollo.

Ruta del sistema de archivos se utiliza para el desarrollo. Direccione una variable de entorno a un directorio local:

DOCPIPE_CUSTOM_OPERATORS=./my_operators docling-pipelines - flow-file pipeline.json

Todo lo que se encuentra en ese directorio se importa al iniciar el programa. No se necesita instalación, por lo que la iteración es rápida.

Paquete de Python sirve para la distribución. Publica los operadores como un paquete pip con el punto de entrada adecuado, instálalo en el mismo entorno y ellos se registrarán automáticamente. Así es como los operadores llegan a otros equipos sin que nadie toque la base de código principal.

URI de S3 es la opción empresarial. Dirige DOCPIPE_CUSTOM_OPERATORS hacia un paquete de operador remoto y el framework lo descarga y lo registra en tiempo de ejecución. Esto permite una gestión centralizada de los operadores en múltiples implementaciones: un único lugar para realizar actualizaciones, y cada implementación las aplica en su siguiente inicio.

Por lo tanto, la lógica específica de la empresa permanece fuera del núcleo del framework. Los procesadores de cumplimiento, los extractores de entidades específicos del dominio y los modelos de puntuación propietarios pueden ser empaquetados como operadores, combinados con elementos integrados en el JSON del flujo y desplegados sin modificar el framework.

Consideraciones operativas

Una pregunta legítima sobre cualquier herramienta de este tipo es si se trata de un buen prototipo o realmente está preparada para uso en producción. A continuación se detallan los aspectos relevantes.

Observabilidad. Se incluye soporte nativo para OpenTelemetry, y cada ejecución de un operador genera un span. Los registros son JSON estructurado con correlación de trazas, que incluye trace_id y span_id en cada línea. Esto funciona con Jaeger, Grafana Tempo, Datadog y AWS X-Ray sin necesidad de configuración en el lado de la aplicación, y no hay sobrecarga alguna cuando la telemetría está desactivada.

Procesamiento incremental. La cadena de procesamiento utiliza el ID determinista de DocIdHashOperator para hacer un seguimiento de lo que ya ha sido procesado. Al ejecutarla nuevamente, solo se procesan los documentos nuevos o modificados; el mismo documento enviado dos veces recibe el mismo hash y se omite. Establecer force_ingest: true en global_config anula esta configuración y vuelve a procesar todo. Los metadatos para las ejecuciones incrementales pueden almacenarse en DuckDB (por defecto), PostgreSQL o en el sistema de archivos.

Seguridad. ACLOperator muestra los metadatos de permisos como una columna para su aplicación posterior, y PIIAndHAPAnnotator detecta y elimina el contenido sensible antes de que llegue al almacén de vectores. Los secretos en la configuración del flujo pueden provenir de HashiCorp Vault: una ruta como vault://path/to/secret escrita en el JSON es resuelta por el motor mientras se ejecuta la tarea. El acceso a la API REST está protegido mediante LDAP y OAuth2/OIDC.

Escala. La ejecución se realiza en tres modos que van desde una computadora portátil hasta una flota distribuida. El valor predeterminado es un grupo de hilos dentro del mismo proceso, que es rápido, sencillo y no depende de otros componentes. Un grupo de procesos ejecuta las operaciones en procesos separados para tareas que requieren mucho uso de la CPU en un único nodo. Para cargas de trabajo de producción distribuida, existe un grupo de trabajo de Prefect que ejecuta contenedores Docker, lo cual permite la escalabilidad horizontal y la gestión centralizada de las ejecuciones. La configuración de micro-loteo controla el uso de memoria en cada modo, lo cual es importante cuando se procesan documentos grandes mediante extracción con LLM.

¿A dónde ir a continuación?

El proyecto se encuentra alojado en GitHub bajo la organización IBM, y su guía de inicio rápido es la forma más rápida de poner en marcha un pipeline. Las áreas que merecen un estudio más detallado incluyen la capa de extracción (integración con Docling, pipelines VLM para documentos con muchas imágenes, ASR para audio y video), la creación de un operador personalizado con lógica compleja desde la declaración inicial hasta las pruebas, el registro y el despliegue, el uso de Prefect con Docker para cargas de trabajo de gran volumen, así como las opciones de mapeo de campos y plantillas de esquema de VectorDBOperator para OpenSearch.

Leer más

  • Ingestión RAG con conciencia de calidad: enrutamiento de documentos según su legibilidad — Un flujo declarativo de pipelines docling que evalúa el idioma, las duplicaciones y la legibilidad según la escala de Flesch, y luego envía los documentos a dos índices de OpenSearch para búsquedas por parte de clientes y desarrolladores.
  • Cómo los pipelines docling almacenan vectores de documentos para RAG con OpenSearch o Milvus — Un análisis del operador vectordb en los pipelines docling de IBM: adaptadores de almacenamiento de vectores conectables, limpieza de fragmentos obsoletos, dimensiones detectadas automáticamente y flujos controlados por JSON.