English | 日本語 | Español | Tiếng Việt | 中文 | 한국어 | Français | Deutsch | Português | Italiano
Nutzen Sie Frontier-LLMs, ohne ihnen Ihre PII zu zeigen. Reversible Anonymisierung direkt auf dem Gerät — tauschen Sie Intelligenz nicht gegen Privatsphäre ein.
Heute haben Sie zwei Optionen. Ein lokales Modell ausführen — privat, aber Sie verzichten auf Frontier-Intelligenz. Oder in ChatGPT / Claude / Gemini einfügen und sich selbst kontrollieren, Prompt für Prompt. Prompt Anonymizer liegt dazwischen:
| Intelligenz | Privatsphäre | Worauf Sie vertrauen müssen | |
|---|---|---|---|
| Lokales Modell | ✗ geopfert | ✓ | nichts |
| Frontier-Modell, ungefiltert | ✓ | ✗ | der Anbieter und Ihre eigene Wachsamkeit |
| Frontier-Modell + Prompt Anonymizer | ✓ | ✓ | Code, den Sie lesen können + eine letzte Durchsicht |
Es ersetzt PII durch konsistente Label (<人名_1>, <Name_1>,
<Nombre_1>, <Tên_1>, …), bevor der Text Ihren Rechner verlässt. Da
derselbe Wert immer dasselbe Label erhält, ergibt die Antwort des LLM
weiterhin Sinn. Kommt die Antwort zurück, stellt das Mapping — das Ihr Gerät
nie verlassen hat — die echten Werte wieder her.
Unterstützte Sprachen: Englisch (en), Japanisch (ja), Spanisch (es),
Vietnamesisch (vi) und — neu — Chinesisch (zh), Koreanisch (ko),
Französisch (fr), Deutsch (de), Portugiesisch (pt) und Italienisch
(it). Der Standardwert von PromptAnonymizer(languages=…) bleibt
("en", "ja"); jede weitere Sprache wird per languages=[...] aktiviert.
Alle Sprachauswahlen in den Oberflächen und die automatische Erkennung
decken alle zehn ab. Die Sprachunterstützung ist registry-gesteuert — eine
Sprache hinzuzufügen bedeutet einen Registry-Eintrag (languages.py /
languages.ts) plus eine Label-Datei.
Die Erkennung läuft auf dem Gerät (WebGPU / WASM im Browser, spaCy oder lokale Transformer in Python). Verlassen Sie sich nicht auf unser Wort: Öffnen Sie die DevTools, beobachten Sie den Netzwerk-Tab oder lesen Sie den Quellcode. Das Projekt ist MIT-lizenziert und klein genug, um es in einem Rutsch zu auditieren.
Inhaltsverzeichnis
Anonymisieren → das Mapping bleibt lokal → die LLM-Antwort behält die Label → wiederherstellen:
| Ziel | Wie | Hinweise |
|---|---|---|
| Browser (WebGPU) | akazah.github.io/prompt-anonymizer | 100 % auf dem Gerät: Das NER läuft per WebGPU in Ihrem Browser (WASM-Fallback). Ihr Text wird nie an einen Server gesendet — prüfen Sie es im Netzwerk-Tab. |
| Desktop-App | Download von Releases (.dmg / .msi / .exe / .AppImage / .deb / .rpm) |
Tauri 2. Vorerst unsigniert — Ihr Betriebssystem warnt beim ersten Start. |
| Chrome-Erweiterung | prompt-anonymizer-extension-*.zip von Releases |
Entpacken → chrome://extensions → Entwicklermodus aktivieren → „Entpackte Erweiterung laden“. Text markieren → Rechtsklick → Anonymize selection. |
| Python / CLI | pip install prompt-anonymizer |
Presidio + spaCy. Siehe Schnellstart unten. |
| Node-CLI (npx) | npx @prompt-anonymizer/cli |
Dieselben Befehle und Flags wie die Python-CLI; transformers.js-NER, vollständig auf dem Gerät. |
| Web Component | @prompt-anonymizer/element |
Framework-unabhängiges <prompt-anonymizer>-Element: Bettet das komplette Anonymisieren-→-Wiederherstellen-Panel in jede Website ein (reines HTML, Svelte, Angular, …). |
| React / Vue | @prompt-anonymizer/react / @prompt-anonymizer/vue |
Fertige <AnonymizerPanel />-Komponente plus ein useAnonymizer()-Hook / Composable für eigene UIs. Siehe Schnellstart unten. |
| Lokaler Proxy + Admin-GUI | npx @prompt-anonymizer/proxy |
OpenAI-kompatibler Reverse-Proxy: Richten Sie OPENAI_BASE_URL darauf, und PII werden maskiert, bevor sie Ihren Rechner verlassen; in den Antworten werden die Label wiederhergestellt (inkl. Streaming). Admin-GUI unter http://127.0.0.1:8787/admin/. Siehe Schnellstart unten. |
| MCP-Server | npx @prompt-anonymizer/mcp |
anonymize / deanonymize / scan-Tools für jeden MCP-Client (Claude Desktop, Claude Code, Cursor, …). Die Label-Zuordnung bleibt im Server-Speicher (mapping_id) und wird dem Modell nur auf explizite Anfrage gezeigt. Siehe Schnellstart unten. |
| Commit-Hook / CI-Gate | prompt-anonymizer scan (beide CLIs) + .pre-commit-hooks.yaml |
Exit-Code-basiertes PII-Gate für Commit- und CI-Prüfungen: meldet file:line:col und den Entitätstyp, nie den gefundenen Text. Standardmäßig offline und ohne Modelle. Siehe unten. |
pip install prompt-anonymizer
python -m spacy download ja_core_news_sm # en: en_core_web_sm; es: es_core_news_sm
python -m spacy download xx_ent_wiki_sm # vi: keine offizielle spaCy-Pipeline — WikiNER
# zh: zh_core_web_sm; ko: ko_core_news_sm; fr/de/pt/it: *_core_news_sm — oder
# alle sm-Modelle auf einmal installieren: uv sync --group models (lg: --group models-lg)from prompt_anonymizer import PromptAnonymizer
pa = PromptAnonymizer(languages=["ja"])
result = pa.anonymize("山田太郎の電話は090-1234-5678", language="ja")
result.text # '<人名_1>の電話は<電話番号_1>'
result.mapping # {'<人名_1>': '山田太郎', '<電話番号_1>': '090-1234-5678'}
pa_es = PromptAnonymizer(languages=["es"])
pa_es.anonymize(
"El cliente es Javier Moreno, teléfono 612 345 678", language="es"
).text # 'El cliente es <Nombre_1>, teléfono <Teléfono_1>'
# vi-Namen benötigen das Transformer-Backend (siehe „Optionales Transformer-NER-Backend“)
pa_vi = PromptAnonymizer(languages=["vi"], ner_backend="hf")
pa_vi.anonymize(
"Tôi tên là Nguyễn Văn An, số điện thoại 0912 345 678", language="vi"
).text # 'Tôi tên là <Tên_1>, số điện thoại <SốĐiệnThoại_1>'
llm_output = call_your_llm(result.text) # die Label überstehen den Roundtrip
pa.deanonymize(llm_output, result.mapping) # echte Werte lokal wiederhergestelltCLI (-l ja|en|es|vi|zh|ko|fr|de|pt|it):
prompt-anonymizer anonymize -l ja --interactive --mapping-file mapping.json \
-t "山田太郎の電話は090-1234-5678"
prompt-anonymizer anonymize -l es -t "El cliente es Javier Moreno, teléfono 612 345 678"
prompt-anonymizer anonymize -l fr -t "Le client est Pierre Durand, téléphone 06 12 34 56 78"
prompt-anonymizer deanonymize --mapping-file mapping.json -t "<人名_1>様 ..."Die Node-CLI spiegelt die Python-CLI (dieselben Befehle, Flags und JSON-Ausgabe) und führt den TypeScript-Kern mit transformers.js-NER auf dem Gerät aus:
npx @prompt-anonymizer/cli anonymize -t "山田太郎の電話は090-1234-5678"Um das fertige Anonymisieren-→-Wiederherstellen-Panel in ein beliebiges Frontend einzubetten, verwenden Sie das framework-unabhängige Web Component:
<script type="module">
import { definePromptAnonymizer } from "@prompt-anonymizer/element";
definePromptAnonymizer();
</script>
<prompt-anonymizer language="auto"></prompt-anonymizer>React (@prompt-anonymizer/react) und Vue 3 (@prompt-anonymizer/vue)
liefern ein typisiertes <AnonymizerPanel />, das dieses Element kapselt:
import { AnonymizerPanel } from "@prompt-anonymizer/react"; // oder "@prompt-anonymizer/vue"
<AnonymizerPanel language="auto" denyList={["ProjectX"]}
onAnonymize={(result) => console.log(result.text)} />Für eigene UIs stellen beide Pakete die Session Anonymisieren → LLM → Wiederherstellen auch als Hook / Composable bereit:
import { useAnonymizer } from "@prompt-anonymizer/react"; // oder "@prompt-anonymizer/vue"
const { anonymize, restore, mapping, busy, error } = useAnonymizer();
const result = await anonymize(input, { language: "ja" });
// result.text an das LLM senden — das Mapping verlässt das Gerät nie — dann:
const { text: restored, unresolved } = await restore(llmReply);Standardmäßig arbeitet die Erkennung nur mit regulären Ausdrücken (E-Mails,
Telefonnummern, …); übergeben Sie ein ner (z. B.
new TransformersNerBackend() aus @prompt-anonymizer/core), um auch Namen
und Orte zu maskieren.
Starten Sie den OpenAI-kompatiblen Proxy und richten Sie einen beliebigen Client darauf — PII werden maskiert, bevor die Anfrage Ihren Rechner verlässt, und die Label werden in der Antwort wiederhergestellt (Streaming inklusive). Mappings bleiben im Speicher des Proxys, pro Anfrage:
npx @prompt-anonymizer/proxy # lauscht auf http://127.0.0.1:8787
# In Ihrer App / Shell:
export OPENAI_BASE_URL=http://127.0.0.1:8787/v1Die Admin-GUI unter http://127.0.0.1:8787/admin/ zeigt den Live-Status und
die Redaktionsereignisse (nur Label und Zähler), bearbeitet die
Proxy-Konfiguration (Upstream, NER, Deny-/Allow-Listen) und bietet einen
rein lokalen Anonymisierungs-Spielplatz. Der Proxy bindet standardmäßig an
127.0.0.1; Originalwerte lassen sich in der GUI nur einsehen, wenn Sie
--record-mappings ausdrücklich aktivieren.
Stellen Sie jedem MCP-Client — Claude Desktop, Claude Code, Cursor, … — Anonymisierungswerkzeuge auf dem Gerät bereit:
# Claude Code:
claude mcp add prompt-anonymizer -- npx -y @prompt-anonymizer/mcpDrei Werkzeuge, alle so konzipiert, dass PII nicht in den Modellkontext gelangen:
anonymize liefert den maskierten Text und eine mapping_id (das Mapping bleibt
im Serverspeicher, sofern Sie es nicht ausdrücklich anfordern), deanonymize
stellt per mapping_id wieder her — optional direkt in eine Datei — und scan
prüft Dateien auf PII und meldet nur file:line:col und den Entitätstyp, nie den
gefundenen Text. Übergeben Sie --ner in den Server-Argumenten, um auch
Namen/Orte zu maskieren (einmaliger Modell-Download beim ersten Einsatz).
Beide CLIs enthalten einen scan-Unterbefehl für Git-Hooks und CI: Er
beendet sich mit 0, wenn die Eingaben sauber sind, mit 1, wenn PII
gefunden werden, und mit 2 bei Fehlern. Gemeldet werden nur
file:line:col und der Entitätstyp — der gefundene Text wird nie
ausgegeben, sodass Hook-Ausgabe und CI-Logs frei von PII bleiben.
Standardmäßig arbeitet er offline, deterministisch und ohne Modelle
(strukturierte PII: E-Mails, Telefonnummern, JP-Postleitzahlen, My Number,
Kreditkarten — plus --deny-Begriffe); --ner aktiviert die
Namens-/Ortserkennung, wo Modelle verfügbar sind.
prompt-anonymizer scan src/prompt.txt docs/*.md # Dateien (z. B. gestagte)
git diff --cached -U0 | prompt-anonymizer scan # oder einen Diff durchleiten
prompt-anonymizer scan --deny ProjectX --json -t "..."Mit dem pre-commit-Framework
(Hook-Definition: .pre-commit-hooks.yaml):
repos:
- repo: https://github.com/akazah/prompt-anonymizer
rev: v0.3.0
hooks:
- id: prompt-anonymizer-scan
# args: [--deny, ProjectX, --allow, support@example.com]Node-Projekte können dasselbe Gate über husky + lint-staged anbinden
(npx @prompt-anonymizer/cli scan):
{ "lint-staged": { "*": "prompt-anonymizer scan" } }Wie alles andere hier ist die Erkennung Best-Effort: Betrachten Sie scan
als Sicherheitsnetz gegen offensichtliche Leaks, nicht als Garantie.
Warum nicht einfach Presidio? Verwenden Sie Microsoft Presidio direkt, wenn Sie ein universelles Framework zur PII-Erkennung / -Anonymisierung brauchen. Prompt Anonymizer nutzt Presidio als Engine seines Python-Kerns und setzt den LLM-Roundtrip-Workflow obendrauf: konsistente Platzhalter, anonymisierter Prompt nach draußen, lokale Wiederherstellung nach der Antwort — plus Browser-, Erweiterungs- und Desktop-Oberflächen, die gar kein Python benötigen.
Warum nicht LLM Guard? LLM Guard ist eine solide Python-seitige Guardrail-Suite mit eigenem Anonymize/Deanonymize. Prompt Anonymizer unterscheidet sich in drei Punkten: japanisch-zentrierte Erkennung (japanische Namen, Adressen, My Number mit Prüfziffernvalidierung), Oberflächen für Nicht-Entwickler (Text in eine Browserseite einfügen — kein Python-Setup) und eine Codebasis, die klein genug ist, um sie wirklich zu lesen.
Warum keine „100 % lokale“ Chrome-Erweiterung? Mehrere Closed-Source-Erweiterungen behaupten lokale Verarbeitung. Behauptungen sind keine Audits. Dieses Projekt ist MIT-lizenziert: Öffnen Sie den Netzwerk-Tab oder lesen Sie den Quellcode. (Bösartige „KI-Privatsphäre“-Erweiterungen, die Konversationen exfiltrieren, sind dokumentiert — die Kategorie hat sich die Skepsis verdient.)
- Erkennung — Presidio + spaCy-NER (Python) oder transformers.js-NER + Regex-Erkenner (Browser/Desktop/Erweiterung), erweitert um registry-gesteuerte, regionsspezifische Telefonmuster (JP, US/NANP, ES, VN, CN, KR, FR, DE, PT, IT) und japan-spezifische Erkenner (〒-Postleitzahlen, My Number mit Prüfziffernvalidierung). E-Mails und Kreditkarten sind sprachunabhängig; JP_POSTAL_CODE und JP_MY_NUMBER werden in jedem Sprachmodus erkannt.
- Konsistente Beschriftung — Spans werden zusammengeführt (Score zuerst) und offsetbasiert vom Ende her ersetzt; identische Werte teilen sich ein Label.
- Umkehrung —
deanonymize(text, mapping)stellt die Originale wieder her, längstes Label zuerst. Das Mapping wird an Sie zurückgegeben und von der Bibliothek nie persistiert; es sicher aufzubewahren liegt in Ihrer Verantwortung.
| Entität | ja-Label | en-Label | es-Label | vi-Label | Engine |
|---|---|---|---|---|---|
| PERSON | 人名 | Name | Nombre | Tên | NER |
| LOCATION | 住所 | Location | Dirección | ĐịaChỉ | NER |
| EMAIL_ADDRESS | メールアドレス | Correo | Muster | ||
| PHONE_NUMBER | 電話番号 | Phone | Teléfono | SốĐiệnThoại | registry-gesteuerte sprachspezifische Muster + libphonenumber-Regionen (JP/US/ES/VN/CN/KR/FR/DE/PT/IT) |
| JP_POSTAL_CODE | 郵便番号 | PostalCode | CódigoPostal | MãBưuĐiện | Muster (benutzerdefiniert) |
| JP_MY_NUMBER | マイナンバー | MyNumber | MyNumber | MyNumber | Muster + Prüfziffer (benutzerdefiniert) |
| CREDIT_CARD | クレジットカード | CreditCard | Tarjeta | ThẻTínDụng | Muster + Luhn-Prüfung (beide Kerne, alle Sprachen) |
| CUSTOM (deny list) | 秘匿情報 | Custom | Personalizado | TùyChỉnh | exakte Übereinstimmung |
| US_SSN (Opt-in) | 社会保障番号 | SSN | SSN | SSN | Muster + Invalidierungsregeln (beide Kerne, alle Sprachen) |
| IBAN_CODE (Opt-in) | IBAN | IBAN | IBAN | IBAN | Muster + Mod-97-Prüfung (beide Kerne, alle Sprachen) |
Die Label der sechs neuen Sprachen (zh, ko, fr, de, pt, it) liegen in
src/prompt_anonymizer/labels/*.yaml (Python) und in LABELS in
web/packages/core/src/labeling.ts (TS).
deny_list erzwingt das Maskieren bestimmter Zeichenketten; allow_list
nimmt sie aus. Opt-in-Entitäten werden standardmäßig nicht erkannt — fordern
Sie sie explizit an: PromptAnonymizer(entities=[...]),
new Anonymizer({ entities }) oder
--entities PERSON,EMAIL_ADDRESS,US_SSN,IBAN_CODE auf einer der beiden
CLIs.
Das Standard-NER ist spaCy; das Modell je Sprache wird aus der zentralen
Registry aufgelöst (siehe Tabelle unten; alle sm-Modelle installieren Sie
mit uv sync --group models, die lg-Modelle mit --group models-lg, oder
verwenden Sie python -m spacy download <Modell>). Vietnamesisch hat keine
offizielle spaCy-Pipeline — beide Modellgrößen verwenden das mehrsprachige
WikiNER-Modell xx_ent_wiki_sm für Tokenisierung und Basis-PER/LOC-NER. Für
einen guten Recall vietnamesischer Namen/Orte verwenden Sie stattdessen das
Transformer-Backend (siehe unten).
Für deutlich besseren PERSON/LOCATION-Recall (besonders ja und vi)
installieren Sie das Extra hf und wechseln das Backend —
Hugging-Face-Modelle je Sprache, vollständig lokal:
| Sprache | spaCy (sm / lg) |
HF NER (ner_backend="hf") |
|---|---|---|
ja |
ja_core_news_sm / ja_core_news_lg |
tsmatz/xlm-roberta-ner-japanese |
en |
en_core_web_sm / en_core_web_lg |
dslim/bert-base-NER |
es |
es_core_news_sm / es_core_news_lg |
Davlan/bert-base-multilingual-cased-ner-hrl |
vi |
xx_ent_wiki_sm (beide Größen) |
NlpHUST/ner-vietnamese-electra-base |
zh |
zh_core_web_sm / zh_core_web_lg |
Davlan/bert-base-multilingual-cased-ner-hrl |
ko |
ko_core_news_sm / ko_core_news_lg |
Davlan/bert-base-multilingual-cased-ner-hrl |
fr |
fr_core_news_sm / fr_core_news_lg |
Davlan/bert-base-multilingual-cased-ner-hrl |
de |
de_core_news_sm / de_core_news_lg |
Davlan/bert-base-multilingual-cased-ner-hrl |
pt |
pt_core_news_sm / pt_core_news_lg |
Davlan/bert-base-multilingual-cased-ner-hrl |
it |
it_core_news_sm / it_core_news_lg |
Davlan/bert-base-multilingual-cased-ner-hrl |
Das mehrsprachige HRL-Modell deckt de/es/fr/it/pt/zh nativ ab;
Koreanisch hat in dieser Familie keinen dedizierten Checkpoint und stützt
sich auf den sprachübergreifenden Transfer von mBERT.
Der TypeScript-Kern (Browser / Erweiterung / Desktop / Node-CLI) führt
transformers.js-ONNX-Modelle aus: ja und en verwenden dieselben Familien
wie oben; es, vi, zh, ko, fr, de, pt und it verwenden alle
Xenova/bert-base-multilingual-cased-ner-hrl (es existiert kein
ONNX-Export eines dedizierten vietnamesischen NER-Modells; das mehrsprachige
Modell überträgt sich gut auf Vietnamesisch, und derselbe
Transfer-Vorbehalt gilt für Koreanisch).
pip install "prompt-anonymizer[hf]"pa = PromptAnonymizer(languages=["ja"], ner_backend="hf") # CLI: --ner-backend hf
pa_vi = PromptAnonymizer(languages=["vi"], ner_backend="hf") # empfohlen für vi-NamenBatch-Verarbeitung ist ebenfalls verfügbar und deutlich schneller als eine Schleife:
results = pa.anonymize_batch(texts, language="ja", batch_size=16)Gemessen auf Span-Ebene an einem geseedeten synthetischen Golden-Set (je 200
Dokumente für alle zehn Sprachen in tests/golden/golden_{lang}.json) —
siehe docs/EVAL.md für die vollständige Tabelle und
uv run python -m prompt_anonymizer.evals zum Reproduzieren (standardmäßig
alle zehn Sprachen). Highlights (Python-Kern, sm-Modelle): ja
PHONE_NUMBER / EMAIL_ADDRESS / JP_POSTAL_CODE / CREDIT_CARD Recall 1.00; ja
PERSON Recall 0.82 mit spaCy, 1.00 mit ner_backend="hf". Der es/vi
PHONE_NUMBER-Recall liegt ebenfalls bei 1.00; vi PERSON/LOCATION profitieren
stark von ner_backend="hf". Der Recall strukturierter PII (Telefon /
E-Mail / Karte) beträgt 1.00 für die sechs neuen Sprachen (zh, ko, fr, de,
pt, it) auf dem Golden-Set — docs/EVAL.md enthält die
Tabelle des TS-Kerns; die Python-NER-Zahlen erzeugt die wöchentliche
Evaluation.
Diese Zahlen dienen dazu, Regressionen zu erkennen — nicht dazu, Recall auf realem Text zu versprechen.
- Die Erkennung ist Best-Effort und nicht garantiert. Falsch-Negative
kommen vor; prüfen Sie den anonymisierten Text immer, bevor Sie ihn
irgendwohin senden (
--interactiveund die Mapping-Tabellen in den Oberflächen existieren genau dafür). - Anonymisierung verbirgt Identifikatoren, nicht den Kontext. Quasi-identifizierende Details im umgebenden Text (eine seltene Berufsbezeichnung, ein bestimmtes Ereignis) können weiterhin eingrenzen, über wen oder was Sie schreiben.
- LOCATION hat den schwächsten Recall, besonders bei unvollständigen japanischen Adressen.
- Das Browser-NER-Modell ist ein einmaliger Download von ~100–300 MB (wird danach gecacht).
- Desktop- und Erweiterungs-Builds sind vorerst unsigniert.
Siehe die offenen Issues und IMPLEMENTATION_PLAN.md. Highlights: PyPI- / npm-Registry-Veröffentlichung (Trusted Publishing aktivieren — Pakete sind heute über GitHub Releases installierbar), Chrome Web Store, Code-Signierung, kleinere japanische NER-Modelle, strukturierte PII für weitere Regionen (mehr Telefon- / nationale ID-Formate mit Prüfsummenvalidierung).
- docs/INTEGRATIONS.md — Rezepte für LiteLLM, OpenWebUI, MCP-Clients, Git-Hooks und CI
- CONTRIBUTING.md — Entwicklungs-Setup (uv / pnpm), Test- und Eval-Befehle
- docs/AUDIT.md — On-Device-Behauptungen Schritt für Schritt selbst prüfen
- SECURITY.md — Melden von Sicherheitslücken und Anonymisierungs-Bypässen
- MIT


