Exercices AI Engineering Retry avec modele de fallback
🎉

Bravo!

Intermédiaire 🧠 Fondamentaux 20 XP 0 personnes ont réussi

Retry avec modele de fallback

Les APIs de LLM ne sont pas fiables a 100%. GPT-4 peut etre sature, Claude peut avoir un timeout, Mistral peut renvoyer une erreur 500. En production, un seul echec ne doit pas faire planter ton application. La solution : le retry avec fallback.

Le principe : tu essaies d'appeler ton modele principal. Si ca echoue, tu reessaies (retry). Si apres N tentatives ca echoue toujours, tu bascules sur un modele de secours (fallback). C'est comme avoir un generateur de secours pour ton electricite.

En vrai, ca donne : essaie GPT-4 -> timeout -> reessaie GPT-4 -> erreur 500 -> bascule sur GPT-3.5 -> succes.

Tu vas ecrire une fonction appel_avec_fallback(fonctions, args, max_retries=2) qui prend :
- fonctions : une liste de fonctions a essayer dans l'ordre (la premiere est le modele principal, les suivantes sont les fallbacks)
- args : un dictionnaire d'arguments a passer a chaque fonction
- max_retries : le nombre maximum de tentatives par fonction

Pour chaque fonction dans la liste, la fonction tente de l'appeler jusqu'a max_retries fois. Si toutes les tentatives echouent, elle passe a la fonction suivante. Si une fonction reussit, elle renvoie immediatement.

Renvoie {"resultat": valeur, "fonction": nom_de_la_fonction, "tentative": numero} en cas de succes.
Renvoie {"erreur": "Tous les modeles ont echoue", "details": liste_des_erreurs} si tout echoue.

Exemple :

compteur = {"n": 0}
def modele_instable(**kwargs):
compteur["n"] += 1
if compteur["n"] < 3:
raise ConnectionError("Timeout")
return "Reponse du modele"

appel_avec_fallback([modele_instable], {"prompt": "Hello"}, max_retries=3)
renvoie {"resultat": "Reponse du modele", "fonction": "modele_instable", "tentative": 3}

Tests (4/5)

Succes au premier essai
def ok(**kw): return 'OK'
r = appel_avec_fallback([ok], {'x': 1})
assert r['resultat'] == 'OK'
assert r['tentative'] == 1
Succes apres retry
compteur = {'n': 0}
def flaky(**kw):
    compteur['n'] += 1
    if compteur['n'] < 2:
        raise Exception('Fail')
    return 'Recovered'
r = appel_avec_fallback([flaky], {}, max_retries=3)
assert r['resultat'] == 'Recovered'
assert r['tentative'] == 2
Fallback utilise
def always_fail(**kw): raise Exception('Down')
def backup(**kw): return 'Backup OK'
r = appel_avec_fallback([always_fail, backup], {}, max_retries=1)
assert r['resultat'] == 'Backup OK'
assert r['fonction'] == 'backup'
Tout echoue
def fail1(**kw): raise Exception('E1')
def fail2(**kw): raise Exception('E2')
r = appel_avec_fallback([fail1, fail2], {}, max_retries=1)
assert r['erreur'] == 'Tous les modeles ont echoue'
assert len(r['details']) == 2

+ 0 tests cachés

Indices (3 disponibles)

solution.py