Dot.Blog

Consulting DotNet C#, XAML, WinUI, WPF, MAUI, IA

Intégrer les métriques de similarité dans une application C# avec ASP.NET Core + QDrant

Dans un article précédent (30/1/26), nous avons comparé plusieurs métriques de similarité : cosinus, produit scalaire (dot product), euclidienne. Mais comment ces méthodes s’intègrent-elles dans une application réelle ?

Cet article vous guide dans la création d’un mini-moteur de recherche sémantique :

  • indexation de documents vectorisés dans QDrant
  • interrogation via ASP.NET Core
  • choix dynamique de la métrique utilisée

🧰 Prérequis

  • QDrant installé localement (Docker ou natif)
  • .NET 9 ou 8
  • Un modèle d'embedding (OpenAI, HuggingFace ou autre)
  • Bibliothèque Qdrant.Client (ou appel HTTP simple)

dotnet add package Qdrant.Client

🧠 Structure de l’app

L'application ASP.NET expose un endpoint HTTP qui reçoit une requête utilisateur (texte libre), calcule son embedding, puis interroge QDrant avec la métrique choisie.

POST /search
{
  "query": "Quels sont les bienfaits du magnésium ?",
  "metric": "cosine"
}

🏗️ 1. Création du contrôleur SemanticSearchController

[ApiController]
[Route("[controller]")]
public class SemanticSearchController : ControllerBase
{
    private readonly QdrantClient _qdrant;

    public SemanticSearchController(QdrantClient qdrant)
    {
        _qdrant = qdrant;
    }

    [HttpPost("search")]
   public async Task<IActionResult> Search([FromBody] SearchQuery query)
    {
        var embedding = await EmbeddingHelper.GetEmbedding(query.Query); // via OpenAI ou autre
        var results = await _qdrant.SearchAsync(new SearchPointsRequest
        {
            CollectionName = "articles",
            Vector = embedding,
            Top = 5,
            Params = new SearchParams { HnswEf = 128 },
            SearchParams = new Distance(query.Metric switch
            {
                "cosine" => Distance.Cosine,
                "dot" => Distance.Dot,
                "euclid" => Distance.Euclid,
                _ => Distance.Cosine
            })
        });

        return Ok(results);
    }
}

public class SearchQuery
{
    public string Query { get; set; }
    public string Metric { get; set; } = "cosine";
}
📐 2. Paramétrer QDrant avec la bonne distance
Chaque collection dans QDrant est créée avec une métrique fixe.
❗ Cela signifie qu’il faut créer plusieurs collections si vous voulez pouvoir comparer différents modes :
{
  "name": "articles_cosine",
  "vectors": {
    "size": 1536,
    "distance": "Cosine"
  }
}

Vous pouvez gérer cette distinction via un champ CollectionName en fonction de la métrique sélectionnée.

🔁 3. Exemple de méthode d’embedding avec Azure OpenAI

public static class EmbeddingHelper
{
    private static readonly HttpClient client = new();

    public static async Task<float[]> GetEmbedding(string text)
    {
        var payload = new
        {
            input = text,
            model = "text-embedding-3-small"
        };

        var content = new StringContent(JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "VOTRE_CLE");

        var response = await client.PostAsync("https://votre-endpoint.openai.azure.com/openai/deployments/embedding-model/embeddings?api-version=2024-02-15-preview", content);
        var json = await response.Content.ReadAsStringAsync();

        var doc = JsonDocument.Parse(json);
        var array = doc.RootElement.GetProperty("data")[0].GetProperty("embedding").EnumerateArray();

        return array.Select(e => (float)e.GetDouble()).ToArray();
   }
}

🎯 Pour aller plus loin

  • Ajouter une couche de score pour pondérer les réponses selon un seuil
  • Intégrer la mémoire conversationnelle dans la requête
  • Stocker les résultats pour audit ou amélioration continue
  • Mettre en place un mécanisme de feedback utilisateur (utile pour l’apprentissage par renforcement)

✅ Conclusion

Ce mini moteur de recherche vectoriel vous donne un socle pour construire :

  • un assistant documentaire intelligent
  • un bot métier basé sur la similarité sémantique
  • une interface interactive pour les contenus indexés

QDrant, combiné à .NET et OpenAI, vous offre une solution self-hosted, performante et contrôlable, sans dépendance à Azure AI Search.

Stay Tuned !

Faites des heureux, PARTAGEZ l'article !