Résumez cet article avec :
Une API de recherche donne des liens à votre agent. Transformer ces liens en données propres et structurées est un autre pipeline, et deux projets open source en couvrent désormais l'essentiel : Crawl4AI récupère et nettoie les pages, DeerFlow décide quoi lire. Voici comment ils s'assemblent, comment y brancher n'importe quel modèle, et les trois choses qui cassent un pipeline de crawl en production.
Chercher n'est pas lire
Un agent qui ne sait pas lire le web répond avec ce que son modèle a appris pendant l'entraînement. La plupart des équipes règlent le problème avec une API de recherche, et nous en avons comparé neuf dans Meilleures API de recherche Web pour agents IA. Mais une recherche renvoie des URL et des extraits. Il reste à ouvrir la page, exécuter son JavaScript, jeter les menus et les bandeaux de cookies, et transformer le reste en quelque chose qu'un modèle peut utiliser sans brûler des tokens sur des liens de navigation.
Cette deuxième moitié est un pipeline de collecte de données, en quatre étapes : trouver les URL qui valent la peine d'être lues, les récupérer et les afficher, nettoyer le résultat, puis extraire ce dont vous avez besoin. Deux projets open source sont devenus la façon standard de le construire. Crawl4AI s'occupe de la récupération et du nettoyage. DeerFlow est l'agent qui décide quoi chercher, quoi ouvrir et quand il en sait assez.
Crawl4AI : la couche qui récupère et nettoie
Crawl4AI est une bibliothèque Python, un outil en ligne de commande et un serveur Docker qui transforment des pages web en Markdown écrit pour les modèles de langage. Il est publié sous licence Apache 2.0 et comptait 85 514 étoiles sur GitHub le 14 octobre 2026, le jour de la sortie de la version 0.9.5. Sa documentation est très complète, voici donc les fonctions qui comptent le plus pour un pipeline d'agent.
Du Markdown filtré, pas du HTML brut. Chaque crawl renvoie du Markdown, et des filtres de contenu le réduisent avant qu'il atteigne un modèle : un filtre d'élagage qui retire les blocs sans valeur, un filtre BM25 qui garde les passages utiles pour une requête, et un filtre LLM pour les cas difficiles. Moins de liens de navigation dans le contexte, c'est moins de tokens facturés et moins de bruit pour le modèle.
Découvrir sans tout crawler. L'AsyncUrlSeeder lit les sitemaps d'un site et l'index de Common Crawl pour lister les URL candidates avant d'afficher la moindre page. Pour explorer plus loin, il existe des stratégies en largeur, en profondeur et best-first, avec un resume_state pour qu'un long crawl survive à un plantage.
Le crawl adaptatif. L'AdaptiveCrawler prend une requête et s'arrête dès qu'il a réuni de quoi y répondre, au lieu de crawler un nombre fixe de pages. Pour un agent, c'est la différence entre lire les trois pages utiles et payer l'affichage de deux cents.
Une extraction qui n'a pas besoin d'un modèle à chaque page. Crawl4AI extrait avec des schémas CSS ou XPath, qui ne coûtent rien par page. Sa fonction generate_schema utilise un LLM une seule fois pour écrire ce schéma, que vous réutilisez ensuite sur toutes les pages de même structure. Quand les pages varient trop pour des règles fixes, LLMExtractionStrategy remplit un schéma Pydantic avec n'importe quel modèle pris en charge par LiteLLM.
Pensé pour les agents. Le serveur Docker expose un endpoint MCP : Claude Code, Cursor ou n'importe quel client MCP peut appeler votre propre crawler comme un outil.
Un point de licence avant de l'intégrer à un produit : le README demande une attribution en plus de la licence Apache 2.0, sous forme d'un badge « Powered by Crawl4AI » ou d'une ligne dans votre documentation. Lisez le dépôt et voyez ce qui s'applique à votre cas.
DeerFlow : l'agent qui décide quoi lire
DeerFlow est le harness d'agents open source de ByteDance. La version 2.0 est une réécriture complète, qui ne partage aucun code avec le framework de deep research d'origine, et elle a pris la première place de GitHub Trending le 28 février 2026. Le projet est sous licence MIT, construit sur LangGraph et LangChain, et comptait 83 853 étoiles le 14 octobre 2026, avec une version 2.1.0 sortie le 24 septembre. Nous l'avons comparé aux plateformes d'agents commerciales dans DeerFlow vs plateformes commerciales d’agents IA.
Pour les données web, c'est sa couche d'outils qui compte. DeerFlow fournit un outil web_search avec plus d'une douzaine de fournisseurs interchangeables, de DuckDuckGo et SearXNG à Tavily, Exa et Firecrawl, et un outil web_fetch distinct avec dix backends, dont Jina Reader, Firecrawl, Browserless et un serveur Crawl4AI auto-hébergé. Recherche et récupération se configurent séparément : l'agent peut trouver les pages avec un fournisseur et les lire avec un autre. Un seul backend de récupération peut être actif à la fois.
Quand Crawl4AI sert de backend de récupération, DeerFlow reçoit directement son Markdown filtré, et vous choisissez le filtre dans la configuration : fit par défaut, ou raw, bm25 ou llm. La liste complète des options est dans le guide de configuration de DeerFlow.
Brancher les deux ensemble
Lancez Crawl4AI comme un service privé. Depuis la version 0.9, le serveur refuse les requêtes non authentifiées : générez un token et liez le port à la machine locale ou à votre réseau Docker interne, jamais à une interface publique.
# Lancer Crawl4AI comme service privé. Ne jamais exposer le port 11235 sur Internet.
export CRAWL4AI_TOKEN="$(openssl rand -hex 32)"
docker run -d --name crawl4ai -p 127.0.0.1:11235:11235 --shm-size=1g \
-e CRAWL4AI_API_TOKEN="$CRAWL4AI_TOKEN" \
unclecode/crawl4ai:0.9.5
Pointez ensuite DeerFlow vers lui. L'entrée du modèle utilise le client OpenAI de LangChain avec une base_url personnalisée, c'est ainsi que DeerFlow parle à n'importe quelle gateway compatible OpenAI. Ici, il passe par l'endpoint chat completions d'Eden AI : faire passer l'agent de Mistral à Claude ou GPT revient à changer une ligne, la chaîne model, avec la même clé et la même facture.
# config.yaml (DeerFlow 2.x) : le modèle via Eden AI, les pages via Crawl4AI
models:
- name: mistral-large
display_name: Mistral Large (via Eden AI)
use: langchain_openai:ChatOpenAI
model: mistral/mistral-large-latest
api_key: $EDENAI_API_KEY
base_url: https://api.edenai.run/v3
tools:
- name: web_fetch # un seul backend web_fetch actif à la fois
group: web
use: deerflow.community.crawl4ai.tools:web_fetch_tool
base_url: http://localhost:11235 # http://crawl4ai:11235 dans Docker Compose
token: $CRAWL4AI_TOKEN
timeout: 30
filter: fit # fit | raw | bm25 | llm
# DeerFlow refuse un backend privé tant que son trafic sortant n'est pas verrouillé :
# network_isolation_confirmed: true
En l'état, DeerFlow refusera d'utiliser ce backend : un crawler sur une adresse privée peut être retourné contre votre propre réseau, donc DeerFlow attend que vous confirmiez que son trafic sortant est verrouillé. La section suivante explique comment. Notez aussi que la configuration d'exemple de DeerFlow propose l'image Crawl4AI 0.9.2. Prenez plutôt la version actuelle.
L'extraction structurée, avec n'importe quel modèle
Tous les pipelines n'ont pas besoin d'un agent. Quand vous savez déjà quelles pages lire et quels champs en tirer, Crawl4AI suffit. L'exemple ci-dessous lit une page de versions et renvoie du JSON typé. Le préfixe openai/ indique à LiteLLM d'utiliser le format de requête OpenAI, et tout ce qui suit est le nom du modèle chez Eden AI.
import asyncio, os
from pydantic import BaseModel
from crawl4ai import AsyncWebCrawler, CacheMode, CrawlerRunConfig, LLMConfig, LLMExtractionStrategy
class Release(BaseModel):
version: str
date: str
highlights: list[str]
llm = LLMConfig(
# "openai/" indique à LiteLLM le format OpenAI ; la suite est l'identifiant du modèle chez Eden AI
provider="openai/mistral/mistral-small-latest",
api_token=os.environ["EDENAI_API_KEY"],
base_url="https://api.edenai.run/v3",
)
config = CrawlerRunConfig(
check_robots_txt=True, # désactivé par défaut dans Crawl4AI
cache_mode=CacheMode.ENABLED, # ne pas récupérer deux fois la même page
extraction_strategy=LLMExtractionStrategy(
llm_config=llm,
schema=Release.model_json_schema(),
extraction_type="schema",
instruction="Liste chaque version avec son numéro, sa date et ses principaux changements.",
),
)
async def main():
async with AsyncWebCrawler() as crawler:
result = await crawler.arun("https://github.com/unclecode/crawl4ai/releases", config=config)
print(result.extracted_content)
asyncio.run(main())
Deux réglages de cette configuration sont volontaires. check_robots_txt est désactivé par défaut dans Crawl4AI, et l'activer est la politesse minimale envers les sites que vous lisez. Le cache évite de récupérer deux fois la même page et de payer deux fois son extraction. Si les pages traitées contiennent des données personnelles ou réglementées, pointez base_url vers l'endpoint européen, https://api.eu.edenai.run/v3, qui n'envoie les requêtes qu'aux modèles autorisés pour la résidence des données dans l'UE et refuse les autres par un HTTP 451.
Trois choses qui cassent un pipeline de crawl open source
1. Le crawler est une surface d'attaque
Un crawler est un serveur qui récupère des URL arbitraires, suit des redirections et fait tourner un navigateur. C'est exactement ce qu'un attaquant cherche à atteindre. La page des avis de sécurité de Crawl4AI liste 19 avis publiés en 2026, dont cinq jugés critiques, parmi lesquels une exécution de code à distance sans authentification via les arguments de lancement du navigateur (CVE-2026-57572) et une traversée de répertoire dans les téléchargements pouvant mener à une exécution de code (CVE-2026-57571). Toutes sont corrigées à partir de la 0.9.4, et le projet est passé à des réglages sécurisés par défaut. La leçon n'est pas d'éviter Crawl4AI. C'est d'épingler une version récente, de la mettre à jour comme n'importe quel service exposé à Internet, et de garder son port privé.
Le deuxième risque est la falsification de requêtes côté serveur (SSRF). Votre crawler résout le DNS et suit les redirections de son côté, donc une page peut le renvoyer vers 169.254.169.254 ou vers une interface d'administration interne. DeerFlow gère bien ce point : il refuse de déléguer la récupération à un backend Crawl4AI, Firecrawl ou Browserless auto-hébergé tant que vous n'avez pas réglé network_isolation_confirmed: true, et sa documentation demande d'abord de bloquer les destinations privées, loopback, link-local et de métadonnées cloud. D'abord la politique de trafic sortant, ensuite le réglage, dans cet ordre.
2. Le consentement est devenu la règle
Le web n'est plus ouvert par défaut aux lecteurs automatisés. Depuis le 1er juillet 2025, Cloudflare bloque par défaut les crawlers IA connus sur les nouveaux domaines et permet aux éditeurs de faire payer l'accès avec pay per crawl. Un pipeline qui l'ignore finit avec des pages vides, des écrans de vérification et des plages d'IP bloquées.
En Europe, les règles vont dans le même sens. La directive sur le droit d'auteur permet aux ayants droit d'exclure leurs contenus de la fouille de textes et de données, de manière lisible par une machine, et le chapitre droit d'auteur du code de bonnes pratiques pour l'IA à usage général engage les fournisseurs de modèles signataires à utiliser des crawlers qui respectent le robots.txt tel que défini par la RFC 9309. Cet engagement vise l'entraînement des modèles, pas chaque agent qui lit une page, mais c'est l'étalon auquel votre pipeline sera comparé. Respectez le robots.txt, identifiez honnêtement votre crawler, limitez le débit par domaine, et préférez le fichier llms.txt quand un site en publie un précisément pour cet usage.
3. Chaque page est une entrée non fiable
Ce que votre agent lit, il peut aussi y obéir. Une page peut cacher des instructions dans du texte blanc, des attributs alt ou des commentaires, et un agent équipé d'outils les exécutera volontiers. Traitez le contenu récupéré comme des données, jamais comme des instructions : tenez l'agent qui lit le web à l'écart des outils qui ont des effets de bord, exécutez le code dans une sandbox, ce que DeerFlow fait par défaut, et relisez tout ce qui sort de votre système. Nous avons approfondi le sujet dans Securing AI Agents Against Document-Borne Prompt Injection.
Quand une API managée est le meilleur choix
L'auto-hébergement donne le contrôle et aucun coût par page, mais il a un prix bien réel : les navigateurs headless consomment de la mémoire, les sites protégés exigent des proxys, et la liste d'avis de sécurité ci-dessus montre le rythme de mises à jour auquel vous vous engagez. Pour beaucoup d'équipes, la bonne réponse est un mélange : l'open source pour les sites à fort volume qu'elles connaissent bien, une API managée pour tout le reste.
Si vous êtes dans la même situation que la plupart des équipes avec qui nous échangeons, vous avez besoin de crawl web dans un agent, vous ne voulez pas faire tourner des navigateurs vous-même, et les noms qui reviennent sont Tavily, Firecrawl et Linkup. Ils répondent au même besoin sous des angles différents. Tavily est une API de recherche pensée pour les agents, qui peut renvoyer le contenu des pages avec les liens. Firecrawl transforme une URL ou un site entier en Markdown propre, et sait crawler, cartographier un site et extraire selon un schéma. Linkup associe la recherche à un endpoint de récupération qui lit une page à la fois. Inutile de choisir d'avance : via Eden AI, les trois sont derrière la même clé API, vous pouvez prendre Tavily pour la recherche, Firecrawl pour le crawl et Linkup pour les pages isolées, les comparer sur vos propres URL, et passer de l'un à l'autre en changeant une chaîne.
Concrètement, Eden AI propose des endpoints web managés derrière la même clé que ses LLM : scraping, plans de site, crawl, scraping par lots, extraction structurée, recherche et deep research, servis par Firecrawl, Linkup et Tavily. Firecrawl est lui-même open source, sous licence AGPL-3.0, une licence qui impose des obligations si vous le modifiez et le proposez sur un réseau : la voie managée est aussi une façon de l'utiliser sans le faire tourner. Changer de fournisseur revient à changer la chaîne model.
import os, requests
response = requests.post(
"https://api.edenai.run/v3/universal-ai",
headers={"Authorization": f"Bearer {os.environ['EDENAI_API_KEY']}"},
json={
"model": "web/scraping/firecrawl", # ou web/scraping/linkup
"input": {"url": "https://docs.crawl4ai.com"},
},
)
print(response.json()["output"]["content"][:500])
En bref
La recherche trouve les pages, Crawl4AI les lit, DeerFlow décide lesquelles valent la peine d'être lues, et un modèle en tire des réponses. Les trois couches peuvent être open source, et la couche modèle peut être le fournisseur de votre choix, via un seul endpoint compatible OpenAI. Ce qui fait la différence en production, ce n'est pas la liste d'outils mais la discipline autour : des versions à jour, un réseau verrouillé, le respect du robots.txt, et un contenu récupéré traité comme une entrée non fiable.
Pour essayer côté modèle, créez votre clé API Eden AI et pointez la base_url de l'un ou l'autre outil vers https://api.edenai.run/v3.




