fahmek — Pilote de terrain chez un professionnel
Guide pratique pour installer fahmek chez un cabinet (comptable, agence, PME) qui utilise déjà ou souhaite utiliser un assistant IA, puis pour constituer un corpus étiqueté local selon le protocole d'annotation.
L'objectif est double : protéger réellement les données du cabinet dès le premier jour, et obtenir, à la fin, un rapport de chiffres (jamais de texte) qui dit ce que fahmek attrape ou rate sur de vrais messages.
1. Ce qu'il faut sur place#
- Une machine avec Docker (le poste du cabinet ou un petit serveur local).
- Un fournisseur de modèle compatible OpenAI accessible depuis cette machine (clé API du cabinet). Seul le texte masqué part chez ce fournisseur.
- Un client de chat qui garde l'historique localement (par exemple une interface web self-hosted pointée sur la passerelle). C'est cet historique, et lui seul, qui servira de source aux messages à étiqueter : fahmek ne journalise jamais le texte, et sa sortie masquée ne doit jamais servir de vérité terrain (ses oublis seraient invisibles).
- L'accord écrit du responsable du cabinet : source des messages, personnes autorisées à les lire, durée de conservation, date de suppression.
2. Installer#
Sur une machine connectée, produire l'archive (make package) et suivre le
guide d'installation, section « Installation sans
Internet » ou les étapes 1 à 7 (machine connectée). Avant docker compose up, définir :
export FAHMEK_API_KEY="$(python -c 'import secrets; print(secrets.token_hex(32))')"
export LITELLM_MASTER_KEY="$(python -c 'import secrets; print(secrets.token_hex(24))')"
export DEMO_MODEL=openai/gpt-4o-mini # ou tout modèle compatible OpenAI
export DEMO_API_BASE=https://api.openai.com/v1
export DEMO_API_KEY=sk-... # clé du cabinet, jamais versionnée
export FAHMEK_POLICY_ID=bank-pilot # voir « Choix de la politique »
docker compose -f docker-compose.demo.yml up -dLe client de chat se configure comme un client OpenAI : URL de base
http://<machine>:4000/v1, clé LITELLM_MASTER_KEY, modèle demo-model.
Pour un client prêt à l'emploi, ajouter -f docker-compose.chat.yml à la
commande ci-dessus : Open WebUI sur http://<machine>:3000, déjà pointé sur
la passerelle, historique conservé dans le volume open-webui (texte non
masqué, sur la machine du cabinet). Ses tâches de fond (titres, étiquettes)
renvoient l'historique restauré au modèle : avec default, un RIB de banque
non listée sans mot de contexte peut partir en clair. Utiliser bank-pilot.
Les modèles réécrivent souvent les jetons (sans «», en gras, tirets bas
échappés) : fahmek les reconnaît grâce à leur code aléatoire de 32 caractères et
les restitue quand même. Un modèle qui modifie le code lui-même (coupé, espacé)
laisse le jeton affiché au lieu de la valeur : aucune fuite.
Vérifier avec python demo/run_demo.py (trois panneaux, aucune fuite), puis
avec un vrai message contenant un ICE et un RIB fictifs.
Choix de la politique. GET /v1/policies (avec X-Fahmek-Key) explique
chaque politique et ses conséquences ; make policies affiche l'effet mesuré
par registre. Pour un cabinet comptable, bank-pilot (fail-closed, CIN sans
contexte masqué, RIB de banque inconnue masqué) est un point de départ
défendable ; noter le choix et sa date.
3. Période d'usage réel#
Deux à quatre semaines d'usage normal suffisent pour un premier corpus. Ne pas guider les utilisateurs vers des messages « intéressants » : les messages ordinaires, les références qui ressemblent à des identifiants sans en être, et les collages de factures comptent autant que les cas évidents. Objectif initial : ~100 messages par registre, positifs et négatifs compris ; un cabinet écrira surtout en français et en mélange — c'est une donnée en soi, à reporter telle quelle.
4. Constituer le corpus, sur place, hors ligne#
Exporter l'historique du client de chat et le convertir en un fichier
brut.jsonl (un objet par ligne) :
{"text": "Bonjour, voici le RIB du client ...", "group_id": "conv-2026-09-14-03"}group_id regroupe tout ce qui vient d'une même conversation, personne ou
famille de modèles de message. Il ne doit contenir aucune donnée personnelle
(un numéro opaque suffit). Ce regroupement est ce qui empêche une fuite entre
les données de mise au point et celles de test.
Puis, avec l'outil fourni (il ne lance jamais le moteur : l'annotateur travaille à l'aveugle, et les positions sont calculées par l'outil en points de code Unicode, jamais à la main) :
# 1. Première passe, à l'aveugle (annotateur A). Reprise possible.
python scripts/label_corpus.py annotate brut.jsonl annote.jsonl
# 2. Relecture indépendante (relecteur B, autre personne). Pseudonymes opaques.
python scripts/label_corpus.py review annote.jsonl relu.jsonl --annotator a1 --reviewer r2
# 3. Répartition mise au point / test, par groupe, reproductible.
python scripts/label_corpus.py split relu.jsonl final.jsonl --holdout 0.3 --seed 42
# 4. Contrôle de schéma et de fuite, comptes par registre.
python scripts/label_corpus.py validate final.jsonlConsignes pendant l'annotation :
- Coller l'identifiant exactement tel qu'il apparaît (espaces, points, chiffres arabes compris) ; l'outil retrouve la position.
- Étiqueter ce que l'utilisateur voulait dire, pas seulement ce qui passe une somme de contrôle : un RIB mal tapé reste sensible.
- Marquer les identifiants supportés même s'ils ne sont pas sensibles dans le
contexte (
sensitive: n), pour distinguer détection et protection. - Les données personnelles non supportées (noms, adresses) se notent à part, comme risque hors périmètre ; elles ne sont pas des étiquettes.
- Ne jamais coller un message dans un assistant IA ni dans un service
d'annotation externe. Ne jamais mettre
brut.jsonl,annote.jsonl,relu.jsonloufinal.jsonlsous Git.
5. Produire le rapport, et seulement lui#
python -m fahmek.evaluation final.jsonl --split development --policy bank-pilot
python -m fahmek.evaluation final.jsonl --split holdout --require-reviewed-holdout --policy bank-pilot --output rapport-holdout.jsonLe rapport ne contient que des comptes, des taux et des empreintes (implémentation, configuration, corpus) : c'est le seul fichier qui quitte le cabinet. Comparer plusieurs politiques sur la mise au point, fixer les seuils d'acceptation avant de lire le holdout, puis appliquer la politique retenue. À la date convenue, supprimer les exports et fichiers de travail.
6. Ce que ce pilote prouve, et ce qu'il ne prouve pas#
Il établit une exactitude locale, par registre, sur les messages d'un cabinet donné, avec l'intervalle de confiance du rapport. Il ne prouve pas une exactitude générale sur le darija, ni la couverture des données personnelles hors périmètre (noms, adresses, documents scannés). Un second site avec un autre profil d'usage augmente la valeur de la preuve plus qu'un site plus long.
Cette page est le guide livré avec fahmek, tenu à jour à chaque version.