Aller au contenu principal

Stockage vectoriel PG

La classe PgVector permet d'effectuer des recherches vectorielles dans PostgreSQL à l'aide de l'extension pgvector. Elle offre des fonctionnalités fiables de recherche par similarité vectorielle au sein de votre base de données PostgreSQL existante.

Options du constructeur
Lien direct vers Options du constructeur

connectionString?:

string
URL de connexion PostgreSQL

host?:

string
Hôte du serveur PostgreSQL

port?:

number
Port du serveur PostgreSQL

database?:

string
Nom de la base de données PostgreSQL

user?:

string
Utilisateur PostgreSQL

password?:

string
Mot de passe PostgreSQL

ssl?:

boolean | ConnectionOptions
Active SSL ou fournit une configuration SSL personnalisée

schemaName?:

string
Nom du schéma que le stockage vectoriel doit utiliser. Le schéma par défaut sera utilisé si cette option n’est pas fournie.

max?:

number
Nombre maximal de connexions dans le pool (par défaut : 20)

idleTimeoutMillis?:

number
Délai d’expiration des connexions inactives en millisecondes (par défaut : 30000)

pgPoolOptions?:

PoolConfig
Options de configuration supplémentaires du pool pg

disableInit?:

boolean
= false
Lorsque cette valeur est true, les opérations DDL automatiques (création du schéma, de l’extension, de la table et de l’index) dans createIndex sont ignorées. Cette option est utile pour les pipelines CI/CD où le schéma et les index sont gérés séparément et où le rôle de base de données utilisé à l’exécution ne dispose pas des privilèges DDL. Elle peut également être activée avec la variable d’environnement MASTRA_DISABLE_STORAGE_INIT.

Exemples de constructeur
Lien direct vers Exemples de constructeur

Chaîne de connexion
Lien direct vers Chaîne de connexion

import { PgVector } from '@mastra/pg'

const vectorStore = new PgVector({
id: 'pg-vector',
connectionString: 'postgresql://user:password@localhost:5432/mydb',
})

Configuration de l’hôte, du port et de la base de données
Lien direct vers Configuration de l’hôte, du port et de la base de données

const vectorStore = new PgVector({
id: 'pg-vector',
host: 'localhost',
port: 5432,
database: 'mydb',
user: 'postgres',
password: 'password',
})

Configuration avancée
Lien direct vers Configuration avancée

const vectorStore = new PgVector({
id: 'pg-vector',
connectionString: 'postgresql://user:password@localhost:5432/mydb',
schemaName: 'custom_schema',
max: 30,
idleTimeoutMillis: 60000,
pgPoolOptions: {
connectionTimeoutMillis: 5000,
allowExitOnIdle: true,
},
})

Méthodes
Lien direct vers Méthodes

createIndex()
Lien direct vers createindex

indexName:

string
Nom de l’index à créer

dimension:

number
Dimension du vecteur (doit correspondre à votre modèle d’embedding)

metric?:

'cosine' | 'euclidean' | 'dotproduct'
= cosine
Métrique de distance pour la recherche par similarité

indexConfig?:

IndexConfig
= { type: 'ivfflat' }
Configuration de l’index

buildIndex?:

boolean
= true
Indique s’il faut construire l’index

metadataIndexes?:

string[]
Tableau de noms de champs de métadonnées sur lesquels créer des index btree. Améliore les performances des requêtes lors du filtrage sur ces champs de métadonnées.

IndexConfig
Lien direct vers indexconfig

type:

'flat' | 'hnsw' | 'ivfflat'
= ivfflat
Type d’index
string

flat:

flat
Analyse séquentielle (sans index) qui effectue une recherche exhaustive.

ivfflat:

ivfflat
Regroupe les vecteurs en listes pour une recherche approximative.

hnsw:

hnsw
Index basé sur un graphe offrant des recherches rapides et un rappel élevé.

ivf?:

IVFConfig
Configuration IVF
object

lists?:

number
Nombre de listes. S’il n’est pas indiqué, il est calculé automatiquement en fonction de la taille du jeu de données. (Minimum : 100, maximum : 4000)

hnsw?:

HNSWConfig
Configuration HNSW
object

m?:

number
Nombre maximal de connexions par nœud (par défaut : 8)

efConstruction?:

number
Complexité lors de la construction (par défaut : 32)

Besoins en mémoire
Lien direct vers Besoins en mémoire

Les index HNSW nécessitent une quantité importante de mémoire partagée lors de leur construction. Pour 100 000 vecteurs :

  • Petites dimensions (64d) : ~60 Mo avec les paramètres par défaut
  • Dimensions moyennes (256d) : ~180 Mo avec les paramètres par défaut
  • Grandes dimensions (384d+) : ~250 Mo ou plus avec les paramètres par défaut

Des valeurs plus élevées de M ou de efConstruction augmentent considérablement les besoins en mémoire. Ajustez les limites de mémoire partagée de votre système si nécessaire.

upsert()
Lien direct vers upsert

indexName:

string
Nom de l’index dans lequel insérer ou mettre à jour les vecteurs

vectors:

number[][]
Tableau de vecteurs d’embedding

metadata?:

Record<string, any>[]
Métadonnées de chaque vecteur

ids?:

string[]
ID de vecteurs facultatifs (générés automatiquement s’ils ne sont pas fournis)

query()
Lien direct vers query

indexName:

string
Nom de l’index à interroger

queryVector:

number[]
Vecteur de requête

topK?:

number
= 10
Nombre de résultats à renvoyer

filter?:

Record<string, any>
Filtres de métadonnées

includeVector?:

boolean
= false
Indique s’il faut inclure le vecteur dans le résultat

minScore?:

number
= 0
Seuil minimal du score de similarité

options?:

{ ef?: number; probes?: number }
Options supplémentaires pour les index HNSW et IVF
object

ef?:

number
Paramètre de recherche HNSW

probes?:

number
Paramètre de recherche IVF

listIndexes()
Lien direct vers listindexes

Renvoie un tableau contenant les noms des index sous forme de chaînes de caractères.

describeIndex()
Lien direct vers describeindex

indexName:

string
Nom de l’index à décrire

Renvoie :

interface PGIndexStats {
dimension: number
count: number
metric: 'cosine' | 'euclidean' | 'dotproduct'
type: 'flat' | 'hnsw' | 'ivfflat'
config: {
m?: number
efConstruction?: number
lists?: number
probes?: number
}
}

deleteIndex()
Lien direct vers deleteindex

indexName:

string
Nom de l’index à supprimer

updateVector()
Lien direct vers updatevector

Met à jour un seul vecteur par ID ou par filtre de métadonnées. Vous devez fournir soit id, soit filter, mais pas les deux.

indexName:

string
Nom de l’index contenant le vecteur

id?:

string
ID du vecteur à mettre à jour (mutuellement exclusif avec filter)

filter?:

Record<string, any>
Filtre de métadonnées permettant d’identifier le ou les vecteurs à mettre à jour (mutuellement exclusif avec id)

update:

{ vector?: number[]; metadata?: Record<string, any>; }
Objet contenant le vecteur et/ou les métadonnées à mettre à jour

Met à jour un vecteur existant par ID ou par filtre. L’objet de mise à jour doit contenir au moins le vecteur ou les métadonnées.

// Update by ID
await pgVector.updateVector({
indexName: 'my_vectors',
id: 'vector123',
update: {
vector: [0.1, 0.2, 0.3],
metadata: { label: 'updated' },
},
})

// Update by filter
await pgVector.updateVector({
indexName: 'my_vectors',
filter: { category: 'product' },
update: {
metadata: { status: 'reviewed' },
},
})

deleteVector()
Lien direct vers deletevector

indexName:

string
Nom de l’index contenant le vecteur

id:

string
ID du vecteur à supprimer

Supprime de l’index indiqué un seul vecteur identifié par son ID.

await pgVector.deleteVector({ indexName: 'my_vectors', id: 'vector123' })

deleteVectors()
Lien direct vers deletevectors

Supprime plusieurs vecteurs par ID ou par filtre de métadonnées. Vous devez fournir soit ids, soit filter, mais pas les deux.

indexName:

string
Nom de l’index contenant les vecteurs à supprimer

ids?:

string[]
Tableau des ID de vecteurs à supprimer (mutuellement exclusif avec filter)

filter?:

Record<string, any>
Filtre de métadonnées permettant d’identifier les vecteurs à supprimer (mutuellement exclusif avec ids)

disconnect()
Lien direct vers disconnect

Ferme le pool de connexions à la base de données. Cette méthode doit être appelée lorsque vous avez fini d’utiliser le stockage.

buildIndex()
Lien direct vers buildindex

indexName:

string
Nom de l’index à définir

metric?:

'cosine' | 'euclidean' | 'dotproduct'
= cosine
Métrique de distance pour la recherche par similarité

indexConfig:

IndexConfig
Configuration du type d’index et de ses paramètres

Construit ou reconstruit un index avec la métrique et la configuration indiquées. Tout index existant est supprimé avant la création du nouvel index.

// Define HNSW index
await pgVector.buildIndex('my_vectors', 'cosine', {
type: 'hnsw',
hnsw: {
m: 8,
efConstruction: 32,
},
})

// Define IVF index
await pgVector.buildIndex('my_vectors', 'cosine', {
type: 'ivfflat',
ivf: {
lists: 100,
},
})

// Define flat index
await pgVector.buildIndex('my_vectors', 'cosine', {
type: 'flat',
})

Types de réponse
Lien direct vers Types de réponse

Les résultats de la requête sont renvoyés au format suivant :

interface QueryResult {
id: string
score: number
metadata: Record<string, any>
vector?: number[] // Only included if includeVector is true
}

Gestion des erreurs
Lien direct vers Gestion des erreurs

Le stockage lève des erreurs typées qui peuvent être interceptées :

try {
await store.query({
indexName: 'index_name',
queryVector: queryVector,
})
} catch (error) {
if (error instanceof VectorStoreError) {
console.log(error.code) // 'connection_failed' | 'invalid_dimension' | etc
console.log(error.details) // Additional error context
}
}

Guide de configuration des index
Lien direct vers Guide de configuration des index

Optimisation des performances
Lien direct vers Optimisation des performances

Réglage d’IVFFlat
Lien direct vers Réglage d’IVFFlat

  • Paramètre lists : définissez-le sur sqrt(n) * 2, où n est le nombre de vecteurs
  • Plus de listes = meilleure précision, mais construction plus lente
  • Moins de listes = construction plus rapide, mais précision potentiellement moindre

Réglage de HNSW
Lien direct vers Réglage de HNSW

  • Paramètre m :
    • 8-16 : précision moyenne, faible consommation de mémoire
    • 16-32 : précision élevée, consommation de mémoire moyenne
    • 32-64 : précision très élevée, forte consommation de mémoire
  • efConstruction:
    • 32-64 : construction rapide, bonne qualité
    • 64-128 : construction plus lente, meilleure qualité
    • 128-256 : construction la plus lente, qualité optimale

Comportement lors de la recréation d’un index
Lien direct vers Comportement lors de la recréation d’un index

Le système détecte automatiquement les changements de configuration et ne reconstruit les index que lorsque cela est nécessaire :

  • Configuration identique : l’index est conservé (aucune recréation)
  • Configuration modifiée : l’index est supprimé puis reconstruit
  • Cela évite les problèmes de performances dus à des recréations d’index inutiles

Bonnes pratiques
Lien direct vers Bonnes pratiques

  • Évaluez régulièrement la configuration de vos index pour garantir des performances optimales.
  • Ajustez des paramètres tels que lists et m en fonction de la taille du jeu de données et des exigences des requêtes.
  • Surveillez les performances des index avec describeIndex() pour suivre leur utilisation
  • Reconstruisez régulièrement les index afin de préserver leur efficacité, en particulier après des modifications importantes des données

Accès direct au pool
Lien direct vers Accès direct au pool

La classe PgVector expose son pool de connexions PostgreSQL sous-jacent sous la forme d’un champ public :

pgVector.pool // instance of pg.Pool

Cela permet des usages avancés, tels que l’exécution directe de requêtes SQL, la gestion des transactions ou la surveillance de l’état du pool. Lorsque vous utilisez directement le pool :

  • Il vous incombe de libérer les clients (client.release()) après utilisation.
  • Le pool reste accessible après l’appel à disconnect(), mais les nouvelles requêtes échoueront.
  • L’accès direct contourne toute logique de validation ou de transaction fournie par les méthodes de PgVector.

Cette conception prend en charge des cas d’usage avancés, mais impose à l’utilisateur une gestion rigoureuse des ressources.

Exemple d’utilisation
Lien direct vers Exemple d’utilisation

Embeddings locaux avec fastembed
Lien direct vers Embeddings locaux avec fastembed

Les embeddings sont des vecteurs numériques utilisés par la fonctionnalité semanticRecall de la mémoire pour retrouver les messages associés en fonction de leur sens (et non de mots-clés). Cette configuration utilise @mastra/fastembed pour générer des embeddings vectoriels.

Pour commencer, installez fastembed :

npm install @mastra/fastembed@latest

Ajoutez ce qui suit à votre agent :

src/mastra/agents/example-pg-agent.ts
import { Memory } from '@mastra/memory'
import { Agent } from '@mastra/core/agent'
import { PostgresStore, PgVector } from '@mastra/pg'
import { fastembed } from '@mastra/fastembed'

export const pgAgent = new Agent({
id: 'pg-agent',
name: 'PG Agent',
instructions:
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
model: 'openai/gpt-5.6-sol',
memory: new Memory({
storage: new PostgresStore({
id: 'pg-agent-storage',
connectionString: process.env.DATABASE_URL!,
}),
vector: new PgVector({
id: 'pg-agent-vector',
connectionString: process.env.DATABASE_URL!,
}),
embedder: fastembed,
options: {
lastMessages: 10,
semanticRecall: {
topK: 3,
messageRange: 2,
},
},
}),
})