Le principe du RAG (Retrieval-Augmented Generation) est de combiner un moteur de recherche sémantique avec un LLM (Large Language Model) afin de générer des réponses contextualisées à partir de documents locaux. Cette approche permet de créer des assistants personnalisés, sans avoir à fine-tuner un modèle.
Dans cet article, nous allons construire un moteur RAG minimaliste en C# qui interroge un index vectoriel local (via QDrant) et appelle l’API OpenAI pour générer des réponses.
🧩 Architecture cible
- Documents vectorisés (embeddings)
- Index vectoriel local (QDrant)
- API Web locale (ASP.NET Minimal API)
- Appel à OpenAI pour générer la réponse finale
📦 Étape 1 : préparer les documents vectorisés
string[] documents = [
"Le C# est un langage de programmation orienté objet.",
"Les records permettent de modéliser des données immuables.",
"Span<T> optimise l’accès mémoire en .NET."
];
foreach (var doc in documents)
{
var vector = await openAiClient.EmbedAsync(doc);
await qdrantClient.UpsertAsync("docs", docId, vector, payload: new { texte = doc });
}
// 🌐 Étape 2 : Minimal API de requêtage en ASP.NET
var builder = WebApplication.CreateBuilder();
var app = builder.Build();
app.MapPost("/ask", async (AskRequest req) =>
{
var questionVector = await openAiClient.EmbedAsync(req.Question);
var matches = await qdrantClient.SearchAsync("docs", questionVector, top: 5);
string context = string.Join("\n", matches.Select(m => m.Payload["texte"]));
string prompt = $"Voici des extraits :\n{context}\n\nQuestion : {req.Question}\nRéponds de manière claire et concise.";
var response = await openAiClient.ChatAsync(prompt);
return Results.Ok(response);
});
app.Run();
🔧 Étape 3 : implémentation de OpenAI et QDrant clients simplifiés
Extrait simplifié de client d’embedding OpenAI :
public async Task<float[]> EmbedAsync(string input)
{
var body = new { model = "text-embedding-3-small", input };
var content = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("https://api.openai.com/v1/embeddings", content);
var json = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
return json.RootElement.GetProperty("data")[0].GetProperty("embedding")
.EnumerateArray().Select(x => x.GetSingle()).ToArray();
}
📤 Exemple de requête
POST /ask
{
"question": "Comment fonctionne Span<T> ?"
}
Réponse : texte généré par GPT-4 à partir des documents les plus proches.
📌 Résumé du flux
- Embedding de la question → vecteur
- Recherche dans QDrant → documents similaires
- Construction d’un prompt contextuel
- Appel à OpenAI pour compléter
🧪 Perspectives
- Ajouter un cache de réponse locale
- Ajouter de la pondération sur la similarité
- Indexer automatiquement des fichiers Markdown, PDF, etc.
- Proposer une UI WinUI ou Blazor locale
🔚 Conclusion
Avec quelques dizaines de lignes de C#, il est possible de construire un moteur RAG simple mais puissant, utilisable localement et sans infrastructure cloud externe. Cette base est idéale pour explorer des assistants spécialisés, des FAQ intelligentes, ou des moteurs documentaires embarqués.
C'est vraiment quelque chose d'important sur lequel il faut que vous vous penchiez, car c'est là que se joue l'avenir de l'informatique. Elle a commencé par envahir tous les objets du four micro-onde à la télé en passant par les bracelets montres, et maintenant qu'elle est partout elle va servir de voie royale à l'IA pour s'insinuer partout. Développer demain obligera à savoir intégrer l'IA dans ses Apps...
Stay Tuned !