> For the complete documentation index, see [llms.txt](https://docs.neuron-ai.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.neuron-ai.dev/neuron-v3-es/rag/data-loader.md).

# Cargador de datos

{% hint style="info" %}
PRERREQUISITOS

Esta guía asume que ya estás familiarizado con RAG. Consulta la documentación dedicada: <https://docs.neuron-ai.dev/rag>
{% endhint %}

Para construir una aplicación de IA estructurada, necesitas la capacidad de convertir toda la información que tienes en texto, para poder generar embeddings, guardarlos en un almacén vectorial y luego alimentar a tu Agente para responder a las preguntas del usuario.

<figure><img src="/files/8afebff6bbf763e38eaebfa876a9b54d40e99e02" alt=""><figcaption></figcaption></figure>

Neuron te ofrece varias herramientas (cargadores de datos) para simplificar este proceso.

```php
use App\Neuron\MyRAG;
use NeuronAI\RAG\DataLoader\FileDataLoader;

MyRAG::make()->addDocuments(
    // Usa el componente cargador de archivos para procesar un archivo de texto
    FileDataLoader::for(__DIR__.'/my-article.md')->getDocuments()
);
```

Usando el kit de herramientas Neuron puedes crear pipelines de carga de datos con la ventaja de interfaces unificadas para facilitar las interacciones entre componentes, como proveedores de embeddings, almacén vectorial y lectores de archivos.

## FileDataLoader

Si necesitas extraer texto de archivos, el `FileDataLoader` permite procesar cualquier documento de texto sencillo.

```php
use NeuronAI\RAG\DataLoader\FileDataLoader;

// Lee un archivo y obtén "documentos"
$documents = FileDataLoader::for(__DIR__.'/my-article.md')->getDocuments();

// Pasa un directorio para procesar todos los archivos
$documents = FileDataLoader::for(__DIR__)->getDocuments();
```

Por defecto `FileDataLoader` lee el contenido de un archivo tal como está en el sistema de archivos, pero no todos los tipos de archivo están listos para ser tratados como texto simple. Neuron te proporciona la ReaderInterface y varios componentes de lectura predefinidos para los formatos de archivo más comunes.

Ten en cuenta que cada lector de archivos está asociado a una extensión de archivo. Así que, en función de la extensión del archivo de entrada, el cargador de datos usará automáticamente el lector adecuado.

### Lector de PDF

{% hint style="warning" %}
Para usar `PdfReader` necesitas instalar la utilidad [**poppler**](https://en.wikipedia.org/wiki/Pdftotext) .
{% endhint %}

```php
use NeuronAI\RAG\DataLoader\FileDataLoader;

// Registra el lector de PDF
$documents = FileDataLoader::for(__DIR__)
    ->addReader('pdf', new \NeuronAI\RAG\DataLoader\PdfReader())
    ->getDocuments();
```

### Lector de HTML a Markdown

{% hint style="warning" %}
Para usar `HtmlReader` necesitas instalar la utilidad [**html2text**](https://github.com/mtibben/html2text) paquete de composer.
{% endhint %}

```php
use NeuronAI\RAG\DataLoader\FileDataLoader;

// Registra el lector de PDF
$documents = FileDataLoader::for(__DIR__)
    ->addReader(['html', 'xhtml'], new \NeuronAI\RAG\DataLoader\HtmlReader())
    ->getDocuments();
```

### StringDataLoader

Si ya estás obteniendo texto de tu base de datos u otras fuentes, puedes usar StringDataLoader para convertir este texto en documentos, listos para ser convertidos en embeddings y almacenados por los otros componentes de Neuron en la cadena:

```php
use App\Neuron\MyRAG;
use NeuronAI\RAG\DataLoader\StringDataLoader;

$contents = [
    // lista de cadenas (texto que quieres convertir en embeddings)
];

foreach ($contents as $text) {
    $documents = StringDataLoader::for($text)->getDocuments(); 
    
    MyRAG::make()->addDocuments($documents);
}
```

### Metadatos del documento

Después de obtener el array de documentos de un cargador de datos, eventualmente puedes adjuntar metadatos personalizados al documento que se guardará en el almacén vectorial junto con otros campos predeterminados del documento:

```php
$documents = FileDataLoader::for($directory)->getDocuments(); 

foreach($documents as $document) {
    $document->addMetadata('user_id', 1234);
}

MyRAG::make()->addDocuments($documents);
```

Una vez que tengas estos campos personalizados en el almacén vectorial, puedes usar la búsqueda híbrida para las bases de datos que admiten esta función.

{% hint style="info" %}
La búsqueda híbrida te permite acotar el alcance de una consulta de búsqueda semántica contra registros que coinciden con ciertos criterios en otros campos del documento, en lugar de comparar solo los embeddings vectoriales. Explora la [sección Vector Store](/neuron-v3-es/rag/vector-store.md) para saber qué bases de datos admiten la búsqueda híbrida.
{% endhint %}

## Divisor de texto

Los cargadores de datos de Neuron reciben archivos o texto como entrada y generan un array de `\NeuronAI\RAG\Document` objetos. Estos documentos son unidades que pueden convertirse en embeddings. El texto original se divide en partes más pequeñas para convertirse en embeddings y almacenarse en el almacén vectorial.

La lógica que usan los cargadores de datos para dividir un texto largo en fragmentos puede personalizarse mediante diferentes estrategias. Neuron tiene un componente dedicado para este propósito llamado "Splitter", y puede asociarse al cargador de datos según la estrategia que prefieras o necesites:

```php
$documents = FileDataLoader::for($directory)
    ->withSplitter(
        new DelimiterTextSplitter()
    )
    ->getDocuments();
```

### DelimiterTextSplitter (predeterminado)

Este es el divisor predeterminado para todos los cargadores de datos.

```php
$documents = FileDataLoader::for($directory)
    ->withSplitter(
        new DelimiterTextSplitter(
            maxLength: 1000,
            separator: '.',
            wordOverlap: 0
        )
    )
    ->getDocuments();
```

Cada uno de estos parámetros tiene un impacto en el rendimiento y la precisión de tu agente RAG.

#### Longitud máxima

Cada fragmento no será más largo que este valor, y eventualmente se dividirá en documentos más pequeños. La longitud puede afectar la precisión de las representaciones de embeddings. Cuanto más largos sean tus unidades de texto, menos precisa será la representación de los embeddings.

#### Separador

El texto primero se divide en fragmentos según un separador. Por defecto, el componente usa el carácter de punto. Eventualmente puedes personalizar este separador usando cualquier delimitador para tu texto.

#### Solapamiento

A veces puede ser útil incorporar palabras del fragmento anterior y del siguiente en un documento para aumentar la conexión semántica entre secciones adyacentes del texto. Por defecto no se aplica solapamiento.

### SentenceTextSplitter

Divide el texto en oraciones, agrupa en fragmentos basados en palabras y, opcionalmente, aplica solapamiento en términos de palabras.

```php
$documents = FileDataLoader::for($directory)
    ->withSplitter(
        new SentenceTextSplitter(
            maxWords: 200,
            overlapWords: 0
        )
    )
    ->getDocuments();
```

**MaxWords**: número máximo de palabras por fragmento

**OverlapWords**: número de palabras superpuestas entre fragmentos

### Implementar divisores personalizados

Puedes implementar una lógica de división personalizada implementando la `SplitterInterface`:

```php
namespace NeuronAI\RAG\Splitter;

use NeuronAI\RAG\Document;

interface SplitterInterface
{
    /**
     * @return Document[]
     */
    public function splitDocument(Document $document): array;

    /**
     * @param  Document[]  $documents
     * @return Document[]
     */
    public function splitDocuments(array $documents): array;
}
```

Puedes interactuar con un servicio externo o crear tu propia lógica para dividir un texto largo en fragmentos más pequeños. Una vez que hayas creado tu implementación personalizada, puedes usarla con los cargadores de datos:

```php
class CustomSplitter implements SplitterInterface
{
    public function splitDocument(Document $document): array
    {
        // Tu lógica aquí...
    }
    
    public function splitDocuments(array $documents): array
    {
        // Tu lógica aquí...
    }
}

// Usa el divisor personalizado en el pipeline del cargador de datos
$documents = FileDataLoader::for($directory)
    ->withSplitter(
        new CustomSplitter()
    )
    ->getDocuments();
```

## Reindexar la fuente de conocimiento

La reindexación es un tema candente en el diseño de sistemas RAG porque la práctica de dividir texto en fragmentos dificulta actualizar piezas individuales de información cuando cambia el contenido del conocimiento original.

En Neuron, la `Document` class está diseñada para llevar algunos metadatos que te ayuden a identificar la fuente de cada pieza de conocimiento almacenada en la base de datos vectorial, como `sourceType` y `sourceName` campos. Usando esta información puedes actualizar fácilmente el almacén vectorial con la versión actualizada del contenido de un archivo previamente usado como fuente de conocimiento.

{% hint style="warning" %}
La nueva versión del archivo **debe tener la misma ruta y nombre** que usaste originalmente, de lo contrario los documentos se añadirán como nuevos.
{% endhint %}

```php
$documents = FileDataLoader::for("/path/to/directory")
    ->withSplitter(
        new SentenceTextSplitter(
            maxWords: 200,
            overlapWords: 0
        )
    )
    ->getDocuments();

// Reindexa por sourceType y sourceName
MyRAG::make()->reindexBySource($documents);
```

Si `sourceType` y `sourceName` algunos de los Documentos ya están presentes en el almacén vectorial, se eliminarán y se guardarán los Documentos de la nueva versión. Los otros documentos se almacenarán como de costumbre en la base de datos vectorial.

## Usa componentes independientes

En los ejemplos siguientes usamos la instancia del agente RAG para procesar la parte final de la canalización de ingesta: generar embeddings para fragmentos de documentos y almacenarlos en la base de datos vectorial.

Como alternativa a aprovechar la instancia del agente RAG, puedes usar el proveedor de embeddings y el almacén vectorial como componentes independientes. Recuerda que aquí el almacén vectorial debe estar conectado al mismo agente RAG.

```php
use App\Neuron\MyRAG;
use NeuronAI\RAG\DataLoader\FileDataLoader;
use NeuronAI\RAG\DataLoader\StringDataLoader;
use NeuronAI\RAG\EmbeddingProvider\OpenAIEmbeddingProvider;
use NeuronAI\RAG\VectorStore\FileVectorStore;

$embedder = new OpenAIEmbeddingProvider(
    key: 'OPENAI_API_KEY',
    model: 'OPENAI_MODEL'
);

$store = new FileVectoreStore(
    directory: __DIR__,
    key: 'demo'
);

// Procesa archivos y contenidos
$documents = FileDataLoader::for(__DIR__.'/documents');
    ->addReader('pdf', new \NeuronAI\RAG\DataLoader\PdfReader())
    ->getDocuments(); 

// Genera embeddings y almacena documentos en la base de datos vectorial
$store->addDocuments(
    $embedder->embedDocuments($documents)
);

```

Con este proceso sencillo puedes ingerir GB de datos en tu almacén vectorial para alimentar a tu agente RAG.
