Réduire les logs Android pour les LLM : Compression sémantique

Réduire les logs Android pour les LLM : Compression sémantique

Introduction

Si vous faites du développement Android avec Claude Code ou Cursor, vous heurterez rapidement ce mur :

  • Les dumps logcat bruts peuvent faire des milliers de lignes
  • Un XML UIAutomator pour un seul écran peut faire des centaines de Ko
  • La sortie d'adb dumpsys peut atteindre des dizaines de milliers de lignes

Si vous vouliez seulement réduire le nombre de tokens, du gzip ordinaire suffirait. Mais les données envoyées aux LLM nécessitent une "compression sémantique" — les objectifs sont fondamentalement différents.

Compression ordinaire Compression sémantique pour LLM
Objectif Réduire les octets Réduire le bruit de raisonnement
Critère Reproductibilité Compréhensibilité IA
Sortie Équivalent à l'original Sémantiquement équivalent

Architecture du pipeline multi-étapes

L'architecture de base pour la compression sémantique ressemble à ceci :

entrée
  ↓ parser           (structuration)
  ↓ normalizer       (normaliser les variations de formatage)
  ↓ dedupe           (supprimer les doublons)
  ↓ réduction sémantique (supprimer les informations non pertinentes)
  ↓ structuration    (organiser)
  ↓ encoder          (encodage TOON/DSL)
  ↓ LLM

Passons en revue chaque étape.


1. Parser — Structurer d'abord

La première tâche est de structurer l'entrée brute.

Exemple logcat :

05-28 10:00:00 E MyApp: NullPointerException

{
  "time": "05-28 10:00:00",
  "level": "E",
  "tag": "MyApp",
  "message": "NullPointerException"
}

La structuration permet le filtrage dans les étapes suivantes.


2. Normalizer — Éliminer les variations de formatage

Unifier les informations qui transmettent la même signification dans différents formats.

Raccourcissement des noms de packages :

com.example.myapp.feature.login.LoginViewModel

LoginViewModel

Normalisation des noms de classes d'exception :

java.lang.NullPointerException

NPE

3. Dedupe — Supprimer les doublons

La répétition est presque toujours nuisible pour les LLM.

Entrée :

Chargement...
Chargement...
Chargement...
Chargement...

Après compression :

Chargement... x4

Un exemple plus significatif — la même stack trace répétée 100 fois :

EXCEPTION repeated x100 { type=NPE source=LoginViewModel.kt line=42 }

Cela seul économise un nombre énorme de tokens.


4. Réduction sémantique — Supprimer ce dont l'IA n'a pas besoin

C'est le cœur de la compression LLM.

Logs de bruit Android spécifiques à exclure

Ceux-ci ne contribuent pas au débogage IA :

Tag Contenu
BufferQueue Internes du système graphique
OpenGLRenderer Moteur de rendu
libEGL OpenGL ES
AudioTrack Internes audio
TrafficStats Statistiques réseau
chatty Messages de suppression de logs
GC_ Collecte des ordures

Exemple de filtre :

NOISE_PATTERNS = [
    r"BufferQueue",
    r"OpenGLRenderer",
    r"libEGL",
    r"AudioTrack",
    r"chatty",
    r"GC_",
]

def filter_noise(line: str) -> bool:
    return not any(re.search(p, line) for p in NOISE_PATTERNS)

Logs importants à conserver

Exception / ANR / Cycle de vie Activity / Erreur réseau / Firebase / WorkManager

5. Structuration — Organiser pour la compréhension LLM

Les LLM gèrent mieux les informations organisées.

Avant :

MainActivity created
Fragment onResume called
API request started

Après :

ACTIVITY{ name=MainActivity state=created }
FRAGMENT{ state=onResume }
API{ state=start }

Les étiquettes explicites améliorent significativement la compréhension IA.


6. Encoder — Encodage TOON/DSL

Enfin, convertir en un format personnalisé (TOON) :

events[3]{type,target,state}:
  ACT|MainActivity|created
  API|LoginApi|start
  ERR|Auth|401

Plus d'informations par ligne, plus de contenu tenant dans la fenêtre de contexte.


UIAutomator et compression de l'arbre UI

Lors de l'utilisation d'Android MCP, le XML UIAutomator est encore plus verbeux.

XML original (extrait) :

{
  "x": 120,
  "y": 400,
  "width": 200,
  "height": 48,
  "padding": 0,
  "alpha": 1.0,
  "focusable": false,
  "clickable": true,
  "text": "Connexion"
}

Après compression :

BTN[text=Connexion]

Le padding et l'alpha sont essentiellement inutiles pour un LLM. Ne garder que les éléments où clickable=true et text est présent réduit les mêmes informations à moins de 1/20 du nombre de tokens.


La spécialisation de domaine est ce qui compte le plus

La logique de compression spécifique à Android surpasse largement la compression générique.

Classification automatique des catégories de logs

CATEGORIES = {
    "lifecycle":   ["onCreate", "onResume", "onPause", "onDestroy"],
    "crash":       ["Exception", "ANR", "Fatal"],
    "network":     ["Retrofit", "OkHttp", "HttpException"],
    "database":    ["Room", "SQLite"],
    "compose":     ["Recomposition", "Composition"],
    "firebase":    ["Firebase", "Firestore", "FCM"],
    "workmanager": ["WorkManager", "Worker"],
}

Passer des logs organisés par catégorie à l'IA regroupe les informations connexes et améliore la précision du débogage.


Interface basée sur des commandes par cas d'utilisation

Les commandes slash créent une interface naturelle pour l'intégration IA :

/logcat     → compression spécifique logcat
/uiauto     → compression spécifique XML UIAutomator
/json       → compression spécifique grands JSON
/stacktrace → extraire uniquement la stack trace

Pour aller plus loin : Implémentation serveur MCP

Ce pipeline peut être implémenté comme serveur MCP :

@mcp.tool()
def compress_logcat(text: str) -> str:
    return run_pipeline(text, mode="logcat")

@mcp.tool()
def compress_uiauto(xml: str) -> str:
    return run_pipeline(xml, mode="uiauto")

@mcp.tool()
def compress_json(data: str) -> str:
    return run_pipeline(data, mode="json")

Claude Desktop et Claude Code peuvent alors appeler ces outils automatiquement. L'idéal est une compression qui se produit de manière transparente, sans que l'utilisateur n'ait à y penser.


Résumé

Étape Effet
Parser Permet le filtrage en aval
Normalizer Élimine les représentations dupliquées d'une même information
Dedupe Compresse les entrées de logs répétées
Réduction sémantique Supprime le bruit non pertinent pour l'IA
Structuration Organise les données pour une meilleure compréhension IA
Encoder (TOON) Augmente la densité d'information

L'insight clé est de savoir ce dont l'IA n'a pas besoin. La compression ordinaire réduit les octets. La compression sémantique pour les LLM réduit le bruit de raisonnement. Garder cette distinction à l'esprit rend la combinaison Android MCP + IA dramatiquement plus puissante.