Exercices Projets guidés Connecter le LLM au CLI
🎉

Bravo!

Débutant 🧠 Fondamentaux 10 XP 0 personnes ont réussi

Connecter le LLM au CLI

Ton CLI sait recevoir des commandes, mais pour l'instant il ne fait rien d'intelligent. C'est comme avoir un telephone sans ligne. Il est temps de brancher le cerveau : connecter un LLM a ton assistant.

Dans Claude Code (le vrai), chaque message que tu tapes est envoye a l'API Anthropic. Le modele analyse ta question, decide quoi faire, et te repond. On va reproduire cette mecanique.

L'idee est de creer un client LLM qui encapsule toute la logique d'appel API. Pourquoi une classe plutot qu'une simple fonction ? Parce qu'un client garde un etat : le modele choisi, le system prompt, la temperature, et plus tard l'historique de conversation. C'est le pattern qu'utilisent toutes les librairies serieuses.

Voici comment fonctionne l'API OpenAI (Anthropic est similaire) :

from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "Tu es un assistant de programmation."},
{"role": "user", "content": "Ecris une boucle for"}
]
)
texte = response.choices[0].message.content

Cree une classe ClientLLM qui encapsule l'appel API. Elle prend a la construction un system_prompt et un model (par defaut "gpt-4o-mini"). Elle accepte aussi un parametre optionnel client pour l'injection de dependances (tests sans API).

La classe doit avoir une methode envoyer(prompt) qui envoie le prompt au LLM et renvoie la reponse sous forme de string. Pour l'instant, pas d'historique : chaque appel est independant.

Elle doit aussi avoir une methode changer_model(nouveau_model) qui change le modele utilise.

Exemple :

llm = ClientLLM("Tu es un assistant Python.", model="gpt-4o-mini")
reponse = llm.envoyer("Qu'est-ce qu'un decorateur ?")
# renvoie un string avec l'explication

llm.changer_model("gpt-4o")
# Les prochains appels utiliseront gpt-4o

Tests (4/5)

Envoyer retourne un string
class FakeMessage:
    def __init__(self, txt):
        self.content = txt

class FakeChoice:
    def __init__(self, txt):
        self.message = FakeMessage(txt)

class FakeResponse:
    def __init__(self, txt):
        self.choices = [FakeChoice(txt)]

class FakeCompletions:
    def create(self, **kwargs):
        return FakeResponse("Reponse du LLM")

class FakeChat:
    def __init__(self):
        self.completions = FakeCompletions()

class FakeClient:
    def __init__(self):
        self.chat = FakeChat()

llm = ClientLLM("Tu es un assistant.", client=FakeClient())
r = llm.envoyer("Bonjour")
assert isinstance(r, str), f"envoyer() doit retourner un string, pas {type(r)}"
assert r == "Reponse du LLM"
Le system prompt est envoye
class FakeMessage:
    def __init__(self):
        self.content = "OK"

class FakeChoice:
    def __init__(self):
        self.message = FakeMessage()

class FakeResponse:
    def __init__(self):
        self.choices = [FakeChoice()]

class FakeCompletions:
    def create(self, **kwargs):
        msgs = kwargs.get("messages", [])
        assert msgs[0]["role"] == "system", "Le premier message doit etre le system prompt"
        assert msgs[0]["content"] == "Tu es un expert Python.", f"System prompt incorrect: {msgs[0]['content']}"
        return FakeResponse()

class FakeChat:
    def __init__(self):
        self.completions = FakeCompletions()

class FakeClient:
    def __init__(self):
        self.chat = FakeChat()

llm = ClientLLM("Tu es un expert Python.", client=FakeClient())
llm.envoyer("Test")
Le modele est transmis a l'API
class FakeMessage:
    def __init__(self):
        self.content = "OK"

class FakeChoice:
    def __init__(self):
        self.message = FakeMessage()

class FakeResponse:
    def __init__(self):
        self.choices = [FakeChoice()]

class FakeCompletions:
    def create(self, **kwargs):
        assert kwargs.get("model") == "gpt-4o", f"Modele attendu gpt-4o, obtenu {kwargs.get('model')}"
        return FakeResponse()

class FakeChat:
    def __init__(self):
        self.completions = FakeCompletions()

class FakeClient:
    def __init__(self):
        self.chat = FakeChat()

llm = ClientLLM("Sys", model="gpt-4o", client=FakeClient())
llm.envoyer("Test")
Changer de modele
class FakeMessage:
    def __init__(self):
        self.content = "OK"

class FakeChoice:
    def __init__(self):
        self.message = FakeMessage()

class FakeResponse:
    def __init__(self):
        self.choices = [FakeChoice()]

class FakeCompletions:
    def create(self, **kwargs):
        assert kwargs.get("model") == "gpt-4o", f"Apres changer_model, le modele doit etre gpt-4o, pas {kwargs.get('model')}"
        return FakeResponse()

class FakeChat:
    def __init__(self):
        self.completions = FakeCompletions()

class FakeClient:
    def __init__(self):
        self.chat = FakeChat()

llm = ClientLLM("Sys", model="gpt-4o-mini", client=FakeClient())
llm.changer_model("gpt-4o")
llm.envoyer("Test")

+ 0 tests cachés

Indices (3 disponibles)

solution.py