RAG Based on Sensitive Data Protection using Faker

Source notebook

Repo path: gemini/use-cases/retrieval-augmented-generation/RAG_Based_on_Sensitive_Data_Protection_using_Faker.ipynb · Open on GitHub · intermediate

Builds a RAG flow that anonymizes PII with Cloud DLP, Faker, Firestore, Chroma, and Gemini.

Summary

The notebook teaches how to protect sensitive data in a RAG workflow by replacing detected PII with Faker-generated values before embedding and retrieval. It loads public Vodafone webpage content, anonymizes it with Cloud DLP and Firestore-backed mappings, stores embeddings in Chroma, answers with Gemini through LangChain LCEL, then de-anonymizes the response.

Key code patterns

Initialize Vertex AI

PROJECT_ID = "[your-project-id]"
LOCATION = "us-central1"
 
import vertexai
vertexai.init(project=PROJECT_ID, location=LOCATION)

Sets the Google Cloud project and region used by Vertex AI models.

Inspect and anonymize PII

info_types = [
    {"name": "PERSON_NAME"},
    {"name": "PHONE_NUMBER"},
    {"name": "FIRST_NAME"},
    {"name": "LAST_NAME"},
]
inspect_config = InspectConfig(info_types=info_types, include_quote=True)
response = self.dlp.inspect_content(
    request=InspectContentRequest(parent=parent, inspect_config=inspect_config, item=item)
)

Uses Cloud DLP to detect selected sensitive data types before replacing them.

Store reversible mappings

doc_ref = self.db.collection("mappings").document(fake_data)
doc_ref.set({"original_data": finding.quote})
text_to_deidentify = text_to_deidentify.replace(finding.quote, fake_data)

Persists fake-to-original mappings in Firestore so generated answers can be de-anonymized.

Embed anonymized documents

gemini_embeddings = VertexAIEmbeddings(model_name="text-embedding-005")
vectorstore = Chroma.from_documents(
    documents=anonymized_docs,
    embedding=gemini_embeddings,
    persist_directory="./chroma_db4",
)

Embeds anonymized content and persists it in a local Chroma vector store.

Compose RAG chain

rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | llm_prompt
    | llm
    | StrOutputParser()
)

Chains retrieval, prompt formatting, Gemini generation, and output parsing with LCEL.

Anonymize query then deanonymize answer

anonymized_text = anonymizer.anonymize("Who is the CEO of Vodafone Group?")
response = rag_chain.invoke(anonymized_text)
anonymizer.deanonymize(response)

Applies the same privacy-preserving transformation to user questions and final answers.

Models & APIs used

  • Models: text-embedding-005, gemini-2.0-flash
  • APIs / services: Vertex AI, Cloud Data Loss Prevention, Sensitive Data Protection, Firestore
  • SDKs / libraries: google-cloud-aiplatform, google-cloud-firestore, google-cloud-dlp, Faker, langchain-core, langchain_google_vertexai, chromadb, vertexai

When to use this

Use this pattern when building RAG over data or prompts that may contain PII and need reversible anonymization.

Gotchas & caveats

  • The notebook requires enabling aiplatform.googleapis.com, firestore.googleapis.com, and dlp.googleapis.com.
  • A Firestore database must be created in Native mode before mappings can be stored.
  • Colab users must authenticate with google.colab.auth.authenticate_user().
  • The notebook installs packages and then restarts the Jupyter runtime.
  • The DLP parent resource uses locations/global while Vertex AI and Firestore are configured with LOCATION.
  • Chroma search_kwargs k is set to 1 because only one document is stored; otherwise Chroma may warn.
  • Replacement-based anonymization is made reversible by Firestore mappings, unlike the notebook’s note that crypto-based tokenization is normally reversible.

Best practices

  • Anonymize source documents before creating embeddings.
  • Anonymize the user query before retrieval against anonymized embeddings.
  • De-anonymize the generated response only after the RAG chain returns an answer.
  • Reuse existing mappings when the same original data is detected again.
  • Constrain the prompt to say it does not know when context is insufficient.
  • Use a lower retriever k when the vector store contains only one document.
  • The notebook recommends a more efficient data extractor service and a more accurate sensitive data detector such as Cloud DLP API for better results.