Aller au contenu

Garder les PII hors d'un pipeline RAG LlamaIndex

Vous voulez un RAG LlamaIndex où ni le fournisseur d'embeddings ni le LLM ne voient de PII. piighost fournit deux composants : PIINodeAnonymizer, un transform d'ingestion qui dé-identifie chaque node avant l'embedding, et PIIQueryEngine, un wrapper qui dé-identifie la requête et restaure la réponse. Les deux partagent un pipeline de thread, donc une valeur garde le même token à 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 l'emballe en objets LlamaIndex réutilisables.

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 thread

Le pipeline dé-identifie et restaure sur un thread corpus. Ici un ExactMatchDetector garde l'exemple déterministe. Remplacez-le par un détecteur à modèle pour du vrai texte.

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 tokens et que le fournisseur d'embeddings ne voie jamais de PII.

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 query engine

PIIQueryEngine dé-identifie la requête dans le même thread, donc le retrieval concorde avec le corpus dé-identifié, et restaure la réponse pour l'utilisateur.

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)

Le LLM a répondu sur <<PERSON:1>> et <<LOCATION:1>>. L'utilisateur voit Patrick et Paris restaurés. Le retrieval tourne sur l'espace dé-identifié, ce qui échange un peu de qualité contre le fait de garder les PII hors de l'appel d'embedding.

Voir aussi

  • Intégration LangChain : dé-identifier un agent LangChain avec le middleware.
  • Roadmap : ce qui est prévu par ailleurs.
  • Le script exécutable est dans examples/llama_index/rag.py.