feat: prompt rules for lossless round-trips (0.3.1)

Two coherence rules added to DEFAULT_SYSTEM_PROMPT:
- different values of the same type get distinct placeholders (context),
  e.g. old/new IBAN -> [PER_1.IBAN:Ancien] / [PER_1.IBAN:Nouveau]
- never absorb adjacent punctuation/separators into a placeholder

Took the live Gemma-4 (Infomaniak) e-learning demo from 4/5 to 5/5 exact
round-trips. 36 tests passing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mobiletic
2026-07-01 09:58:56 +01:00
parent f5c9f0fbd4
commit 2584bd8c95
3 changed files with 13 additions and 2 deletions

View File

@@ -4,6 +4,16 @@ All notable changes to this project are documented here. The format is based on
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.3.1] - Unreleased
### Changed
- Default prompt hardening for lossless round-trips: (1) two **different** values of the same type never
share a placeholder — they must be distinguished by context (e.g. `[PER_1.IBAN:Ancien]` vs
`[PER_1.IBAN:Nouveau]`), preventing a within-message collision (old/new IBAN); (2) the model must not
absorb adjacent **punctuation/separators** (commas, spaces, parentheses) into a placeholder. Together
these took the live Gemma-4 e-learning demo from 4/5 to 5/5 exact round-trips.
## [0.3.0] - Unreleased
### Changed

View File

@@ -1,6 +1,6 @@
{
"name": "@mobiletic/anonymizer",
"version": "0.3.0",
"version": "0.3.1",
"description": "Framework-agnostic PII anonymization & pseudonymization: pluggable LLM detection for free-form PII (names, addresses) with a deterministic regex fallback, deterministic coreference, and streaming-safe de-anonymization.",
"license": "MIT",
"author": "Mobiletic",

View File

@@ -27,8 +27,9 @@ export const DEFAULT_SYSTEM_PROMPT = [
'COHÉRENCE (impératif) :',
'- Chaque clé de "mapping" est EXACTEMENT un placeholder présent dans "texte_anonymise" ; chaque placeholder du texte est une clé de "mapping".',
'- Les VALEURS de "mapping" sont les données ORIGINALES réelles, JAMAIS un autre placeholder.',
'- Deux valeurs DIFFÉRENTES ne partagent JAMAIS le même placeholder. Pour deux valeurs du même type chez la même personne (ex. ancien et nouvel IBAN), distingue-les par un CONTEXTE différent : [PER_1.IBAN:Ancien] et [PER_1.IBAN:Nouveau].',
'- Format OBLIGATOIRE : [TYPE_N] ou [TYPE_N.ATTRIBUT:CONTEXTE] (TYPE en MAJUSCULES, N entier ; ex. [ORG_1.NOM:Entreprise], jamais [ORG:Entreprise]).',
'- Remplace UNIQUEMENT la valeur, pas le libellé voisin (ex. « numéro AVS 756… » → seul « 756… » devient un placeholder ; le mot « AVS » reste).',
'- Remplace UNIQUEMENT la valeur elle-même — jamais le libellé voisin (« numéro AVS 756… » → seul « 756… » ; « AVS » reste) NI la ponctuation/séparateurs voisins (virgules, espaces, parenthèses restent HORS des placeholders, ex. « 14 rue X, 1700 Ville » garde la virgule).',
'',
'RÈGLES:',
'1. Coréférence: la MÊME personne garde le MÊME identifiant (PER_1) dans tout le texte.',