> 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/vector-store.md).

# Almacén vectorial

Actualmente ofrecemos soporte de primera parte para el siguiente almacén vectorial:

### Memoria

Esta es una implementación de un almacén vectorial volátil que mantiene tus embeddings en la memoria de la máquina durante la sesión actual. Es útil cuando no necesitas almacenar los embeddings generados para uso a largo plazo, sino solo durante las sesiones de interacción actuales (o para uso local).

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\MemoryVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        return new MemoryVectorStore();
    }
}
```

### Archivo

El almacenamiento en archivos podría ser útil para casos de uso de bajo volumen o para entornos locales y de pruebas. Los documentos incrustados se almacenarán en el sistema de archivos y se procesarán durante la búsqueda por similitud.

`FileVectorStore` usa generadores de PHP para leer los documentos incrustados desde el sistema de archivos. Nunca mantendrá más de `topK` elementos en memoria mientras itera muy rápido. Puedes almacenar miles de documentos en tu sistema de archivos local, solo teniendo en cuenta el tiempo máximo que puedes aceptar para realizar la búsqueda por similitud.

También puedes usar este componente para liberar agentes con algo de conocimiento ya incorporado en un archivo.

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\FileVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        return new FileVectorStore(
            directory: storage_path(),
            topK: 4
        );
    }
}
```

### PHPVector

Adaptador PHPVector sobre [`ezimuel/phpvector`](https://github.com/ezimuel/PHPVector). Es una base de datos vectorial pura en PHP que implementa **HNSW** (Hierarchical Navigable Small World) para búsqueda aproximada de vecinos más cercanos y **BM25** para recuperación de texto completo. Ambos motores pueden combinarse en una sola **búsqueda híbrida** canalización.

Puedes instalar el componente con composer:

```shellscript
composer require neuron-core/php-vector
```

Úsalo en un contexto RAG:

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\PHPVector\PHPVector;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyRAG extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        return new PHPVector(
            path: '/var/data/mydb',
            topK: 5,
        );
    }
}
```

### MariaDB

MariaDB admite el tipo de columna VECTOR a partir de la versión 11.7. Para que este componente funcione, necesitas crear la tabla para almacenar los documentos y los vectores relacionados. Aquí tienes el script SQL que puedes usar para hacerlo:

```sql
CREATE TABLE IF NOT EXISTS rag_documents (
    id UUID NOT NULL PRIMARY KEY,
    content TEXT,
    sourceType VARCHAR(255),
    sourceName VARCHAR(255),
    metadata JSON,
    embedding VECTOR(1536) NOT NULL,
    VECTOR INDEX (embedding)
)
```

Úsalo en un contexto RAG:

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\MariaDBVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        return new MariaDBVectorStore(
            new \PDO(...), // O obtener la instancia de PDO desde el ORM
        );
    }
}
```

### Pinecone

Pinecone facilita proporcionar memoria a largo plazo para aplicaciones de IA de alto rendimiento. Es una base de datos vectorial administrada y nativa de la nube, con una API sencilla y sin problemas de infraestructura. Pinecone ofrece resultados de consulta frescos y filtrados con baja latencia a la escala de miles de millones de vectores.

Así es como usar Pinecone en tu agente:

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\PineconeVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        return new PineconeVectorStore(
            key: 'PINECONE_API_KEY',
            indexUrl: 'PINECONE_INDEX_URL'
        );
    }
}
```

Pinecone también admite búsqueda híbrida que te permite filtrar documentos no solo por similitud con el prompt de entrada, sino también por los metadatos almacenados junto con tus documentos. Puedes pasar filtros adicionales a tu instancia de agente para que Pinecone los tenga en cuenta al filtrar documentos.

Puedes añadir el `addVectorStoreFilters()` método a la clase de tu agente para pasar filtros en tiempo de ejecución:

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\PineconeVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    protected array $vectorStoreFilters = [];

    ...

    protected function vectorStore(): VectorStoreInterface
    {
        $store = new PineconeVectorStore(
            key: 'PINECONE_API_KEY',
            indexUrl: 'PINECONE_INDEX_URL'
        );

        return $store->withFilters($this->vectorStoreFilters);
    }

    public function addVectorStoreFilters(array $filters): self
    {
        $this->vectorStoreFilters = $filters;
        return $this;
    }
}
```

Cuando ejecutes tu agente, puedes pasar filtros sobre la marcha:

```php
$response = MyRAG::make()
    ->addVectorStoreFilters([
        // Añadir filtros
    ])
    ->chat(new UserMessage(...))
    ->getMessage();
```

Echa un vistazo a la documentación oficial de Pinecone para entender mejor los filtros de metadatos: <https://docs.pinecone.io/reference/api/2025-04/data-plane/query#body-filter>

### Weaviate

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\WeaviateVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        return new WeaviateVectorStore(
            collection: 'WEAVIATE_COLLECTION_NAME',
            host: 'http://localhost:8080', // URL local o en la nube
            key: 'WEAVIATE_KEY' // opcional para despliegue local
        );
    }
}
```

### Elasticsearch

La base de datos vectorial de código abierto de Elasticsearch ofrece una forma eficiente de crear, almacenar y buscar embeddings vectoriales. Para usar Elasticsearch como almacén vectorial en la implementación de tus agentes, tienes que importar el cliente oficial:

```bash
composer require elasticsearch/elasticsearch
```

Así es como crear un RAG que use Elasticsearch:

```php
namespace App\Neuron;

use Elastic\Elasticsearch\ClientBuilder;
use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\ElasticsearchVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        $elasticsearch = ClientBuilder::create()
           ->setHosts(['<elasticsearch-endpoint>'])
           ->setApiKey('<api-key>')
           ->build();
       
        return new ElasticsearchVectorStore(
            client: $elasticsearch,
            index: 'neuron-ai'
        );
    }
}
```

Elasticsearch también admite búsqueda híbrida. Puedes pasar filtros adicionales a tu instancia de agente para que Elasticsearch los tenga en cuenta al filtrar documentos.

Puedes añadir el `addVectorStoreFilters()` método a la clase de tu agente para pasar filtros en tiempo de ejecución:

```php
namespace App\Neuron;

use Elastic\Elasticsearch\Client;
use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\ElasticsearchVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    protected array $vectorStoreFilters = [];

    ...

    protected function vectorStore(): VectorStoreInterface
    {
        // Crear el cliente
        $elasticsearch = ClientBuilder::create()
           ->setHosts(['<elasticsearch-endpoint>'])
           ->setApiKey('<api-key>')
           ->build();
           
        // Crear el almacén
        $store = new ElasticsearchVectorStore(
            client: $this->elasticsearch,
            index: 'neuron-ai'
        );

        // Aplicar filtros
        return $store->withFilter($this->vectorStoreFilters);
    }

    public function addVectorStoreFilters(array $filters): self
    {
        $this->vectorStoreFilters = $filters;
        return $this;
    }
}
```

Pasar filtros dinámicamente en tiempo de ejecución:

```php
$response = MyRAG::make()
    ->addVectorStoreFilters([
        // Añadir filtros
    ])
    ->chat(new UserMessage(...))
    ->getMessage();
```

### OpenSearch

OpenSearch es la alternativa de código abierto pura a Elasticsearch. Para usar OpenSearch en tus agentes necesitas instalar su cliente oficial:

```bash
composer require opensearch-project/opensearch-php
```

Una vez que tengas el cliente oficial instalado en tu aplicación, puedes devolver una instancia de `OpenSearchVectorStore` en tu agente RAG:

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\OpenSearchVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;
use OpenSearch\GuzzleClientFactory;

class MyChatBot extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        $opensearch = new GuzzleClientFactory()->create([
            'base_uri' => 'http://localhost:9200',
        ]);
        
        return new OpenSearchVectorStore(
            client: $opensearch,
            index: 'neuron-ai',
        );
    }
}
```

### Typesense

[Typesense](https://typesense.org/) es una alternativa de código abierto a las opciones anteriores. Para usar Typesense en tus agentes necesitas instalar su cliente oficial:

```bash
composer require typesense/typesense-php
```

Una vez que tengas el cliente oficial instalado en tu aplicación, puedes devolver una instancia de TypesenseVectorStore en tu agente RAG:

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\TypesenseVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        $typesense = new \Typesense\Client([
            'api_key' => 'TYPESENSE_API_KEY',
            'nodes' => [
                [
                    'host' => 'TYPESENSE_NODE_HOST',
                    'port' => 'TYPESENSE_NODE_PORT',
                    'protocol' => 'TYPESENSE_NODE_PROTOCOL'
                ],
            ]
        ]);
        
        return new TypesenseVectorStore(
            client: $typesense,
            collection: 'neuron-ai',
            vectorDimension: 1024
        );
    }
}
```

### Qdrant

[Qdrant](https://qdrant.tech/) es una base de datos vectorial de código abierto con sólidas capacidades de búsqueda por similitud. Para usar Qdrant en tus agentes tienes que proporcionar una `collectionUrl`. Esto significa que primero necesitarás crear una colección en Qdrant con sus atributos como: nombre, algoritmo de búsqueda por similitud, dimensión del vector, etc.

Una vez que tengas la URL de la colección, puedes adjuntar la `QdrantVectorStore` instancia a tu agente.

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\QdrantVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        return new QdrantVectorStore(
            collectionUrl: 'http://localhost:6333/collections/neuron-ai/',
            key: 'QDRANT_API_KEY'
        );
    }
}
```

### ChromaDB

[Chroma](https://trychroma.com/) es una base de datos de código abierto diseñada para ser una fuente de datos para aplicaciones de IA. Para usar ChromaDB en tus agentes tienes que proporcionar el nombre de una colección interna donde quieras almacenar los embeddings.

Una vez que hayas creado la colección en tu instancia de Chroma, puedes adjuntar la `ChromaVectorStore` instancia al agente:

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\ChromaVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        return new ChromaVectorStore(
            collection: 'neuron-ai',
            //host: 'http://localhost:8000', <-- Esto es por defecto
            topK: 5
        );
    }
}
```

### Meilisearch

[Meilisearch](https://www.meilisearch.com/) es un motor de búsqueda híbrida, pero la implementación de Neuron lo utiliza exclusivamente como un almacén vectorial para embeddings y búsqueda por similitud.

El `indexUid` debe ser el identificador de un índice de Meilisearch que hayas creado y configurado. Asegúrate de que este índice defina un campo vectorial cuya dimensión coincida con el tamaño del embedding producido por el generador de embeddings que estás usando. El `generador de embeddings` valor (por ejemplo, `predeterminado`) debe corresponder a un generador de embeddings con nombre configurado en tu configuración de Neuron para que los vectores almacenados y la configuración del índice permanezcan alineados. Añade el componente a tu RAG:

```php
namespace App\Neuron;

use NeuronAI\RAG\RAG;
use NeuronAI\RAG\VectorStore\MeilisearchVectorStore;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyChatBot extends RAG
{
    ...

    protected function vectorStore(): VectorStoreInterface
    {
        return new MeilisearchVectorStore(
            indexUid: 'MEILISEARCH_INDEXUID',
            host: 'http://localhost:8000', // O usa la URL de la nube
            key: 'MEILISEARCH_API_KEY',
            embedder: 'default',
            topK: 5
        );
    }
}
```

### Implementar almacenes vectoriales personalizados

Si quieres crear un nuevo proveedor, tienes que implementar la `VectorStoreInterface` interfaz:

```php
namespace NeuronAI\RAG\VectorStore;

use NeuronAI\RAG\Document;

interface VectorStoreInterface
{
    public function addDocument(Document $document): void;

    /**
     * @param  Document[]  $documents
     */
    public function addDocuments(array $documents): void;

    public function deleteBySource(string $sourceName, string $sourceType): void;

    /**
     * Devuelve los documentos más similares al embedding.
     *
     * @param  float[]  $embedding
     * @return Document[]
     */
    public function similaritySearch(array $embedding, int $k = 4): iterable;
}
```

Hay dos métodos diferentes para añadir un solo documento o una colección de documentos porque muchas bases de datos proporcionan APIs distintas para estos casos de uso. Si la base de datos con la que quieres interactuar no maneja estas solicitudes de forma diferente, puedes implementar `addDocument()` como marcador de posición.

similaritySearch debe devolver documentos con una puntuación de similitud, no una distancia de similitud. Si la base de datos subyacente devuelve una distancia, puedes convertirla en una puntuación usando la clase de utilidad `VectorSimilarity`:

```php
namespace App\Neuron\VectorStore;

use NeuronAI\RAG\Document;
use NeuronAI\RAG\VectorSimilarity;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyVectorStore implements VectorStoreInterface
{
    ...


    /**
     * @param float[] $embeddings
     */
    public function similaritySearch(array $embedding): iterable
    {
        $documents = // obtener documentos del almacén vectorial

        return \array_map(function (Document $document) {
            return $document->setScore(
                VectorSimilarity::similarityFromDistance($similarity)
            );
        }, $documents);
    }
}
```

Esta es la plantilla básica para una nueva implementación de proveedor de IA.

```php
namespace App\Neuron\VectorStore;

use GuzzleHttp\Client;
use GuzzleHttp\RequestOptions;
use NeuronAI\RAG\Document;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyVectorStore implements VectorStoreInterface
{
    protected Client $client;

    public function __construct(
        string $key,
        protected string $index,
        protected int $topK = 5
    ) {
        $this->client = new Client([
            'base_uri' => 'https://api.vector-store.com',
            'headers' => [
                'Accept' => 'application/json',
                'Content-Type' => 'application/json',
                'Authorization' => "Bearer {$key}",
            ]
        ]);
    }

    public function addDocument(Document $document): void
    {
        $this->addDocuments([$document]);
    }

    /**
     * @param Document[] $documents
     */
    public function addDocuments(array $documents): void
    {
        $this->client->post("indexes/{$this->index}", [
            RequestOptions::JSON => \array_map(function (Document $document) {
                return [
                    'vector' => $document->embedding,
                ];
            }, $documents)
        ]);
    }

    /**
     * @return Document[]
     */
    public function similaritySearch(array $embedding): iterable
    {
        // realizar la búsqueda por similitud y devolver un array de objetos Document
    }
}
```

Después de crear tu propia implementación, puedes usarla en el agente:

```php
namespace App\Neuron;

use App\Neuron\VectorStore\MyVectorStore;
use NeuronAI\Agent;
use NeuronAI\RAG\VectorStore\VectorStoreInterface;

class MyAgent extends Agent
{
    protected function vectorStore(): VectorStoreInterface
    {
        return new MyVectorStore(
            key: 'VECTORSTORE_API_KEY',
            index: 'neuron-ai',
        );
    }
}
```

{% hint style="warning" %}
Recomendamos encarecidamente que envíes nuevas implementaciones de almacenes vectoriales mediante un PR en el repositorio oficial o utilizando otros [Inspector.dev](https://inspector.dev/developer-support/) canales de soporte. La nueva implementación puede recibir un impulso importante en su avance por parte de la comunidad.
{% endhint %}
