Recherche par le sens, pas par les métadonnées : Filtrage sémantique d’images avec 4D.Vector

Traduit automatiquement de Deepl

Vos utilisateurs ne pensent pas en termes de noms de fichiers ou de hiérarchies de dossiers. Ils pensent en termes d’idées.

  • « Un robot peint à l’aquarelle.
  • « Une plage ensoleillée remplie de couleurs. »
  • « Quelque chose qui ressemble à Mona Lisa… mais qui vient du futur. »

Peu importe que cette idée provienne d’une image, d’une commande client, d’un e-mail ou d’un document 4D Write Pro – le défi est le même : comment fournir des résultats qui correspondent à l’intention, et pas seulement à des mots-clés ?

Avec 4D.Vector et 4D AI Kit, votre application peut enfin comprendre le sens. Dans ce billet, nous allons l’illustrer avec la recherche sémantique de similarités d’images. Et voici la clé : nous ne travaillons pas vraiment avec des images brutes – nous travaillons avec leurs descriptions. La même approche fonctionne pour n’importe quel type de données textuelles dans votre application.

DEMO_AI_Vector_ImageSearch

Pourquoi les vecteurs + l’IA changent tout

La recherche traditionnelle n’a qu’une seule tâche : trouver des termes exacts. Mais vos utilisateurs ne savent pas toujours quel terme exact utiliser. Ils décrivent des choses. Ils expriment une intention. Ils pensent en langage humain, beau et désordonné.

Pour que la recherche fonctionne de la même manière que vos utilisateurs, il ne suffit pas de faire correspondre des chaînes de caractères. Vous avez besoin de compréhension – et c’est là que les vector embeddings entrent en jeu.

Alors, qu’est-ce qu’un embedding exactement ?

L’intégration est la façon de transformer des données désordonnées et non structurées – une phrase, une invite ou une image – en un vecteur structuré de nombres. Il ne s’agit pas simplement d’une liste de tokens ou de mots-clés. Il s’agit d’un instantané mathématique du sens.

Lorsque vous envoyez la phrase « un robot peint à l’aquarelle » au modèle text-embedding-ada-002 d’OpenAI, celui-ci renvoie quelques centaines de valeurs à virgule flottante. Chacune d’entre elles capture quelque chose : le sujet, l’humeur, le style, les relations sémantiques incorporées dans cette phrase. Des phrases similaires produisent des vecteurs similaires. Les phrases dissemblables ? Elles sont plus éloignées les unes des autres.

Il s’agit de placer le sens sur une carte. Plus deux phrases sont proches dans cet espace à haute dimension, plus elles se ressemblent, quelle que soit la formulation. C’est le fondement de la recherche, des recommandations, du regroupement et de la catégorisation basés sur le sens.

Un cas d’utilisation réel : la recherche d’images par signification

Dans notre page de démonstration, vous pouvez laisser les utilisateurs effectuer des recherches sémantiques. Ils saisissent une requête ou en choisissent une dans une liste, et votre application renvoie des images classées en fonction de leur adéquation avec l’idée.

L’interface utilisateur est volontairement minimale :

  • Un champ de texte pour les invites personnalisées
  • Une liste déroulante d’invites prédéfinies
  • Une matrice qui affiche les images, classées en fonction de leur similitude avec l’invite.

Voici la clé : nous ne vectorisons pas les images brutes. Au lieu de cela, chaque image est analysée parOpenAIVision d’AIKit , qui génère une légende et une description en langage naturel. C’est cette description qui est intégrée dans un 4D.Vector et stockée.

De cette façon, tout est comparé au niveau du sens, et non des pixels.

Remarque : cet exemple utilise 4D Qodly Pro, mais la même logique s’applique parfaitement aux formulaires 4D standard. En fait, tout le code s’exécute à l’intérieur des méthodes et des fonctions 4D. La seule différence réside dans la manière dont vous choisissez d’afficher les résultats – dans un formulaire 4D classique ou dans une page Qodly.

Comment générer le vecteur

Lorsque quelqu’un tape une invite et clique sur« Use Custom Prompt« , 4D exécute la fonction calculate() de la classe VectorManagement:

exposed shared Function calculate($prompt : Text) : cs.PicturesSelection

Cette fonction commence par saisir votre clé API OpenAI en mémoire (Storage.OpenAI.key) – qui doit être soumise dans le premier champ de saisie de l’onglet Info. Si vous avez sauté cette étape et cliqué sur Use Custom Prompt, une fenêtre modale apparaîtra pour vous demander d’entrer votre clé avant de continuer :

If (Storage.OpenAI.key#"")
	$apiKey:=Storage.OpenAI.key
Else 
	$apiModal:=Web Form.setApiKeyModal
	$apiModal.show()
End if 

Remarque : cet exemple utilise OpenAI pour les opérations d’IA, mais vous pouvez utiliser n’importe quel fournisseur compatible avec OpenAI – même un modèle local avec Ollama. Nous utilisons OpenAI ici parce qu’il est simple à mettre en place et ne nécessite pas d’installation locale. Si vous souhaitez suivre le mouvement, demandez une clé OpenAI ici.

Ensuite, vous appelez la fonction generateVector() dans la classe AIManagement:

var $vector := cs.AIManagement.new($apiKey).generateVector($prompt)

Que se passe-t-il ici ?

Vous utilisez le modèle text-embedding-ada-002 d’OpenAI – optimisé pour les textes courts – pour transformer l’invite en un vecteur à haute dimension. En utilisant la méthode .create() pour envoyer l’invite et le modèle text-embedding-ada-002 sous forme de requête à OpenAI, vous obtenez une structure JSON contenant le vecteur. Ce vecteur est ensuite enveloppé dans un objet 4D.Vector, ce qui nous donne quelque chose que nous pouvons comparer et trier nativement en 4D.

property clientAI : Object

Class constructor($openAIKey : Text)
  This.clientAI := cs.AIKit.OpenAI.new($openAIKey)

Function generateVector($text : Text) : 4D.Vector
  var $model := "text-embedding-ada-002"
  var $result := This.clientAI.embeddings.create($text; $model)
  return $result.vector

À ce stade, vous avez traduit l’invite de l’utilisateur dans un format structuré que 4D peut utiliser pour une comparaison sémantique.

De l’invite aux résultats classés

Une fois votre vecteur en main, vous le comparez à tous les vecteurs de description d’image stockés dans la base de données :

var $pictureList := This._calculateVectors($vector)

Voici ce qui se passe à l’intérieur de _calculateVectors:

For each ($picture; $pictureList)
  $picture.cosineSimilarity := $vector.cosineSimilarity($picture.vector)
  $picture.dotSimilarity := $vector.dotSimilarity($picture.vector)
  $picture.euclideanDistance := $vector.euclideanDistance($picture.vector)
  $picture.save()
End for each 

Chaque mesure de similarité vous donne un objectif différent :

  • Lasimilarité cosinusienne mesure à quel point deux vecteurs pointent dans la même direction. Idéale pour classer les similarités sémantiques.
  • Le produit de points tient compte à la fois de la direction et de la magnitude. Il est utile lorsque vous souhaitez tenir compte de la « force » d’alignement de deux vecteurs.
  • Ladistance euclidienne est la distance brute entre deux points dans l’espace. Plus la distance est faible, plus les deux points sont similaires.

Si vous êtes novice en matière de mathématiques vectorielles dans 4D, le premier article de blog de cette série explique comment créer et comparer des vecteurs à l’aide de ces méthodes et quand utiliser chacune d’entre elles.

Une fois que tous les scores de similarité ont été calculés et stockés sur les entités image, vous pouvez trier par similarité cosinus et renvoyer les résultats :

return $pictureList.orderBy("cosineSimilarity desc")

Cela signifie que les images les plus pertinentes d’un point de vue conceptuel apparaissent en premier, indépendamment de leur nom de fichier, de leur description ou de leurs métadonnées.

Que se passe-t-il si l’utilisateur choisit une invite prédéfinie ?

Si l’utilisateur choisit une invite dans la liste déroulante et clique sur Utiliser l’invite sélectionnée, vous sautez entièrement l’étape d’intégration :

exposed shared Function calculateWithSelectedPrompt($prompt : cs.PromptsEntity) : cs.PicturesSelection
  var $pictureList:=This._calculateVectors($prompt.Vector)
  return $pictureList.orderBy("cosineSimilarity desc")

Aucun appel supplémentaire à OpenAI n’est nécessaire – le vecteur de l’invite est déjà enregistré dans la base de données. Vous réutilisez simplement l’adresse 4D.Vector stockée dans la classe de données Prompts lors de la première création de l’invite.

Tout comme les descriptions d’images, chaque invite est vectorisée une fois, puis stockée pour être réutilisée. Cela vous permet

  • Pas d’appel à l’API → Résultats instantanés, pas de délai d’attente sur le réseau

  • Pas de coût de jeton → plus adapté au budget, en particulier à grande échelle

  • Fonctionne hors ligne → Tout s’exécute localement, sans dépendance à l’égard d’un service externe.

DU TÉLÉCHARGEMENT D’IMAGES À LA DESCRIPTION VECTORISÉE

Lorsque quelqu’un télécharge une image, vous n’intégrez pas les pixels. Au lieu de cela, vous décrivez l’image avec OpenAI Vision et intégrez cette description.

Dans la fonction vectorizeImageDescription, deux invites sont définies : l’une pour une courte légende, l’autre pour une description plus complète. Toutes deux sont conçues pour renvoyer des phrases simples et fluides, optimisées pour l’intégration :

// --- Prompts (single, fluent, embedding-friendly) ---
$captionPrompt:="You are a precise visual captioner. "+\
	"Write one short, clear English sentence (12–20 words) that summarizes the main subject of the image. "+\
	"Keep it straightforward and descriptive, not poetic. Output only the sentence."

$descriptionPrompt:="You are a detailed scene describer. "+\
	"Write a longer English paragraph (80–150 words) that expands on the caption. "+\
	"Include context, secondary elements (icons, arrows, checklists, text, logos), and atmosphere so nothing important is missed. "+\
	"Avoid repeating the caption verbatim. Output only the description."

À l’aide de ces invites, OpenAI Vision analyse l’image. Cela se fait en deux étapes :

  • .create() instancie un VisionHelper lié à l’image téléchargée.
  • .prompt() envoie une instruction en langage naturel avec cette image à l’API OpenAI Chat, en renvoyant une légende ou une description.
// --- Get caption ---
$caption:=$client.chat.vision.create($imageData).prompt($captionPrompt).choice.message.text
	
// --- Get description ---
$description:=$client.chat.vision.create($imageData).prompt($descriptionPrompt).choice.message.text

À ce stade, vous disposez d’une légende et d’une description. Elles sont sauvegardées avec l’image elle-même et, surtout, la description est vectorisée pour la recherche sémantique :

// --- Save entity ---
$pictureEntity:=ds.Pictures.new()
$pictureEntity.picture:=$imageToUpload.picture
$pictureEntity.prompt:=$caption
$pictureEntity.description:=$description
$pictureEntity.vector:=cs.AIManagement.new($apiKey).generateVector($description+$caption)
$status:=$pictureEntity.save()

Ce que vous voyez dans l’interface utilisateur

Une fois la comparaison effectuée, votre matrice est mise à jour instantanément. Les images sont classées en fonction de leur score de similarité.

  • Vous recherchez « une aquarelle d’un robot » – et vous voyez des images avec des textures douces et des formes robotiques :

Visual results of a semantic AI image search using the prompt 'a watercolor painting of a robot,' showing six top-matching artworks with cosine similarity scores in a futuristic 4D interface.

  • Vous passez à : « une scène de plage vibrante et ensoleillée avec des éléments colorés » – et vous obtenez un ensemble de résultats totalement différents, mais tout aussi pertinents :

Semantic image search results for the prompt 'a vibrant and sunny beach scene with colorful elements,' ranked by AI using vector comparisons in a real-time 4D interface.

Qu’il s’agisse d’images saisies ou téléchargées, vous comparez toujours des idées, et non des pixels ou des noms de fichiers.

Ce que vous obtenez en tant que développeur

L’utilisation des vecteurs avec l’IA apporte une valeur réelle et immédiate à vos applications 4D :

  • Une recherche plus intelligente: Permettez aux utilisateurs d’effectuer des recherches en fonction du sens, et non des mots-clés. Pas de tags, pas de filtres – juste des résultats pertinents.

  • Logique native: Tout fonctionne à l’intérieur de 4D. Pas besoin de moteurs de recherche externes ou d’outils tiers.

  • Modèle réutilisable: Fonctionne pour les images, les documents, les produits, les tickets – tout ce que vous voulez comparer par concept.

  • Peu de configuration, beaucoup d’impact: Quelques lignes de code suffisent pour obtenir un classement, un filtrage et des recommandations basés sur l’intelligence artificielle.

  • Moins cher + plus rapide: Intégrez une fois, stockez le vecteur et réutilisez-le pour toujours. Pas d’appels répétés à l’API ni de coûts de jetons.

  • Une base prête pour l’IA: Vous ne vous contentez pas d’ajouter la recherche – vous posez les bases pour les chatbots, les recommandations et les flux de travail plus intelligents.

Avec 4D.Vector et 4D AI Kit, vous n’avez pas besoin de construire l’intelligence – vous la branchez.

Réflexions finales

Vous n’ajoutez pas l’IA à votre application, vous intégrez l’intelligence à votre logique de base.

Avec 4D.Vector et 4D AI Kit, vous donnez à votre application la capacité de comprendre l’intention, et pas seulement l’entrée. De faire ressortir le sens, et pas seulement les correspondances.

Les outils sont prêts. Le code est léger. La valeur est réelle. Tout ce dont vous avez besoin maintenant… c’est d’une invite.

Avatar
Product Marketing Manager – Basma a rejoint 4D en 2019 et a évolué vers son rôle actuel après avoir travaillé dans le développement, la documentation et la stratégie de contenu. Elle collabore étroitement avec les équipes produit, ingénierie, marketing, support et direction pour façonner le “pourquoi”, le “comment” et le “quoi” derrière chaque fonctionnalité et chaque publication. Cette solide expérience transversale lui permet aujourd’hui de concevoir des messages clairs et de créer du contenu approfondi — notamment des articles techniques — pour le blog et le site web de 4D. Titulaire d’un Master en ingénierie logicielle, Basma allie maîtrise technique et sens éditorial. Son expérience dans des domaines tels que le développement, les migrations, les audits, les webinaires et la formation lui donne un avantage unique en marketing produit — en lui permettant de transformer la complexité en clarté et de créer du contenu qui parle vraiment aux développeurs.