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

# 向量存储

Neuron 为您提供可直接使用的组件，用于将您的智能体连接到向量数据库。

我们目前为以下向量存储提供第一方支持：

### 内存

这是一个易失性向量存储的实现，它会在当前会话中将你的嵌入保存在机器内存中。当你不需要长期保存生成的嵌入，只需要在当前交互会话期间（或用于本地使用）保存时，它很有用。

```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();
    }
}
```

### 文件

文件存储适用于低流量使用场景或本地和预发布环境。嵌入式文档将存储在文件系统中，并在相似度搜索期间进行处理。

`FileVectorStore` 使用 PHP 生成器从文件系统中读取嵌入式文档。迭代时它永远不会在内存中保留超过 `topK` 个项目，同时保持非常快的速度。你可以在本地文件系统中存储数千个文档，只需注意你可接受执行相似度搜索的最大时间。

你还可以使用此组件，将已经包含某些知识的智能体以文件形式发布。

```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

基于 [`ezimuel/phpvector`](https://github.com/ezimuel/PHPVector)的 PHPVector 适配器。它是一个纯 PHP 向量数据库，实现了 **HNSW** （分层可导航小世界）近似最近邻搜索，以及 **BM25** 用于全文检索。这两种引擎可以组合到单个 **混合搜索** 流程中。

你可以使用 composer 安装该组件：

```shellscript
composer require ezimuel/phpvector
```

在 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 从 11.7 版本开始支持 VECTOR 列类型。要让此组件正常工作，你需要创建用于存储文档及其相关向量的表。以下是你可以使用的 SQL 脚本：

```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)
)
```

在 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(...), // 或从 ORM 中获取 PDO 实例
        );
    }
}
```

### Pinecone

Pinecone 让为高性能 AI 应用提供长期记忆变得很容易。它是一个托管的、云原生的向量数据库，拥有简单的 API，而且没有基础设施负担。Pinecone 以低延迟在数十亿向量的规模下提供新鲜、经过过滤的查询结果。

以下是在你的智能体中使用 Pinecone 的方法：

```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 还支持混合搜索，它不仅允许你按与输入提示的相似度筛选文档，还可以按与你的文档一起存储的元数据进行筛选。你可以向智能体实例传递额外的过滤条件，这样 Pinecone 在筛选文档时就会将它们纳入考虑。

你可以添加 `addVectorStoreFilters()` 方法到你的智能体类中，以便在运行时传递过滤条件：

```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;
    }
}
```

当你运行智能体时，可以动态传入过滤条件：

```php
$response = MyRAG::make()
    ->addVectorStoreFilters([
        // 添加过滤条件
    ])
    ->chat(new UserMessage(...))
    ->getMessage();
```

查看 Pinecone 官方文档，以更好地理解元数据过滤器： <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
            key: 'WEAVIATE_KEY' // 本地部署时可选
        );
    }
}
```

### Elasticsearch

Elasticsearch 的开源向量数据库提供了一种高效的方式来创建、存储和搜索向量嵌入。要在你的智能体实现中使用 Elasticseach 作为向量存储，你必须导入官方客户端：

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

以下是创建一个使用 Elasticsearch 的 RAG 的方法：

```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 也支持混合搜索。你可以向智能体实例传递额外的过滤条件，这样 Elasticsearch 在筛选文档时就会将它们纳入考虑。

你可以添加 `addVectorStoreFilters()` 方法到你的智能体类中，以便在运行时传递过滤条件：

```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
    {
        // 创建客户端
        $elasticsearch = ClientBuilder::create()
           ->setHosts(['<elasticsearch-endpoint>'])
           ->setApiKey('<api-key>')
           ->build();
           
        // 创建存储
        $store = new ElasticsearchVectorStore(
            client: $this->elasticsearch,
            index: 'neuron-ai'
        );

        // 应用过滤条件
        return $store->withFilter($this->vectorStoreFilters);
    }

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

在运行时动态传递过滤条件：

```php
$response = MyRAG::make()
    ->addVectorStoreFilters([
        // 添加过滤条件
    ])
    ->chat(new UserMessage(...))
    ->getMessage();
```

### OpenSearch

Opensearch 是 Elasticsearch 的纯开源替代方案。要在你的智能体中使用 Opensearch，你需要安装其官方客户端：

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

一旦你的应用中安装了官方客户端，你就可以返回一个 `OpenSearchVectorStore` 的实例，放入你的 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/) 是上述选项的开源替代方案。要在你的智能体中使用 Typesense，你需要安装其官方客户端：

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

一旦你的应用中安装了官方客户端，你就可以在你的 RAG 智能体中返回一个 TypesenseVectorStore 的实例：

```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/) 是一个具有强大相似度搜索能力的开源向量数据库。要在你的智能体中使用 Qdrant，你必须提供一个 `collectionUrl`。这意味着你首先需要在 Qdrant 上创建一个集合，并设置其属性，如：名称、相似度搜索算法、向量维度等。

一旦你有了集合 URL，你就可以将 `QdrantVectorStore` 实例附加到你的智能体上。

```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/) 是一个开源数据库，专为成为 AI 应用的数据源而设计。要在你的智能体中使用 ChromaDB，你必须提供一个内部集合的名称，用于存储嵌入。

一旦你在 Chroma 实例上创建了集合，你就可以将 `ChromaVectorStore` 实例附加到智能体：

```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', <-- 这是默认值
            topK: 5
        );
    }
}
```

### Meilisearch

[Meilisearch](https://www.meilisearch.com/) 是一个混合搜索引擎，但 Neuron 的实现将其专门用作嵌入和相似度搜索的向量存储。

该 `indexUid` 参数应为你已创建并配置的 Meilisearch 索引的标识符。请确保该索引定义了一个向量字段，其维度与你所使用的嵌入器生成的嵌入大小匹配。 `嵌入器` 值（例如， `default`）必须对应于你在 Neuron 配置中设置的一个命名嵌入器，以确保存储的向量与索引配置保持一致。将该组件添加到你的 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', // 或使用云端 URL
            key: 'MEILISEARCH_API_KEY',
            embedder: 'default',
            topK: 5
        );
    }
}
```

### 实现自定义向量存储

如果你想创建一个新的提供者，你需要实现 `VectorStoreInterface` 接口：

```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;

    /**
     * 返回与嵌入最相似的文档。
     *
     * @param  float[]  $embedding
     * @return Document[]
     */
    public function similaritySearch(array $embedding, int $k = 4): iterable;
}
```

之所以有用于添加单个文档或文档集合的两个不同方法，是因为许多数据库为这些用例提供了不同的 API。如果你想交互的数据库不以不同方式处理这些请求，你可以将 `addDocument()` 实现为占位符。

similaritySearch 应返回带有相似度分数而不是相似度距离的文档。如果底层数据库返回的是距离，你可以使用工具类 `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 = // 从向量存储中获取文档

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

这是新的 AI 提供者实现的基础模板。

```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
    {
        // 执行相似度搜索并返回 Document 对象数组
    }
}
```

创建你自己的实现后，你可以在智能体中使用它：

```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" %}
我们强烈建议你通过官方仓库中的 PR，或通过其他 [Inspector.dev](https://inspector.dev/developer-support/) 支持渠道提交新的向量存储实现。新的实现将有可能在社区的推动下获得重要的发展加速。
{% endhint %}
