Un petit enregistreur de requêtes LLM que j'utilise pour reproduire les échecs de production

DEV - 17/07
La plupart des échecs LLM sont faciles à décrire et étonnamment difficiles à reproduire. Un utilisateur signale que le...

La plupart des échecs LLM sont faciles à décrire et étonnamment difficiles à reproduire.

Un utilisateur signale que le modèle a renvoyé une réponse vide. Un appel d'outil a disparu au milieu d'un flux. Un fournisseur a rejeté une demande qui fonctionnait partout ailleurs.

Ensuite, j'ouvre les journaux et je trouve quelque chose comme ceci :

Échec de la requête LLM : 400 requête incorrecte
Entrer en mode plein écran Quitter le mode plein écran

Techniquement vrai. Opérationnellement inutile.

La pièce manquante est généralement la forme exacte de la demande : le modèle, les paramètres, les rôles des messages, les définitions des outils, le comportement du délai d'attente et la réponse brute du fournisseur.

Je voulais quelque chose de plus petit qu'une plate-forme d'observabilité complète, j'ai donc construit un enregistreur de requêtes autouraller chercher. Il stocke suffisamment d'informations pour inspecter ou rejouer un appel ayant échoué sans enregistrer la clé API.

Ce que l'enregistreur capture

Pour chaque demande, je souhaite :

  • un identifiant de demande unique
  • horodatage et durée
  • URL et modèle
  • corps de requête désinfecté
  • Statut HTTP
  • corps de réponse brut
  • erreurs de réseau ou de délai d'attente

Je n'enregistre délibérément pas leAutorisationen-tête.

Le contenu des invites est également rédigé par défaut. La capture complète de la charge utile doit être activée explicitement, car le stockage des invites de production peut créer un problème bien pire que le bogue étudié.

L'enregistreur

Cet exemple s'exécute sur Node.js 18 ou version ultérieure et n'a aucune dépendance externe.

Créerenregistré-fetch.mjs:

importer { randomUUID } depuis "node:crypto" ; importer { mkdir, writeFile } depuis "node:fs/promises" ; importer le chemin depuis "node:path" ; function sanitize(value, captureContent) ...
[Courte citation de 8% de l'article original]
Loading...