Changer le thème

Base vectorielle trop chère ? Vectorize gratuit : recherche sémantique en 30 minutes

Easton editorial illustration: cost-quality-speed triangle

Vous voulez une recherche intelligente sur votre blog, et Pinecone commence à ~50 $/mois. Les bases vectorielles comprennent le sens, trouvent du contenu similaire et alimentent les bases de connaissances IA — mais pour un projet perso, le prix pique.

Cloudflare Vectorize : quota gratuit largement suffisant ; 1 M de vecteurs, 30 000 requêtes ≈ 0,31 $. Cet article explique ce qu’est Vectorize, pourquoi c’est économique, et comment lancer une démo de recherche sémantique complète en 30 minutes.

Partie 1 : concepts essentiels

Base vectorielle en trois phrases

La première fois que j’ai vu « vecteur 768 dimensions », j’ai flanché. En pratique, ce n’est pas si terrible.

Une base classique stocke texte, nombres, dates. Une base vectorielle stocke le sens. Vous tapez « smartphone Apple » : la recherche par mots-clés ne trouve que cette chaîne exacte ; la recherche vectorielle rapproche « iPhone », « nouveau modèle Apple », « flagship Apple ».

Le mécanisme : passer le texte par un modèle d’embedding (OpenAI, BGE, etc.) qui renvoie des nombres, par ex. [0,23, -0,45, 0,78, ...] — 768 valeurs. Deux textes proches en sens → vecteurs proches en géométrie.

Exemple sur mon blog : requête « ordinateur portable pas cher » → article « laptop bon rapport qualité-prix » sans mot commun — c’est la recherche sémantique.

Pourquoi Vectorize ? Comparaison avec trois acteurs

Pinecone, Weaviate, Milvus sonnent pro — pourtant, pour petits projets et indés, Vectorize m’a convaincu après comparaison.

Coût (le plus concret)

Pinecone : plan standard dès ~50 $/mois minimum, ~41 $/mois pour 1 M de vecteurs. Weaviate serverless ~25 $/mois ; 1 M de vecteurs 1536D + requêtes → facture pouvant grimper à ~153 $ (version compressée ~25 $).

Vectorize (mes tests) : 1 M de vecteurs 768D, 1 000 requêtes/jour (~30 000/mois) → 0,31 $. Le blog Cloudflare cite −75 % requêtes, −98 % stockage.

0,31 $
Coût 1 M vecteurs, 30k requêtes
Pinecone dès 50 $/mois, Weaviate dès 25 $/mois — Vectorize ~0,31 $, ~50 $/mois économisés vs Pinecone

Quota gratuit pour un petit projet ou un MVP. Payer seulement quand ça scale — c’est raisonnable.

Intégration

Pinecone et Weaviate : compte, clés API, réseau. Déjà sur Workers : Vectorize s’intègre dans wrangler.toml, appel env.VECTORIZE_INDEX, sans variables d’env dédiées.

Avec Pinecone, j’ai perdu ~30 min rien qu’à sécuriser la clé API dans Workers. Vectorize : pas ce sujet.

Scénarios

Vectorize n’est pas universel :

  • Petit projet, MVP, blog : Vectorize (coût, simplicité)
  • Entreprise, milliards de vecteurs : Pinecone (infra, support)
  • Multimodal : Weaviate (image, vidéo, audio natif)

Cloudflare : jusqu’à 5 M de vecteurs par index. Trois ans de blog perso, ~200 articles — loin du plafond.

5 M vecteurs
Quota stockage
Index jusqu’à 5 M vecteurs
3 M/mois
Requêtes gratuites
Ordre de grandeur ~3 M requêtes/mois
~50 $/mois économisés
vs Pinecone
1 M vecteurs, 30k requêtes ≈ 0,31 $

En clair : vous débutez en recherche vectorielle ou le budget est serré → Vectorize est le meilleur point de départ. Migrer plus tard reste faisable.

Quatre cas d’usage concrets

1. Recherche documentaire

Centaines de docs techniques, manuels, juridique — Ctrl+F rate souvent le bon doc. Sémantique : « comment demander un remboursement » → « procédure frais », « guide déplacements ». Base interne : moins de questions « où est le fichier ? » dès la première semaine.

2. Recommandations

« À lire aussi » par tags ou au hasard, c’est limité. Vectorize trouve le contenu vraiment proche : sur « React Hooks best practices », proposer « pièges useEffect » plutôt qu’un tuto Vue. +40 % de clics vs aléatoire sur mon blog.

3. RAG

Retrieval-Augmented Generation : le LLM répond sur vos données. Question produit → retrieval → contexte → réponse ancrée dans la doc, moins d’invention. Standard des chatbots support.

4. Déduplication / regroupement

Feedback : « login failed », « cannot sign in », « stuck at login » → un cluster. Modération : doublons et copies marketing similaires.

Dès que vous avez besoin de « trouver du contenu similaire », une base vectorielle aide.

Partie 2 : mise en pratique

Préparation : environnement en 5 minutes

Étape 1 — Compte Cloudflare

cloudflare.com, gratuit. Déjà client CDN/DNS ? Réutilisez le compte.

Étape 2 — Wrangler CLI

npm install -g wrangler

yarn/pnpm : commande équivalente. Vérification :

wrangler --version

Étape 3 — Connexion

wrangler login

Autorisez dans le navigateur ; le terminal doit afficher « Successfully logged in ».

Étape 4 — Projet

mkdir vectorize-demo
cd vectorize-demo
wrangler init

Réponses par défaut (Entrée) suffisent. TypeScript recommandé (JavaScript OK).

Fichiers attendus :

  • wrangler.toml
  • src/index.ts
  • package.json

Ensuite : créer le premier index.

Créer le premier index vectoriel

Création

wrangler vectorize create my-search-index --preset @cf/baai/bge-small-en-v1.5

my-search-index : nom libre (lettres, chiffres, tirets). --preset : modèle d’embedding intégré BGE 768D.

Sortie attendue :

✅ Successfully created index my-search-index

Les presets Cloudflare évitent d’acheter une API OpenAI pour l’embedding. bge-small-en-v1.5 : bon compromis vitesse/coût. Recherche en chinois : @cf/baai/bge-base-zh-v1.5.

wrangler.toml

[[vectorize]]
binding = "VECTORIZE_INDEX"
index_name = "my-search-index"

binding = nom dans le code ; index_name = nom créé ci-dessus.

Vérification

wrangler vectorize list

my-search-index doit apparaître.

Erreurs fréquentes

  • « Index already exists » : renommer l’index ou wrangler vectorize delete
  • Oubli de [[vectorize]]env.VECTORIZE_INDEX undefined
  • Preset invalide : liste dans la doc Cloudflare Vectorize

Prochaine étape : insérer des données et rechercher.

Code : recherche sémantique en ~30 lignes

Insertion

src/index.ts :

export interface Env {
  VECTORIZE_INDEX: VectorizeIndex;
  AI: Ai; // Cloudflare Workers AI
}
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);
    // Route d'insertion
    if (url.pathname === '/insert') {
      const articles = [
        {
          id: '1',
          title: 'Introduction à Cloudflare Workers',
          content: 'Cloudflare Workers est une plateforme serverless en périphérie pour exécuter du code'
        },
        {
          id: '2',
          title: 'Guide architecture Serverless',
          content: 'Le serverless simplifie déploiement et montée en charge sans gérer des serveurs'
        },
        {
          id: '3',
          title: 'Programmation asynchrone JavaScript',
          content: 'Promise et async/await sont la façon moderne de gérer l\'asynchrone'
        }
      ];
      // Génération des embeddings par lot
      const embeddings = await Promise.all(
        articles.map(async (article) => {
          const embedding = await env.AI.run('@cf/baai/bge-small-en-v1.5', {
            text: `${article.title} ${article.content}`
          });
          return {
            id: article.id,
            values: embedding.data[0], // vecteur 768D
            metadata: {
              title: article.title,
              content: article.content
            }
          };
        })
      );
      // Insertion dans Vectorize
      await env.VECTORIZE_INDEX.upsert(embeddings);
      return new Response('Insertion réussie !', { status: 200 });
    }
    return new Response('Not found', { status: 404 });
  }
};

Résumé : 3 articles exemple → embeddings Workers AI 768D → upsert. metadata garde titre et contenu pour l’affichage.

Recherche

// Dans fetch, ajouter :
if (url.pathname === '/search') {
  const query = url.searchParams.get('q');
  if (!query) {
    return new Response('Paramètre de requête q manquant', { status: 400 });
  }
  const queryEmbedding = await env.AI.run('@cf/baai/bge-small-en-v1.5', {
    text: query
  });
  const results = await env.VECTORIZE_INDEX.query(queryEmbedding.data[0], {
    topK: 5,
    returnMetadata: true
  });
  const formattedResults = results.matches.map((match) => ({
    id: match.id,
    score: match.score,
    title: match.metadata?.title,
    content: match.metadata?.content
  }));
  return new Response(JSON.stringify(formattedResults, null, 2), {
    headers: { 'Content-Type': 'application/json' }
  });
}

Flux : paramètre q → vecteur de requête → query top 5 → JSON avec scores.

Test local

wrangler dev

Serveur local souvent http://localhost:8787.

curl http://localhost:8787/insert

Puis :

curl "http://localhost:8787/search?q=plateforme+serverless"

Exemple de résultat :

[
  {
    "id": "1",
    "score": 0.89,
    "title": "Introduction à Cloudflare Workers",
    "content": "Cloudflare Workers est une plateforme serverless..."
  },
  {
    "id": "2",
    "score": 0.85,
    "title": "Guide architecture Serverless",
    "content": "Le serverless simplifie déploiement..."
  }
]

Le score (0–1) mesure la similarité. Requête « plateforme serverless » sans mot exact dans les titres — mais Workers et Serverless remontent : effet sémantique.

Notes

  • Pas d’API OpenAI : Workers AI intégré, quota gratuit, pas de clé
  • upsert : update ou insert selon l’id
  • topK : souvent 5–10 suffit

Astuces : trois optimisations

1. Filtre metadata

Blog avec catégories « tech », « vie », « notes » : pour « Python », limiter à tech.

À l’insertion :

metadata: {
  title: article.title,
  content: article.content,
  category: 'tech'
}

À la recherche :

const results = await env.VECTORIZE_INDEX.query(queryEmbedding.data[0], {
  topK: 5,
  returnMetadata: true,
  filter: { category: 'tech' }
});

Évite de matcher « j’ai un python comme animal » en catégorie vie.

2. Recherche hybride (sémantique + mots-clés)

Pour « React 18 », booster les titres contenant exactement la requête :

const vectorResults = await env.VECTORIZE_INDEX.query(queryEmbedding.data[0], {
  topK: 20,
  returnMetadata: true
});
const finalResults = vectorResults.matches
  .map((match) => {
    let boostedScore = match.score;
    if (match.metadata?.title.includes(query)) {
      boostedScore += 0.2;
    }
    return { ...match, score: boostedScore };
  })
  .sort((a, b) => b.score - a.score)
  .slice(0, 5);

3. Lots (batch)

Centaines ou milliers d’articles : insérer par lots de 100. 500 articles : ~20 min en unitaire → ~3 min en batch.

const batchSize = 100;
for (let i = 0; i < allArticles.length; i += batchSize) {
  const batch = allArticles.slice(i, i + batchSize);
  const embeddings = await Promise.all(
    batch.map(async (article) => {
      // ... génération embedding
    })
  );
  await env.VECTORIZE_INDEX.upsert(embeddings);
}

Astuce : cache Workers KV pour requêtes populaires répétées.

Partie 3 : pièges et limites

Problèmes fréquents

1. Dimension mismatch

Dimension mismatch: expected 768, got 1536 — index 768D, embeddings 1536D (ex. OpenAI). Recréer l’index ou changer de modèle ; décider dès le départ.

2. Quota gratuit

~5 M vecteurs 768D, ~3 M requêtes/mois. Petit blog : souvent 0 $. Dépassement : toujours très bas (0,31 $ pour l’exemple ci-dessus).

3. Choix du modèle

  • Chinois : @cf/baai/bge-base-zh-v1.5
  • Anglais : @cf/baai/bge-small-en-v1.5
  • Multilingue : @cf/baai/bge-m3
  • OpenAI text-embedding-3-small (1536D) via API externe si besoin de qualité max

BGE intégrés : suffisants dans la majorité des cas.

4. Migration depuis Pinecone

  1. Exporter vecteurs + metadata Pinecone
  2. Convertir au format Vectorize
  3. upsert par lots

Même dimension obligatoire (1536D des deux côtés si preset 1536D).

const pineconeVectors = await pineconeIndex.fetch({ ids: allIds });
const vectorizeFormat = Object.entries(pineconeVectors.vectors).map(
  ([id, vector]) => ({
    id,
    values: vector.values,
    metadata: vector.metadata
  })
);
const batchSize = 100;
for (let i = 0; i < vectorizeFormat.length; i += batchSize) {
  const batch = vectorizeFormat.slice(i, i + batchSize);
  await env.VECTORIZE_INDEX.upsert(batch);
}

5. Résultats imprécis

  • Modèle générique vs domaine médical, juridique, etc.
  • Texte trop court → titre + résumé + ~200 caractères du corps
  • HTML/bruit non nettoyé

Quand changer de solution

> 5 M vecteurs → Pinecone ou Milvus self-hosted (rare en pratique).

Multimodal → Weaviate.

Requêtes graphe complexes → GraphRAG + Neo4j.

Latence < 10 ms → Redis + Faiss.

Vectorize : 50–200 ms, OK pour la plupart des cas.

Ne pas viser la perfection au jour 1 : valider le produit, migrer si besoin — formats proches, migration scriptable en quelques heures. Mieux vaut un MVP qu’un mois de comparaison d’outils sans code.

Conclusion

Les bases vectorielles sont-elles chères ? Ça dépend. Pinecone dès ~50 $/mois ; Vectorize gratuit suffit souvent pour une app de taille modeste. Ma recherche sémantique de blog : 0 $ après deux mois.

De la théorie au code, des bases aux optimisations — vous devriez pouvoir démarrer Vectorize rapidement. Prochaines étapes :

  1. Exemple officiel Cloudflare — 5 min pour voir le rendu
  2. Discord Cloudflare pour les questions
  3. Brancher vos données : base interne, notes perso, chatbot support

La recherche sémantique n’est pas magique — il faut commencer. Une fois en prod, ça résout de vrais problèmes.

Si cet article vous a aidé, partagez-le avec d’autres qui montent des apps IA — on économise et on avance ensemble.

Recherche sémantique Vectorize en 30 minutes

De l’environnement à l’index vectoriel, puis ~30 lignes de code pour une recherche sémantique complète, avec astuces et pièges

Estimated time: PT30M

  1. 1

    Step 1: Configuration en 5 minutes : compte Cloudflare et Wrangler CLI

    Étape 1 : compte Cloudflare
  2. 2

    Step 2: • Déjà sur CDN/DNS Cloudflare

    réutiliser le compte
  3. 3

    Step 3: Étape 2

    Wrangler CLI
  4. 4

    Step 4: • Terminal

    npm install -g wrangler
  5. 5

    Step 5: • yarn/pnpm

    commande équivalente
  6. 6

    Step 6: • Vérifier

    wrangler —version
  7. 7

    Step 7: Étape 3

    connexion
  8. 8

    Step 8: Étape 4

    projet
  9. 9

    Step 9: • Fichiers

    wrangler.toml, src/index.ts, package.json
  10. 10

    Step 10: Créer l’index : une commande

    Création :
  11. 11

    Step 11: • Sortie attendue

    Successfully created index my-search-index
  12. 12

    Step 12: • bge-small-en-v1.5

    rapide et économique
  13. 13

    Step 13: • Chinois

    @cf/baai/bge-base-zh-v1.5
  14. 14

    Step 14: • Index already exists

    autre nom ou wrangler vectorize delete
  15. 15

    Step 15: • Oubli [[vectorize]]

    env.VECTORIZE_INDEX undefined
  16. 16

    Step 16: • Preset invalide

    doc Cloudflare
  17. 17

    Step 17: ~30 lignes : insertion et recherche

    Insertion : src/index.ts, articles exemple, Workers AI → vecteur 768D, upsert, metadata titre/contenu. Recherche : route /search, paramètre q, query top 5, scores JSON. Test : wrangler dev, curl /insert, curl /search?q=plateforme+serverless — scores 0–1, match sémantique serverless/Workers. Notes : Workers AI intégré (pas de clé OpenAI), upsert = update/insert, topK 5–10 en général.
  18. 18

    Step 18: Astuces : metadata, hybride, batch

    1) Filtre metadata (category tech). 2) Hybride : topK 20 + boost titre contenant la requête + tri. 3) Batch 100 articles : perf nettement meilleure ; cache KV pour requêtes répétées.
  19. 19

    Step 19: Pièges

    Dimension mismatch 768 vs 1536 — recréer index ou changer modèle. Quota ~5 M vecteurs, ~3 M req/mois, souvent 0 $ petit projet. Modèles BGE zh/en/m3 ou OpenAI 1536D. Précision : domaine, texte assez long, nettoyage HTML ; titre+résumé+200 car.

FAQ

Vectorize vs Pinecone et Weaviate : avantages et coûts ?
Comparaison des coûts :

Pinecone :
• Minimum ~50 $/mois
• ~41 $/mois pour 1 M de vecteurs

Weaviate :
• Serverless dès ~25 $/mois
• 1 M de vecteurs 1536D + requêtes : facture pouvant monter à ~153 $ (version compressée ~25 $)

Vectorize (mesure réelle) :
• 1 M de vecteurs 768D, 1 000 requêtes/jour (~30 000/mois) : ~0,31 $
• Oui, 0,31 dollar
• Le blog Cloudflare annonce −75 % sur les requêtes et −98 % sur le stockage — crédible en pratique
• Quota gratuit suffisant pour un petit projet ou valider un MVP

Intégration :
• Pinecone et Weaviate : compte séparé, clés API, réseau
• Déjà sur Cloudflare Workers : Vectorize « clé en main » — quelques lignes dans wrangler.toml, appel via env.VECTORIZE_INDEX, sans variables d'environnement dédiées

Cas d'usage :
• Petit projet, MVP, blog perso : Vectorize (coût bas, rapide)
• Entreprise, échelle milliards de vecteurs : Pinecone (infra et support)
• Multimodal (image, vidéo, audio) : Weaviate plus complet
Quel quota gratuit Vectorize ? Est-ce suffisant ?
Quota gratuit (ordre de grandeur) :
• Stockage : ~5 M de vecteurs 768D
• Requêtes : ~3 M/mois

Pour un petit site, largement suffisant. Mon blog (~200 articles, ~300 visites/jour, ~30 recherches/jour) : 0 $ le premier mois.

Au-delà du gratuit, le pay-as-you-go reste très bas — 1 M de vecteurs, 30 000 requêtes ≈ 0,31 $.

Cloudflare annonce des index jusqu'à 5 M de vecteurs. Pour la plupart des apps, c'est large — trois ans de blog perso et ~200 articles, loin du plafond.

Pour débuter en recherche vectorielle avec un budget serré, Vectorize est un excellent point de départ. Migrer plus tard reste possible.
Comment mettre en place une recherche sémantique en 30 minutes ?
Setup (~5 min) :

1) Compte Cloudflare (cloudflare.com, gratuit)
2) Wrangler CLI : npm install -g wrangler puis wrangler --version
3) Connexion : wrangler login (autorisation navigateur)
4) Projet : mkdir vectorize-demo && cd vectorize-demo && wrangler init

Créer l'index :
• wrangler vectorize create my-search-index --preset @cf/baai/bge-small-en-v1.5

wrangler.toml :
• [[vectorize]]
• binding = "VECTORIZE_INDEX"
• index_name = "my-search-index"

~30 lignes de code :

1) Insertion : articles exemple → embeddings via Workers AI → upsert
2) Recherche : paramètre q → vecteur de requête → query top 5 → scores
3) Test local : wrangler dev, curl /insert puis curl /search?q=plateforme+serverless
À quoi sert Vectorize ? Quels cas concrets ?
1) Recherche documentaire intelligente :
• Des centaines de docs techniques, manuels, textes juridiques — Ctrl+F insuffisant
• Recherche sémantique : « comment demander un remboursement » trouve « procédure frais » et « guide déplacements »
• Base de connaissances interne : moins de « où est le doc ? » la première semaine

2) Recommandations d'articles :
• Au-delà des tags ou du hasard
• Sur « bonnes pratiques React Hooks », proposer « pièges useEffect » plutôt qu'un tuto Vue
• Sur mon blog : +40 % de clics vs recommandations aléatoires

3) RAG (alimenter l'IA avec votre base) :
• Retrieval-Augmented Generation : répondre sur vos données privées
• Question produit → retrieval Vectorize → contexte au LLM → moins d'hallucinations
• Courant en chatbots support

4) Déduplication et regroupement :
• Feedback utilisateurs : « échec connexion », « impossible de se connecter », « login KO » → même cluster
• Modération : doublons et contenus marketing similaires
Problèmes fréquents avec Vectorize et solutions ?
1) Dimension mismatch (expected 768, got 1536) :
• Index créé en 768D (bge-small) mais embeddings en 1536D (ex. OpenAI text-embedding-3-small)
• Tous les vecteurs d'un index doivent avoir la même dimension
• Recréer l'index avec le bon preset ou changer de modèle d'embedding — choisir dès le départ

2) Quota gratuit :
• Ordre de grandeur : ~5 M vecteurs 768D stockés, ~3 M requêtes/mois
• Petit projet : souvent 0 $
• Dépassement : toujours très peu cher (cf. 0,31 $ ci-dessus)

3) Modèle d'embedding :
• @cf/baai/bge-base-zh-v1.5 pour le chinois
• @cf/baai/bge-small-en-v1.5 pour l'anglais (bon compromis)
• @cf/baai/bge-m3 multilingue (100+ langues)
• OpenAI text-embedding-3-small (1536D) possible via API externe, plus cher
• En général les BGE intégrés Cloudflare suffisent

4) Résultats imprécis :
• Modèle générique inadapté au domaine (ex. médical)
• Texte d'entrée trop court — titre + résumé > titre seul
• HTML/bruit non nettoyé
• Astuce : titre + résumé + ~200 premiers caractères du corps pour l'embedding
Quand migrer vers une autre solution ? Limites de Vectorize ?
Signal 1 : > 5 M de vecteurs par index → Pinecone ou cluster Milvus

Signal 2 : multimodal (image, audio, vidéo) — Vectorize texte seulement → Weaviate

Signal 3 : requêtes type graphe de connaissances complexes → GraphRAG + Neo4j, etc.

Signal 4 : latence < 10 ms (reco temps réel) → Redis + Faiss en mémoire

Vectorize : latence typique 50–200 ms, OK pour la plupart des apps.

Conseil : valider le produit avec Vectorize d'abord ; migrer au besoin — format de vecteurs proche, script de migration en quelques heures. Ne pas bloquer un mois sur le choix d'outil.

9 min de lecture · Publié le: 1 déc. 2025 · Mis à jour le: 27 juil. 2026

Commentaires

Connectez-vous avec GitHub pour laisser un commentaire

Easton BlogEaston Blog