<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Srikanth Manvi - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Srikanth Manvi - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/fr/search-labs/author/srikanth-manvi</link>
    </image>
    <link>https://www.elastic.co/fr/search-labs/author/srikanth-manvi</link>
    <atom:link href="https://www.elastic.co/fr/search-labs/rss/author/srikanth-manvi.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[fr]]></language>
    <lastBuildDate>Tue, 22 Sep 2026 01:53:56 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Comment utiliser le connecteur Elasticsearch Vector Store pour Microsoft Semantic Kernel pour le développement d'agents d'intelligence artificielle ?]]></title>
    <description><![CDATA[Microsoft Semantic Kernel est un kit de développement léger et open-source qui vous permet de créer facilement des agents d'intelligence artificielle et d'intégrer les derniers modèles d'intelligence artificielle dans votre base de code C#, Python ou Java. Avec la sortie du connecteur Semantic Kernel Elasticsearch Vector Store, les développeurs qui utilisent Semantic Kernel pour créer des agents d'intelligence artificielle peuvent désormais utiliser Elasticsearch comme un magasin vectoriel d'entreprise évolutif tout en continuant à utiliser les abstractions de Semantic Kernel.]]></description>
    <content:encoded><![CDATA[<p>En collaboration avec l'équipe <a href="https://learn.microsoft.com/en-us/semantic-kernel/overview/">de Microsoft Semantic Kernel,</a> nous annonçons la disponibilité du <a href="https://github.com/elastic/semantic-kernel-net/">connecteur Semantic Kernel Elasticsearch Vector</a> Store, pour les utilisateurs <a href="https://learn.microsoft.com/en-us/semantic-kernel/overview/">de Microsoft Semantic Kernel (.NET).</a> Semantic Kernel simplifie la création d'agents d'intelligence artificielle de niveau professionnel, notamment en permettant d'améliorer les grands modèles de langage (LLM) grâce à des réponses plus pertinentes et fondées sur des données provenant d'un magasin de vecteurs. Semantic Kernel fournit une couche d'abstraction transparente pour interagir avec les magasins vectoriels tels qu'Elasticsearch, offrant des fonctionnalités essentielles telles que la création, l'énumération et la suppression de collections d'enregistrements et le téléchargement, l'extraction et la suppression d'enregistrements individuels.</p><p>Le <a href="https://learn.microsoft.com/en-us/semantic-kernel/concepts/vector-store-connectors/out-of-the-box-connectors/elasticsearch-connector?pivots=programming-language-csharp">connecteur Semantic Kernel Elasticsearch Vector Store, prêt à l'emploi, prend</a> en charge les <a href="https://learn.microsoft.com/en-us/semantic-kernel/concepts/vector-store-connectors/?pivots=programming-language-csharp#the-vector-store-abstraction">abstractions du Semantic Kernel</a> vector store, ce qui permet aux développeurs de brancher très facilement Elasticsearch en tant que magasin vectoriel lors de la création d'agents d'intelligence artificielle.</p><p>Elasticsearch est solidement ancré dans la communauté des logiciels libres et a récemment adopté la <a href="https://www.elastic.co/blog/elasticsearch-is-open-source-again">licence AGPL</a>. Associés au noyau sémantique Microsoft open-source, ces outils offrent une solution puissante, prête pour l'entreprise. Vous pouvez commencer localement en démarrant Elasticsearch en quelques minutes en exécutant cette commande <code>curl -fsSL https://elastic.co/start-local | sh </code>(voir <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html">start-local</a> pour plus de détails) et évoluer vers des versions <a href="https://cloud.elastic.co/registration?onboarding_token=vectorsearch&amp;utm_source=semantickernel&amp;utm_content=documentation">hébergées dans le nuage</a> ou <a href="https://www.elastic.co/guide/en/elasticsearch/reference/8.16/install-elasticsearch.html">auto-hébergées</a> tout en mettant en production vos agents d'IA.</p><p>Dans ce blog, nous verrons comment utiliser le <a href="https://github.com/elastic/semantic-kernel-net/">connecteur Semantic Kernel Elasticsearch Vector Store</a> lors de l'utilisation de Semantic Kernel. Une version Python du connecteur sera disponible à l'avenir.</p><h2>Scénario de haut niveau : Construire une application RAG avec Semantic Kernel &amp; Elasticsearch</h2><p>Dans la section suivante, nous présentons un exemple. À un niveau élevé, nous construisons une application RAG (Retrieval Augmented Generation) qui prend la question d'un utilisateur en entrée et renvoie une réponse. Nous utiliserons Azure OpenAI<a href="https://devblogs.microsoft.com/semantic-kernel/introducing-new-ollama-connector-for-local-models/">(un LLM local</a> peut également être utilisé) comme LLM, Elasticsearch comme magasin de vecteurs et Semantic Kernel (.net) comme cadre pour relier tous les composants ensemble.</p><p>Si vous n'êtes pas familier avec les architectures RAG, vous pouvez vous familiariser rapidement avec cet article <a href="https://www.elastic.co/search-labs/blog/retrieval-augmented-generation-rag">: https://www.elastic.co/search-labs/blog/retrieval-augmented-generation-rag</a>.</p><p>La réponse est générée par le LLM qui est alimenté par le contexte, pertinent pour la question, récupéré à partir du vectorstore Elasticsearch. La réponse inclut également la source qui a été utilisée comme contexte par le LLM.</p><h3>Exemple de GCR</h3><p>Dans cet exemple spécifique, nous créons une application qui permet aux utilisateurs de poser des questions sur les hôtels stockés dans une base de données interne. L'utilisateur peut par exemple rechercher un hôtel spécifique, en fonction de différents critères, ou demander une liste d'hôtels.</p><p>Pour la base de données d'exemple, nous avons généré une <a href="https://github.com/elastic/semantic-kernel-net/blob/main/Elastic.SemanticKernel.Playground/hotels.csv">liste d'hôtels</a> contenant 100 entrées. La taille de l'échantillon est volontairement réduite pour vous permettre d'essayer la démo du connecteur aussi facilement que possible. Dans une application réelle, le connecteur Elasticsearch montrerait ses avantages par rapport à d'autres options, telles que l'implémentation du magasin vectoriel `InMemory`, en particulier lorsque l'on travaille avec de très grandes quantités de données.</p><p>L'application de démonstration complète se trouve dans le <a href="https://github.com/elastic/semantic-kernel-net/tree/main/Elastic.SemanticKernel.Playground">référentiel du</a> connecteur Elasticsearch vector store.</p><p>Commençons par ajouter les paquets NuGet et les directives nécessaires à notre projet :</p>dotnet add package "Elastic.Clients.Elasticsearch" -v 8.16.2
dotnet add package "Elastic.SemanticKernel.Connectors.Elasticsearch" -v 0.1.2
dotnet add package "Microsoft.Extensions.Hosting" -v 9.0.0
dotnet add package "Microsoft.SemanticKernel.Connectors.AzureOpenAI" -v 1.30.0
dotnet add package "Microsoft.SemanticKernel.PromptTemplates.Handlebars" -v 1.30.0using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

using Elastic.Clients.Elasticsearch;
using Elastic.Transport;

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Data;
using Microsoft.SemanticKernel.Embeddings;
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;<p>Nous pouvons maintenant créer notre modèle de données et le doter d'attributs spécifiques au Semantic Kernel pour définir le schéma du modèle de stockage et quelques indications pour la recherche textuelle :</p>/// &lt;summary&gt;
/// Data model for storing a "hotel" with a name, a description, a  description embedding and an optional reference link.
/// &lt;/summary&gt;
public sealed record Hotel
{
	[VectorStoreRecordKey]
	public required string HotelId { get; set; }

	[TextSearchResultName]
	[VectorStoreRecordData(IsFilterable = true)]
	public required string HotelName { get; set; }

	[TextSearchResultValue]
	[VectorStoreRecordData(IsFullTextSearchable = true)]
	public required string Description { get; set; }

	[VectorStoreRecordVector(Dimensions: 1536, DistanceFunction.CosineSimilarity, IndexKind.Hnsw)]
	public ReadOnlyMemory&lt;float&gt;? DescriptionEmbedding { get; set; }

	[TextSearchResultLink]
	[VectorStoreRecordData]
	public string? ReferenceLink { get; set; }
}<p>Les attributs du schéma du modèle de stockage (`VectorStore*`) sont les plus pertinents pour l'utilisation réelle du connecteur Elasticsearch Vector Store, à savoir :</p><p></p><ul><li><p><code>VectorStoreRecordKey</code> pour marquer une propriété d'une classe d'enregistrement comme étant la clé sous laquelle l'enregistrement est stocké dans un magasin vectoriel.</p></li><li><p><code>VectorStoreRecordData</code> pour marquer une propriété d'une classe d'enregistrement comme "data".</p></li><li><p><code>VectorStoreRecordVector</code> pour marquer une propriété d'une classe d'enregistrement en tant que vecteur.</p></li></ul><p>Tous ces attributs acceptent divers paramètres facultatifs qui peuvent être utilisés pour personnaliser davantage le modèle de stockage. Dans le cas de <code>VectorStoreRecordKey </code>, par exemple, il est possible de spécifier une fonction de distance différente ou un type d'indice différent.</p><p>Les attributs de recherche de texte (<code>TextSearch*</code>) seront importants dans la dernière étape de cet exemple. Nous y reviendrons plus tard.</p><p>Dans l'étape suivante, nous initialisons le moteur du noyau sémantique et obtenons des références aux services de base. Dans une application réelle, l' <a href="https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection">injection de dépendances</a> devrait être utilisée au lieu d'accéder directement à la collection de services. La même chose s'applique à la configuration et aux secrets codés en dur, qui doivent être lus à l'aide d'un <a href="https://learn.microsoft.com/en-us/dotnet/core/extensions/configuration">fournisseur de configuration</a>:</p>var builder = Host.CreateApplicationBuilder(args);

// Register AI services.
var kernelBuilder = builder.Services.AddKernel();

kernelBuilder.AddAzureOpenAIChatCompletion("gpt-4o", "https://my-service.openai.azure.com", "my_token");

kernelBuilder.AddAzureOpenAITextEmbeddingGeneration("ada-002", "https://my-service.openai.azure.com", "my_token");

// Register text search service.
kernelBuilder.AddVectorStoreTextSearch&lt;Hotel&gt;();

// Register Elasticsearch vector store.
var elasticsearchClientSettings = new ElasticsearchClientSettings(new Uri("https://my-elasticsearch-instance.cloud"))
    .Authentication(new BasicAuthentication("elastic", "my_password"));

kernelBuilder.AddElasticsearchVectorStoreRecordCollection&lt;string, Hotel&gt;("skhotels", elasticsearchClientSettings);

// Build the host.
using var host = builder.Build();

// For demo purposes, we access the services directly without using a DI context.

var kernel = host.Services.GetService&lt;Kernel&gt;()!;
var embeddings = host.Services.GetService&lt;ITextEmbeddingGenerationService&gt;()!;
var vectorStoreCollection = host.Services.GetService&lt;IVectorStoreRecordCollection&lt;string, Hotel&gt;&gt;()!;

// Register search plugin.
var textSearch = host.Services.GetService&lt;VectorStoreTextSearch&lt;Hotel&gt;&gt;()!;
kernel.Plugins.Add(textSearch.CreateWithGetTextSearchResults("SearchPlugin"));<p>Le service <code>vectorStoreCollection</code> peut maintenant être utilisé pour créer la collection et ingérer quelques <a href="https://github.com/elastic/semantic-kernel-net/blob/main/Elastic.SemanticKernel.Playground/hotels.csv">enregistrements de démonstration :</a></p>await vectorStoreCollection.CreateCollectionIfNotExistsAsync();

// CSV format: ID;Hotel Name;Description;Reference Link
var hotels = (await File.ReadAllLinesAsync("hotels.csv"))
    .Select(x =&gt; x.Split(';'));

foreach (var chunk in hotels.Chunk(25))
{
    var descriptionEmbeddings = await embeddings.GenerateEmbeddingsAsync(chunk.Select(x =&gt; x[2]).ToArray());
    
    for (var i = 0; i &lt; chunk.Length; ++i)
    {
        var hotel = chunk[i];
        await vectorStoreCollection.UpsertAsync(new Hotel
        {
            HotelId = hotel[0],
            HotelName = hotel[1],
            Description = hotel[2],
            DescriptionEmbedding = descriptionEmbeddings[i],
            ReferenceLink = hotel[3]
        });
    }
}<p>Cela montre comment Semantic Kernel réduit l'utilisation d'un magasin de vecteurs, avec toute sa complexité, à quelques simples appels de méthodes.</p><p>Sous le capot, un nouvel index est créé dans Elasticsearch et tous les mappages de propriétés nécessaires sont créés. Notre ensemble de données est ensuite intégré de manière totalement transparente dans le modèle de stockage et finalement stocké dans l'index. Voici à quoi ressemblent les mappings dans Elasticsearch.</p>{
  "mappings": {
    "properties": {
      "descriptionEmbedding": {
        "dims": 1536,
        "index": true,
        "index_options": {
          "type": "hnsw"
        },
        "similarity": "cosine",
        "type": "dense_vector"
      },
      "hotelName": {
        "type": "keyword"
      },
      "description": {
        "type": "text"
      }
    }
  }
}<p>Le site <code>embeddings.GenerateEmbeddingsAsync()</code> appelle de manière transparente le service Azure AI Embeddings Generation configuré.</p><p>La dernière étape de cette démonstration est encore plus magique.</p><p>Avec un seul appel à <code>InvokePromptAsync</code>, toutes les opérations suivantes sont effectuées lorsque l'utilisateur pose une question sur les données :</p><p>1. L'intégration de la question de l'utilisateur est générée.</p><p>2. Le magasin de vecteurs est parcouru à la recherche d'entrées pertinentes</p><p>3. Les résultats de la requête sont insérés dans un modèle d'invite</p><p>4. La requête proprement dite, sous la forme de l'invite finale, est envoyée au service d'achèvement de chat de l'IA.</p>// Invoke the LLM with a template that uses the search plugin to
// 1. get related information to the user query from the vector store
// 2. add the information to the LLM prompt.
var response = await kernel.InvokePromptAsync(
    promptTemplate: """
                    Please use this information to answer the question:
                    {{#with (SearchPlugin-GetTextSearchResults question)}}
                      {{#each this}}
                        Name: {{Name}}
                        Value: {{Value}}
                        Source: {{Link}}
                        -----------------
                      {{/each}}
                    {{/with}}
                    
                    Include the source of relevant information in the response.

                    Question: {{question}}
                    """,
    arguments: new KernelArguments
    {
        { "question", "Please show me all hotels that have a rooftop bar." },
    },
    templateFormat: "handlebars",
    promptTemplateFactory: new HandlebarsPromptTemplateFactory());<p>Vous vous souvenez des attributs <code>TextSearch*</code> que nous avons définis précédemment dans notre modèle de données ? Ces attributs nous permettent d'utiliser les espaces réservés correspondants dans notre modèle d'invite, qui sont automatiquement remplis avec les informations provenant de nos entrées dans le magasin de vecteurs.</p><p>La réponse finale à notre question "Veuillez m'indiquer tous les hôtels qui disposent d'un bar sur le toit." est la suivante :</p>Console.WriteLine(response.ToString());

// &gt; The hotel that has a rooftop bar is Skyline Suites. You can find more information about this hotel [here](https://example.com/yz567).<p>La réponse se réfère correctement à l'entrée suivante dans notre fichier hotels.csv</p>9;
Skyline Suites;
Offering panoramic city views from every suite, this hotel is perfect for those who love the urban landscape. Enjoy luxurious amenities, a rooftop bar, and close proximity to attractions. Luxurious and contemporary.;
https://example.com/yz567<p>Cet exemple montre très bien comment l'utilisation de Microsoft Semantic Kernel permet une réduction significative de la complexité grâce à ses abstractions bien pensées, tout en permettant un très haut niveau de flexibilité. En changeant une seule ligne de code, par exemple, le magasin de vecteurs ou les services d'intelligence artificielle utilisés peuvent être remplacés sans qu'il soit nécessaire de remanier une autre partie du code.</p><p>Dans le même temps, le cadre fournit un ensemble considérable de fonctionnalités de haut niveau, telles que la fonction `InvokePrompt`, ou le système de plugin de modèle ou de recherche.</p><p>L'application de démonstration complète se trouve dans le référentiel du connecteur Elasticsearch vector store.</p><h2>Quelles sont les autres possibilités offertes par Elasticsearch ?</h2><ul><li><p><a href="https://www.elastic.co/search-labs/blog/semantic-search-simplified-semantic-text">Nouveau mappage semantic_text d'Elasticsearch : Simplifier la recherche sémantique</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/semantic-reranking-with-retrievers">Classement sémantique dans Elasticsearch à l'aide d'extracteurs</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-1">Techniques avancées de RAG partie 1 : Traitement des données</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/advanced-rag-techniques-part-2">Techniques avancées de RAG, partie 2 : Requêtes et tests</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/elasticsearch-rag-with-llama3-opensource-and-elastic">Construire RAG avec Llama 3 open-source et Elastic</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/local-rag-agent-elasticsearch-langgraph-llama3">Un tutoriel sur la construction d'un agent local utilisant LangGraph, LLaMA3 et Elasticsearch vector store à partir de zéro</a></p></li></ul><h2>Elasticsearch &amp; Semantic Kernel : Quelle est la prochaine étape ?</h2><ul><li><p>Nous avons montré comment le magasin vectoriel Elasticsearch peut être facilement intégré au Semantic Kernel lors de la construction d'applications GenAI en .NET. Restez à l'écoute pour une prochaine intégration de Python.</p></li><li><p>Comme Semantic Kernel construit des abstractions pour des fonctions de recherche avancées telles que la <a href="https://www.elastic.co/search-labs/tutorials/search-tutorial/vector-search/hybrid-search">recherche hybride</a>, la connexion Elasticsearch permettra aux développeurs .NET de les mettre en œuvre facilement tout en utilisant Semantic Kernel.</p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-connector-microsoft-semantic-kernel</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-connector-microsoft-semantic-kernel</guid>
    <category><![CDATA[IA]]></category>
    <category><![CDATA[.NET]]></category>
    <category><![CDATA[Base vectorielle]]></category>
    <dc:creator><![CDATA[Florian Bernd,Srikanth Manvi]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2d8725035e86f8a8/6a17fe447f6f1564f8c09d74/0564fe794e4c66d0507317822d7aa71826183d20-1311x762.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 06 Dec 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Protéger les informations sensibles et PII dans RAG avec Elasticsearch et LlamaIndex]]></title>
    <description><![CDATA[Comment protéger les données sensibles et PII dans une application RAG avec Elasticsearch et LlamaIndex.]]></description>
    <content:encoded><![CDATA[<p></p><p></p><p>Dans ce billet, nous examinerons les moyens de protéger les informations personnelles identifiables (PII) et les données sensibles lors de l'utilisation de LLM publics dans un flux RAG (Retrieval Augmented Generation). Nous explorerons le masquage des IIP et des données sensibles à l'aide de bibliothèques open source et d'expressions régulières, ainsi que l'utilisation de LLM locaux pour masquer les données avant d'invoquer un LLM public.</p><p>Avant de commencer, rappelons la terminologie utilisée dans ce billet.</p><h2>Terminologie</h2><p><a href="https://www.llamaindex.ai/">LlamaIndex</a> est un cadre de données de premier plan pour la création d'applications LLM (Large Language Model). LlamaIndex fournit des abstractions pour les différentes étapes de la construction d'une application RAG (Retrieval Augmented Generation). Des structures telles que LlamaIndex et LangChain fournissent des abstractions afin que les applications ne soient pas étroitement liées aux API d'un LLM spécifique.</p><p><a href="https://www.elastic.co/enterprise-search">Elasticsearch</a> est proposé par <a href="https://elastic.co/">Elastic</a>. Elastic est un leader de l'industrie avec Elasticsearch, un magasin de données évolutif et une base de données vectorielle qui prend en charge la recherche en texte intégral pour la précision, la recherche vectorielle pour la compréhension sémantique, et la recherche hybride pour le meilleur des deux mondes. Elasticsearch est un moteur de recherche et d'analyse RESTful distribué, un magasin de données évolutif et une base de données vectorielle. Les fonctionnalités d'Elasticsearch que nous utilisons dans ce blog sont disponibles dans la version gratuite et ouverte d'Elasticsearch.</p><p>La <a href="https://www.promptingguide.ai/techniques/rag">génération assistée par récupération (RAG)</a> est une technique ou un modèle d'IA dans lequel les LLM sont dotés de connaissances externes pour générer des réponses aux questions des utilisateurs. Cela permet d'adapter les réponses du programme d'éducation et de formation tout au long de la vie à un contexte spécifique et de les rendre moins génériques.</p><p>Les <a href="https://www.elastic.co/guide/en/elasticsearch/reference/8.13/semantic-search.html">encastrements</a> sont des représentations numériques de la signification d'un texte ou d'un média. Il s'agit de représentations de dimensions inférieures d'informations de dimensions supérieures.</p><h2>RAG et protection des données</h2><p>En règle générale, les grands modèles linguistiques (LLM) permettent de générer des réponses sur la base des informations disponibles dans le modèle, qui peut être formé à partir de données Internet. Toutefois, pour les questions pour lesquelles les informations ne sont pas disponibles dans le modèle, les MFR doivent être alimentés par des connaissances externes ou des détails spécifiques qui ne sont pas contenus dans le modèle. Ces informations peuvent se trouver dans votre base de données ou dans votre système de connaissances interne. La génération améliorée par récupération (RAG) est une technique dans laquelle, pour une requête d'utilisateur donnée, vous récupérez d'abord le contexte/l'information pertinente des systèmes externes (au LLM) (par exemple votre base de données) et envoyez ce contexte avec la requête d'utilisateur au LLM pour générer une réponse plus spécifique et plus pertinente.</p><p>Cela rend la technique RAG très efficace pour les applications de réponse aux questions, de création de contenu et partout où une compréhension approfondie du contexte et des détails est bénéfique.</p><p>Par conséquent, dans une filière RAG, vous courez le risque d'exposer des informations internes telles que des PII (informations personnelles identifiables) et des informations sensibles (par exemple des noms, des dates de naissance, des numéros de compte, etc.</p><p>Bien que vos données soient sécurisées lorsque vous utilisez une base de données vectorielle comme Elasticsearch (grâce à divers leviers tels que le <a href="https://www.elastic.co/guide/en/cloud-enterprise/current/ece-configure-rbac.html">contrôle d'accès basé sur les rôles</a>, la <a href="https://www.elastic.co/search-labs/blog/dls-internal-knowledge-search">sécurité au niveau du document</a>, etc.), il convient d'être prudent lorsque vous envoyez des données à l'extérieur vers un LLM public.</p><p>La protection des informations d'identification personnelle (PII) et des données sensibles est cruciale lors de l'utilisation de grands modèles de langage (LLM), et ce pour plusieurs raisons :</p><ul><li><p><strong>Conformité en matière de protection de la vie privée</strong>: De nombreuses régions disposent de réglementations strictes, telles que le règlement général sur la protection des données (RGPD) en Europe ou le California Consumer Privacy Act (CCPA) aux États-Unis, qui imposent la protection des données personnelles. Le respect de ces lois est nécessaire pour éviter les conséquences juridiques et les amendes.</p></li><li><p><strong>Confiance des utilisateurs</strong>: Garantir la confidentialité et l'intégrité des informations sensibles permet de renforcer la confiance des utilisateurs. Les utilisateurs sont plus enclins à utiliser et à interagir avec des systèmes dont ils pensent qu'ils protègent leur vie privée.</p></li><li><p><strong>Sécurité des données</strong>: La protection contre les violations de données est essentielle. Les données sensibles exposées aux MLD sans garanties adéquates peuvent faire l'objet d'un vol ou d'une utilisation abusive, entraînant des dommages potentiels tels que l'usurpation d'identité ou la fraude financière.</p></li><li><p><strong>Considérations éthiques</strong>: D'un point de vue éthique, il est important de respecter la vie privée des utilisateurs et de traiter leurs données de manière responsable. Un mauvais traitement des IPI peut conduire à la discrimination, à la stigmatisation ou à d'autres conséquences négatives pour la société.</p></li><li><p><strong>Réputation de l'entreprise</strong>: Les entreprises qui ne protègent pas les données sensibles peuvent voir leur réputation entachée, ce qui peut avoir des effets négatifs à long terme sur leurs activités, notamment la perte de clients et de revenus.</p></li><li><p><strong>Réduction des risques d'abus</strong>: Le traitement sécurisé des données sensibles permet d'éviter l'utilisation malveillante des données ou du modèle, comme l'entraînement des modèles sur des données biaisées ou l'utilisation des données pour manipuler ou nuire à des personnes.</p></li></ul><p>Dans l'ensemble, une protection solide des IPI et des données sensibles est nécessaire pour garantir la conformité légale, maintenir la confiance des utilisateurs, assurer la sécurité des données, respecter les normes éthiques, protéger la réputation de l'entreprise et réduire le risque d'abus.</p><h2>Récapitulatif rapide</h2><p>Dans l'<a href="https://www.elastic.co/search-labs/blog/rag-with-llamaIndex-and-elasticsearch">article précédent</a>, nous avons expliqué comment mettre en œuvre l'expérience Q&amp;A en utilisant une technique RAG avec Elasticsearch comme base de données vectorielle tout en utilisant LlamaIndex et un Mistral LLM fonctionnant localement. Ici, nous nous appuyons sur cette base.</p><p>La lecture de l'article précédent est facultative car nous allons maintenant discuter/récapituler rapidement ce que nous avons fait dans l'article précédent.</p><p>Nous disposions d'un échantillon de données de conversations de centre d'appel entre des agents et des clients d'une compagnie d'assurance habitation fictive. Nous avons créé une application RAG simple qui répond à des questions telles que "Quels sont les problèmes liés à l'eau pour lesquels les clients déposent des réclamations ?</p><p>Voici comment se présentait le flux à un niveau élevé.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9d3882da43bfdac0/6a17050867045bd5fe45c0e9/9d51295472f8bcca3d1973248acb724f8b94767e-1054x555.png" alt="Flux RAG" /><p>Pendant la phase d'indexation, nous avons chargé et indexé des documents en utilisant le pipeline LlamaIndex. Les documents ont été regroupés et stockés dans la base de données vectorielles Elasticsearch avec leur intégration.</p><p>Pendant la phase d'interrogation, lorsque l'utilisateur pose une question, LlamaIndex récupère les documents similaires les plus pertinents par rapport à l'interrogation. Ces documents les plus pertinents, accompagnés de la requête, ont été envoyés au Mistral LLM local, qui a ensuite généré la réponse à renvoyer à l'utilisateur. N'hésitez pas à consulter l'article précédent ou à <a href="https://github.com/srikanthmanvi/RAG-InsuranceCompany/tree/main">explorer le code</a>.</p><p>Dans l'article précédent, le LLM fonctionnait localement. Cependant, en production, vous pouvez vouloir utiliser un LLM externe fourni par diverses entreprises comme <a href="https://openai.com/">OpenAI</a>, <a href="https://mistral.ai/">Mistral</a>, <a href="https://www.anthropic.com/claude">Anthropic</a>, etc. Cela peut être dû au fait que votre cas d'utilisation nécessite un modèle de base plus important ou que l'exécution locale n'est pas une option en raison des besoins de production de l'entreprise tels que l'évolutivité, la disponibilité, les performances, etc.</p><p>L'introduction d'un LLM externe dans votre pipeline RAG vous expose à un risque de fuite involontaire de données sensibles et d'informations confidentielles vers les LLM. Dans cet article, nous allons explorer les options permettant de masquer les informations PII dans le cadre de votre processus RAG avant d'envoyer des documents à un LLM externe.</p><h2>RAG avec un LLM public</h2><p>Avant d'aborder la question de la protection des informations confidentielles et sensibles dans un pipeline RAG, nous allons d'abord construire une application RAG simple utilisant LlamaIndex, la base de données vectorielle Elasticsearch et OpenAI LLM.</p><h3>Produits requis</h3><p>Nous aurons besoin des éléments suivants.</p><ul><li><p><strong>Elasticsearch</strong> est opérationnel en tant que base de données vectorielle pour le stockage des embeddings. Suivez les instructions de l'article précédent sur l'<a href="https://www.elastic.co/search-labs/blog/rag-with-llamaIndex-and-elasticsearch#install-elasticsearch">installation d'Elasticsearch</a>.</p></li><li><p>Clés d'API ouvertes pour l'IA.</p></li></ul><h3>Application simple du RAG</h3><p>Pour référence, le code entier peut être trouvé dans ce <a href="https://github.com/srikanthmanvi/RAG-InsuranceCompany/tree/protecting-pii">dépôt Github</a>(branch:protecting-pii). Le clonage du dépôt est facultatif car nous allons parcourir le code ci-dessous.</p><p>Dans votre IDE préféré, créez une nouvelle application Python avec les 3 fichiers ci-dessous.</p><ul><li><p><code>index.py</code> où se trouve le code lié à l'indexation des données.</p></li><li><p><code>query.py</code> où se trouve le code lié à l'interrogation et à l'interaction avec le LLM.</p></li><li><p><code>.env</code> où se trouvent les propriétés de configuration telles que les clés d'API.</p></li></ul><p>Nous devons installer quelques paquets. Nous commençons par créer un nouvel <a href="https://docs.python.org/3/library/venv.html">environnement virtuel</a> python dans le dossier racine de votre application.</p>python3 -m venv .venv
<p>Activez l'environnement virtuel et installez les paquets requis ci-dessous.</p>source .venv/bin/activate
pip install llama-index 
pip install llama-index-embeddings-openai
pip install llama-index-vector-stores-elasticsearch
pip install sentence-transformers
pip install python-dotenv
pip install openai
<p>Configurer les propriétés de connexion d'OpenAI et d'Elasticsearch dans le fichier .env fichier.</p>OPENAI_API_KEY="REPLACEME"
ELASTIC_CLOUD_ID="REPLACEME"
ELASTIC_API_KEY="REPLACEME"
<h4>Indexation des données</h4><p>Téléchargez le fichier <a href="https://github.com/srikanthmanvi/RAG-InsuranceCompany/blob/main/conversations.json">conversations.json</a> qui contient les <em>conversations</em> entre les clients et les agents du centre d'appel de notre compagnie d'assurance habitation fictive. Placez le fichier dans le répertoire racine de l'application avec les 2 fichiers python et le fichier .env. que vous avez créé précédemment. Vous trouverez ci-dessous un exemple du contenu du fichier.</p>{
"conversation_id": 103,
"customer_name": "Sophia Jones",
"agent_name": "Emily Wilson",
"policy_number": "JKL0123",
"conversation": "Customer: Hi, I'm Sophia Jones. My Date of Birth is November 15th, 1985, Address is 303 Cedar St, Miami, FL 33101, and my Policy Number is JKL0123.\nAgent: Hello, Sophia. How may I assist you today?\nCustomer: Hello, Emily. I have a question about my policy.\nCustomer: There's been a break-in at my home, and some valuable items are missing. Are they covered?\nAgent: Let me check your policy for coverage related to theft.\nAgent: Yes, theft of personal belongings is covered under your policy.\nCustomer: That's a relief. I'll need to file a claim for the stolen items.\nAgent: We'll assist you with the claim process, Sophia. Is there anything else I can help you with?\nCustomer: No, that's all for now. Thank you for your assistance, Emily.\nAgent: You're welcome, Sophia. Please feel free to reach out if you have any further questions or concerns.\nCustomer: I will. Have a great day!\nAgent: You too, Sophia. Take care.",
"summary": "A customer inquires about coverage for stolen items after a break-in at home, and the agent confirms that theft of personal belongings is covered under the policy. The agent offers assistance with the claim process, resulting in the customer expressing relief and gratitude."
}
<p>Passez le code ci-dessous dans <code>index.py</code> qui se charge de l'indexation des données.</p># index.py
# pip install sentence-transformers
# pip install llama-index-embeddings-openai
# pip install llama-index-embeddings-huggingface

import json
import os
from dotenv import load_dotenv
from llama_index.core import Document
from llama_index.core import Settings
from llama_index.core.ingestion import IngestionPipeline
from llama_index.core.node_parser import SentenceSplitter
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.vector_stores.elasticsearch import ElasticsearchStore


def get_documents_from_file(file):
   """Reads a json file and returns list of Documents"""

   with open(file=file, mode='rt') as f:
       conversations_dict = json.loads(f.read())

   # Build Document objects using fields of interest.
   documents = [Document(text=item['conversation'],
                         metadata={"conversation_id": item['conversation_id']})
                for
                item in conversations_dict]
   return documents

# Load .env file contents into env
load_dotenv('.env')
Settings.embed_model = HuggingFaceEmbedding(
   model_name="BAAI/bge-small-en-v1.5"
)

def main():
   # ElasticsearchStore is a VectorStore that
   # takes care of Elasticsearch Index and Data management.
   es_vector_store = ElasticsearchStore(index_name="convo_index",
                                        vector_field='conversation_vector',
                                        text_field='conversation',
                                        es_cloud_id=os.getenv("ELASTIC_CLOUD_ID"),
                                        es_api_key=os.getenv("ELASTIC_API_KEY"))

   # LlamaIndex Pipeline configured to take care of chunking, embedding
   # and storing the embeddings in the vector store.
   llamaindex_pipeline = IngestionPipeline(
       transformations=[
           SentenceSplitter(chunk_size=350, chunk_overlap=50),
           Settings.embed_model
       ],
       vector_store=es_vector_store
   )

   # Load data from a json file into a list of LlamaIndex Documents
   documents = get_documents_from_file(file="conversations.json")
   llamaindex_pipeline.run(documents=documents)
   print(".....Indexing Data Completed.....\n")

if __name__ == "__main__":
   main()
<p>L'exécution du code ci-dessus crée un index dans Elasticsearch, stocke les embeddings dans l'index Elasticsearch nommé <code>convo_index</code>.</p><p>Si vous avez besoin d'explications sur la LlamaIndex IngestionPipeline, veuillez vous référer à l'article précédent dans la section <a href="https://www.elastic.co/search-labs/blog/rag-with-llamaIndex-and-elasticsearch#indexing-data">Create IngestionPipeline</a>.</p><h4>Interrogation</h4><p>Dans l'article précédent, nous avons utilisé un LLM local pour les <a href="https://www.elastic.co/search-labs/blog/rag-with-llamaIndex-and-elasticsearch#querying">requêtes</a>.</p><p>Dans ce billet, nous utilisons le LLM public, OpenAI, comme indiqué ci-dessous.</p># query.py
from llama_index.core import VectorStoreIndex, QueryBundle, Settings
from llama_index.llms.openai import OpenAI
from index import es_vector_store

# Public LLM where we send user query and Related Documents
llm = OpenAI()

index = VectorStoreIndex.from_vector_store(es_vector_store)

# This query_engine, for a given user query retrieves top 10 similar documents from
# Elasticsearch vector database and sends the documents along with the user query to the LLM.
# Note that documents are sent as-is. So any PII/Sensitive data is sent to the LLM.
query_engine = index.as_query_engine(llm, similarity_top_k=10)

query="Give me summary of water related claims that customers raised."
bundle = QueryBundle(query, embedding=Settings.embed_model.get_query_embedding(query))
result = query_engine.query(bundle)
print(result)
<p>Le code ci-dessus affiche la réponse d'OpenAI comme suit.</p><p>Les clients ont fait part de diverses réclamations liées à l'eau, notamment des dégâts des eaux dans les sous-sols, des éclatements de canalisations, des dommages causés aux toits par la grêle, et des refus de demandes d'indemnisation pour des raisons telles que l'absence de notification en temps utile, des problèmes d'entretien, l'usure progressive et les dommages préexistants. Dans chaque cas, les clients ont exprimé leur frustration face aux refus de demandes d'indemnisation et ont demandé des évaluations et des décisions équitables concernant leurs demandes d'indemnisation.</p><h2>Masquage des IIP dans le RAG</h2><p>Ce que nous avons couvert jusqu'à présent consiste à envoyer des documents tels quels à OpenAI avec la requête de l'utilisateur.</p><p>Dans le pipeline RAG, une fois que le contexte pertinent est extrait d'un magasin vectoriel, nous avons la possibilité de masquer les IIP et les informations sensibles avant d'envoyer la requête et le contexte au mécanisme d'apprentissage tout au long de la vie.</p><p>Il existe plusieurs façons de masquer les informations PII avant de les envoyer à un MLD externe, chacune d'entre elles ayant ses propres mérites. Nous examinons ci-dessous quelques-unes des options possibles</p><ol><li><p>Utilisation de bibliothèques NLP comme spacy.io ou <a href="https://microsoft.github.io/presidio/">Presidio</a> (bibliothèque open source gérée par Microsoft).</p></li><li><p>Utiliser LlamaIndex prêt à l'emploi <code>NERPIINodePostprocessor.</code></p></li><li><p>Utilisation de LLM locaux via <code>PIINodePostprocessor</code></p></li></ol><p>Une fois que vous avez implémenté la logique de masquage en utilisant l'une des méthodes ci-dessus, vous pouvez configurer la LlamaIndex IngestionPipeline avec un PostProcessor (votre propre PostProcessor personnalisé ou l'un des PostProcessors prêts à l'emploi de LlamaIndex).</p><h3>Utilisation des bibliothèques NLP</h3><p>Dans le cadre du pipeline RAG, nous pouvons masquer les données sensibles à l'aide de bibliothèques NLP. Nous utiliserons le paquet spacy.io dans cette démonstration.</p><p>Créez un nouveau fichier <code>query_masking_nlp.py</code> et ajoutez le code ci-dessous.</p># query_masking_nlp.py

# pip install spacy
# python3 - m spacy download en_core_web_sm
import re
from typing import List, Optional

import spacy
from llama_index.core import VectorStoreIndex, QueryBundle, Settings
from llama_index.core.postprocessor.types import BaseNodePostprocessor
from llama_index.core.schema import NodeWithScore
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.llms.openai import OpenAI
from index import es_vector_store

# Load the spaCy model
nlp = spacy.load("en_core_web_sm")

# Compile regex patterns for performance
phone_pattern = re.compile(r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b')
email_pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')
date_pattern = re.compile(r'\b(\d{1,2}[-/]\d{1,2}[-/]\d{2,4}|\d{2,4}[-/]\d{1,2}[-/]\d{1,2})\b')
dob_pattern = re.compile(
r"(January|February|March|April|May|June|July|August|September|October|November|December)\s(\d{1,2})(st|nd|rd|th),\s(\d{4})")
address_pattern = re.compile(r'\d+\s+[\w\s]+\,\s+[A-Za-z]+\,\s+[A-Z]{2}\s+\d{5}(-\d{4})?')
zip_code_pattern =  re.compile(r'\b\d{5}(?:-\d{4})?\b')
policy_number_pattern = re.compile(r"[A-Z]{3}\d{4}\.$")  # 3 characters followed by 4 digits, in our case e.g XYZ9876

Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")

# match = re.match(policy_number_pattern, "XYZ9876")
# print(match)


def mask_pii(text):
   """
   Masks Personally Identifiable Information (PII) in the given
   text using pre-defined regex patterns and spaCy's named entity recognition.
   Args:
       text (str): The input text containing potential PII.
   Returns:
       str: The text with PII masked.
   """

   # Process the text with spaCy for NER
   doc = nlp(text)

   # Mask entities identified by spaCy NER (e.g First/Last Names etc)
   for ent in doc.ents:
       if ent.label_ in ["PERSON", "ORG", "GPE"]:
           text = text.replace(ent.text, '[MASKED]')

   # Apply regex patterns after NER to avoid overlapping issues
   text = phone_pattern.sub('[PHONE MASKED]', text)
   text = email_pattern.sub('[EMAIL MASKED]', text)
   text = date_pattern.sub('[DATE MASKED]', text)
   text = address_pattern.sub('[ADDRESS MASKED]', text)
   text = dob_pattern.sub('[DOB MASKED]', text)
   text = zip_code_pattern.sub('[ZIP MASKED]', text)
   text = policy_number_pattern.sub('[POLICY MASKED]', text)

   return text


class CustomPostProcessor(BaseNodePostprocessor):
   """
   Custom Postprocessor which masks Personally Identifiable Information (PII).
   PostProcessor is called on the Documents before they are sent to the LLM.
   """
   def _postprocess_nodes(
           self, nodes: List[NodeWithScore], query_bundle: Optional[QueryBundle]
   ) -&gt; List[NodeWithScore]:
       # Masks PII
       for n in nodes:
          n.node.set_content(mask_pii(n.text))
       return nodes

   
# Use Public LLM to send user query and Related Documents
llm = OpenAI()
index = VectorStoreIndex.from_vector_store(es_vector_store)

# This query_engine, for a given user query retrieves top 10 similar documents from
# Elasticsearch vector database and sends the documents along with the user query to the LLM.
# Note that documents are masked based on custom logic defined in CustomPostProcessor._postprocess_nodes.
query_engine = index.as_query_engine(llm, similarity_top_k=10, node_postprocessors=[CustomPostProcessor()])



query = "Give me summary of water related claims that customers raised."
bundle = QueryBundle(query, embedding=Settings.embed_model.get_query_embedding(query))
response = query_engine.query(bundle)
print(response)

<p>La réponse du LLM est présentée ci-dessous.</p>Les clients ont fait part de diverses réclamations liées à l'eau, notamment des dégâts d'eau dans les sous-sols, des éclatements de canalisations, des dommages causés aux toits par la grêle et des inondations en cas de fortes pluies. Ces demandes ont engendré des frustrations en raison de refus de demandes fondés sur des motifs tels que l'absence de notification en temps utile, les problèmes d'entretien, l'usure progressive et les dommages préexistants. Les clients ont fait part de leur déception, de leur stress et de leur charge financière à la suite de ces refus, et ont demandé des évaluations équitables et des examens approfondis de leurs demandes d'indemnisation. Certains clients ont également été confrontés à des retards dans le traitement des demandes d'indemnisation, ce qui a aggravé leur mécontentement à l'égard du service fourni par la compagnie d'assurance.<p>Dans le code ci-dessus, lors de la création du moteur de requête de l'index Llama, nous fournissons un CustomPostProcessor.</p><p>La logique invoquée par le QueryEngine est définie dans la méthode <code>_postprocess_nodes</code> de <code>CustomPostProcessor</code>. Nous utilisons la bibliothèque SpaCy.io pour détecter les entités nommées dans nos documents et nous utilisons ensuite des expressions régulières pour remplacer ces noms ainsi que les informations sensibles avant d'envoyer les documents au LLM.</p><p>À titre d'exemple, voici des parties de conversations originales et de la conversation masquée créée par le CustomPostProcessor.</p><p>Texte original :</p>Client : Bonjour, je m'appelle Matthew Lopez, je suis né le 12 octobre 1984 et j'habite au 456 Cedar St, Smalltown, NY 34567. Mon numéro de police est TUV8901. Agent : Bonjour, Matthew. Comment puis-je vous aider aujourd'hui ? Le client : Bonjour, je suis extrêmement déçu de la décision de votre société de refuser ma demande d'indemnisation.<p>Texte masqué par le CustomPostProcessor.</p>Client : Bonjour, je m'appelle [MASKED], [MASKED] est [DOB MASKED], et j'habite au 456 Cedar St, [MASKED], [MASKED] 34567. Mon numéro de police est [MASKED]. Agent : Bonjour, [MASQUÉ]. Comment puis-je vous aider aujourd'hui ? Le client : Bonjour, je suis extrêmement déçu de la décision de votre société de refuser ma demande d'indemnisation.<p>Remarque :</p><p><em>Identifier et masquer les IPI et les informations sensibles n'est pas une tâche aisée. Couvrir les différents formats et la sémantique des informations sensibles nécessite une bonne compréhension de votre domaine et de vos données. Bien que le code présenté ci-dessus puisse fonctionner pour certains cas d'utilisation, il se peut que vous deviez le modifier en fonction de vos besoins et de vos tests.</em></p><h3>Utiliser le LlamaIndex prêt à l'emploi <code>NERPIINodePostprocessor</code></h3><p>LlamaIndex a facilité la protection des informations PII dans un pipeline RAG en introduisant les éléments suivants <code>NERPIINodePostprocessor.</code></p>from llama_index.core import VectorStoreIndex, QueryBundle, Settings
from llama_index.core.postprocessor import NERPIINodePostprocessor
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.llms.openai import OpenAI
from index import es_vector_store

Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")

# Use Public LLM to send user query and Related Documents
llm = OpenAI()

ner_processor = NERPIINodePostprocessor()
index = VectorStoreIndex.from_vector_store(es_vector_store)

# This query_engine, for a given user query retrieves top 10 similar documents from
# Elasticsearch vector database and sends the documents along with the user query to the LLM.
# Note that documents masked using the NERPIINodePostprocessor so that PII/Sensitive data is not sent to the LLM.
query_engine = index.as_query_engine(llm, similarity_top_k=10, node_postprocessors=[ner_processor])

query = "Give me summary of fire related claims that customers raised."
bundle = QueryBundle(query, embedding=Settings.embed_model.get_query_embedding(query))
response = query_engine.query(bundle)
print(response)
<p>La réponse est la suivante</p>Des clients ont déposé des demandes d'indemnisation pour des dommages causés par des incendies à leurs propriétés. Dans un cas, une demande d'indemnisation pour des dommages causés par l'incendie d'un garage a été refusée parce que l'incendie criminel était exclu de la couverture. Un autre client a déposé une demande d'indemnisation pour des dommages causés par un incendie à sa maison, qui étaient couverts par sa police. En outre, un client a signalé un incendie dans sa cuisine et a reçu l'assurance que les dommages causés par l'incendie étaient couverts.<h3>Utilisation de LLM locaux via <code>PIINodePostprocessor</code></h3><p>Nous pourrions également utiliser un LLM fonctionnant localement ou dans votre réseau privé pour effectuer le travail de masquage avant d'envoyer les données à un LLM public.</p><p>Nous utiliserons Mistral fonctionnant sur Ollama sur votre machine locale pour effectuer le masquage.</p><h4>Exécuter Mistral localement</h4><p>Téléchargez et installez <a href="https://ollama.com/">Ollama</a>. Après avoir installé Ollama, lancez la commande suivante pour télécharger et exécuter <a href="https://ollama.com/library/mistral">mistral</a></p>ollama run mistral
<p>Le téléchargement et l'exécution locale du modèle pour la première fois peuvent prendre quelques minutes. Vérifiez si le mistral fonctionne en posant une question telle que la suivante : "Ecrivez un poème sur les nuages" et vérifiez si le poème vous plaît. Gardez ollama en marche car nous aurons besoin d'interagir avec le modèle mistral plus tard par le biais du code.</p><p>Créez un nouveau fichier appelé <code>query_masking_local_LLM.py</code> et ajoutez le code ci-dessous.</p># pip install llama-index-llms-ollama
from llama_index.core import VectorStoreIndex, QueryBundle, Settings
from llama_index.core.postprocessor import PIINodePostprocessor
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.llms.ollama import Ollama
from llama_index.llms.openai import OpenAI
from index import es_vector_store

Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5")

# Use Public LLM to send user query and Related Documents and Local LLM to mask
public_llm = OpenAI()
local_llm = Ollama(model="mistral")

pii_processor = PIINodePostprocessor(llm=local_llm)
index = VectorStoreIndex.from_vector_store(es_vector_store)

# This query_engine, for a given user query retrieves top 10 similar documents from
# Elasticsearch vector database and sends the documents along with the user query to the public LLM.
# Note that documents are masked using the local llm via PIINodePostprocessor
# so that PII/Sensitive data is not sent to the public LLM.
query_engine = index.as_query_engine(public_llm, similarity_top_k=10, node_postprocessors=[pii_processor])


query = "Give me summary of fire related claims that customers raised."
bundle = QueryBundle(query, embedding=Settings.embed_model.get_query_embedding(query))
result = query_engine.query(bundle)
print(result)
<p>La réponse ressemble à ce qui est indiqué ci-dessous</p>Des clients ont déposé des demandes d'indemnisation pour des dommages causés par des incendies à leurs propriétés. Dans un cas, une demande d'indemnisation pour des dommages causés par l'incendie d'un garage a été refusée parce que l'incendie criminel était exclu de la couverture. Un autre client a déposé une demande d'indemnisation pour des dommages causés par un incendie à sa maison, qui étaient couverts par sa police. En outre, un client a signalé un incendie dans sa cuisine et a reçu l'assurance que les dommages causés par l'incendie étaient couverts.<h3>Conclusion</h3><p>Dans cet article, nous avons montré comment protéger les informations confidentielles et les données sensibles lors de l'utilisation de LLM publics dans un flux RAG. Nous avons démontré qu'il y avait plusieurs façons d'y parvenir. Il est fortement recommandé de tester ces approches en fonction de votre cas d'utilisation et de vos besoins avant de les adopter.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/rag-security-masking-pii</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/rag-security-masking-pii</guid>
    <category><![CDATA[IA]]></category>
    <dc:creator><![CDATA[Srikanth Manvi]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9d3882da43bfdac0/6a17050867045bd5fe45c0e9/9d51295472f8bcca3d1973248acb724f8b94767e-1054x555.png" length="0" type="image/png"/>
    <pubDate>Thu, 25 Jul 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[RAG (Retrieval Augmented Generation) avec LlamaIndex, Elasticsearch et Mistral]]></title>
    <description><![CDATA[Apprenez à mettre en œuvre un système RAG (Retrieval Augmented Generation) en utilisant LlamaIndex, Elasticsearch et Mistral en local.]]></description>
    <content:encoded><![CDATA[<p>Dans ce blog, nous verrons comment mettre en œuvre l'expérience Q&amp;A en utilisant une technique RAG (Retrieval Augmented Generation) avec Elasticsearch comme base de données vectorielle. Nous utiliserons LlamaIndex et un LLM Mistral fonctionnant localement.</p><p>Avant de commencer, nous allons examiner quelques termes.</p><h3>Terminologie</h3><p><a href="https://www.llamaindex.ai/">LlamaIndex</a> est un cadre de données de premier plan pour la création d'applications LLM (Large Language Model). LlamaIndex fournit des abstractions pour les différentes étapes de la construction d'une application RAG (Retrieval Augmented Generation). Des structures telles que LlamaIndex et LangChain fournissent des abstractions afin que les applications ne soient pas étroitement liées aux API d'un LLM spécifique.</p><p><a href="https://www.elastic.co/enterprise-search">Elasticsearch</a> est proposé par <a href="https://elastic.co/">Elastic</a>. Elastic est un leader de l'industrie avec Elasticsearch, un moteur de recherche et d'analyse qui prend en charge la recherche en texte intégral pour la précision, la recherche vectorielle pour la compréhension sémantique, et la recherche hybride pour le meilleur des deux mondes. Elasticsearch est un magasin de données évolutif et une base de données vectorielle. Les fonctionnalités d'Elasticsearch que nous utilisons dans ce blog sont disponibles dans la version gratuite et ouverte d'Elasticsearch.</p><p><a href="https://www.promptingguide.ai/techniques/rag">Retrieval Augment Generation (RAG)</a> est une technique/un modèle d'IA dans lequel les LLM sont dotés de connaissances externes pour générer des réponses aux requêtes des utilisateurs. Cela permet d'adapter les réponses du programme d'éducation et de formation tout au long de la vie à un contexte spécifique et les réponses sont plus spécifiques.</p><p><a href="https://docs.mistral.ai/">Mistral</a> propose des modèles LLM open-source et optimisés pour les entreprises. Dans ce tutoriel, nous utiliserons leur modèle open source <a href="https://docs.mistral.ai/models/#mistral-7b">mistral-7b</a> qui fonctionne sur votre ordinateur portable. Si vous ne souhaitez pas exécuter le modèle sur votre ordinateur portable, vous pouvez utiliser la version en nuage, auquel cas vous devrez modifier le code de ce blog afin d'utiliser les clés et les paquets API appropriés.</p><p><a href="https://ollama.com/">Ollama</a> permet d'exécuter des LLM localement sur votre ordinateur portable. Nous utiliserons Ollama pour exécuter localement le modèle open source Mistral-7b.</p><p>Les <a href="https://www.elastic.co/guide/en/elasticsearch/reference/8.13/semantic-search.html">encastrements</a> sont des représentations numériques de la signification d'un texte ou d'un média. Il s'agit de représentations de dimensions inférieures d'informations de dimensions supérieures.</p><h3>Construire une application RAG avec LlamaIndex, Elasticsearch &amp; Mistral : Aperçu du scénario</h3><p><strong>Scénario :</strong></p><p>Nous disposons d'un échantillon de données (sous forme de fichier JSON) de conversations entre des agents et des clients d'une compagnie d'assurance habitation fictive. Nous allons créer une application RAG simple qui peut répondre à des questions telles que</p><p><code>Give me summary of water related issues.</code></p><h3>Débit élevé</h3><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9d3882da43bfdac0/6a17050867045bd5fe45c0e9/9d51295472f8bcca3d1973248acb724f8b94767e-1054x555.png" alt="Flux RAG" /><p>Mistral LLM fonctionne localement à l'aide d'Ollama.</p><p>Ensuite, nous chargeons les <em>conversations</em> du fichier JSON en tant que <code>Documents</code> dans le <a href="https://developers.llamaindex.ai/python/examples/vector_stores/elasticsearchindexdemo/">magasin ElasticsearchStore</a> (qui est un magasin VectorStore soutenu par Elasticsearch). Lors du chargement des documents, nous créons des enchâssements à l'aide du modèle Mistral exécuté localement. Nous stockons ces encastrements ainsi que les <em>conversations</em> dans le magasin vectoriel Elasticsearch de LlamaIndex<a href="https://developers.llamaindex.ai/python/examples/vector_stores/elasticsearchindexdemo/">(ElasticsearchStore)</a>.</p><p>Nous configurons une ligne d'ingestion LlamaIndex et lui fournissons le LLM local que nous utilisons, dans ce cas Mistral fonctionnant via Ollama.</p><p>Lorsque nous posons une question telle que "Donnez-moi un résumé des problèmes liés à l'eau", Elasticsearch effectue une recherche sémantique et renvoie les <em>conversations</em> liées aux problèmes de l'eau. Ces <em>conversations</em>, ainsi que la question initiale, sont envoyées au LLM local pour générer une réponse.</p><h3>Étapes de la création de l'application RAG</h3><h4>Exécuter Mistral localement</h4><p>Téléchargez et installez <a href="https://ollama.com/">Ollama</a>. Après avoir installé Ollama, lancez la commande suivante pour télécharger et exécuter <a href="https://ollama.com/library/mistral">mistral</a></p>ollama run mistral
<p>Le téléchargement et l'exécution locale du modèle pour la première fois peuvent prendre quelques minutes. Vérifiez si le mistral fonctionne en posant une question telle que la suivante : "Ecrivez un poème sur les nuages" et vérifiez si le poème vous plaît. Gardez ollama en marche car nous aurons besoin d'interagir avec le modèle mistral plus tard par le biais du code.</p><h4>Installer Elasticsearch</h4><p>Faites fonctionner Elasticsearch en créant un déploiement dans le nuage<a href="https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud">(instructions ici</a>) ou en l'exécutant dans Docker<a href="https://www.elastic.co/search-labs/tutorials/install-elasticsearch/docker">(instructions ici).</a> Vous pouvez également créer un déploiement autonome d'Elasticsearch au niveau de la production en commençant <a href="https://www.elastic.co/search-labs/tutorials/install-elasticsearch/docker#self-hosted-production-deployments">ici.</a></p><p>Si vous utilisez le déploiement dans le nuage, saisissez la clé API et l'ID du nuage pour le déploiement, comme indiqué dans les instructions. Nous les utiliserons plus tard.</p><h4>Application RAG</h4><p>Pour référence, le code complet peut être trouvé dans ce <a href="https://github.com/srikanthmanvi/RAG-InsuranceCompany">dépôt Github</a>. Le clonage de la base de données est facultatif car nous allons parcourir le code ci-dessous.</p><p>Dans votre IDE préféré, créez une nouvelle application Python avec les 3 fichiers ci-dessous.</p><ul><li><p><code>index.py</code> où se trouve le code lié à l'indexation des données.</p></li><li><p><code>query.py</code> où se trouve le code lié à l'interrogation et à l'interaction avec le LLM.</p></li><li><p><code>.env</code> où se trouvent les propriétés de configuration telles que les clés d'API.</p></li></ul><p>Nous devons installer quelques paquets. Nous commençons par créer un nouvel <a href="https://docs.python.org/3/library/venv.html">environnement virtuel</a> python dans le dossier racine de votre application.</p>python3 -m venv .venv
<p>Activez l'environnement virtuel et installez les paquets requis ci-dessous.</p>source .venv/bin/activate
pip install llama-index 
pip install llama-index-embeddings-ollama
pip install llama-index-llms-ollama
pip install llama-index-vector-stores-elasticsearch
pip install sentence-transformers
pip install python-dotenv
<h4>Indexation des données</h4><p>Téléchargez le fichier <a href="https://github.com/srikanthmanvi/RAG-InsuranceCompany/blob/main/conversations.json">conversations.json</a> qui contient les <em>conversations</em> entre les clients et les agents du centre d'appel de notre compagnie d'assurance habitation fictive. Placez le fichier dans le répertoire racine de l'application avec les 2 fichiers python et le fichier .env. que vous avez créé précédemment. Vous trouverez ci-dessous un exemple du contenu du fichier.</p>{
    "conversation_id": 103,
    "customer_name": "Sophia Jones",
    "agent_name": "Emily Wilson",
    "policy_number": "JKL0123",
    "conversation": "Customer: Hi, I'm Sophia Jones. My Date of Birth is November 15th, 1985, Address is 303 Cedar St, Miami, FL 33101, and my Policy Number is JKL0123.\nAgent: Hello, Sophia. How may I assist you today?\nCustomer: Hello, Emily. I have a question about my policy.\nCustomer: There's been a break-in at my home, and some valuable items are missing. Are they covered?\nAgent: Let me check your policy for coverage related to theft.\nAgent: Yes, theft of personal belongings is covered under your policy.\nCustomer: That's a relief. I'll need to file a claim for the stolen items.\nAgent: We'll assist you with the claim process, Sophia. Is there anything else I can help you with?\nCustomer: No, that's all for now. Thank you for your assistance, Emily.\nAgent: You're welcome, Sophia. Please feel free to reach out if you have any further questions or concerns.\nCustomer: I will. Have a great day!\nAgent: You too, Sophia. Take care.",
    "summary": "A customer inquires about coverage for stolen items after a break-in at home, and the agent confirms that theft of personal belongings is covered under the policy. The agent offers assistance with the claim process, resulting in the customer expressing relief and gratitude."
}
<p>Nous définissons une fonction appelée <code>get_documents_from_file</code> dans <code>index.py</code> qui lit le fichier json et crée une liste de documents. Les objets <a href="https://docs.llamaindex.ai/en/stable/module_guides/loading/documents_and_nodes/">document</a> sont l'unité de base de l'information avec laquelle LlamaIndex travaille.</p># index.py
import json, os
from llama_index.core import Document, Settings
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.ingestion import IngestionPipeline
from llama_index.embeddings.ollama import OllamaEmbedding
from llama_index.vector_stores.elasticsearch import ElasticsearchStore
from dotenv import load_dotenv

def get_documents_from_file(file):
   """Reads a json file and returns list of Documents"""

   with open(file=file, mode='rt') as f:
       conversations_dict = json.loads(f.read())
      
   # Build Document objects using fields of interest.
   documents = [Document(text=item['conversation'],
                         metadata={"conversation_id": item['conversation_id']})
                for
                item in conversations_dict]
   return documents
<p>Créer un pipeline d'ingestion</p><p>Tout d'abord, ajoutez au fichier <code>.env</code> l'Elasticsearch CloudID et les clés API que vous avez obtenues dans la section <code>Install Elasticsearch</code>. Votre fichier <code>.env</code> devrait ressembler à ce qui suit (avec des valeurs réelles).</p>ELASTIC_CLOUD_ID=&lt;REPLACE WITH YOUR CLOUD ID&gt;
ELASTIC_API_KEY=&lt;REPLACE WITH YOUR API_KEY&gt;
<p>LlamaIndex <a href="https://docs.llamaindex.ai/en/stable/module_guides/loading/ingestion_pipeline/">IngestionPipeline</a> vous permet de composer un pipeline à l'aide de plusieurs composants. Ajoutez le code ci-dessous au fichier <code>index.py</code>.</p># index.py

# Load .env file contents into env
# ELASTIC_CLOUD_ID and ELASTIC_API_KEY are expected to be in the .env file.
load_dotenv('.env')

# ElasticsearchStore is a VectorStore that
# takes care of ES Index and Data management.
es_vector_store = ElasticsearchStore(index_name="calls",
                                     vector_field='conversation_vector',
                                     text_field='conversation',
                                     es_cloud_id=os.getenv("ELASTIC_CLOUD_ID"),
                                     es_api_key=os.getenv("ELASTIC_API_KEY"))


def main():
    # Embedding Model to do local embedding using Ollama.
    ollama_embedding = OllamaEmbedding("mistral")

    # LlamaIndex Pipeline configured to take care of chunking, embedding
    # and storing the embeddings in the vector store.
    pipeline = IngestionPipeline(
        transformations=[
            SentenceSplitter(chunk_size=350, chunk_overlap=50),
            ollama_embedding,
        ],
        vector_store=es_vector_store
    )

    # Load data from a json file into a list of LlamaIndex Documents
    documents = get_documents_from_file(file="conversations.json")

    pipeline.run(documents=documents)
    print(".....Done running pipeline.....\n")


if __name__ == "__main__":
    main()

<p>Comme nous l'avons déjà mentionné, la LlamaIndex IngestPipeline peut être composée de plusieurs éléments. Nous ajoutons 3 composants au pipeline dans la ligne <code>pipeline = IngestionPipeline(...</code>.</p><ul><li><p><a href="https://docs.llamaindex.ai/en/stable/module_guides/loading/node_parsers/modules/?h=sentencesp#sentencesplitter">SentenceSplitter</a>: Comme on peut le voir dans la définition de <code>get_documents_from_file()</code>, chaque document possède un champ texte qui contient la conversation trouvée dans le fichier json. Ce champ de texte est un long texte. Pour que la recherche sémantique fonctionne bien, elle doit être décomposée en morceaux de textes plus petits. La classe <a href="https://docs.llamaindex.ai/en/stable/module_guides/loading/node_parsers/modules/?h=sentencesp#sentencesplitter">SentenceSplitter</a> s'en charge pour nous. Ces morceaux sont appelés nœuds dans la terminologie de LlamaIndex. Les nœuds contiennent des métadonnées qui renvoient au document auquel ils appartiennent. Vous pouvez également utiliser Elasticsearch Ingestpipeline pour le découpage, comme indiqué dans ce <a href="https://www.elastic.co/search-labs/blog/chunking-via-ingest-pipelines">blog.</a></p></li><li><p><a href="https://docs.llamaindex.ai/en/stable/module_guides/models/embeddings/">OllamaEmbedding</a>: Les modèles d'incorporation convertissent un texte en nombres (également appelés vecteurs). La représentation numérique nous permet d'effectuer une <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html">recherche sémantique</a> où les résultats de la recherche correspondent à la signification du mot plutôt que d'effectuer une simple recherche textuelle. Nous fournissons à l'IngestionPipeline le site <code>OllamaEmbedding("mistral")</code>. Les morceaux que nous découpons à l'aide de SentenceSplitter sont envoyés au modèle Mistral qui s'exécute sur votre machine locale via Ollama, mistral crée alors des embeddings pour les morceaux.</p></li><li><p><a href="https://developers.llamaindex.ai/python/examples/vector_stores/elasticsearchindexdemo/">ElasticsearchStore</a>: Le magasin vectoriel ElasticsearchStore de LlamaIndex sauvegarde les embeddings créés dans un index Elasticsearch. ElasticsearchStore se charge de créer et d'alimenter le contenu de l'index Elasticsearch spécifié. Lors de la création de l'ElasticsearchStore (référencé par <code>es_vector_store</code>), nous fournissons le nom de l'index Elasticsearch que nous voulons créer (<code>calls</code> dans notre cas), le champ de l'index dans lequel nous voulons stocker les embeddings (<code>conversation_vector</code> dans notre cas) et le champ dans lequel nous voulons stocker le texte (<code>conversation</code> dans notre cas). En résumé, selon notre configuration, <code>ElasticsearchStore</code> crée un nouvel index dans Elasticsearch avec <code>conversation_vector</code> et <code>conversation</code> comme champs (parmi d'autres champs créés automatiquement).</p></li></ul><p>Pour relier le tout, nous exécutons le pipeline en appelant <code>pipeline.run(documents=documents)</code>.</p><p>Lancez le script index.py pour exécuter le pipeline d'ingestion :</p>python index.py
<p>Une fois l'exécution du pipeline terminée, nous devrions voir un nouvel index dans Elasticsearch appelé <code>calls</code>. En exécutant une simple requête elasticsearch à l'aide de la Dev Console, vous devriez être en mesure de voir les données chargées avec les embeddings.</p>GET calls/_search?size=1
<p>Pour résumer ce que nous avons fait jusqu'à présent, nous avons créé des documents à partir d'un fichier JSON, nous les avons divisés en morceaux, nous avons créé des embeddings pour ces morceaux et nous avons stocké les embeddings (et la conversation textuelle) dans un magasin vectoriel (ElasticsearchStore).</p><h4>Interrogation</h4><p>Le <a href="https://docs.llamaindex.ai/en/stable/module_guides/indexing/vector_store_guide/">VectorStoreIndex</a> llamaIndex vous permet de retrouver des documents pertinents et d'interroger des données. Par défaut, VectorStoreIndex stocke les intégrations en mémoire dans un <a href="https://docs.llamaindex.ai/en/stable/module_guides/indexing/vector_store_guide/">SimpleVectorStore</a>. Cependant, des entrepôts de vecteurs externes (comme <a href="https://developers.llamaindex.ai/python/examples/vector_stores/elasticsearchindexdemo/">ElasticsearchStore</a>) peuvent être utilisés à la place pour rendre les enregistrements persistants.</p><p>Ouvrez le site <code>query.py</code> et collez le code ci-dessous</p># query.py
from llama_index.core import VectorStoreIndex, QueryBundle, Response, Settings
from llama_index.embeddings.ollama import OllamaEmbedding
from llama_index.llms.ollama import Ollama
from index import es_vector_store

# Local LLM to send user query to
local_llm = Ollama(model="mistral")
Settings.embed_model= OllamaEmbedding("mistral")

index = VectorStoreIndex.from_vector_store(es_vector_store)
query_engine = index.as_query_engine(local_llm, similarity_top_k=10)

query="Give me summary of water related issues"
bundle = QueryBundle(query, embedding=Settings.embed_model.get_query_embedding(query))
result = query_engine.query(bundle)
print(result)
<p>Nous définissons un LLM local (<code>local_llm</code>) pour indiquer le modèle Mistral fonctionnant sur Ollama. Ensuite, nous créons un VectorStoreIndex (<code>index</code>) à partir du magasin de vecteurs ElasticssearchStore que nous avons créé précédemment, puis nous obtenons un moteur de requête à partir de l'index. Lors de la création du moteur de requête, nous référençons le LLM local qui doit être utilisé pour répondre, nous fournissons également (<code>similarity_top_k=10</code>) pour configurer le nombre de documents qui doivent être récupérés dans le magasin vectoriel et envoyés au LLM pour obtenir une réponse.</p><p>Lancez le script <code>query.py</code> pour exécuter le flux RAG :</p>python query.py
<p>Nous envoyons la demande à <code>Give me summary of water related issues</code> (n'hésitez pas à personnaliser <code>query</code>) et la réponse du LLM, qui est accompagnée des documents correspondants, devrait ressembler à ce qui suit.</p>Dans le contexte fourni, nous voyons plusieurs cas où les clients se sont renseignés sur la couverture des dommages liés à l'eau. Dans deux cas, les inondations ont causé des dommages aux sous-sols et les fuites de toiture ont été à l'origine d'un autre cas. Les agents ont confirmé que les deux types de dégâts des eaux sont couverts par leurs polices respectives. Par conséquent, les problèmes liés à l'eau, tels que les inondations et les fuites de toit, sont généralement couverts par les polices d'assurance habitation.<h4>Quelques mises en garde :</h4><p>Cet article de blog est une introduction pour débutants à la technique RAG avec Elasticsearch et omet donc la configuration des fonctionnalités qui vous permettront de passer de ce point de départ à la production. Lorsque vous construisez pour des cas d'utilisation en production, vous voudrez prendre en compte des aspects plus sophistiqués comme la possibilité de protéger vos données avec <a href="https://www.elastic.co/search-labs/blog/dls-internal-knowledge-search">Document Level Security</a>, le découpage de vos données dans le cadre d'un <a href="https://www.elastic.co/search-labs/blog/chunking-via-ingest-pipelines">pipeline d'ingestion</a> Elasticsearch ou même l'exécution d'autres <a href="https://www.elastic.co/guide/en/machine-learning/current/ml-nlp-overview.html">tâches de ML</a> sur les mêmes données que celles utilisées pour les cas d'utilisation GenAI/Chat/Q&amp;A.</p><p>Vous pouvez également envisager d'obtenir des données et de créer des embeddings à partir de diverses sources externes (par exemple Azure Blob Storage, Dropbox, Gmail, etc.) à l'aide d'<a href="https://www.elastic.co/guide/en/enterprise-search/current/connectors.html">Elastic Connectors.</a></p><p>Elastic rend possible tout ce qui précède et plus encore, et fournit une solution d'entreprise complète pour les cas d'utilisation de la GenAI et au-delà.</p><h4>Quelle est la suite ?</h4><ul><li><p>Vous avez peut-être remarqué que nous envoyons 10 conversations connexes avec la question de l'utilisateur au LLM pour formuler une réponse. Ces conversations peuvent contenir des IPI (informations personnelles identifiables) telles que le nom, la date de naissance, l'adresse, etc. Dans notre cas, le LLM est local, la fuite de données n'est donc pas un problème. Cependant, lorsque vous souhaitez utiliser un LLM fonctionnant dans le nuage (par exemple OpenAI), il n'est pas souhaitable d'envoyer des textes contenant des informations PII. Dans un blog ultérieur, nous verrons comment masquer les informations PII avant de les envoyer aux LLM externes dans le flux RAG.</p></li><li><p>Dans ce billet, nous avons utilisé un LLM local. Dans le prochain billet sur le masquage des données PII dans RAG, nous verrons comment passer facilement d'un LLM local à un LLM public.</p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/rag-with-llamaIndex-and-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/rag-with-llamaIndex-and-elasticsearch</guid>
    <category><![CDATA[IA]]></category>
    <dc:creator><![CDATA[Srikanth Manvi]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9d3882da43bfdac0/6a17050867045bd5fe45c0e9/9d51295472f8bcca3d1973248acb724f8b94767e-1054x555.png" length="0" type="image/png"/>
    <pubDate>Fri, 12 Apr 2024 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>