--- icon: lucide/link --- # Intégration LlamaIndex Vous voulez un RAG LlamaIndex où ni le fournisseur d'embeddings ni le LLM ne voient de données confidentielles. `piighost` fournit deux composants. `PIINodeAnonymizer` est une transformation d'ingestion qui dé-identifie chaque node avant l'embedding. `PIIQueryEngine` enveloppe le moteur de requête, dé-identifie la requête et restaure la réponse. Les deux partagent un pipeline de conversation, donc une valeur garde le même jeton à travers le corpus et la requête. Pour la même idée orchestrée à la main sur un flux RAG simple, voir le script `examples/langchain/rag.py`. Cette page emballe cette idée en objets LlamaIndex réutilisables. !!! note "Prérequis" `piighost` installé avec l'extra llama-index, `pip install "piighost[llama-index]"`, plus `llama-index-embeddings-openai` et `llama-index-llms-openai` et un `OPENAI_API_KEY`. ## 1. Construire le pipeline de conversation Le pipeline dé-identifie et restaure sur une conversation dédiée au corpus. Ici un `ExactMatchDetector` garde l'exemple déterministe. Remplacez-le par un détecteur à modèle pour du vrai texte. ```python from piighost.components.detector import ExactMatchDetector from piighost.pipeline import ThreadAnonymizationPipeline THREAD = "docs" detector = ExactMatchDetector({"Patrick": "PERSON", "Paris": "LOCATION"}) pipeline = ThreadAnonymizationPipeline(detector) ``` ## 2. Dé-identifier à l'ingestion, avant l'embedding Placez `PIINodeAnonymizer` dans les transformations avant le modèle d'embedding, pour que l'index soit bâti sur des jetons et que le fournisseur d'embeddings ne voie jamais de données confidentielles. ```python from llama_index.core import Document, Settings, VectorStoreIndex from llama_index.core.node_parser import SentenceSplitter from llama_index.embeddings.openai import OpenAIEmbedding from piighost.integrations.llama_index import PIINodeAnonymizer Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small") anonymizer = PIINodeAnonymizer(pipeline=pipeline, thread_id=THREAD) index = VectorStoreIndex.from_documents( [Document(text="Patrick lives in Paris.")], transformations=[SentenceSplitter(), anonymizer], ) ``` ## 3. Envelopper le moteur de requête `PIIQueryEngine` dé-identifie la requête dans la même conversation que le corpus, et restaure la réponse pour l'utilisateur. La recherche porte donc sur le corpus dé-identifié. ```python from llama_index.llms.openai import OpenAI from piighost.integrations.llama_index import PIIQueryEngine Settings.llm = OpenAI(model="gpt-5.6-terra") engine = PIIQueryEngine( inner=index.as_query_engine(), pipeline=pipeline, thread_id=THREAD, ) answer = engine.query("Where does Patrick live?") print(answer.response) ``` La réponse est restaurée pour l'affichage. Sa formulation dépend du modèle, par exemple : ```text Patrick lives in Paris. ``` Le LLM a répondu sur `<>`{ .placeholder } et `<>`{ .placeholder }. L'utilisateur voit `Patrick`{ .pii } et `Paris`{ .pii } restaurés. La recherche tourne sur le texte dé-identifié. Il y perd un peu de qualité, en échange de quoi les données confidentielles restent hors de l'appel d'embedding. ## Voir aussi - [Intégration LangChain](langchain.md) : dé-identifier un agent LangChain avec le middleware. - [Roadmap](../roadmap.md) : ce qui est prévu par ailleurs. - Le script exécutable est dans `examples/llama_index/rag.py`.