A lightweight LLM-based privacy filter for masking sensitive entities in text.
Project description
🧩 llm-privacy-filter
A lightweight, modular, LLM-powered privacy filtering library for masking sensitive information in text.
🧠 Overview
llm-privacy-filter is a modular text anonymization toolkit built on top of the LangChain ecosystem.
It uses large language models (LLMs) to detect and mask sensitive entities (like names, emails, phone numbers, and IDs) from natural language text, based on configurable privacy sensitivity thresholds.
It’s ideal for:
- Pre-processing user data before training or inference.
- Privacy-preserving text analytics and LLM evaluation pipelines.
- Redacting personally identifiable information (PII) in compliance with GDPR/CCPA.
📦 Features
✅ Mask sensitive entities using LLM reasoning ✅ Adjustable sensitivity levels (0.0–1.0) for granular privacy control ✅ Simple unified API with multiple model providers (Ollama, OpenAI, Anthropic, Gemini, etc.) ✅ Pydantic-based structured outputs ✅ Zero external database or service dependency
🏗️ Installation
Basic installation
pip install llm-privacy-filter
With provider integrations
# For Ollama (default)
pip install llm-privacy-filter[ollama]
# For OpenAI models
pip install llm-privacy-filter[openai]
# For Anthropic models
pip install llm-privacy-filter[anthropic]
# For Google Gemini models
pip install llm-privacy-filter[gemini]
# Install all providers
pip install llm-privacy-filter[all]
Python ≥3.9 is required.
⚙️ Quick Start
from llm_privacy_filter import Masker
masker = Masker(
model="gpt-oss:120b-cloud", # or any supported model
model_provider="ollama" # ollama | openai | anthropic | google-genai
)
text = """
Dr. Jane A. Smith, a senior researcher at MIT, was born on March 12, 1985.
She can be reached at jane.smith@example.com or +1-202-555-0198.
She lives at 45 Cherry Street, Boston, MA, and holds a US passport number X1234567.
"""
masked_text, mapping = masker.mask_text(text, sensitivity=1.0)
print(masked_text)
print(mapping)
Example Output:
{
"masked_text": "[name.salutation] [name.first] [name.last], a senior researcher at [organization.education], was born on [date.date_of_birth]. She can be reached at [email_address] or [phonenumber.mobile]. She lives at [address], and holds a [passport_number].",
"text_to_entities": {
"Jane": ["name.first"],
"Smith": ["name.last"],
"MIT": ["organization.education"],
"March 12, 1985": ["date.date_of_birth"],
"jane.smith@example.com": ["email_address"],
"+1-202-555-0198": ["phonenumber.mobile"],
"45 Cherry Street, Boston, MA": ["address"],
"X1234567": ["passport_number"]
}
}
🧩 Architecture
Project Structure
data4i-llm_privacy_filter/
│
├── pyproject.toml # Build metadata and dependencies
├── requirements.txt # Full dependency list (for development)
├── LICENSE # MIT license
├── README.md # This documentation
│
└── llm_privacy_filter/
├── __init__.py # Public interface
├── __main__.py # CLI entrypoint
├── core.py # Main Masker class
├── pdet.py # Privacy Data Entity Taxonomy (PDET)
├── privacy_states.py # Pydantic models for outputs
├── prompt_template.py # Prompt template for structured LLM masking
├── providers.py # Dynamic LLM provider initialization
└── utils.py # Utility helpers for entity flattening & sorting
🔍 Core Components
1️⃣ Masker (in core.py)
Handles the full pipeline: entity sorting → prompt generation → LLM inference → structured output.
Usage:
masker = Masker(model="gpt-4o-mini", model_provider="openai")
masked_text, entity_map = masker.mask_text("My name is John Doe", sensitivity=0.8)
Methods:
| Method | Description |
|---|---|
mask_text(text, sensitivity) |
Masks sensitive text according to threshold |
generalize_text(text, sensitivity) |
Placeholder for semantic generalization (future use) |
2️⃣ PDET (in pdet.py)
Defines the Privacy Data Entity Taxonomy:
a sensitivity-based mapping (0.0–1.0) of entity categories such as name, email, passport_number, etc.
Example:
{
0.8: [
{"name": ["first", "last", "middle"]},
"email_address",
"phonenumber",
"ip_address"
]
}
3️⃣ MaskState (in privacy_states.py)
A structured Pydantic model for consistent LLM outputs.
from pydantic import BaseModel
class MaskState(BaseModel):
masked_text: str
text_to_entities: dict[str, list[str]]
4️⃣ MASKING_PROMPT_TEMPLATE (in prompt_template.py)
Prompt design guiding the LLM’s structured response format.
"You are a privacy filter that masks sensitive information..."
Ensures consistent JSON output with masked_text and text_to_entities keys.
5️⃣ get_llm() (in providers.py)
Dynamic loader for multiple LLM backends via LangChain.
Supported Providers:
| Provider | Package |
|---|---|
ollama |
langchain-ollama |
openai |
langchain-openai |
anthropic |
langchain-anthropic |
google-genai |
langchain-google-genai |
mistral |
langchain-mistralai |
Example:
from llm_privacy_filter.providers import get_llm
llm = get_llm("gpt-4o-mini", "openai")
6️⃣ utils.py
Helper functions:
flatten_entity_list()→ Handles nested dicts inPDETlist_to_str()→ Converts lists to readable comma-joined stringssort_entities()→ Filters and formats entity categories by sensitivity threshold
Example:
from llm_privacy_filter.utils import sort_entities
entities = sort_entities(PDET, sensitivity=0.8)
print(entities)
# -> name.first, name.last, email_address, ip_address
🧪 Running from Command Line
You can run the library directly as a CLI test:
python -m llm_privacy_filter
Output Example:
[name.salutation] [name.first] [name.last], a senior researcher at [organization.education]...
🧰 Development Setup
git clone https://github.com/Data4i/llm_privacy_filter.git
cd llm_privacy_filter
python -m venv venv
source venv/bin/activate
pip install -e .
Run example:
python -m llm_privacy_filter
🧪 Testing (Coming Soon)
Tests will be added under tests/ using pytest.
pytest -v
🌐 Supported LLM Providers
| Provider | Model Example | Notes |
|---|---|---|
| Ollama | gpt-oss:120b-cloud |
Local & private |
| OpenAI | gpt-4o-mini |
Cloud-based |
| Anthropic | claude-3.5-sonnet |
High-context reasoning |
gemini-1.5-pro |
Multimodal capabilities |
🪪 License
This project is licensed under the MIT License — free for personal and commercial use.
👤 Author
Okechukwu Obiahu 📧 paulobiahu@gmail.com 🌐 GitHub: Data4i
⭐ Support
If you find this project helpful:
- Give it a ⭐ on GitHub — Data4i/llm_privacy_filter
- Share your feedback or issues in the Issue Tracker
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file llm_privacy_filter-1.0.1.tar.gz.
File metadata
- Download URL: llm_privacy_filter-1.0.1.tar.gz
- Upload date:
- Size: 11.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
321355d346dce524b27fc17c29d75c1822eb9d2ee3ea9bf0160e4f8960fd468f
|
|
| MD5 |
60694ad72f26a251e27b80685cfb4dec
|
|
| BLAKE2b-256 |
3789dc169f48b33bea4f589906f0d762229934c50235dbd6583ee7a2cc3b0e67
|
File details
Details for the file llm_privacy_filter-1.0.1-py3-none-any.whl.
File metadata
- Download URL: llm_privacy_filter-1.0.1-py3-none-any.whl
- Upload date:
- Size: 10.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0edc18d41a21776822292ed09baa6fbc1ad1d3ce11289a5f5f1c5ec46209aab9
|
|
| MD5 |
7932ed20e782e8f99e7921ac09eaca5d
|
|
| BLAKE2b-256 |
8e282913b2409ba810ec2d51a9e2f4e46519bd1540551f41584f6be2dfd1f122
|