Fichier de configuration
Vous allez décrire un pipeline complet dans un fichier TOML. Le fichier part de trois lignes et devient un pipeline conversationnel, qui garde un jeton stable d'un tour de conversation à l'autre. Chaque étape change une seule chose dans le fichier, puis vous vérifiez le fichier et vous le lancez pour voir ce qui a changé.
1. Mettre en place la boucle de vérification
Deux commandes pilotent toutes les étapes qui suivent. Commencez par un pipeline.toml volontairement faux, avec pattern là où le schéma attend patterns.
[detector]
type = "regex"
pattern = { EMAIL = '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}' }Validez-le.
piighost validate pipeline.tomlLa sortie doit être :
invalid configuration in pipeline.toml: 1 validation error for PipelineConfig
detector.regex.pattern
Extra inputs are not permitted [type=extra_forbidden, input_value={'EMAIL': '[a-z0-9._%+-]+...a-z0-9.-]+\\.[a-z]{2,}'}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.13/v/extra_forbiddenLa commande nomme la section et la clé fautive, et sort en code 1. Ce code de sortie en fait aussi un garde-fou de CI. Relancez-la après chaque modification ci-dessous. Elle ne construit aucun composant, donc elle ne charge aucun modèle.
Exportez le schéma une fois et pointez votre éditeur dessus pour obtenir la complétion sur les noms de sections et de clés.
piighost schema > schema.jsonLes deux commandes sont documentées dans l'interface en ligne de commande.
2. Construire un pipeline en trois lignes
Corrigez la clé, patterns avec un s. Le fichier ne porte plus qu'une section, et cela suffit à construire un pipeline.
[detector]
type = "regex"
patterns = { EMAIL = '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}' }piighost validate pipeline.tomlLa sortie doit être :
OK: pipeline.tomlÉcrivez run.py à côté. Il charge le fichier et dé-identifie le texte que vous passez en ligne de commande. Toutes les étapes suivantes réutilisent run.py tel quel.
import asyncio
import sys
from piighost.config import load_pipeline
async def main() -> None:
pipeline = load_pipeline("pipeline.toml")
result = await pipeline.anonymize(sys.argv[1])
print(result.text)
asyncio.run(main())python run.py "Write to alice@corp.com from 10.0.0.7."La sortie doit être :
Write to <<EMAIL:1>> from 10.0.0.7.Le fichier ne déclare aucun anonymiseur, et pourtant le jeton nomme le label et le numérote. Il ne déclare aucun linker, et pourtant les deux occurrences d'une même adresse partageraient ce jeton. L'anonymiseur et le linker retombent chacun sur leur valeur par défaut, et la résolution des chevauchements aussi. Ce fichier est sur le disque sous examples/config/detector_only.toml.
3. Choisir le jeton
Demandez un caviardage simple à la place du jeton numéroté, avec une section [anonymizer.placeholder].
[detector]
type = "regex"
patterns = { EMAIL = '[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}' }
[anonymizer.placeholder]
type = "redact"python run.py "Write to alice@corp.com from 10.0.0.7."La sortie doit être :
Write to <<REDACT>> from 10.0.0.7.L'adresse a disparu, et son label avec elle. examples/config/minimal.toml porte ce fichier, avec le linker par défaut écrit explicitement. examples/config/minimal.json porte le même fichier en JSON. Le suffixe du fichier choisit le parseur. La référence de configuration liste tous les styles de jeton.
4. Tirer un groupe du catalogue
Votre motif ne couvre que l'email, donc l'adresse IP du texte d'exemple est passée en clair. Remplacez le motif en ligne par le groupe generic du catalogue, qui porte l'email, l'URL, l'IPv4 et la carte bancaire. Sans suffixe, la référence suit la dernière version du groupe, récupérée sur le catalogue à chaque construction du pipeline. Pour figer le groupe, épinglez-le sur un commit, comme catalog:piighost/generic:fab51b33. Il est alors récupéré une seule fois, puis relu depuis le cache sur disque. Le fichier n'a plus de section [anonymizer.placeholder], donc le jeton numéroté par défaut revient et distingue les quatre labels.
[detector]
type = "regex"
catalogs = ["catalog:piighost/generic"]python run.py "Write to alice@corp.com and prénom@corp.com from 10.0.0.7."La sortie doit être :
Write to <<EMAIL:1>> and <<EMAIL:2>> from <<IPV4:1>>.L'adresse IP est couverte, et l'adresse accentuée aussi. Un format qui vous est propre, un numéro de commande comme CMD-2024-0042, n'est dans aucun groupe. Déclarez-le en ligne, à côté du groupe.
[detector]
type = "regex"
catalogs = ["catalog:piighost/generic"]
patterns = { ORDER = 'CMD-\d{4}-\d{4}' }python run.py "Order CMD-2024-0042 for alice@corp.com, from 10.0.0.7."La sortie doit être :
Order <<ORDER:1>> for <<EMAIL:1>>, from <<IPV4:1>>.Le numéro de commande est devenu un jeton. Un label déclaré des deux côtés prend votre motif, parce que les groupes fusionnent d'abord et vos motifs en ligne ensuite.
5. Faire tourner deux détecteurs à la fois
Le groupe generic reconnaît des formats, et un prénom n'a pas de format. Déclarez les prénoms que vous connaissez déjà dans un second détecteur, et laissez un détecteur composite lancer les deux et fusionner ce qu'ils renvoient.
[detector]
type = "composite"
[[detector.detectors]]
type = "regex"
catalogs = ["catalog:piighost/generic"]
patterns = { ORDER = 'CMD-\d{4}-\d{4}' }
[[detector.detectors]]
type = "exact"
values = { Patrick = "PERSON", Patrik = "PERSON" }python run.py "Patrick writes to alice@corp.com. Patrik answers from 10.0.0.7."La sortie doit être :
<<PERSON:1>> writes to <<EMAIL:1>>. <<PERSON:2>> answers from <<IPV4:1>>.Les prénoms et les formats sont attrapés en une seule passe. Une même personne écrite de deux façons reçoit encore deux jetons, <<PERSON:1>> et <<PERSON:2>>. L'étape suivante règle ce doublon.
6. Fusionner les entités presque identiques
Patrick et Patrik sont la même personne, et un modèle qui lit deux jetons suit deux personnes. Installez l'extra fuzzy.
uv add "piighost[config,fuzzy]"pip install "piighost[config,fuzzy]"Ajoutez une section [entity_resolver] à la fin du fichier. Cette section regroupe les entités dont les valeurs sont assez proches l'une de l'autre.
[entity_resolver]
type = "fuzzy"
threshold = 0.85python run.py "Patrick writes to alice@corp.com. Patrik answers from 10.0.0.7."La sortie doit être :
<<PERSON:1>> writes to <<EMAIL:1>>. <<PERSON:1>> answers from <<IPV4:1>>.Les deux orthographes partagent <<PERSON:1>>. Retirez la section et l'étape disparaît, comme pour toute étape optionnelle.
7. Garder les jetons d'un message à l'autre
Chaque exécution de run.py repart de zéro dans la numérotation, car le pipeline ne garde rien d'un appel au suivant. Ajoutez une section [memory] à la fin du fichier. Cette section donne au pipeline un stockage par conversation, et change le chargeur que vous appelez.
[memory]
type = "in_memory"piighost validate pipeline.tomlLa sortie doit être :
OK: pipeline.tomlLe fichier est valide, et run.py le refuse maintenant.
python run.py "Patrick writes to alice@corp.com."La trace se termine sur :
piighost.exceptions.ConfigError: this configuration declares a memory; use load_thread_pipelineUn fichier qui porte une mémoire décrit un pipeline conversationnel, donc il passe par load_thread_pipeline. Écrivez thread.py, qui envoie deux messages sur la conversation "thread-42".
import asyncio
from piighost.config import load_thread_pipeline
async def main() -> None:
pipeline = load_thread_pipeline("pipeline.toml")
first = await pipeline.anonymize(
"Patrick writes to alice@corp.com.", thread_id="thread-42"
)
print(first.text)
second = await pipeline.anonymize(
"Patrik answers from 10.0.0.7.", thread_id="thread-42"
)
print(second.text)
asyncio.run(main())python thread.pyLa sortie doit être :
<<PERSON:1>> writes to <<EMAIL:1>>.
<<PERSON:1>> answers from <<IPV4:1>>.Le second message réutilise le <<PERSON:1>> attribué par le premier. Chaque chargeur refuse les fichiers de l'autre. load_thread_pipeline sur un fichier sans mémoire lève donc this configuration declares no memory; use load_pipeline.
Voir aussi
- Référence de configuration pour chaque section, chaque
typeet chaque clé. - Déploiement pour une mémoire partagée entre workers, Redis ou une base SQL, avec les valeurs stockées chiffrées au repos. Les deux fichiers sont
examples/config/thread_redis.tomletexamples/config/thread_sqlalchemy.toml. - Masquer ou laisser en clair pour la liste à masquer et la liste à laisser en clair.