Retour à l’accueil

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.

Lecture audio non disponible dans ce navigateur
Ce que Building Shippy nous a appris sur la création d'agents

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/activate

Installez les dépendances principales :

pip install openai gitpython pydantic httpx redis celery

Ces 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/0

Chargez 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.content

4. 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=info

Exemples 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.txt

Exemple 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.content

Exemple 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.stderr

Leç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.