Embeddings
L'endpoint embeddings permet de convertir du texte en représentations vectorielles numériques pour la recherche sémantique, la classification et l'analyse de similarité.
Endpoint
POST https://api.yodi.tg/v1/embeddings
Qu'est-ce qu'un embedding ?
Un embedding est une représentation vectorielle d'un texte dans un espace multidimensionnel où :
- Les textes similaires sont proches dans l'espace vectoriel
- La distance entre vecteurs reflète la similarité sémantique
- Les opérations mathématiques sur les vecteurs ont du sens sémantique
Paramètres de requête
Paramètres obligatoires
| Paramètre | Type | Description |
|---|---|---|
model | string | Identifiant du modèle d'embedding (ex: "yodi-embed") |
input | string ou array | Texte(s) à convertir en embeddings |
Paramètres optionnels
| Paramètre | Type | Défaut | Description |
|---|---|---|---|
encoding_format | string | "float" | Format d'encodage ("float" ou "base64") |
dimensions | integer | null | Nombre de dimensions (pour modèles compatibles) |
user | string | null | Identifiant utilisateur pour le monitoring |
Exemples de requête
cURL
curl -X POST "https://api.yodi.tg/v1/embeddings" \
-H "Authorization: Bearer your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"model": "yodi-embed",
"input": "L'\''intelligence artificielle transforme notre monde"
}'
Python SDK
from yodi import Client
client = Client(api_key="your_api_key_here")
response = client.embeddings.create(
model="yodi-embed",
input="L'intelligence artificielle transforme notre monde"
)
embedding_vector = response.data[0].embedding
print(f"Dimension du vecteur : {len(embedding_vector)}")
print(f"Premiers éléments : {embedding_vector[:5]}")
JavaScript SDK
import { YodiClient } from 'yodi-sdk';
const client = new YodiClient({
apiKey: 'your_api_key_here'
});
const response = await client.embeddings.create({
model: 'yodi-embed',
input: 'L\'intelligence artificielle transforme notre monde'
});
const embeddingVector = response.data[0].embedding;
console.log(`Dimension du vecteur : ${embeddingVector.length}`);
Embeddings multiples
# Traiter plusieurs textes en une fois
texts = [
"L'intelligence artificielle est fascinante",
"Les voitures autonomes utilisent l'IA",
"J'aime les pizzas margherita",
"La cuisine italienne est délicieuse"
]
response = client.embeddings.create(
model="yodi-embed",
input=texts
)
embeddings = [item.embedding for item in response.data]
print(f"Nombre d'embeddings créés : {len(embeddings)}")
Réponse
Structure de la réponse
{
"message": "SUCCESS",
"error": false,
"data": {
"object": "list",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [
0.0023064255,
-0.009327292,
0.015797645,
"... 1533 autres valeurs"
]
}
],
"model": "yodi-embed",
"usage": {
"prompt_tokens": 8,
"total_tokens": 8
}
},
"status": 200
}
Champs de la réponse
| Champ | Type | Description |
|---|---|---|
object | string | Type d'objet ("list") |
data | array | Liste des embeddings |
model | string | Modèle utilisé |
usage | object | Informations sur l'utilisation |
Calculs de similarité
Similarité cosinus
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
def calculate_similarity(embedding1, embedding2):
"""Calcule la similarité cosinus entre deux embeddings"""
return cosine_similarity([embedding1], [embedding2])[0][0]
# Exemple
texts = [
"Les chats sont des animaux domestiques",
"Les félins vivent souvent avec les humains",
"J'aime les voitures de sport"
]
response = client.embeddings.create(
model="yodi-embed",
input=texts
)
embeddings = [item.embedding for item in response.data]
# Calculer les similarités
sim_1_2 = calculate_similarity(embeddings[0], embeddings[1])
sim_1_3 = calculate_similarity(embeddings[0], embeddings[2])
print(f"Similarité textes 1-2 (chats/félins) : {sim_1_2:.3f}")
print(f"Similarité textes 1-3 (chats/voitures) : {sim_1_3:.3f}")
Distance euclidienne
def euclidean_distance(embedding1, embedding2):
"""Calcule la distance euclidienne entre deux embeddings"""
return np.linalg.norm(np.array(embedding1) - np.array(embedding2))
distance = euclidean_distance(embeddings[0], embeddings[1])
print(f"Distance euclidienne : {distance:.3f}")
Cas d'usage
1. Recherche sémantique
class SemanticSearch:
def __init__(self, documents):
self.documents = documents
self.embeddings = self._create_embeddings()
def _create_embeddings(self):
"""Crée les embeddings pour tous les documents"""
response = client.embeddings.create(
model="yodi-embed",
input=self.documents
)
return [item.embedding for item in response.data]
def search(self, query, top_k=5):
"""Recherche les documents les plus similaires à la requête"""
# Créer l'embedding de la requête
query_response = client.embeddings.create(
model="yodi-embed",
input=query
)
query_embedding = query_response.data[0].embedding
# Calculer les similarités
similarities = []
for i, doc_embedding in enumerate(self.embeddings):
similarity = calculate_similarity(query_embedding, doc_embedding)
similarities.append((i, similarity, self.documents[i]))
# Trier par similarité décroissante
similarities.sort(key=lambda x: x[1], reverse=True)
return similarities[:top_k]
# Utilisation
documents = [
"Les pandas géants vivent en Chine",
"Python est un langage de programmation",
"Les serpents python sont de grands constricteurs",
"La Chine a une riche culture traditionnelle",
"Le machine learning utilise souvent Python"
]
search_engine = SemanticSearch(documents)
results = search_engine.search("programmation informatique", top_k=3)
for rank, (doc_idx, similarity, document) in enumerate(results, 1):
print(f"{rank}. ({similarity:.3f}) {document}")
2. Classification par clustering
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
def cluster_texts(texts, n_clusters=3):
"""Groupe les textes par similarité sémantique"""
# Créer les embeddings
response = client.embeddings.create(
model="yodi-embed",
input=texts
)
embeddings = [item.embedding for item in response.data]
# Clustering K-means
kmeans = KMeans(n_clusters=n_clusters, random_state=42)
clusters = kmeans.fit_predict(embeddings)
# Organiser les résultats
clustered_texts = {i: [] for i in range(n_clusters)}
for text, cluster in zip(texts, clusters):
clustered_texts[cluster].append(text)
return clustered_texts
# Exemple avec des textes de différentes catégories
texts = [
"Le machine learning révolutionne l'IA",
"Les réseaux de neurones sont puissants",
"J'adore les pâtes carbonara",
"La pizza napolitaine est délicieuse",
"Les algorithmes d'apprentissage automatique",
"La cuisine française est raffinée",
"Les voitures électriques sont l'avenir",
"Tesla produit des véhicules innovants"
]
clusters = cluster_texts(texts, n_clusters=3)
for cluster_id, cluster_texts in clusters.items():
print(f"\nCluster {cluster_id}:")
for text in cluster_texts:
print(f" - {text}")
3. Détection de plagiat
def detect_plagiarism(reference_texts, candidate_text, threshold=0.8):
"""Détecte le plagiat en comparant les embeddings"""
all_texts = reference_texts + [candidate_text]
response = client.embeddings.create(
model="yodi-embed",
input=all_texts
)
embeddings = [item.embedding for item in response.data]
candidate_embedding = embeddings[-1] # Le dernier est le candidat
plagiarism_detected = []
for i, ref_embedding in enumerate(embeddings[:-1]):
similarity = calculate_similarity(candidate_embedding, ref_embedding)
if similarity > threshold:
plagiarism_detected.append({
'reference_index': i,
'reference_text': reference_texts[i],
'similarity': similarity
})
return plagiarism_detected
# Exemple
references = [
"L'intelligence artificielle est une technologie révolutionnaire",
"Les voitures autonomes utilisent des capteurs avancés",
"Le changement climatique affecte notre planète"
]
candidate = "L'IA est une technologie qui révolutionne notre époque"
results = detect_plagiarism(references, candidate, threshold=0.7)
for result in results:
print(f"Similarité: {result['similarity']:.3f}")
print(f"Référence: {result['reference_text']}")
print(f"Candidat: {candidate}")
4. Recommandation de contenu
class ContentRecommender:
def __init__(self, content_database):
self.content_database = content_database
self.content_embeddings = self._create_content_embeddings()
def _create_content_embeddings(self):
"""Crée les embeddings pour tous les contenus"""
texts = [item['content'] for item in self.content_database]
response = client.embeddings.create(
model="yodi-embed",
input=texts
)
return [item.embedding for item in response.data]
def get_user_profile_embedding(self, user_interactions):
"""Crée un profil utilisateur basé sur ses interactions"""
interaction_texts = [interaction['content'] for interaction in user_interactions]
response = client.embeddings.create(
model="yodi-embed",
input=interaction_texts
)
# Moyenne pondérée des embeddings
embeddings = [item.embedding for item in response.data]
weights = [interaction['weight'] for interaction in user_interactions]
weighted_embedding = np.average(embeddings, axis=0, weights=weights)
return weighted_embedding
def recommend(self, user_interactions, top_k=5):
"""Recommande du contenu basé sur le profil utilisateur"""
user_embedding = self.get_user_profile_embedding(user_interactions)
similarities = []
for i, content_embedding in enumerate(self.content_embeddings):
similarity = calculate_similarity(user_embedding, content_embedding)
similarities.append((i, similarity, self.content_database[i]))
similarities.sort(key=lambda x: x[1], reverse=True)
return similarities[:top_k]
# Exemple d'utilisation
content_db = [
{'id': 1, 'content': 'Guide du machine learning pour débutants', 'category': 'tech'},
{'id': 2, 'content': 'Recettes de cuisine italienne traditionnelle', 'category': 'food'},
{'id': 3, 'content': 'Les dernières innovations en IA conversationnelle', 'category': 'tech'},
{'id': 4, 'content': 'Comment cultiver des légumes bio chez soi', 'category': 'garden'},
{'id': 5, 'content': 'Histoire de l\'intelligence artificielle', 'category': 'tech'}
]
recommender = ContentRecommender(content_db)
user_interactions = [
{'content': 'J\'adore apprendre sur l\'intelligence artificielle', 'weight': 1.0},
{'content': 'Les algorithmes de machine learning sont fascinants', 'weight': 0.8},
{'content': 'Programmation Python pour l\'IA', 'weight': 0.9}
]
recommendations = recommender.recommend(user_interactions, top_k=3)
print("Recommandations:")
for rank, (idx, similarity, content) in enumerate(recommendations, 1):
print(f"{rank}. ({similarity:.3f}) {content['content']}")
Optimisation et bonnes pratiques
Mise en cache des embeddings
import pickle
import hashlib
import os
class EmbeddingCache:
def __init__(self, cache_dir="embeddings_cache"):
self.cache_dir = cache_dir
os.makedirs(cache_dir, exist_ok=True)
def _get_cache_key(self, text, model):
"""Génère une clé de cache unique"""
content = f"{model}:{text}"
return hashlib.md5(content.encode()).hexdigest()
def get(self, text, model):
"""Récupère un embedding du cache"""
cache_key = self._get_cache_key(text, model)
cache_file = os.path.join(self.cache_dir, f"{cache_key}.pkl")
if os.path.exists(cache_file):
with open(cache_file, 'rb') as f:
return pickle.load(f)
return None
def set(self, text, model, embedding):
"""Sauvegarde un embedding dans le cache"""
cache_key = self._get_cache_key(text, model)
cache_file = os.path.join(self.cache_dir, f"{cache_key}.pkl")
with open(cache_file, 'wb') as f:
pickle.dump(embedding, f)
def get_embedding_with_cache(text, model="yodi-embed"):
"""Récupère un embedding avec mise en cache"""
cache = EmbeddingCache()
# Vérifier le cache
cached_embedding = cache.get(text, model)
if cached_embedding:
return cached_embedding
# Créer l'embedding si pas en cache
response = client.embeddings.create(model=model, input=text)
embedding = response.data[0].embedding
# Sauvegarder en cache
cache.set(text, model, embedding)
return embedding
Traitement par lots optimisé
def create_embeddings_batch(texts, model="yodi-embed", batch_size=100):
"""Crée des embeddings par lots pour optimiser les performances"""
all_embeddings = []
for i in range(0, len(texts), batch_size):
batch = texts[i:i + batch_size]
try:
response = client.embeddings.create(
model=model,
input=batch
)
batch_embeddings = [item.embedding for item in response.data]
all_embeddings.extend(batch_embeddings)
print(f"Traité: {min(i + batch_size, len(texts))}/{len(texts)} textes")
except Exception as e:
print(f"Erreur pour le lot {i//batch_size + 1}: {e}")
# Ajouter des embeddings vides pour maintenir l'ordre
all_embeddings.extend([None] * len(batch))
return all_embeddings
Gestion d'erreurs
from yodi.exceptions import YodiAPIError
import time
def robust_embedding_creation(texts, max_retries=3):
"""Création d'embeddings avec gestion d'erreurs robuste"""
for attempt in range(max_retries):
try:
response = client.embeddings.create(
model="yodi-embed",
input=texts
)
return [item.embedding for item in response.data]
except YodiAPIError as e:
if e.status_code == 429: # Rate limit
wait_time = 2 ** attempt
print(f"Rate limit atteint, attente {wait_time}s...")
time.sleep(wait_time)
elif e.status_code == 400:
print(f"Erreur de requête: {e.message}")
return None
else:
print(f"Erreur API: {e}")
if attempt == max_retries - 1:
raise
except Exception as e:
print(f"Erreur inattendue: {e}")
if attempt == max_retries - 1:
raise
return None
Limites et considérations
- Taille d'entrée : Maximum 8192 tokens par texte
- Limite de batch : Maximum 100 textes par requête
- Dimensions : Varie selon le modèle (généralement 1536)
- Coût : Facturation par token d'entrée
- Persistance : Les embeddings sont déterministes