← Zakaria Khchiche · Tous les articles

3 bugs silencieux dans un framework d’agents IA open source

Audit d'OGX (ex-Llama Stack) : recherche hybride, filtres pgvector et comptage des tokens qui renvoyaient des résultats plausibles mais faux.

Zakaria Khchiche · · également publié sur Medium

Un bug qui plante, on le voit tout de suite. Un bug qui renvoie un résultat plausible mais faux peut tourner des mois en production sans que personne ne s’en aperçoive.

En auditant le code d’OGX, un framework open source pour construire des agents IA, j’en ai trouvé trois de ce type. Aucun ne lève d’erreur. Chacun fausse discrètement un résultat : la pertinence d’une recherche, un filtre de documents ou une facture de tokens.

Le contexte : OGX, l’ex-Llama Stack

OGX est la suite du projet Llama Stack lancé par Meta. Il fournit les briques standard d’une application agentique : inférence, API Responses compatible OpenAI, bases vectorielles pour le RAG (Elasticsearch, pgvector, Qdrant…).

Quand une équipe bâtit ses agents sur ce genre de socle, elle fait confiance à ces briques sans les relire. C’est justement là qu’un audit est utile : chercher ce qui marche « presque ».

Bug 1 : une lettre en trop qui désactive un réglage de recherche

La recherche hybride d’Elasticsearch fusionne une recherche par mots-clés et une recherche vectorielle (RRF). Le paramètre rank_window_size définit combien de candidats sont pris en compte dans cette fusion.

Dans le code, la liste des paramètres autorisés contenait rank_windows_size, avec un « s » en trop. Résultat : le bon paramètre était jugé inconnu et supprimé en silence.

# avant
allowed_rrf_params = {"rank_constant", "rank_windows_size", "filter"}
# après
allowed_rrf_params = {"rank_constant", "rank_window_size", "filter"}

Concrètement, on demande rank_window_size = 50 et Elasticsearch reçoit 10 (la valeur par défaut). Après correction, il reçoit bien 50.

Un seul caractère à corriger. Le correctif est proposé dans la pull request #6697, fusionnée par les mainteneurs.

Bug 2 : des filtres pgvector qui ne trouvent jamais les booléens

Sur pgvector, on peut filtrer les documents sur leurs métadonnées, par exemple « publié = vrai ». Pour les filtres « dans la liste » (IN) et « hors de la liste » (NOT IN), le code convertissait chaque valeur en texte Python : True devenait "True".

Or PostgreSQL extrait la métadonnée JSON sous la forme "true". Les deux ne correspondent jamais. Même problème pour un nombre stocké 2023.0 filtré sur 2023.

Testé sur une vraie base PostgreSQL 16, avec deux documents :

Filtre                  | Avant            | Après correction
publié dans [vrai]      | aucun résultat   | document 0
publié hors de [vrai]   | documents 0 et 1 | document 1
année dans [2023]       | aucun résultat   | document 1

Le pire cas est le filtre d’exclusion : il laisse passer des documents qu’on voulait écarter. Dans un RAG, cela veut dire des sources non publiées ou obsolètes injectées dans le contexte du modèle. Le correctif applique aux listes le même typage que les comparaisons simples.

Le correctif est proposé dans la pull request #6698, fusionnée par les mainteneurs.

Bug 3 : un compteur de tokens qui oublie les appels précédents

Un agent fait souvent plusieurs appels au modèle pour une seule réponse, par exemple quand il utilise des outils. L’API Responses additionne bien les tokens d’entrée et de sortie de tous ces appels.

Mais deux compteurs détaillés étaient écrasés au lieu d’être additionnés : les tokens servis depuis le cache et les tokens de raisonnement. Seul le dernier appel comptait.

Exemple sur 2 appels               | Avant | Après correction
Tokens en cache (80 + 120)         | 120   | 200
Tokens de raisonnement (10 + 15)   | 15    | 25

Ce sont précisément les deux chiffres qui servent à piloter les coûts. Le cache baisse la facture, le raisonnement l’augmente. Un tableau de bord basé sur ces valeurs sous-estimait les deux.

Le bug est signalé dans l’issue #6699, résolue, avec le correctif proposé (commit e8177d0).

Ce que ça change pour une équipe qui industrialise des agents

  1. Testez ce qui est silencieux. Un paramètre ignoré ou un filtre qui ne filtre pas ne déclenche aucune alerte. Il faut un test qui vérifie la valeur réellement envoyée, pas seulement l’absence d’erreur.
  2. Testez avec de vrais types. Les bugs 2 et 3 n’apparaissent qu’avec des booléens, des décimaux ou plusieurs appels enchaînés. Les jeux de test « chaînes de caractères et un seul appel » passent à côté.
  3. Ne faites pas une confiance aveugle au socle. Un framework open source populaire reste du code écrit vite. Relire les briques critiques (filtrage, coûts) avant la mise en production coûte quelques heures.
  4. Contribuez en retour. Chaque correctif fait ici fait quelques lignes. Le proposer en amont profite à tous ceux qui utilisent le même socle.

Vous construisez des agents sur OGX ou un autre framework ? Je serais curieux de savoir quels bugs silencieux vous avez croisés.

Pour en parler ou faire auditer vos propres agents : LinkedIn · Malt · Medium · https://zakariakhchiche.github.io/

Vous formez vos équipes à l'IA générative ? J'anime avec Spar-x (organisme certifié Qualiopi, formations finançables par votre OPCO) une formation Copilot Studio : https://zakariakhchiche.github.io/formation-copilot-studio/ et j'ai publié un kit AI Act article 4 gratuit : https://zakariakhchiche.github.io/kit-ai-act/