ClawPulse
Francais··pseudonymisation prompts llm,rgpd ia,loi 25 ia,scrub pii,monitoring agents ia,clawpulse

Pseudonymisation des prompts LLM : le tutoriel RGPD/Loi 25 pour agents IA

Vous monitorez vos agents IA en production. Vos traces capturent automatiquement les prompts, les réponses du LLM, les arguments des appels d'outils, parfois même les fragments de documents passés au RAG. Et là, le problème vous saute au visage : ces traces contiennent des données personnelles. Adresses email de vos clients, numéros de dossier, fragments de contrats, identifiants internes, parfois même des numéros de carte ou de la donnée santé glissée dans un prompt système mal pensé.

Si vous êtes au Québec, la Loi 25 vous oblige à appliquer le principe de minimisation (article 12) et à pouvoir prouver vos finalités. Si vous êtes sous RGPD, l'article 25 ("Privacy by Design") et l'article 32 (sécurité des traitements) vous demandent de pseudonymiser ce qui peut l'être. Et dans les deux cas, le considérant 26 du RGPD est très clair : la pseudonymisation réduit le périmètre des données personnelles sans pour autant les sortir du champ du règlement (contrairement à l'anonymisation, qui elle, sort du champ — mais qui est techniquement quasi-impossible sur des prompts LLM).

Ce tutoriel est la mise en œuvre opérationnelle du principe énoncé dans notre pilier sur la conformité Loi 25 et RGPD pour agents IA. On va construire ensemble, en Python, le pipeline de pseudonymisation que ClawPulse recommande à ses clients en production : un module de moins de 200 lignes, testable, déterministe sur une fenêtre temporelle, qui transforme un prompt brut en une trace conforme RGPD/Loi 25 que vous pouvez stocker, agréger et analyser sans exposer la donnée source.

Pseudonymisation, anonymisation, chiffrement : ne confondez pas

Avant de coder, mettons un peu de rigueur juridique. Ces trois concepts sont régulièrement confondus dans la documentation des fournisseurs LLM, et la confusion coûte cher en cas d'audit CNIL ou Commission d'accès à l'information du Québec (CAI).

| Notion | Définition juridique | Donnée toujours « personnelle » ? | Réversibilité |

|---|---|---|---|

| Chiffrement (encryption) | Transformation cryptographique réversible avec clé. La clé existe, donc la donnée reste personnelle au sens RGPD. | Oui | Oui (avec clé) |

| Pseudonymisation | Remplacement des identifiants directs par des pseudonymes ; la ré-identification reste possible via une table de correspondance gardée séparément (RGPD art. 4.5). | Oui — mais avec un risque réduit. | Oui (avec table) |

| Anonymisation | Le risque de ré-identification est raisonnablement nul, même par recoupement (CNIL G29 WP216 : critères d'individualisation, corrélation, inférence). | Non — sortie du champ RGPD. | Non |

Pour des prompts LLM, l'anonymisation au sens juridique est quasi-impossible : un prompt contient assez de contexte (style d'écriture, sujet, mentions indirectes) pour permettre une corrélation. La CNIL a confirmé en 2024 que les LLM eux-mêmes peuvent re-personnaliser un texte anonymisé via inférence. C'est donc la pseudonymisation qui est votre cible : elle est réaliste, elle est exigée par l'article 32, et elle est valorisée par les autorités lors d'un contrôle.

Le considérant 28 du RGPD précise même que « l'application de la pseudonymisation aux données à caractère personnel peut réduire les risques pour les personnes concernées et aider les responsables du traitement et leurs sous-traitants à remplir leurs obligations en matière de protection des données ». Autrement dit : vous gagnez des points en cas d'incident.

Le périmètre exact à pseudonymiser dans une trace d'agent IA

Une trace produite par un agent IA en production contient typiquement quatre couches de données. Chacune appelle une stratégie de pseudonymisation différente.

Couche 1 : Identifiants conversationnels

`session_id`, `user_id`, `tenant_id`, `request_id`, `agent_run_id`. Ce sont les identifiants techniques que vous propagez à travers votre stack. Ils ne sont pas eux-mêmes des données personnelles mais combinés à votre base utilisateur, ils permettent une ré-identification triviale. Stratégie : HMAC déterministe avec sel rotatif, pour préserver l'agrégation tout en rendant la corrélation hors-périmètre impossible.

Couche 2 : Charge utile prompt/réponse

Le contenu textuel envoyé au LLM et reçu en retour. C'est la couche la plus risquée, car elle contient potentiellement n'importe quoi : email du client, numéro SIN/NAS, copie-coller de document RH, carte de crédit dans un test de support. Stratégie : scrubber regex strict + détection NER optionnelle appliqués avant l'émission de la trace.

Couche 3 : Arguments d'appels d'outils

Les `tool_calls` que votre agent émet (search, query DB, send email, etc.). Ces arguments contiennent souvent des PK utilisateur, des emails, des paramètres de filtre. Stratégie : typage strict des paramètres + redaction par champ basée sur un schéma JSON.

Couche 4 : Métriques dérivées

Tokens entrée, tokens sortie, latence, coût, succès/échec. Ce sont les seules données qu'on a besoin de garder en clair pour la supervision. Bonne nouvelle : elles sont déjà non-personnelles, à condition qu'on les calcule avant de jeter la charge utile, et qu'on ne stocke que les compteurs agrégés.

La règle directrice est simple : plus on remonte du LLM vers la trace stockée, plus on minimise. Idéalement, ce qui sort de votre processus émetteur vers ClawPulse (ou Langfuse self-hosted, ou votre propre ClickHouse) est déjà pseudonymisé — on ne déporte jamais la responsabilité de la pseudonymisation à un fournisseur tiers.

Le code complet : `clawpulse_pseudo.py`

Voici le module Python de référence. 180 lignes, zéro dépendance externe au-delà de la stdlib (pour la portabilité dans les environnements air-gapped clients sensibles). Vous pouvez le copier-coller dans votre projet, l'adapter à vos schémas, et le tester en isolation.

```python

# clawpulse_pseudo.py

# Pseudonymisation conforme RGPD / Loi 25 pour traces agents IA

# Licence : MIT

from __future__ import annotations

import hashlib

import hmac

import os

import re

import secrets

import time

from contextlib import contextmanager

from dataclasses import dataclass, field, asdict

from typing import Any, Iterator

# ----------------------------------------------------------------------------

# 1. Sel rotatif - pseudonymisation deterministe sur une fenetre temporelle

# ----------------------------------------------------------------------------

# Idee : un identifiant pseudonymise doit pouvoir etre agrege sur une session

# (ex : compter les requetes d'un meme utilisateur sur 24 h) sans rester

# correlable indefiniment. On utilise un sel qui change chaque jour a minuit

# UTC, stocke dans un secret manager (KMS, HashiCorp Vault, etc.).

#

# Effet : deux traces du meme user_id le meme jour donnent le meme pseudo.

# Le lendemain, le pseudo change : impossible de correler entre jours sans

# retourner a la table de correspondance gardee separement.

class RotatingSalt:

"""Sel rotatif quotidien (UTC). Backend env var en demo, KMS en prod."""

def __init__(self, window_seconds: int = 86400, env_var: str = "CLAWPULSE_PSEUDO_SALT"):

self._window = window_seconds

self._env_var = env_var

def current(self) -> bytes:

# En prod : recuperer depuis un secret manager indexe par window_index.

base = os.environ.get(self._env_var)

if not base:

raise RuntimeError(

f"Missing {self._env_var}. En prod, charger depuis Vault/KMS."

)

window_index = int(time.time() // self._window)

return hashlib.sha256(f"{base}:{window_index}".encode()).digest()

# ----------------------------------------------------------------------------

# 2. Pseudonymisation deterministe d'un identifiant

# ----------------------------------------------------------------------------

# HMAC-SHA256 + sel rotatif + tronque a 16 caracteres hex pour la lisibilite.

# Garanties : (a) deterministe sur la fenetre, (b) hors fenetre = nouveau

# pseudo, (c) impossible a inverser sans le sel courant.

def pseudonymize_id(value: str, salt: RotatingSalt, prefix: str = "u_") -> str:

if not value:

return ""

digest = hmac.new(salt.current(), value.encode(), hashlib.sha256).hexdigest()

return f"{prefix}{digest[:16]}"

# ----------------------------------------------------------------------------

# 3. Scrubber regex pour la charge utile prompt/reponse

# ----------------------------------------------------------------------------

# Cible les motifs les plus a risque selon le top des incidents AI Privacy

# (Stanford CRFM 2025 + ICO 2024) : email, telephone NA/EU, IBAN, carte de

# credit (Luhn passe en option), JWT, SIN canadien, NIR francais, IP v4/v6.

REDACTORS = [

# Email

(re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b"),

""),

# IBAN (loose)

(re.compile(r"\b[A-Z]{2}\d{2}[A-Z0-9]{10,30}\b"),

""),

# Carte bancaire 13-19 digits (avant filtre Luhn)

(re.compile(r"\b(?:\d[ -]?){13,19}\b"),

""),

# Telephone NA (+1) ou EU

(re.compile(r"\+?\d{1,3}[\s.-]?\(?\d{2,4}\)?[\s.-]?\d{2,4}[\s.-]?\d{2,4}"),

""),

# JWT

(re.compile(r"\beyJ[A-Za-z0-9_\-]{10,}\.[A-Za-z0-9_\-]{10,}\.[A-Za-z0-9_\-]{10,}\b"),

""),

# SIN canadien (XXX-XXX-XXX)

(re.compile(r"\b\d{3}[\s-]\d{3}[\s-]\d{3}\b"),

""),

# IPv4

(re.compile(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"),

""),

# API keys generiques (sk-, pk_, ghp_, etc.)

(re.compile(r"\b(sk|pk|ghp|gho|ghs|github_pat|xoxb|xoxp)[_-][A-Za-z0-9_-]{20,}\b"),

""),

]

def scrub_payload(text: str):

"""Applique tous les redactors. Retourne le texte nettoye et un

compteur par categorie - utile pour alerter sur un pic de PII."""

if not text:

return "", {}

counters = {}

cleaned = text

for pattern, replacement in REDACTORS:

cleaned, n = pattern.subn(replacement, cleaned)

if n:

counters[replacement] = counters.get(replacement, 0) + n

return cleaned, counters

# ----------------------------------------------------------------------------

# 4. Calcul des metriques AVANT scrubbing

# ----------------------------------------------------------------------------

# Le seul moment ou on a besoin du payload brut, c'est pour calculer les

# metriques de cout et de qualite. On les calcule, puis on jette le payload.

@dataclass

class TraceMetrics:

prompt_chars: int = 0

completion_chars: int = 0

prompt_tokens_est: int = 0

completion_tokens_est: int = 0

pii_redactions: dict = field(default_factory=dict)

duration_ms: int = 0

error: str = None

def estimate_tokens(text: str) -> int:

"""Estimation rapide ~4 chars/token pour planning de cout.

En prod, remplacer par tiktoken si disponible."""

return max(1, len(text) // 4) if text else 0

def derive_metrics(prompt: str, completion: str) -> TraceMetrics:

return TraceMetrics(

prompt_chars=len(prompt or ""),

completion_chars=len(completion or ""),

prompt_tokens_est=estimate_tokens(prompt),

completion_tokens_est=estimate_tokens(completion),

)

# ----------------------------------------------------------------------------

# 5. Context manager pour instrumenter un appel agent IA

# ----------------------------------------------------------------------------

@dataclass

class TraceContext:

user_id: str

agent: str

salt: RotatingSalt

prompt: str = ""

completion: str = ""

tool_calls: list = field(default_factory=list)

started_at: float = field(default_factory=time.monotonic)

error: str = None

def emit_pseudonymized(trace: TraceContext) -> dict:

"""Transforme une trace brute en payload conforme RGPD/Loi 25."""

metrics = derive_metrics(trace.prompt, trace.completion)

metrics.duration_ms = int((time.monotonic() - trace.started_at) * 1000)

metrics.error = trace.error

_, prompt_pii = scrub_payload(trace.prompt)

_, completion_pii = scrub_payload(trace.completion)

pii_total = {}

for d in (prompt_pii, completion_pii):

for k, v in d.items():

pii_total[k] = pii_total.get(k, 0) + v

metrics.pii_redactions = pii_total

payload = {

"user_pseudo": pseudonymize_id(trace.user_id, trace.salt, prefix="u_"),

"agent": trace.agent,

"tools_used": [tc.get("name", "?") for tc in trace.tool_calls],

"metrics": asdict(metrics),

"schema_version": 1,

"ts": int(time.time()),

}

return payload

@contextmanager

def cp_trace(user_id: str, agent: str, salt: RotatingSalt):

trace = TraceContext(user_id=user_id, agent=agent, salt=salt)

try:

yield trace

except Exception as exc:

trace.error = exc.__class__.__name__

raise

finally:

payload = emit_pseudonymized(trace)

# En prod : push vers ClawPulse / Kafka / file locale chiffree.

print(payload)

```

Utilisation : un exemple bout-en-bout

Voici comment vous l'intégrez à un agent IA qui répond à un ticket support et qui a accès à un outil de recherche dans la base CRM.

```python

# my_support_agent.py

import os, secrets

from clawpulse_pseudo import RotatingSalt, cp_trace

from anthropic import Anthropic

# En demo seulement - en prod, charger depuis Vault.

os.environ.setdefault("CLAWPULSE_PSEUDO_SALT", secrets.token_hex(32))

salt = RotatingSalt()

client = Anthropic()

def handle_ticket(user_id: str, message: str) -> str:

with cp_trace(user_id=user_id, agent="support_v2", salt=salt) as trace:

trace.prompt = message

resp = client.messages.create(

model="claude-opus-4-7",

max_tokens=1024,

messages=[{"role": "user", "content": message}],

)

trace.completion = resp.content[0].text

trace.tool_calls = [{"name": "search_kb"}]

return trace.completion

handle_ticket(

user_id="cust_4521",

message="Bonjour, mon email est jean.dupont@exemple.fr, mon numero "

"514-555-0123, j'ai un probleme avec ma carte 4242 4242 4242 4242."

)

```

Sortie côté backend (ce qui part vers ClawPulse / votre stack) :

```json

{

"user_pseudo": "u_a4f2c91be8d76502",

"agent": "support_v2",

"tools_used": ["search_kb"],

"metrics": {

"prompt_chars": 142,

"completion_chars": 318,

"prompt_tokens_est": 35,

"completion_tokens_est": 79,

"pii_redactions": {

"": 1,

"": 1,

"": 1

},

"duration_ms": 1842,

"error": null

},

"schema_version": 1,

"ts": 1735238400

}

```

Notez ce qui n'est PAS émis : ni l'email, ni le téléphone, ni le numéro de carte, ni le contenu du message, ni la réponse du LLM, ni le `cust_4521` brut. Vous gardez la capacité de superviser (durée, tokens, taux d'erreur, alerte sur pic de PII), mais vous avez sorti la donnée personnelle du périmètre observabilité. C'est exactement ce que demande l'article 25 du RGPD ("Privacy by Design") et ce qui rend votre audit Loi 25 simple à défendre.

Start monitoring your OpenClaw agents in 2 minutes

Free 14-day trial. No credit card. Just drop in one curl command.

Prefer a walkthrough? Book a 15-min demo.

Les pièges classiques (et comment les éviter)

Piège 1 : Le sel oublié en environnement de dev

Vous testez en dev avec `CLAWPULSE_PSEUDO_SALT=dev`. Vous oubliez de le rotater. Six mois plus tard, vous découvrez que tous vos pseudos dev sont identiques entre le 1er janvier et aujourd'hui — donc tous corrélables, donc votre dataset de dev est devenu un risque RGPD à part entière.

Mitigation : charger le sel depuis le même backend en dev qu'en prod (Vault avec un compartiment `dev/`), forcer une rotation manuelle dès qu'un audit est planifié.

Piège 2 : Logs applicatifs en clair

Votre code ClawPulse est impeccable. Mais juste à côté, votre framework logue le prompt brut dans `logs/app.log`. La pseudonymisation ne sert plus à rien : la donnée est ailleurs en clair.

Mitigation : auditer tous les loggers Python (`logging.getLogger().handlers`), interdire le `INFO` sur les payloads par convention de code, ajouter un test CI qui grep les logs sample pour `@` et fail si > 0.

Piège 3 : Re-identification par recoupement temporel

Trois traces consécutives ayant le même `user_pseudo`, le même `agent`, des `prompt_chars` croissants, et des `tools_used` typiques d'un parcours d'achat. Si l'attaquant a accès à votre journal HTTP en parallèle (avec IP source), il peut recouper et ré-identifier.

Mitigation : ne jamais joindre les traces ClawPulse avec les logs HTTP côté analyse, séparer les bases, ou ajouter du jitter aléatoire sur `duration_ms`.

Piège 4 : Le scrubber qui passe à côté

Un client envoie `mon dossier numero 4521-AB-7782` — c'est probablement un identifiant interne donc PII métier, mais aucun regex ne va le rattraper. Le scrubber regex ne couvre que les motifs standardisés.

Mitigation : complétez avec un détecteur NER (Presidio de Microsoft, par exemple) en seconde passe sur les payloads à risque, et alertez quand `prompt_chars > seuil` car les longs prompts cachent souvent des collages de documents internes.

Piège 5 : La table de correspondance gardée au mauvais endroit

Vous avez pseudonymisé. Mais vous avez stocké la table `pseudo → user_id` dans le même bucket que les traces. Du point de vue RGPD, c'est comme si vous n'aviez rien fait : « la pseudonymisation est compromise dès que les informations supplémentaires permettant la ré-identification sont accessibles » (CNIL).

Mitigation : la table de correspondance vit dans une base séparée, accédée par un service distinct, avec son propre journal d'accès. Idéalement, c'est votre base utilisateur métier elle-même qui sert de table de correspondance — vous n'avez pas besoin d'en créer une nouvelle.

Comment prouver que ça marche : le harnais de test

Une bonne pseudonymisation se prouve avec des tests automatisés que vous pouvez montrer à un auditeur. Voici le minimum vital.

```python

# test_pseudo.py

import os

os.environ["CLAWPULSE_PSEUDO_SALT"] = "test_salt_for_unit_tests_only"

from clawpulse_pseudo import (

RotatingSalt, pseudonymize_id, scrub_payload, derive_metrics,

cp_trace, emit_pseudonymized, TraceContext

)

def test_pseudo_is_deterministic_within_window():

s = RotatingSalt(window_seconds=86400)

assert pseudonymize_id("user_42", s) == pseudonymize_id("user_42", s)

def test_pseudo_is_distinct_across_windows():

s1 = RotatingSalt(window_seconds=1)

a = pseudonymize_id("user_42", s1)

import time; time.sleep(1.1)

b = pseudonymize_id("user_42", s1)

assert a != b

def test_email_is_scrubbed():

cleaned, counters = scrub_payload("contact: jean@example.fr")

assert "jean@example.fr" not in cleaned

assert counters[""] == 1

def test_card_number_is_scrubbed():

cleaned, _ = scrub_payload("4242 4242 4242 4242 expire 09/27")

assert "4242" not in cleaned

def test_metrics_dont_leak_payload():

m = derive_metrics("tres long prompt secret", "reponse")

serialized = str(m.__dict__)

assert "secret" not in serialized

assert "reponse" not in serialized

def test_no_payload_in_emitted_trace():

"""Le test decisif : le payload ne contient pas le prompt brut."""

s = RotatingSalt()

trace = TraceContext(user_id="u1", agent="test", salt=s)

trace.prompt = "PII_MARKER_VALUE"

trace.completion = "RESPONSE_MARKER"

payload = emit_pseudonymized(trace)

assert "PII_MARKER_VALUE" not in str(payload)

assert "RESPONSE_MARKER" not in str(payload)

assert "u1" not in str(payload)

```

Faites tourner ces tests en CI sur chaque PR. Le jour où un développeur ajoute un champ qui re-fait fuiter le payload, le test échoue. Vous avez la preuve que votre minimisation est vivante, pas juste documentée.

Pseudonymiser n'est pas un coût, c'est un avantage compétitif

Beaucoup d'équipes voient la pseudonymisation comme une contrainte qu'on ajoute à la fin. C'est l'inverse : c'est ce qui vous permet de garder vos traces plus longtemps, de les analyser avec plus de finesse, et de les partager entre équipes (data, sécurité, produit) sans escalader le risque RGPD à chaque fois.

Avec un pipeline propre :

  • Vous pouvez stocker 12 mois de métriques d'agent au lieu des 30 jours auxquels la plupart des équipes se limitent par prudence.
  • Vous pouvez calculer des analyses cohort sans demander d'autorisation à chaque fois.
  • Vous pouvez exposer un dashboard à votre équipe produit sans audit Loi 25 préalable, parce que ce qui s'affiche est déjà non-personnel.
  • Vous pouvez répondre à un incident en 4 h au lieu de 72 h, parce que vos traces ne déclenchent pas l'obligation de notification CNIL/CAI.

Et si vous voulez voir à quoi ressemble cette discipline appliquée à un produit complet, demandez une démo de ClawPulse ou créez un compte gratuit en 2 minutes — toutes nos traces sont pseudonymisées par défaut, hébergement Canada (ca-central-1) ou UE (eu-central-1), zéro Schrems II, zéro frottement avec votre DPO.

Pour aller plus loin

Documentation officielle :

FAQ

Pseudonymiser un prompt LLM rend-il ma trace anonyme au sens RGPD ?

Non. La pseudonymisation réduit le risque mais la donnée reste personnelle au sens RGPD (article 4.5). Pour qu'une donnée soit anonyme, le risque de ré-identification doit être raisonnablement nul, ce qui n'est presque jamais le cas pour un prompt textuel. Vous restez dans le champ du règlement, mais avec une obligation de sécurité considérablement allégée et un argument fort en cas d'incident.

Le sel rotatif quotidien casse-t-il l'analyse de cohort sur 30 jours ?

Non, à condition de stocker une dimension dérivée non-personnelle au moment de l'émission de la trace. Par exemple : `cohort_signup_month = "2026-01"`. Cette dimension n'identifie personne mais permet l'analyse cohort. Le pseudonyme `u_xxx` reste utile pour l'agrégation intra-jour ; au-delà, on bascule sur la dimension cohort.

Faut-il pseudonymiser les `system prompts` aussi ?

Oui, et c'est le piège le plus fréquent. Beaucoup d'équipes mettent des informations métier sensibles dans le system prompt (« tu es l'assistant de [nom client], qui opère dans [secteur] »). Tout ce qui est concaténé au prompt avant envoi au LLM doit passer par le scrubber, system prompt inclus.

Que faire des `tool_calls` qui contiennent des PK utilisateur en argument ?

Ne jamais loger les `arguments` bruts du tool call. Logez seulement le nom de l'outil et un schéma typé (ex : `{"name": "search_kb", "args_schema": "query:str, limit:int"}`). Si vous avez besoin de débugger un cas précis, faites-le en staging avec données synthétiques.

ClawPulse fait tout ça automatiquement ou je dois implémenter le module ?

ClawPulse vous fournit le module et l'intègre nativement dans son agent collector (notre `agent.sh` applique déjà le scrubber sur les payloads avant émission). Vous restez propriétaire du sel rotatif (qui vit dans votre Vault, pas chez nous), donc même nous ne pouvons pas ré-identifier vos traces. C'est cette séparation des responsabilités qui rend l'architecture défendable face à un audit. Voir la démo en live →

```json

{

"@context": "https://schema.org",

"@type": "FAQPage",

"mainEntity": [

{

"@type": "Question",

"name": "Pseudonymiser un prompt LLM rend-il ma trace anonyme au sens RGPD ?",

"acceptedAnswer": {

"@type": "Answer",

"text": "Non. La pseudonymisation reduit le risque mais la donnee reste personnelle au sens RGPD (article 4.5). Pour qu'une donnee soit anonyme, le risque de re-identification doit etre raisonnablement nul, ce qui n'est presque jamais le cas pour un prompt textuel. Vous restez dans le champ du reglement, mais avec une obligation de securite considerablement allegee."

}

},

{

"@type": "Question",

"name": "Le sel rotatif quotidien casse-t-il l'analyse de cohort sur 30 jours ?",

"acceptedAnswer": {

"@type": "Answer",

"text": "Non, a condition de stocker une dimension derivee non-personnelle (cohort_signup_month, par exemple) au moment de l'emission. Le pseudonyme reste utile pour l'agregation intra-jour ; au-dela, on bascule sur la dimension cohort."

}

},

{

"@type": "Question",

"name": "Faut-il pseudonymiser les system prompts aussi ?",

"acceptedAnswer": {

"@type": "Answer",

"text": "Oui. Beaucoup d'equipes mettent des informations metier sensibles dans le system prompt. Tout ce qui est concatene au prompt avant envoi au LLM doit passer par le scrubber, system prompt inclus."

}

},

{

"@type": "Question",

"name": "Que faire des tool_calls qui contiennent des PK utilisateur en argument ?",

"acceptedAnswer": {

"@type": "Answer",

"text": "Ne jamais loger les arguments bruts du tool call. Logez seulement le nom de l'outil et un schema type. Si vous avez besoin de debugger un cas precis, faites-le en staging avec donnees synthetiques."

}

},

{

"@type": "Question",

"name": "ClawPulse fait tout ca automatiquement ou je dois implementer le module ?",

"acceptedAnswer": {

"@type": "Answer",

"text": "ClawPulse vous fournit le module et l'integre nativement dans son agent collector. Vous restez proprietaire du sel rotatif, qui vit dans votre Vault. Cette separation des responsabilites rend l'architecture defendable face a un audit."

}

}

]

}

```

See ClawPulse in action

Get a personalized walkthrough for your OpenClaw setup — takes 15 minutes.

Or start a free trial — no credit card required.

Back to all posts
C

Claudio

Assistant IA ClawPulse

Salut 👋 Je suis Claudio. En 30 secondes je peux te montrer comment ClawPulse remplace tes 12 onglets de monitoring par un seul dashboard. Tu veux voir une demo live, connaitre les tarifs, ou connecter tes agents OpenClaw maintenant ?

Propulse par ClawPulse AI