Ce que Building Shippy nous a appris sur la création d'agents
Les leçons tirées du développement de Shippy, un agent IA pour la logistique, révèlent que la conception modulaire, la validation avec intervention humaine et la gestion de l'ambiguïté du monde réel sont essentielles pour construire des agents fiables et évolutifs.
Tags
Résumé rapide
Les leçons tirées du développement de Shippy, un agent IA pour la logistique, révèlent que la conception modulaire, la validation avec intervention humaine et la gestion de l'ambiguïté du monde réel sont essentielles pour construire des agents fiables et évolutifs.
Ce que la construction de Shippy nous a appris sur la création d'agents
Créer des agents IA fiables est l'un des problèmes les plus difficiles de l'apprentissage automatique appliqué aujourd'hui. Au cours de l'année écoulée, notre équipe a développé Shippy, un agent open source conçu pour automatiser les workflows de livraison logicielle — de la revue de code au déploiement. Ce qui a commencé comme une simple preuve de concept s'est transformé en une formation approfondie sur l'architecture des agents, la gestion des erreurs et la conception système. Cet article partage les leçons pratiques que nous avons apprises, avec des exemples de code concrets et des étapes de configuration que vous pouvez appliquer à vos propres projets d'agents.
Le problème que nous voulions résoudre
Livrer un logiciel implique des dizaines de tâches répétitives : linting, exécution de tests, mise à jour des changelogs, incrémentation de versions et déclenchement de déploiements. La plupart des équipes utilisent des pipelines CI/CD, mais ces pipelines sont fragiles — ils cassent quand un test est instable, qu'une dépendance change ou qu'un fichier de configuration est déplacé. Nous voulions un agent capable non seulement d'exécuter ces étapes, mais aussi de se remettre des échecs, de communiquer son état et de s'adapter à de nouvelles structures de projet sans intervention manuelle.
L'objectif était ambitieux : construire un agent capable de cloner un dépôt, comprendre son système de build, exécuter des tests, corriger les problèmes courants et ouvrir une pull request avec la correction — le tout sans intervention humaine au-delà de l'objectif initial.
Prérequis
Avant de plonger dans l'implémentation, voici les prérequis essentiels pour construire un agent comme Shippy :
- **Python 3.10+** – La logique de l'agent est écrite en Python, utilisant des motifs asynchrones pour l'exécution parallèle des tâches.
- **Git** – L'agent doit pouvoir cloner, commiter et pousser vers des dépôts.
- **Clé API OpenAI** – Nous avons utilisé GPT-4 pour le raisonnement et la génération de code, mais n'importe quelle API LLM fonctionne.
- **Docker** (optionnel) – Pour exécuter les tests dans des environnements isolés.
- **Une file d'attente de tâches** – Nous avons utilisé Redis + Celery pour gérer les tâches longues de manière asynchrone.
- **Node.js 18+** – Requis uniquement si votre agent doit interagir avec des projets JavaScript/TypeScript.
Installation pas à pas
Parcourons la configuration d'une version minimale de Shippy sur votre machine locale. Cela vous donnera un agent fonctionnel capable de cloner un dépôt, d'analyser sa structure et de proposer une correction pour un test défaillant.
1. Créer un environnement virtuel et installer les dépendances
Commencez par configurer un environnement Python isolé :
python3 -m venv shippy-env
source shippy-env/bin/activateInstallez les dépendances principales :
pip install openai gitpython pydantic httpx redis celeryCes paquets fournissent l'interface LLM (`openai`), les opérations Git (`gitpython`), la validation des données (`pydantic`), les requêtes HTTP (`httpx`) et la gestion asynchrone des tâches (`redis`, `celery`).
2. Configurer les variables d'environnement
Créez un fichier `.env` à la racine de votre projet :
OPENAI_API_KEY=sk-votre-clé-ici
GITHUB_TOKEN=ghp_votre-token-ici
REDIS_URL=redis://localhost:6379/0Chargez ces variables dans votre code Python :
import os
from dotenv import load_dotenv
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
REDIS_URL = os.getenv("REDIS_URL")3. Configurer le cœur de l'agent
Créez `agent.py` avec la classe agent de base :
from openai import OpenAI
from git import Repo
import json
class ShippyAgent:
def __init__(self, api_key: str, github_token: str):
self.client = OpenAI(api_key=api_key)
self.github_token = github_token
def clone_repo(self, repo_url: str, local_path: str) -> Repo:
"""Clone un dépôt GitHub vers un chemin local."""
repo = Repo.clone_from(
repo_url,
local_path,
env={"GIT_ASKPASS": "echo", "GITHUB_TOKEN": self.github_token}
)
return repo
def analyze_project(self, repo_path: str) -> dict:
"""Analyse la structure du projet pour comprendre le système de build."""
import os
files = os.listdir(repo_path)
structure = {}
if "package.json" in files:
structure["type"] = "node"
elif "pyproject.toml" in files:
structure["type"] = "python"
elif "Cargo.toml" in files:
structure["type"] = "rust"
else:
structure["type"] = "inconnu"
return structure
def generate_fix(self, error_log: str, project_type: str) -> str:
"""Utilise un LLM pour générer une correction pour une erreur donnée."""
prompt = f"""
Vous êtes un ingénieur logiciel senior. À partir de ce journal d'erreurs d'un projet {project_type}, suggérez une correction de code.
Journal d'erreurs :
{error_log}
Fournissez la correction sous forme de diff ou de modification de code.
"""
response = self.client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}],
temperature=0.2
)
return response.choices[0].message.content4. Ajouter une file d'attente de tâches pour les opérations longues
Créez `tasks.py` pour le traitement en arrière-plan :
from celery import Celery
from agent import ShippyAgent
app = Celery('shippy', broker='redis://localhost:6379/0')
@app.task
def fix_repo(repo_url: str, error_log: str):
agent = ShippyAgent(
api_key="votre-clé-openai",
github_token="votre-token-github"
)
local_path = "/tmp/repos/" + repo_url.split("/")[-1].replace(".git", "")
repo = agent.clone_repo(repo_url, local_path)
structure = agent.analyze_project(local_path)
fix = agent.generate_fix(error_log, structure["type"])
# Appliquer la correction et créer une PR (simplifié)
with open(f"{local_path}/fix.patch", "w") as f:
f.write(fix)
return {"status": "correction_générée", "patch_file": "fix.patch"}Lancez le worker Celery :
celery -A tasks worker --loglevel=infoExemples d'utilisation
Voyons maintenant Shippy en action avec des scénarios concrets.
Exemple 1 : Corriger un test Python défaillant
Supposons que vous ayez un projet Python où les tests échouent à cause d'un import manquant. Lancez l'agent :
from agent import ShippyAgent
agent = ShippyAgent(
api_key="sk-votre-clé",
github_token="ghp_votre-token"
)
erreur = """
ModuleNotFoundError: No module named 'requests'
Fichier: tests/test_api.py, ligne 3
"""
resultat = agent.generate_fix(erreur, "python")
print(resultat)
# Sortie : Ajoutez `import requests` en haut de test_api.py, ou ajoutez `requests` à requirements.txtExemple 2 : Automatiser une revue de code
L'agent peut également relire les pull requests. Voici un réviseur de PR minimal :
def review_pr(repo_url: str, pr_number: int):
# Cloner la branche de la PR
repo = agent.clone_repo(repo_url, "/tmp/pr-review")
# Obtenir le diff
diff = repo.git.diff("main", "feature-branch")
# Demander au LLM de relire
prompt = f"Relisez ce diff et listez les éventuels problèmes :\n{diff}"
response = agent.client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.contentExemple 3 : Exécution dans Docker pour l'isolation
Pour exécuter les tests en toute sécurité sans affecter votre système hôte, utilisez Docker :
docker run --rm -v $(pwd):/workspace python:3.11 bash -c "cd /workspace && pip install -r requirements.txt && pytest"Intégrez cela dans l'agent :
import subprocess
def run_tests_in_docker(repo_path: str) -> str:
resultat = subprocess.run(
["docker", "run", "--rm", "-v", f"{repo_path}:/workspace", "python:3.11",
"bash", "-c", "cd /workspace && pip install -r requirements.txt && pytest"],
capture_output=True, text=True
)
return resultat.stdout + resultat.stderrLeçons clés apprises
1. Les agents ont besoin d'une récupération d'erreur robuste
La première version de Shippy supposait que chaque étape réussirait. Ce n'était pas le cas. Nous avons appris à implémenter une logique de réessai avec backoff exponentiel. Par exemple, si un clone Git échoue à cause de problèmes réseau, réessayez jusqu'à trois fois :
import time
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
def clone_with_retry(repo_url, local_path):
return Repo.clone_from(repo_url, local_path)2. Le contexte est primordial
Les LLM sont puissants mais manquent de connaissances spécifiques au projet. Nous avons constaté que fournir à l'agent le README du projet, l'historique des commits récents et la configuration CI améliorait considérablement la qualité des corrections. Nous avons ajouté une étape de "collecte de contexte" qui lit ces fichiers avant de générer une réponse.
3. Tester dans des environnements proches de la production
Exécuter des agents sur votre ordinateur portable est acceptable pour le prototypage, mais la production nécessite une isolation. Les conteneurs Docker pour chaque tâche ont empêché la pollution d'état entre les exécutions. Nous avons également ajouté des timeouts pour éviter les agents incontrôlables :
from concurrent.futures import TimeoutError
with timeout(seconds=120):
resultat = agent.run_task()4. L'humain dans la boucle reste essentiel
Malgré des résultats impressionnants, l'agent produisait parfois des corrections absurdes. Nous avons ajouté une étape de relecture où l'agent génère une PR, mais un humain doit l'approuver avant de la fusionner. Cela équilibre automatisation et sécurité.
5. La surveillance et la journalisation sont non négociables
Nous avons instrumenté chaque action de l'agent avec une journalisation structurée. Cela nous a permis de déboguer les échecs et d'améliorer les invites au fil du temps. Utilisez le module `logging` de Python avec un formateur JSON :
import logging
import json
class JsonFormatter(logging.Formatter):
def format(self, record):
return json.dumps(record.__dict__)
logger = logging.getLogger("shippy")
handler = logging.StreamHandler()
handler.setFormatter(JsonFormatter())
logger.addHandler(handler)Conclusion
Construire Shippy nous a appris que les agents IA ne sont pas magiques — ce sont des systèmes soigneusement conçus qui combinent le raisonnement des LLM avec des pratiques d'ingénierie robustes. La leçon la plus importante est que la fiabilité des agents vient de l'infrastructure, pas seulement du modèle. La logique de réessai, la collecte de contexte, l'isolation et la supervision humaine ont transformé un prototype fragile en un outil utile.
Si vous construisez votre propre agent, commencez petit. Clonez un dépôt, exécutez un test, corrigez un seul problème. Ajoutez ensuite la gestion des erreurs. Puis la surveillance. Puis la fonctionnalité suivante. Le chemin de la démo à la production est pavé de cas particuliers, mais le voyage en vaut la peine. Les agents capables de livrer des logiciels de manière autonome ne sont pas de la science-fiction — ce sont simplement de bonnes pratiques d'ingénierie.
*Pour approfondir les motifs de conception d'agents, consultez le blog Hugging Face, OpenAI News, le blog Microsoft AI et Anthropic News.*
Sources
FAQ
De quoi parle cet article ?
Cet article traite de « Ce que Building Shippy nous a appris sur la création d'agents » dans la catégorie Agents IA. Les leçons tirées du développement de Shippy, un agent IA pour la logistique, révèlent que la conception modulaire, la validation avec intervention humaine et la gestion de l'ambiguïté du monde réel sont essentielles pour construire des agents fiables et évolutifs.
À qui cet article est-il utile ?
Il est utile aux lecteurs qui veulent comprendre les outils et usages de l’IA de façon pratique.
Que faire ensuite ?
Lisez l’article, vérifiez les sources indiquées, puis testez les idées pertinentes pour votre contexte.



