Aller au contenu principal

Premier workflow : naviguer et interagir

Votre premier agent Computer Use

Dans cette leçon, vous allez construire un workflow complet : un agent qui navigue sur un site web, lit son contenu et effectue des actions. Vous assemblerez les briques vues dans les leçons précédentes en un programme fonctionnel.

Le scénario

Votre agent va :

  1. Ouvrir un moteur de recherche
  2. Taper une requête
  3. Cliquer sur le premier résultat
  4. Lire le titre de la page atteinte

C’est un scénario simple mais il couvre toutes les actions fondamentales : navigation, frappe, clic et extraction d’information.

L’exécuteur d’actions

D’abord, créez la fonction qui traduit les décisions du modèle en actions réelles sur le navigateur :

import time

def execute_action(page, action: dict):
    """Exécute une action Computer Use sur le navigateur."""
    action_type = action.get("action")
    
    if action_type == "click":
        x, y = action["coordinate"]
        page.mouse.click(x, y)
        time.sleep(0.5)  # Attendre la réaction de l'UI
    
    elif action_type == "type":
        page.keyboard.type(action["text"], delay=50)
    
    elif action_type == "key":
        page.keyboard.press(action["key"])
    
    elif action_type == "scroll":
        x, y = action["coordinate"]
        direction = action.get("direction", "down")
        amount = action.get("amount", 3)
        delta = -amount * 100 if direction == "up" else amount * 100
        page.mouse.wheel(0, delta)
        time.sleep(0.3)
    
    elif action_type == "screenshot":
        pass  # Le screenshot sera pris au prochain tour de boucle
    
    else:
        print(f"Action inconnue : {action_type}")

Le time.sleep() après chaque action est important : il laisse le temps à la page de réagir avant le prochain screenshot.

La boucle complète

Voici l’agent complet qui orchestre la boucle :

import anthropic
import base64
from playwright.sync_api import sync_playwright

client = anthropic.Anthropic()
DISPLAY_WIDTH = 1280
DISPLAY_HEIGHT = 720
MAX_ITERATIONS = 15

def run_agent(task: str, start_url: str = "https://www.google.com"):
    """Lance un agent Computer Use sur une tâche donnée."""
    pw = sync_playwright().start()
    browser = pw.chromium.launch(headless=False)  # False pour observer
    page = browser.new_page(viewport={
        "width": DISPLAY_WIDTH, "height": DISPLAY_HEIGHT
    })
    page.goto(start_url)
    
    messages = []
    tools = [{
        "type": "computer_20241022",
        "name": "computer",
        "display_width_px": DISPLAY_WIDTH,
        "display_height_px": DISPLAY_HEIGHT,
    }]
    
    for i in range(MAX_ITERATIONS):
        # Capturer l'écran
        screenshot_bytes = page.screenshot()
        screenshot_b64 = base64.b64encode(screenshot_bytes).decode("utf-8")
        
        # Construire le message
        if i == 0:
            content = [
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": "image/png",
                        "data": screenshot_b64,
                    }
                },
                {"type": "text", "text": task}
            ]
        else:
            content = [
                {
                    "type": "tool_result",
                    "tool_use_id": last_tool_use_id,
                    "content": [{
                        "type": "image",
                        "source": {
                            "type": "base64",
                            "media_type": "image/png",
                            "data": screenshot_b64,
                        }
                    }]
                }
            ]
        
        messages.append({"role": "user", "content": content})
        
        # Appeler le modèle
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=1024,
            tools=tools,
            messages=messages,
        )
        
        # Ajouter la réponse à l'historique
        messages.append({"role": "assistant", "content": response.content})
        
        # Vérifier si la tâche est terminée
        if response.stop_reason == "end_turn":
            final_text = ""
            for block in response.content:
                if hasattr(block, "text"):
                    final_text += block.text
            print(f"Tâche terminée : {final_text}")
            break
        
        # Exécuter les actions
        for block in response.content:
            if block.type == "tool_use":
                last_tool_use_id = block.id
                print(f"  Action : {block.input.get('action')} "
                      f"— {block.input}")
                execute_action(page, block.input)
    
    browser.close()
    pw.stop()

Lancer le workflow

if __name__ == "__main__":
    run_agent(
        task=(
            "Recherche Computer Use Anthropic sur Google, "
            "puis clique sur le premier résultat. "
            "Dis-moi le titre de la page."
        )
    )

Quand vous exécutez ce script avec headless=False, vous verrez le navigateur s’ouvrir, la recherche se taper, le clic se faire, et le modèle vous rapporter le titre de la page atteinte.

Déboguer les problèmes courants

L’IA clique au mauvais endroit

Vérifiez que display_width_px et display_height_px correspondent exactement au viewport de Playwright. Une différence de même 1 pixel peut décaler les coordonnées.

L’IA tourne en boucle

Ajoutez un compteur d’itérations maximum (comme MAX_ITERATIONS dans l’exemple) et un mécanisme de détection de boucle : si le même screenshot revient 3 fois, arrêtez l’agent.

La page n’a pas fini de charger

Ajoutez une attente après la navigation :

page.goto(url)
page.wait_for_load_state("networkidle")

Points clés à retenir

  • Un agent Computer Use combine un exécuteur d’actions, une boucle de contrôle et un historique de messages
  • Le premier message contient le screenshot initial et la tâche ; les suivants contiennent les résultats des outils
  • Limitez toujours le nombre d’itérations pour éviter les boucles infinies
  • Utilisez headless=False pendant le développement pour observer le comportement de l’agent