🤖 Agents IA

agent-browser-agent-builder

Construction d'agents de navigation web autonomes incluant scraping intelligent, interaction DOM et gestion de sessions.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- agent-browser-agent-builder --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } agent-browser-agent-builder -Launch"

🚀 Déjà installé ?

claude "/agent-browser-agent-builder"

Ou tapez /agent-browser-agent-builder dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

browser agentagent navigateuragent web autonomePuppeteer agent

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/agent-browser-agent-builder ~/.claude/skills/

Payload du plugin : skills/agent-browser-agent-builder · source éditable : agent-skills/browser-agent-builder

📖 Manuel

Browser Agent Builder

1. Choisir le framework

CritèrePlaywrightPuppeteerSelenium
Multi-navigateur✅ Chromium, Firefox, WebKit❌ Chrome/Edge uniquement✅ tous
Auto-wait natif❌ (manuel)❌ (manuel)
Interception réseauroute()setRequestInterception❌ limité
Support mobiledevices preset
Ecosystème / docExcellent (2024–2026)BonVieillissant

Décision : Playwright par défaut sur tout nouveau projet. Puppeteer si contrainte Chrome-only ou lib existante. Selenium uniquement legacy/Java.

# Installation Playwright (Node.js)
npm init -y && npm i -D playwright
npx playwright install chromium   # ou --with-deps pour CI

# Python
pip install playwright && playwright install chromium

2. Architecture de l'agent

┌───────────────────────────────────────────────┐
│                  Orchestrateur                │
│  (LLM : planifie, décide, retry si échec)     │
└────────┬──────────────┬────────────┬──────────┘
         │              │            │
    Navigation      Extraction   Mémoire/État
  (goto/click/fill) (DOM/vision) (cookies, historique)

Composants minimaux :

3. Implémenter l'interaction DOM robuste

// Sélecteurs stables — ordre de préférence
page.getByRole('button', { name: 'Valider' })      // 1er choix
page.getByTestId('submit-btn')                      // 2e choix
page.getByLabel('Email')                            // 3e choix
page.locator('[data-id="checkout"]')                // 4e choix
// Jamais : page.locator('.css-1a2b3c')             // ❌ généré dynamiquement

// Auto-wait + retry inclus dans Playwright — ne pas ajouter de sleep manuel
await page.getByRole('button', { name: 'Valider' }).click()

// Shadow DOM
const shadow = page.locator('my-component').locator('pierce=button')

// iFrame
const frame = page.frameLocator('#checkout-iframe')
await frame.getByLabel('Numéro carte').fill('4111111111111111')

4. Intégrer la vision LLM (multimodal)

Utiliser les screenshots quand le DOM est insuffisant (canvas, interfaces riches, CAPTCHAs visuels lisibles).

import Anthropic from '@anthropic-ai/sdk'

const client = new Anthropic()

async function describePageAndAct(page: Page): Promise<string> {
  const screenshot = await page.screenshot({ type: 'png' })
  const b64 = screenshot.toString('base64')

  const response = await client.messages.create({
    model: 'claude-sonnet-4-6',
    max_tokens: 512,
    messages: [{
      role: 'user',
      content: [
        { type: 'image', source: { type: 'base64', media_type: 'image/png', data: b64 } },
        { type: 'text', text: 'Quelle action faut-il effectuer ensuite pour compléter le formulaire ?' }
      ]
    }]
  })
  return (response.content[0] as any).text
}

Règle : vision = fallback coûteux — toujours tenter le sélecteur DOM d'abord.

5. Gestion de session et authentification

// Sauvegarder l'état de session après login
await page.context().storageState({ path: 'session.json' })

// Réutiliser à la session suivante
const context = await browser.newContext({
  storageState: 'session.json'
})

// TOTP (2FA) avec otplib
import { totp } from 'otplib'
const code = totp.generate(process.env.TOTP_SECRET!)
await page.getByLabel('Code OTP').fill(code)

6. Anti-détection — périmètre légal uniquement

// Playwright : stealth via playwright-extra
import { chromium } from 'playwright-extra'
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
chromium.use(StealthPlugin())

// Profil réaliste
const context = await chromium.launchPersistentContext('', {
  userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
  viewport: { width: 1366, height: 768 },
  locale: 'fr-FR',
  timezoneId: 'Africa/Tunis'
})

// Délais humains : randomiser, ne jamais fixer
const delay = (ms: number) => new Promise(r => setTimeout(r, ms))
await delay(500 + Math.random() * 1000)

7. Orchestration multi-pages et error recovery

async function withRetry<T>(fn: () => Promise<T>, maxAttempts = 3): Promise<T> {
  for (let i = 0; i < maxAttempts; i++) {
    try {
      return await fn()
    } catch (err) {
      if (i === maxAttempts - 1) throw err
      await page.screenshot({ path: `error_attempt_${i}.png` })
      await page.reload()
      await delay(2000)
    }
  }
  throw new Error('unreachable')
}

// State machine simple
type Step = 'login' | 'search' | 'extract' | 'done'
let step: Step = 'login'
while (step !== 'done') {
  switch (step) {
    case 'login':  await doLogin();  step = 'search'; break
    case 'search': await doSearch(); step = 'extract'; break
    case 'extract': await extract(); step = 'done'; break
  }
}

8. Tests et monitoring

// Playwright Test — test E2E du workflow critique
import { test, expect } from '@playwright/test'

test('workflow checkout complet', async ({ page }) => {
  await page.goto('https://shop.example.com')
  await page.getByRole('button', { name: 'Ajouter au panier' }).click()
  await expect(page.getByText('1 article')).toBeVisible()
})
# Lancer en CI (headless, reporters JUnit)
npx playwright test --reporter=junit --output=results.xml

Monitoring : alerter si taux d'échec > 5 % sur 1 h. Versionner les snapshots DOM avec des tests de régression sur les sélecteurs clés.

Anti-patterns / Pièges

Bonnes pratiques 2026