openai-privacy-filter

OpenAI Privacy Filter — bidirectional token-classification model for PII detection and masking in text

22 stars

Best use case

openai-privacy-filter is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

OpenAI Privacy Filter — bidirectional token-classification model for PII detection and masking in text

Teams using openai-privacy-filter should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/openai-privacy-filter/SKILL.md --create-dirs "https://raw.githubusercontent.com/Aradotso/trending-skills/main/skills/openai-privacy-filter/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/openai-privacy-filter/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How openai-privacy-filter Compares

Feature / Agentopenai-privacy-filterStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

OpenAI Privacy Filter — bidirectional token-classification model for PII detection and masking in text

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# OpenAI Privacy Filter

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.

OpenAI Privacy Filter is a bidirectional token-classification model (1.5B params, 50M active) for detecting and masking PII spans in text. It runs in a single forward pass with constrained Viterbi decoding, supports a 128k-token context window, and is licensed Apache 2.0.

## Installation

```bash
pip install -e .
# or from a cloned repo:
git clone https://github.com/openai/privacy-filter
cd privacy-filter
pip install -e .
```

After install, the `opf` CLI is available. On first use it downloads the model checkpoint to `~/.opf/privacy_filter` unless `OPF_CHECKPOINT` is set.

```bash
export OPF_CHECKPOINT=/path/to/local/checkpoint_dir
```

## Detected PII Categories

| Label | Description |
|---|---|
| `account_number` | Bank/card/account numbers |
| `private_address` | Physical addresses |
| `private_email` | Email addresses |
| `private_person` | Personal names |
| `private_phone` | Phone numbers |
| `private_url` | Personal URLs |
| `private_date` | Dates of birth / personal dates |
| `secret` | Credentials, tokens, API keys |

## CLI Usage

### One-shot redaction

```bash
# Redact inline text
opf "Alice was born on 1990-01-02 and her email is alice@example.com."

# Force CPU inference
opf --device cpu "Alice was born on 1990-01-02."

# Use a specific checkpoint
opf --checkpoint /path/to/checkpoint_dir "Alice Johnson, SSN 123-45-6789"

# Redact an entire file
opf -f /path/to/document.txt

# Pipe input
cat document.txt | grep "sensitive" | opf

# Interactive mode (no input provided)
opf
```

### Evaluation

```bash
# Evaluate on a labeled JSONL dataset
opf eval examples/data/sample_eval_five_examples.jsonl

# See all eval options
opf eval --help
```

### Finetuning

```bash
# Finetune on your labeled dataset
opf train /path/to/train.jsonl --output-dir /path/to/finetuned_checkpoint

# See all training options
opf train --help
```

## Python API

```python
from opf import PrivacyFilter

# Load with default checkpoint (~/.opf/privacy_filter or OPF_CHECKPOINT)
pf = PrivacyFilter()

# Or specify a checkpoint explicitly
pf = PrivacyFilter(checkpoint="/path/to/checkpoint_dir")

# Redact a single string
result = pf.redact("Alice Johnson called from +1-800-555-0199.")
print(result.redacted_text)
# "██████████████ called from ██████████████."

# Access detected spans
for span in result.spans:
    print(span.label, span.text, span.start, span.end)
```

### Batch processing

```python
from opf import PrivacyFilter

pf = PrivacyFilter(device="cuda")  # or "cpu"

texts = [
    "Contact Bob Smith at bob@example.com",
    "Her SSN is 123-45-6789 and DOB is 1985-03-15",
    "API key: sk-abc123xyz789",
]

results = pf.redact_batch(texts)
for r in results:
    print(r.redacted_text)
    print(r.spans)
```

### Precision/Recall tuning via operating points

```python
from opf import PrivacyFilter

# High recall (broader masking, more false positives)
pf_recall = PrivacyFilter(operating_point="high_recall")

# High precision (stricter masking, fewer false positives)
pf_precision = PrivacyFilter(operating_point="high_precision")

# Default balanced
pf_default = PrivacyFilter()
```

## Data Format

### Input for eval and training (JSONL)

Each line is a JSON object:

```jsonl
{"text": "Alice was born on 1990-01-02.", "spans": [{"start": 0, "end": 5, "label": "private_person"}, {"start": 18, "end": 28, "label": "private_date"}]}
{"text": "Email bob@corp.com for details.", "spans": [{"start": 6, "end": 18, "label": "private_email"}]}
```

### JSON output schema

```json
{
  "redacted_text": "██████ was born on ██████████.",
  "spans": [
    {
      "label": "private_person",
      "text": "Alice",
      "start": 0,
      "end": 5,
      "score": 0.987
    },
    {
      "label": "private_date",
      "text": "1990-01-02",
      "start": 18,
      "end": 28,
      "score": 0.973
    }
  ]
}
```

See `OUTPUT_SCHEMAS.md` in the repo for full payload spec.

## Finetuning Workflow

```bash
# Prepare labeled JSONL (see data format above)
# Run finetuning
opf train train.jsonl \
  --output-dir ./my_finetuned_model \
  --eval-file eval.jsonl \
  --epochs 3 \
  --batch-size 8

# Use the finetuned model
opf --checkpoint ./my_finetuned_model "redact this text"
```

See `FINETUNING.md` and `examples/scripts/finetuning/` for runnable demo harnesses.

## Environment Variables

| Variable | Purpose |
|---|---|
| `OPF_CHECKPOINT` | Path to model checkpoint directory (overrides default `~/.opf/privacy_filter`) |

## Project Structure

```
opf/
├── __main__.py          # CLI entrypoint (redact, eval, train)
├── _api.py              # Python-facing API
├── _cli/                # Argument parsing, terminal rendering
├── _core/               # Runtime loading, span conversion, decoding
├── _eval/               # Dataset loading, metrics, eval runners
├── _train/              # Finetuning argument parsing and runners
├── _model/              # Transformer impl, checkpoint config, weight loading
examples/
├── data/                # Sample eval/finetune JSONL fixtures
├── scripts/finetuning/  # Runnable finetuning demo scripts
```

## Common Patterns

### Pipeline: sanitize files before uploading to an LLM

```python
from opf import PrivacyFilter
import json

pf = PrivacyFilter()

def sanitize_for_llm(raw_text: str) -> str:
    result = pf.redact(raw_text)
    return result.redacted_text

with open("raw_data.txt") as f:
    clean = sanitize_for_llm(f.read())

print(clean)
```

### Audit: log all detected PII spans without redacting

```python
from opf import PrivacyFilter

pf = PrivacyFilter()

def audit_pii(text: str) -> list[dict]:
    result = pf.redact(text)
    return [
        {"label": s.label, "text": s.text, "start": s.start, "end": s.end}
        for s in result.spans
    ]

findings = audit_pii("Bob Jones (DOB: 1978-06-15) owes $1,200.")
print(json.dumps(findings, indent=2))
```

### Filter specific label types only

```python
from opf import PrivacyFilter

pf = PrivacyFilter()

def redact_only(text: str, labels: list[str]) -> str:
    result = pf.redact(text)
    # Rebuild text redacting only chosen labels
    chars = list(text)
    for span in result.spans:
        if span.label in labels:
            for i in range(span.start, span.end):
                chars[i] = "█"
    return "".join(chars)

# Only redact emails and phones, keep names
output = redact_only(
    "Call Alice at 555-1234 or alice@example.com",
    labels=["private_phone", "private_email"]
)
print(output)
# "Call Alice at ████████ or █████████████████"
```

## Troubleshooting

**Model not found / auto-download fails**
- Set `OPF_CHECKPOINT` to a local checkpoint directory, or ensure internet access for the first run.
- Checkpoint is downloaded from https://huggingface.co/openai/privacy-filter.

**CUDA out of memory**
- Use `--device cpu` or reduce batch size with `--batch-size 1`.

**Low recall on domain-specific identifiers**
- Finetune on representative labeled examples using `opf train`.
- Try `operating_point="high_recall"` for broader masking.

**Fragmented span boundaries**
- Expected in heavy-punctuation or mixed-format text; the Viterbi decoder mitigates this but is not perfect.
- Finetuning on in-domain data is the recommended fix.

**Non-English / non-Latin text**
- The model is primarily English; multilingual performance is not guaranteed. Evaluate on your target language before production use.

## References

- [Model weights (HuggingFace)](https://huggingface.co/openai/privacy-filter)
- [Live demo](https://huggingface.co/spaces/openai/privacy-filter)
- [Model card (PDF)](https://cdn.openai.com/pdf/c66281ed-b638-456a-8ce1-97e9f5264a90/OpenAI-Privacy-Filter-Model-Card.pdf)
- `FINETUNING.md` — finetuning workflow
- `OUTPUT_SCHEMAS.md` — JSON response formats
- `EVAL_AND_OUTPUT_MODES.md` — output and eval mode details

Related Skills

privacy-parser-pii-extraction

22
from Aradotso/trending-skills

Extract structured PII spans from text using the OpenAI Privacy Filter 1.5B model reversed — returns what, where, and which type instead of masking.

openai-symphony-autonomous-agents

22
from Aradotso/trending-skills

Symphony turns project work into isolated, autonomous implementation runs, allowing teams to manage work instead of supervising coding agents.

gpt2api-openai-gateway

22
from Aradotso/trending-skills

OpenAI-compatible SaaS gateway that reverse-engineers chatgpt.com to provide GPT Image 2, multi-account pooling, batch image generation, and billing management.

freebuff2api-openai-proxy

22
from Aradotso/trending-skills

OpenAI-compatible proxy server for Freebuff that translates standard OpenAI API requests into Freebuff's backend format with multi-token rotation and Docker deployment.

bouncer-feed-filter

22
from Aradotso/trending-skills

AI-powered browser extension that filters unwanted posts from Twitter/X feeds using natural language rules and multiple AI backends

```markdown

22
from Aradotso/trending-skills

---

zeroboot-vm-sandbox

22
from Aradotso/trending-skills

Sub-millisecond VM sandboxes for AI agents using copy-on-write KVM forking via Zeroboot

yourvpndead-vpn-detection

22
from Aradotso/trending-skills

Android app that detects VPN/proxy servers (VLESS/xray/sing-box) via local SOCKS5 vulnerability, exposing exit IPs and server configs without root

xata-postgres-platform

22
from Aradotso/trending-skills

Expert skill for Xata open-source cloud-native Postgres platform with copy-on-write branching, scale-to-zero, and Kubernetes deployment

x-mentor-skill-nuwa

22
from Aradotso/trending-skills

AI-powered X (Twitter) content strategy skill that distills methodologies from 6 top creators + open-source algorithm data into actionable writing, growth, and monetization guidance.

wx-favorites-report

22
from Aradotso/trending-skills

End-to-end pipeline to extract, decrypt, and visualize WeChat Mac favorites from encrypted SQLite DB into an interactive HTML report.

wterm-web-terminal

22
from Aradotso/trending-skills

Web terminal emulator with Zig/WASM core, DOM rendering, and React/vanilla JS bindings