
Cette suite de guides va vous permettre de construire “DevOps Buddy” — un assistant IA qui répond à vos questions DevOps. En 30 minutes, vous aurez un chatbot fonctionnel avec streaming, historique de conversation, et la capacité de changer de modèle en une ligne. Ce projet servira de fil rouge pour toute la série LiteLLM.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Appeler un LLM avec
completion()— la fonction universelle de LiteLLM - Afficher les réponses en streaming pour une meilleure expérience utilisateur
- Maintenir une conversation en gérant l’historique des messages
- Changer de modèle (GPT, Claude, Ollama) sans modifier votre code
- Gérer les erreurs (rate limiting, timeout, API down)
Le projet DevOps Buddy
Section intitulée « Le projet DevOps Buddy »DevOps Buddy est un assistant spécialisé DevOps que nous allons faire évoluer au fil des guides :
| Guide | Fonctionnalité ajoutée |
|---|---|
| Ce guide | Chatbot de base avec streaming et conversation |
| Async | Analyse de fichiers de config en parallèle |
| Embeddings | Recherche dans une base de connaissances DevOps |
| Router | Production : fallbacks, caching, monitoring |
À la fin de cette série, vous aurez un assistant DevOps complet, utilisable en production.
Pourquoi LiteLLM ?
Section intitulée « Pourquoi LiteLLM ? »Chaque fournisseur IA impose sa propre syntaxe. Avec LiteLLM, vous n’en apprenez qu’une seule :
from litellm import completion
# Même code pour TOUS les providers — seul le modèle changeresponse = completion( model="gpt-4.1-mini", # ou "claude-3-5-haiku-latest", "ollama/llama3.2" messages=[{"role": "user", "content": "Comment optimiser un Dockerfile ?"}])Avantage pour DevOps Buddy : on peut tester GPT, Claude, ou un modèle local sans changer une ligne de code applicatif.
Créer votre clé API OpenAI
Section intitulée « Créer votre clé API OpenAI »Avant de commencer, vous devez créer une clé API sur la plateforme OpenAI.
-
Créez un compte OpenAI :
Rendez-vous sur platform.openai.com et créez un compte (ou connectez-vous si vous en avez déjà un).
-
Accédez à la section API Keys :
Dans le menu de gauche, cliquez sur “API keys” ou allez directement sur platform.openai.com/api-keys.
-
Créez une nouvelle clé :
Cliquez sur “Create new secret key”. Donnez-lui un nom descriptif comme
devops-buddy-key. -
Copiez la clé immédiatement :
La clé s’affiche une seule fois. Copiez-la dans un endroit sûr. Elle ressemble à :
sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -
Ajoutez des crédits :
Allez dans “Billing” > “Add payment method”. Ajoutez 5-10 $ pour commencer — c’est largement suffisant pour tout ce tutoriel (le modèle
gpt-4.1-minicoûte environ 0.15 $ / million de tokens en entrée).
Mise en place du projet
Section intitulée « Mise en place du projet »-
Créez le dossier du projet :
Fenêtre de terminal mkdir -p ~/lab-devops-buddycd ~/lab-devops-buddy -
Initialisez l’environnement :
Fenêtre de terminal python -m venv venvsource venv/bin/activatepip install litellm python-dotenv -
Configurez votre clé API :
Créez un fichier
.envavec votre clé :.env # Collez votre clé OpenAI iciOPENAI_API_KEY=sk-proj-votre-cle-ici# Optionnel : pour tester les fallbacks plus tardANTHROPIC_API_KEY=sk-ant-... -
Ajoutez
.envau gitignore :Fenêtre de terminal echo ".env" >> .gitignore
Étape 1 : premier appel — une question DevOps
Section intitulée « Étape 1 : premier appel — une question DevOps »Créons notre premier script qui pose une question DevOps :
from litellm import completionfrom dotenv import load_dotenv
load_dotenv()
# Notre première question DevOpsresponse = completion( model="gpt-4.1-mini", messages=[ {"role": "user", "content": "Explique la différence entre Docker et une VM en 3 lignes."} ])
print(response.choices[0].message.content)Exécutez :
python 01_question_simple.pyRésultat attendu :
Docker est une plateforme de virtualisation légère qui exécute des applicationsdans des conteneurs isolés partageant le même noyau du système d'exploitationhôte. Une machine virtuelle (VM) émule un système complet, incluant un noyauet un matériel virtuel, ce qui la rend plus lourde en ressources. Ainsi, Dockeroffre une meilleure efficacité et rapidité, tandis que les VM fournissent uneisolation plus complète.Anatomie de la réponse
Section intitulée « Anatomie de la réponse »# Le texte généréprint(response.choices[0].message.content)
# Le modèle utiliséprint(response.model) # gpt-4.1-mini
# Les tokens consommés (pour suivre les coûts)print(f"Tokens: {response.usage.total_tokens}")print(f"Coût estimé: ${response._hidden_params.get('response_cost', 0):.4f}")Étape 2 : streaming — voir la réponse s’écrire
Section intitulée « Étape 2 : streaming — voir la réponse s’écrire »Pour une meilleure UX, affichons la réponse mot par mot :
from litellm import completionfrom dotenv import load_dotenv
load_dotenv()
response = completion( model="gpt-4.1-mini", messages=[ {"role": "user", "content": "Liste 5 bonnes pratiques pour un Dockerfile"} ], stream=True # Active le streaming)
for chunk in response: content = chunk.choices[0].delta.content or "" print(content, end="", flush=True)
print() # Nouvelle ligne finaleRésultat : le texte apparaît progressivement, comme sur ChatGPT.
Voici 5 bonnes pratiques pour rédiger un Dockerfile efficace :
1. **Utiliser une image officielle et légère comme base** Privilégiez des images optimisées (par exemple `alpine` ou `python:slim`) pour réduire la taille finale et minimiser les vulnérabilités.
2. **Minimiser le nombre de couches (instructions RUN, COPY, etc.)** Combinez plusieurs commandes en une seule pour limiter le nombre de couches.
3. **Utiliser `.dockerignore` pour exclure les fichiers inutiles** Évitez de copier docs, fichiers temporaires, dossiers locaux.
4. **Spécifier un utilisateur non-root pour l'exécution** Utilisez la directive `USER` pour limiter les droits.
5. **Définir clairement l'instruction ENTRYPOINT ou CMD** Indiquez explicitement quelle commande sera exécutée au lancement.Étape 3 : conversation avec historique
Section intitulée « Étape 3 : conversation avec historique »L’IA n’a pas de mémoire. Pour une vraie conversation, il faut renvoyer l’historique à chaque appel :
from litellm import completionfrom dotenv import load_dotenv
load_dotenv()
# Personnalité de DevOps BuddySYSTEM_PROMPT = """Tu es DevOps Buddy, un assistant expert en DevOps et DevSecOps.
Tes spécialités :- CI/CD (GitLab, GitHub Actions, Jenkins)- Conteneurs (Docker, Kubernetes, Podman)- Infrastructure as Code (Terraform, Ansible)- Observabilité (Prometheus, Grafana, Loki)- Sécurité (scanning, SAST/DAST, secrets)
Réponds de manière concise et pratique. Donne des exemples de code quand pertinent."""
def chat(messages: list, user_input: str) -> str: """Envoie un message et retourne la réponse.""" messages.append({"role": "user", "content": user_input})
response = completion( model="gpt-4.1-mini", messages=messages, stream=True )
full_response = "" for chunk in response: content = chunk.choices[0].delta.content if content: print(content, end="", flush=True) full_response += content
print("\n") messages.append({"role": "assistant", "content": full_response}) return full_response
def main(): print("🤖 DevOps Buddy v1.0") print("Posez vos questions DevOps. Tapez 'quit' pour quitter.\n")
messages = [{"role": "system", "content": SYSTEM_PROMPT}]
while True: user_input = input("👤 Vous: ").strip() if user_input.lower() in ["quit", "exit", "q"]: print("👋 À bientôt !") break if not user_input: continue
print("\n🤖 DevOps Buddy: ", end="") chat(messages, user_input)
if __name__ == "__main__": main()Testez une conversation :
🤖 DevOps Buddy v1.0
👤 Vous: Comment sécuriser un secret dans GitLab CI ?🤖 DevOps Buddy: Pour sécuriser un secret dans GitLab CI, utilisez les **Variables CI/CD** :
1. Allez dans Settings > CI/CD > Variables2. Ajoutez votre secret avec l'option "Masked" et "Protected"...
👤 Vous: Et comment y accéder dans le pipeline ?🤖 DevOps Buddy: Dans votre `.gitlab-ci.yml`, référencez la variable avec `$NOM_VARIABLE` :
```yamldeploy: script: - echo "Déploiement avec $DEPLOY_TOKEN"```...L’assistant se souvient du contexte grâce à l’historique des messages.
Étape 4 : changer de modèle dynamiquement
Section intitulée « Étape 4 : changer de modèle dynamiquement »L’avantage de LiteLLM : tester différents modèles sans changer le code :
from litellm import completionfrom dotenv import load_dotenv
load_dotenv()
QUESTION = "Donne 3 bonnes pratiques pour écrire un Dockerfile"
MODELES = [ "gpt-4.1-mini", "claude-3-5-haiku-latest", # "ollama/llama3.2", # Décommentez si Ollama est installé]
for modele in MODELES: print(f"\n{'='*50}") print(f"🤖 Réponse de {modele}") print('='*50)
try: response = completion( model=modele, messages=[{"role": "user", "content": QUESTION}], max_tokens=300 ) print(response.choices[0].message.content) print(f"\n📊 Tokens: {response.usage.total_tokens}") except Exception as e: print(f"❌ Erreur: {e}")Cas d’usage : comparer la qualité/coût des réponses pour choisir le meilleur modèle.
Étape 5 : gestion des erreurs
Section intitulée « Étape 5 : gestion des erreurs »En production, il faut gérer les erreurs gracieusement :
from litellm import completionfrom litellm.exceptions import ( AuthenticationError, RateLimitError, APIConnectionError)from dotenv import load_dotenvimport time
load_dotenv()
def ask_with_retry(question: str, max_retries: int = 3) -> str: """Pose une question avec gestion des erreurs et retries."""
for attempt in range(max_retries): try: response = completion( model="gpt-4.1-mini", messages=[{"role": "user", "content": question}], timeout=30 ) return response.choices[0].message.content
except AuthenticationError: raise Exception("❌ Clé API invalide. Vérifiez OPENAI_API_KEY.")
except RateLimitError: wait = 2 ** attempt # Backoff exponentiel print(f"⏳ Rate limit atteint, attente {wait}s...") time.sleep(wait)
except APIConnectionError: print(f"🔌 Connexion échouée, tentative {attempt + 1}/{max_retries}") time.sleep(1)
raise Exception("❌ Échec après plusieurs tentatives")
# Testtry: answer = ask_with_retry("Qu'est-ce que Kubernetes ?") print(answer)except Exception as e: print(e)Structure du projet
Section intitulée « Structure du projet »À ce stade, votre projet ressemble à :
lab-devops-buddy/├── .env # Clés API (ne pas commiter)├── venv/ # Environnement virtuel├── 01_question_simple.py # Premier appel├── 02_streaming.py # Streaming├── 03_conversation.py # Chatbot avec historique├── 04_multi_modeles.py # Test multi-providers└── 05_erreurs.py # Gestion des erreursÀ retenir
Section intitulée « À retenir »completion(): fonction centrale pour appeler n’importe quel LLMstream=True: affiche la réponse progressivement- Historique manuel : renvoyer tous les messages à chaque appel
- System prompt : définit la personnalité de l’assistant
- Changement de modèle : une seule ligne à modifier
Prochaines étapes
Section intitulée « Prochaines étapes »Notre assistant répond aux questions une par une. Dans le prochain guide, on va lui apprendre à analyser plusieurs fichiers en parallèle — idéal pour auditer des Dockerfiles ou des pipelines CI.