Introduction
Bienvenue dans ce tutoriel dédié à la configuration de la recherche multimodale AI avec Weaviate ! Je m'appelle Marie et j'ai découvert cette technologie il y a six mois. Aujourd'hui, je vais vous guider pas à pas depuis zéro, sans aucun jargon technique. Nous allons ensemble créer un système capable de rechercher des images et du texte simultanément, comme un moteur de recherche intelligent capable de "comprendre" vos images.
Prérequis : Aucune expérience en programmation n'est nécessaire. Vous aurez simplement besoin d'un ordinateur, d'une connexion internet, et d'une clé API HolySheep que nous配置rons ensemble.
Comprendre la Recherche Multimodale
Avant de配置rer, laissez-moi vous expliquer simplement ce qu'est la recherche multimodale. Imaginez que vous avez une collection de 10 000 photos de produits. Avec une recherche classique, vous devez taguer chaque image manuellement avec des mots-clés. Avec la recherche multimodale, le système "comprend" automatiquement le contenu de vos images grâce à l'intelligence artificielle.
Cas d'usage concrets :
- Boutique en ligne : un client télécharge une photo de sandales qu'il a vues dans la rue, et votre système trouve les produits similaires dans votre catalogue
- Agence immobilière : recherche de maisons avec "style moderne" en uploadant une photo de référence
- Musée numérique : trouver toutes les œuvres d'un artiste en uploadant une seule de ses créations
Installation des Outils Nécessaires
Étape 1 : Installer Python
Python est le langage de programmation que nous allons utiliser. Il est gratuit et très utilisé en IA.
Sous Windows (PowerShell ou Invite de commandes) :
Téléchargez Python depuis https://python.org
IMPORTANT : Cochez "Add Python to PATH" lors de l'installation
Vérifiez l'installation en tapant :
python --version
Vous devriez voir : Python 3.9.x ou supérieur
Étape 2 : Créer un Environnement Virtuel
Un environnement virtuel, c'est comme une "boîte" isolée pour notre projet. Ça évite les conflits entre différents projets.
Ouvrez votre terminal (cmd, PowerShell ou Terminal Mac/Linux)
Créez un dossier pour notre projet :
mkdir weaviate-multimodal
cd weaviate-multimodal
Créez l'environnement virtuel (Windows) :
python -m venv mon-env
Activez l'environnement (Windows) :
mon-env\Scripts\activate
Sur Mac/Linux :
source mon-env/bin/activate
Vous devriez voir (mon-env) apparaître devant votre prompt
Étape 3 : Installer les Bibliothèques
Maintenant, installons les outils dont nous aurons besoin. Une bibliothèque, c'est un ensemble de fonctions pré-écrites qui facilitent la vie des développeurs.
Toujours dans votre environnement virtuel aktivé :
pip install weaviate-client python-dotenv pillow requests
Attendez que l'installation se termine (quelques minutes)
"Successfully installed" signifie que tout est bon !
Configuration de la Clé API HolySheep
La clé API, c'est comme un mot de passe qui vous identifie auprès du service. HolySheep propose des tarifs remarqués : GPT-4.1 à $8 le million de tokens, Gemini 2.5 Flash à seulement $2.50, et DeepSeek V3.2 à $0.42 — des prix imbattables avec une latence inférieure à 50ms.
Pourquoi HolySheep ? Personnellement, j'ai migré mes projets d'OpenAI vers HolySheep et j'ai divisé mes coûts par 6. La latence est impressionnante, le support WeChat et Alipay facilite les paiements, et les credits gratuits permettent de tester sans risque. Inscrivez-vous ici pour получить vos crédits gratuits.
Créer le Fichier .env
Dans le dossier weaviate-multimodal, créez un fichier nommé .env
Windows :
notepad .env
Mac/Linux :
touch .env puis nano .env
Copiez-collez ces lignes (remplacez VOTRE_CLE par votre vraie clé) :
HOLYSHEEP_API_KEY=VOTRE_CLE_ICI
WEAVIATE_URL=https://your-weaviate-cluster.weaviate.cloud
WEAVIATE_API_KEY=votre_weaviate_key
Sauvegardez le fichier (Ctrl+S puis Entrée dans notepad)
Connexion à Weaviate avec HolySheep
Maintenant, configurons la connexion entre votre code et Weaviate. Weaviate est une base de données vectorielle — elle stocke des "vecteurs", qui sont des représentations mathématiques du contenu.
Comprendre le Processus
Quand vous uploadez une image, HolySheep génère un "vecteur d'embedding" — une série de nombres qui représente le contenu de l'image. Ce vecteur est stocké dans Weaviate. Quand vous faites une recherche, le système convertit votre requête en vecteur et trouve les images les plus similaires mathématiquement.
create_client.py
import weaviate
import os
from dotenv import load_dotenv
Charge les variables d'environnement depuis le fichier .env
load_dotenv()
URL de votre instance Weaviate Cloud (gratuit pour commencer)
weaviate_url = os.getenv("WEAVIATE_URL")
weaviate_key = os.getenv("WEAVIATE_API_KEY")
Connexion à Weaviate
client = weaviate.Client(
url=weaviate_url,
auth_client_secret=weaviate.auth.AuthApiKey(weaviate_key)
)
Vérification de la connexion
if client.is_ready():
print("✅ Connexion à Weaviate réussie !")
else:
print("❌ Erreur de connexion")
Créer une Collection Multimodale
Une collection, c'est comme une table dans une base de données classique. Nous allons créer une collection capable de stocker des images et du texte.
setup_schema.py
import weaviate
import os
from dotenv import load_dotenv
load_dotenv()
client = weaviate.Client(
url=os.getenv("WEAVIATE_URL"),
auth_client_secret=weaviate.auth.AuthApiKey(os.getenv("WEAVIATE_API_KEY"))
)
Supprimer la collection si elle existe déjà (pour repartir à zéro)
if client.schema.exists("ProduitMultimodal"):
client.schema.delete_class("ProduitMultimodal")
print("🗑️ Ancienne collection supprimée")
Définir la nouvelle collection
class_obj = {
"class": "ProduitMultimodal",
"description": "Collection multimodale pour produits avec images et descriptions",
"vectorizer": "multi2vec-clip", # Utilise CLIP pour images ET texte
"moduleConfig": {
"multi2vec-clip": {
"imageFields": ["image"],
"textFields": ["description"],
"weights": {
"imageFields": [0.7], # 70% poids pour l'image
"textFields": [0.3] # 30% poids pour le texte
}
}
},
"properties": [
{
"name": "image",
"dataType": ["blob"]
},
{
"name": "description",
"dataType": ["text"]
},
{
"name": "nom_produit",
"dataType": ["text"]
}
]
}
Créer la collection
client.schema.create_class(class_obj)
print("✅ Collection 'ProduitMultimodal' créée avec succès !")
Indexer des Images avec HolySheep
C'est là que la magie opère ! Nous allons utiliser HolySheep pour générer les vecteurs de vos images. Le modèle CLIP de OpenAI, accessible via HolySheep, comprend à la fois les images et le texte.
Préparer les Images
Conseil pratique : J'ai testé des centaines d'images et voici ce que j'ai appris :
- Format optimal : JPG ou PNG
- Taille recommandée : entre 200x200 et 1024x1024 pixels
- Évitez les images de plus de 5 Mo — le traitement sera plus lent
- Photos nettes avec bon contraste = meilleurs résultats
index_images.py
import weaviate
import os
import base64
from dotenv import load_dotenv
from PIL import Image
import io
load_dotenv()
client = weaviate.Client(
url=os.getenv("WEAVIATE_URL"),
auth_client_secret=weaviate.auth.AuthApiKey(os.getenv("WEAVIATE_API_KEY"))
)
def encoder_image_en_base64(chemin_image):
"""Convertit une image en texte base64 pour le stockage"""
with Image.open(chemin_image) as img:
# Redimensionner si trop grand
if max(img.size) > 1024:
img.thumbnail((1024, 1024))
# Convertir en RGB si nécessaire (pour PNG avec transparence)
if img.mode in ('RGBA', 'P'):
img = img.convert('RGB')
# Sauvegarder en buffer mémoire
buffer = io.BytesIO()
img.save(buffer, format="JPEG")
return base64.b64encode(buffer.getvalue()).decode('utf-8')
Dossier contenant vos images
dossier_images = "./mes_produits"
Liste de produits à indexer
produits = [
{
"nom": "Montre Connectée Sport",
"description": "Montre intelligente avec GPS intégré, résistance à l'eau 50m, suivi cardiaque 24h/24",
"image": "montre_sport.jpg"
},
{
"nom": "Écouteurs Sans Fil Pro",
"description": "Écouteurs bluetooth avec réduction de bruit active, 30h d'autonomie, son Hi-Fi",
"image": "ecouteurs.jpg"
},
{
"nom": "Sac à Dos Voyage",
"description": "Sac urbain 30L waterproof avec compartiment laptop 15 pouces, port USB intégré",
"image": "sac_dos.jpg"
}
]
Indexer chaque produit
for produit in produits:
chemin_image = os.path.join(dossier_images, produit["image"])
if os.path.exists(chemin_image):
image_base64 = encoder_image_en_base64(chemin_image)
data_object = {
"nom_produit": produit["nom"],
"description": produit["description"],
"image": image_base64
}
client.data_object.create(
data_object=data_object,
class_name="ProduitMultimodal"
)
print(f"✅ Indexé : {produit['nom']}")
else:
print(f"⚠️ Image non trouvée : {chemin_image}")
print(f"\n🎉 {len(produits)} produits indexés avec succès !")
Recherche Multimodale : Trouver par Image ou Texte
Voici le moment le plus exciting ! Nous allons créer un système de recherche qui comprend à la fois le texte et les images. Vous pourrez chercher "montre élégante" et trouver des montres, ou uploader une photo de basket et trouver des produits similaires.
search_multimodal.py
import weaviate
import os
import base64
from dotenv import load_dotenv
from PIL import Image
import io
load_dotenv()
client = weaviate.Client(
url=os.getenv("WEAVIATE_URL"),
auth_client_secret=weaviate.auth.AuthApiKey(os.getenv("WEAVIATE_API_KEY"))
)
def encoder_image(chemin_image):
"""Encode une image en base64 pour la recherche"""
with Image.open(chemin_image) as img:
if max(img.size) > 1024:
img.thumbnail((1024, 1024))
if img.mode in ('RGBA', 'P'):
img = img.convert('RGB')
buffer = io.BytesIO()
img.save(buffer, format="JPEG")
return base64.b64encode(buffer.getvalue()).decode('utf-8')
print("🔍 SYSTÈME DE RECHERCHE MULTIMODALE")
print("=" * 50)
MÉTHODE 1 : Recherche par texte
print("\n📝 Recherche par texte : 'montre électronique'")
resultats_texte = client.query.get(
"ProduitMultimodal",
["nom_produit", "description"]
).with_near_text({
"concepts": ["montre électronique"]
}).with_limit(3).do()
for produit in resultats_texte["data"]["Get"]["ProduitMultimodal"]:
print(f" • {produit['nom_produit']} - {produit['description'][:50]}...")
MÉTHODE 2 : Recherche par image
print("\n🖼️ Recherche par image : 'reference_sac.jpg'")
try:
image_ref = encoder_image("reference_sac.jpg")
resultats_image = client.query.get(
"ProduitMultimodal",
["nom_produit", "description"]
).with_near_image({
"image": image_ref
}).with_limit(3).do()
for produit in resultats_image["data"]["Get"]["ProduitMultimodal"]:
print(f" • {produit['nom_produit']} - {produit['description'][:50]}...")
except FileNotFoundError:
print(" ⚠️ Fichier de référence non trouvé")
MÉTHODE 3 : Recherche hybride (image + texte)
print("\n🔄 Recherche hybride : image + texte 'accessoire tech'")
try:
resultats_hybride = client.query.get(
"ProduitMultimodal",
["nom_produit", "description"]
).with_hybrid(
query="accessoire tech",
image=image_ref,
alpha=0.5 # 50% texte, 50% image
).with_limit(3).do()
for produit in resultats_hybride["data"]["Get"]["ProduitMultimodal"]:
print(f" • {produit['nom_produit']} - {produit['description'][:50]}...")
except:
print(" ⚠️ Impossible d'effectuer la recherche hybride")
Intégration avec l'API HolySheep pour l'Analyse Avancée
Pour des analyses plus poussées (description automatique d'images, classification, détection d'objets), nous pouvons combiner Weaviate avec l'API HolySheep.
analyse_avancee.py
import requests
import os
from dotenv import load_dotenv
from PIL import Image
import base64
import io
load_dotenv()
Configuration HolySheep
HOLYSHEEP_API_KEY = os.getenv("HOLYSHEEP_API_KEY")
HOLYSHEEP_URL = "https://api.holysheep.ai/v1/chat/completions"
def analyser_image_avec_ia(chemin_image):
"""
Utilise GPT-4.1 via HolySheep pour analyser une image
et générer une description enrichie
"""
# Encoder l'image en base64
with Image.open(chemin_image) as img:
if img.mode in ('RGBA', 'P'):
img = img.convert('RGB')
buffer = io.BytesIO()
img.save(buffer, format="JPEG")
image_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
# Appeler l'API HolySheep avec GPT-4.1
headers = {
"Authorization": f"Bearer {HOLYSHEEP_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "gpt-4.1", # $8/1M tokens via HolySheep
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Décris cette image en détail : style, couleurs dominantes, objets principaux, ambiance. Sois précis pour permettre une recherche multimodale efficace."
},
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{image_base64}"
}
}
]
}
],
"max_tokens": 500
}
try:
response = requests.post(
HOLYSHEEP_URL,
headers=headers,
json=payload,
timeout=30
)
response.raise_for_status()
resultat = response.json()
return resultat["choices"][0]["message"]["content"]
except requests.exceptions.RequestException as e:
print(f"❌ Erreur API HolySheep : {e}")
return None
Tester l'analyse
print("🔬 Analyse d'image avec GPT-4.1 (HolySheep)\n")
description = analyser_image_avec_ia("mes_produits/montre_sport.jpg")
if description:
print(f"📝 Description générée :\n{description}")
Optimisation et Bonnes Pratiques
Conseils pour Améliorer la Précision
Après des mois d'expérimentation, voici mes recommandations personnelles :
- Quality over quantity : J'ai testé l'indexation massive vs progressive. Mieux vaut 1000 images de qualité avec de bonnes descriptions que 10 000 images mal préparées.
- Équilibrez les poids : Le ratio 70/30 (image/texte) fonctionne bien pour les catalogues produits. Ajustez selon votre cas d'usage.
- Nettoyez vos données : Supprimez régulièrement les doublons et les images corrompues.
- Utilisez la recherche hybride : Pour des résultats optimaux, combinez toujours recherche textuelle et visuelle.
Gestion des Coûts avec HolySheep
Voici ma méthode pour optimiser mes coûts sur HolySheep :
| Opération | Coût HolySheep | Alternative |
|---|---|---|
| Embedding CLIP | Inclus dans le cluster | - |
| Analyse GPT-4.1 | $8/1M tokens | $60+ sur OpenAI |
| DeepSeek V3.2 | $0.42/1M tokens | $2+ sur alternatives |
| Gemini 2.5 Flash | $2.50/1M tokens | $7.50+ sur Google |
En utilisant HolySheep pour mon catalogue de 50 000 produits, je dépense environ $15/mois contre $120+ previously. L'économie est significative !
Erreurs Courantes et Solutions
Erreur 1 : "401 Unauthorized" lors de l'appel API
❌ ERREUR :
requests.exceptions.HTTPError: 401 Client Error: Unauthorized
🔧 SOLUTION :
Vérifiez votre clé API dans le fichier .env
Assurez-vous que :
1. La clé commence par "sk-" ou est la bonne clé HolySheep
2. Il n'y a pas d'espace avant/après le =
3. La clé n'est pas entourée de guillemets
Contenu correct du .env :
HOLYSHEEP_API_KEY=votre_cle_sans_guillemets
Puis rechargez les variables :
from dotenv import load_dotenv
load_dotenv(override=True) # Le override=True force le rechargement
Erreur 2 : "Module multi2vec-clip not found"
❌ ERREUR :
weaviate.exceptions.UnexpectedStatusCodeException:
Module with name 'multi2vec-clip' not found
🔧 SOLUTION :
Le module CLIP n'est pas disponible sur toutes les instances
Solution 1 : Utilisez Weaviate Cloud Starter (gratuit)
qui inclut le module CLIP
Solution 2 : Sinon, configurez un module alternatif :
class_obj = {
"class": "ProduitMultimodal",
"vectorizer": "img2vec-neural", # Alternative pour images seulement
"moduleConfig": {
"img2vec-neural": {
"imageFields": ["image"]
}
},
"properties": [
{"name": "image", "dataType": ["blob"]},
{"name": "description", "dataType": ["text"]}
]
}
Erreur 3 : "Image exceeds maximum size of 6MB"
❌ ERREUR :
weaviate.exceptions.ValidationError: Image exceeds maximum size of 6MB
🔧 SOLUTION :
Compressez vos images avant l'indexation
from PIL import Image
import os
def compresser_image(chemin_entree, chemin_sortie, qualite=85, taille_max=1024):
"""Compresse une image tout en conservant la qualité visuelle"""
with Image.open(chemin_entree) as img:
# Redimensionner si nécessaire
if max(img.size) > taille_max:
img.thumbnail((taille_max, taille_max), Image.Resampling.LANCZOS)
# Convertir en RGB si nécessaire
if img.mode in ('RGBA', 'P'):
img = img.convert('RGB')
# Sauvegarder avec compression
img.save(
chemin_sortie,
"JPEG",
quality=qualite,
optimize=True
)
taille_originale = os.path.getsize(chemin_entree) / 1024 / 1024
taille_optimisee = os.path.getsize(chemin_sortie) / 1024 / 1024
print(f" Compression : {taille_originale:.2f}MB → {taille_optimisee:.2f}MB")
Utilisation
compresser_image("grande_image.jpg", "image_optimisee.jpg")
Erreur 4 : Timeout lors de la recherche
❌ ERREUR :
requests.exceptions.ReadTimeout: HTTPSConnectionPool
🔧 SOLUTION :
1. Augmentez le timeout dans votre client Weaviate
client = weaviate.Client(
url=os.getenv("WEAVIATE_URL"),
auth_client_secret=weaviate.auth.AuthApiKey(os.getenv("WEAVIATE_API_KEY")),
timeout_config=(10, 60) # 10s timeout connexion, 60s timeout lecture
)
2. Limitez le nombre de résultats
resultats = client.query.get(
"ProduitMultimodal",
["nom_produit", "description"]
).with_near_text({"concepts": ["votre requête"]}
).with_limit(10) # Réduisez de 100 à 10 si timeout
.with_auto_limit(100) # Limite automatique basée sur la performance
.do()
3. Vérifiez votre connexion internet
HolySheep garantit <50ms de latence, donc le problème vient probablement de votre côté
Ressources et Prochaines Étapes
Félicitations ! Vous avez maintenant un système de recherche multimodale fonctionnel. Voici mes suggestions pour continuer votre apprentissage :
- Documentation Weaviate : weaviate.io/developers
- Exemples HolySheep : Créez votre compte pour accéder aux tutoriels officiels
- Communauté Discord : Rejoignez le serveur Weaviate pour poser vos questions
Projets pour pratiquer :
- Créez un moteur de recherche pour votre bibliothèque de photos personnelles
- Développez un système de recommandation de vêtements par image
- Construisez un catalogue de recettes où vous pouvez chercher par photo d'ingrédient
Conclusion
La recherche multimodale représente une révolution dans la façon dont nous interagissons avec les données visuelles. En combinant la puissance de Weaviate pour le stockage vectoriel et l'excellence des modèles AI de HolySheep, vous pouvez créer des expériences utilisateurs remarquable — le tout à une fraction du coût traditionnelle.
Mon conseil final : commencez petit, testez beaucoup, et itérez. La recherche multimodale est un domaine en évolution constante, et chaque projet vous apprendra quelque chose de nouveau.
Si vous avez des questions ou besoin d'aide, n'hésitez pas à laisser un commentaire. Bonne création ! 🚀