--- icon: lucide/messages-square --- # Pipeline conversationnel Vous allez construire un `ThreadAnonymizationPipeline` qui garde un jeton stable pour une même valeur d'un message à l'autre. Une valeur vue au message 1 conserve son `<>`{ .placeholder } au message 2, au lieu de repartir de zéro à chaque appel. Vous assemblez le pipeline avec une mémoire en RAM, envoyez deux messages de la même conversation, puis effacez la conversation. !!! note "Prérequis" `piighost` installé, voir [Installation](installation.md). Cet exemple n'utilise que le socle, sans extra. ## 1. Assembler le pipeline `ThreadAnonymizationPipeline` prend les mêmes composants qu'`AnonymizationPipeline` (détecteur, linker, anonymiseur), plus une mémoire de conversation. Seul le détecteur est obligatoire. Le code ci-dessous ne passe que lui, et les autres composants gardent leurs valeurs par défaut. La mémoire accumule les détections de chaque message, conversation par conversation. Le pipeline peut ainsi attribuer les jetons sur l'ensemble de la conversation plutôt que sur un message isolé. La mémoire par défaut, `InMemoryConversationMemory`, garde cet état dans un dictionnaire du processus. Rien ne survit à un redémarrage et rien n'est partagé entre processus. Cette mémoire convient donc au développement et aux tests. Le détecteur reste simple ici avec `ExactMatchDetector`, qui repère des valeurs connues. Le résultat est ainsi vérifiable, sans modèle. ```python import asyncio from piighost.components.detector import ExactMatchDetector from piighost.pipeline import ThreadAnonymizationPipeline detector = ExactMatchDetector({"Patrick": "PERSON", "Paris": "LOCATION"}) pipeline = ThreadAnonymizationPipeline(detector) ``` ## 2. Dé-identifier deux messages de la même conversation `anonymize` prend le texte et un `thread_id`. Le `thread_id` est obligatoire. Il n'y a pas de conversation partagée par défaut. Deux appelants ne peuvent donc pas tomber par erreur dans la même conversation, où chacun verrait les données confidentielles de l'autre. Le code envoie deux messages sur la conversation `"thread-42"`. ```python async def main() -> None: first = await pipeline.anonymize("Patrick habite à Paris.", thread_id="thread-42") print(first.text) second = await pipeline.anonymize( "Est-ce que Patrick aime Paris ?", thread_id="thread-42" ) print(second.text) asyncio.run(main()) ``` La sortie doit être : ```text <> habite à <>. Est-ce que <> aime <> ? ``` `Patrick`{ .pii } garde `<>`{ .placeholder } du premier au second message, et `Paris`{ .pii } garde `<>`{ .placeholder }. Avec un `AnonymizationPipeline` ordinaire, chaque appel repartirait à `<>`{ .placeholder } sans lien avec le message précédent. La mémoire de la conversation est ce qui rend le numéro stable. ## 3. Restaurer une valeur `deanonymize` reconstruit les jetons de la conversation depuis sa mémoire. Il restaure donc n'importe quel texte qui porte ces jetons, y compris une réponse du modèle que le pipeline n'a jamais dé-identifiée. ```python async def main() -> None: restored = await pipeline.deanonymize( "Bonjour <> !", thread_id="thread-42" ) print(restored) asyncio.run(main()) ``` La sortie doit être : ```text Bonjour Patrick ! ``` ## 4. Oublier une conversation `forget_thread` efface la mémoire d'une conversation et renvoie le compte de ce qui a été supprimé. Utile pour respecter une demande d'effacement ou libérer la RAM à la fin d'une conversation. ```python async def main() -> None: forgotten = await pipeline.forget_thread(thread_id="thread-42") print(forgotten) asyncio.run(main()) ``` La sortie doit être : ```text Forgotten(messages=2, detections=4) ``` ## Comment ça marche `ThreadAnonymizationPipeline` encapsule le pipeline de base avec une mémoire par conversation. À chaque message, il met en cache les détections, puis attribue les jetons sur l'union des détections de toute la conversation, pas du seul message courant. Une valeur reçoit donc un jeton pour l'ensemble de la conversation. Le rendu reste par message. Seules les positions du message courant sont remplacées, car chaque message compte ses positions depuis son propre début. ## Voir aussi - Pour partager la mémoire entre plusieurs processus, remplacez `InMemoryConversationMemory` par une mémoire persistante. Voir la [référence de configuration](../configuration/toml.md) pour la déclarer en configuration. - Pour brancher ce pipeline dans un agent LangGraph, voir le [Middleware LangChain](langchain.md). - Pour lire les règles de gestion d'une conversation, de `BR-CONV-01` à `BR-CONV-11`, voir [Suivre une conversation et restaurer la réponse](../../../openwiki/fr/processes/follow-a-conversation.md).