piighost

Anonymize PII before it reaches the LLM

piighost is a Python library for building PII anonymization pipelines. It swaps personal data for stable placeholders the model can reason about, then restores the real values for your tools and your users. Your agent code does not change.

Hi, this is Patrick Dupont from Acme Corp. My order #ACME-9123 should be delivered to 12 rue de la Paix, Paris. You can reach me by email at patrick.dupont@acme.com or by phone at +33 6 12 34 56 78.

The problem

You should not have to choose between good models and data privacy

Hosted clouds leak raw data

OpenAI, Anthropic, and Google ship the best models on the market. But every byte of context you send them, including raw user PII, leaves your jurisdiction the moment the request hits the wire. A single prompt becomes a data export.

Local models trade quality

Self-hosting keeps the data inside your network, but you give up part of the state of the art and you take on the GPU bill and the patching. The privacy gain comes with a permanent operational cost, and the model you can run is rarely the model you wish you were running.

Compliance does not wait

GDPR, HIPAA, and data-residency rules apply whether or not your stack was built with them in mind. Sending raw PII to a third party is a liability you cannot undo once a request has left, and it forces every later product decision through a legal review.

Bans throw away the upside

Some teams respond by banning hosted LLMs outright. That protects the data, but it also forfeits the productivity gains everyone else is capturing, and people route around the ban anyway by pasting work into personal accounts the company cannot see.

Why piighost

More than a PII detector

Finding sensitive data is the easy part. piighost gives you everything around it: detectors you compose, placeholders you can undo, consistency across a whole conversation, and a pipeline you run on your own terms.

Composable detectors

Combine regex, NER, and LLM detectors in a single pipeline and keep the ones you trust. Built-in chunking splits long documents, so even large files are fully covered.

Reversible, transparent tokens

Every value becomes a stable placeholder and is restored automatically. Your users and your tools always see the real data, while the model only ever sees the placeholder.

Consistent across a conversation

The same value keeps the same placeholder for a whole conversation, across every message, tool call, and agent. Nothing drifts, so the model never loses track of who is who.

Config-driven and self-hosted

Describe a whole pipeline in one config file and run it entirely on your own infrastructure. Nothing leaves your walls, and there is no extra service to trust.

How it works

A layer between your agent and the model

User message

Hi, this is Patrick Dupont. Could you forward this to Marie Lambert and Jean Moreau? My email is patrick.dupont@acme.com, and you can also cc marie.lambert@acme.com. The case ID is #ACME-9123.

piighost runs your detectors over the message and reports every PII span it finds: names, emails, identifiers, anything the model does not need to see. Overlapping detections from multiple detectors are arbitrated by confidence before anything is replaced.

The ecosystem

One privacy layer, many projects

Start with the library. Reach for the server, the chat demo, and the proofreader as you grow.

Quick start

Drop it into your agent framework

Add piighost to the framework you already use. Your agent code stays the same.

uv add 'piighost[langchain,gliner2]'
from langchain.agents import create_agent

from piighost.components.detector.ner import Gliner2Detector
from piighost.pipeline import ThreadAnonymizationPipeline
from piighost.integrations.langchain import PIIAnonymizationMiddleware

# Any detector works: regex, NER, or an LLM. Here a GLiNER2 NER model.
detector = Gliner2Detector("fastino/gliner2-multi-v1", labels=["PERSON", "LOCATION"])
pipeline = ThreadAnonymizationPipeline(detector)
middleware = PIIAnonymizationMiddleware(pipeline=pipeline)

agent = create_agent(
    model="openai:gpt-5.6-terra",
    tools=[lookup_city],
    middleware=[middleware],
)

# The model only sees "<<PERSON:1>>"; lookup_city still receives "Patrick".

Frequently asked questions

How do I anonymize PII before sending a prompt to a model in Python?
Install piighost, build a pipeline around a detector, and pass your text through it before the model sees it. The pipeline finds personal data and swaps it for placeholders like <<PERSON:1>>, then restores the real values in the reply. You choose the detector: regex, classic NER, GLiNER, or an LLM.
What is the difference between regex, NER and LLM detection?
They are peer detectors you pick between. Regex matches fixed patterns such as emails or card numbers and is fast and exact. NER (classic models or GLiNER) recognizes names, places and organizations from context. An LLM detector reads intent for tricky cases. piighost is detector-agnostic, so you can combine them.
How do I use piighost with LangChain, Pydantic AI or LlamaIndex?
piighost ships integrations for LangChain, Pydantic AI and LlamaIndex. You wrap your pipeline in the provided helper (middleware, hooks or a node anonymizer) so PII is replaced before the model runs and restored afterward. The model only ever reasons over placeholders like <<PERSON:1>>, never the real values.
Is piighost GDPR compliant, and how do stable placeholders work?
piighost performs reversible pseudonymization in the GDPR sense, which supports compliance but does not replace your own legal review. Stable placeholders mean the same entity always maps to the same token (Patrick becomes <<PERSON:1>> everywhere), so the model keeps context while the real value stays out of its reach.
Does my data stay local? What is actually sent to the model?
Only the anonymized text is sent to the model, with every detected value replaced by a placeholder such as <<PERSON:1>>. The mapping from tokens back to real values stays on your side and is never sent. After the model responds, piighost restores the original values locally so your users see the real data.

Ship AI features without shipping user data

Install piighost, wire your detector, and keep PII out of the model.