DocETL : pipelines déclaratifs pour traiter des documents avec des LLM
A system for agentic LLM-powered data processing and ETL
En bref
- De quoi s’agit-il ?
- DocETL transforme des opérations décrites en langage naturel (map, reduce, filter, resolve) en pipelines exécutés sur des collections de documents, avec une couche d'optimisation automatique. Le projet est jeune, la documentation est dense, et l'adoption suppose d'accepter un coût en appels LLM qui reste à mesurer soi-même.
- À qui s’adresse-t-il ?
- DocETL convient aux équipes qui traitent déjà des volumes de documents non structurés et qui veulent décrire leurs transformations en langage naturel plutôt que d'écrire chaque appel LLM à la main. Il ne convient pas si vous n'avez pas de clé de fournisseur LLM, si vos données tiennent dans un tableur, ou si vous avez besoin d'un débit déterministe sans coût variable.
- Puis-je l’utiliser commercialement ?
- Oui. MIT est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de licence.
- Est-il encore maintenu ?
- Oui. Les derniers commits datent d’il y a 10 jours.
- En quel langage est-il écrit ?
- Principalement Python, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Le problème : écrire à la main des appels LLM sur des collections
Traiter un lot de tickets, de transcriptions ou de PDF avec un LLM implique aujourd'hui d'écrire soi-même chaque appel, de le paralléliser, de gérer les limites de débit, puis de réconcilier les sorties. DocETL part du constat inverse : l'utilisateur décrit chaque opération en langage naturel, par exemple extraire toutes les plaintes d'un ticket, et la bibliothèque fournit les opérateurs (map, reduce, filter, resolve, split, gather, extract) et orchestre leur exécution en parallèle sur la collection. Le public visé est donc celui qui a déjà des données non structurées en volume et qui veut raisonner en étapes de pipeline plutôt qu'en boucles d'appels API. Le README résume la promesse ainsi : sans DocETL, il faut écrire chaque appel LLM, les relier, puis régler à la main l'équilibre entre précision, coût et latence.
Map, reduce, resolve : ce que fait réellement le moteur
Le mécanisme visible dans le matériel est un modèle map-reduce étendu. Un pipeline commence par une source (docetl.read_json dans l'API Python, ou un bloc datasets en YAML), puis chaque opération transforme la collection. L'exemple du README enchaîne deux étapes : un map qui classe chaque ticket et produit un schéma typé (category, priority), puis un reduce qui regroupe par reduce_key et résume les tickets d'une même catégorie. Le schéma de sortie est déclaré explicitement, ce qui laisse le moteur valider la forme des résultats au lieu de renvoyer du texte libre. Le README mentionne aussi des opérateurs supplémentaires (resolve, split, gather, extract) sans en détailler la sémantique dans le texte fourni. La couche d'optimisation, nommée MOAR dans la documentation et rattachée à un article VLDB 2026, est décrite comme capable de changer de modèle, de réécrire les prompts, de décomposer les opérations et de remplacer certaines sous-tâches par du code. C'est la partie la plus intéressante du projet, et aussi la moins vérifiable depuis le seul README : le document renvoie à une page Optimization sans exposer les critères de décision.
Deux façons de décrire un pipeline : Python ou YAML
L'API Python est présentée comme la voie recommandée pour la production, les notebooks et les scripts. On fixe un modèle par défaut avec docetl.default_model, on borne la charge avec docetl.rate_limits, qui accepte deux compteurs distincts, llm_call et llm_tokens, chacun exprimé en nombre par unité de temps. Le README donne cet exemple : cinq cents appels et deux cent mille tokens par minute. On construit ensuite le pipeline par enchaînement d'appels, puis on inspecte le résultat avec pipeline.schema(), on teste sur un petit lot avec pipeline.show(), et on lance l'exécution complète avec pipeline.collect(). Le coût cumulé est exposé via pipeline.total_cost. La variante YAML couvre le même terrain sans Python : un bloc datasets, un default_model, une liste operations avec name, type, prompt et output.schema, puis un bloc pipeline avec steps et output. L'exécution passe par docetl run pipeline.yaml. Cette séparation entre prototypage Python et configuration déclarative est cohérente, mais elle implique deux surfaces d'API à suivre lors des mises à jour.
Installation et limites de débit : ce que la doc impose
L'installation tient en deux commandes : pip install docetl, puis l'export d'une clé de fournisseur, par exemple OPENAI_API_KEY. Le README précise qu'une clé de n'importe quel fournisseur LLM convient, sans lister lesquels ni comment les configurer, ce qui est un manque réel si vous n'utilisez pas OpenAI. Pour le développement, le dépôt se clone, puis make install et make tests-basic, dont le README indique un coût inférieur à un centime avec OpenAI. Ce chiffre ne concerne que la suite de tests du projet, pas vos propres pipelines. Le point de friction le plus concret reste la régulation du débit : sans bloc rate_limits, rien dans le matériel fourni n'indique comment DocETL se comporte face à une limite atteinte. C'est le genre de détail qu'il faut vérifier sur un échantillon avant de lancer un traitement complet.
Là où DocETL n'est pas le bon outil
Trois cas de figure ressortent du matériel. D'abord, si vos données sont déjà structurées et que vos transformations s'expriment en SQL, la couche LLM ajoute un coût variable et une variabilité de sortie sans bénéfice : le README positionne DocETL sur des données structurées et non structurées, mais l'intérêt vient des secondes. Ensuite, si vous avez besoin d'un résultat strictement reproductible, la réécriture de prompts et la substitution de sous-tâches par du code, décrites dans la couche d'optimisation, introduisent un écart entre ce que vous écrivez et ce qui est exécuté. Le README ne documente pas de mode désactivant cette optimisation, ni de journal des réécritures appliquées. Enfin, l'absence de détail sur la gestion des erreurs par opérateur dans le texte fourni laisse ouverte la question du comportement quand un map échoue sur une partie des documents. Ces points ne disqualifient pas l'outil, mais ils déplacent la charge de vérification vers l'utilisateur.
Face à une chaîne maison ou à un orchestrateur générique
L'alternative la plus directe est le script maison : une boucle Python qui appelle le fournisseur, avec sa propre gestion de parallélisme et de reprise. La différence n'est pas la qualité du résultat, c'est la nature du travail. Un script maison vous donne un contrôle total sur chaque prompt et chaque appel, au prix de l'écriture et de la maintenance de la plomberie. DocETL déplace cette plomberie dans la bibliothèque et ajoute une couche d'optimisation que vous ne contrôlez pas finement. Un orchestrateur de workflows générique, lui, raisonne en tâches et en dépendances, pas en opérateurs sémantiques : il ne sait pas qu'un reduce regroupe par clé ni qu'un schéma de sortie doit être validé. Le choix se joue donc sur une question simple : voulez-vous décrire des transformations sémantiques et laisser le moteur choisir les modèles, ou voulez-vous garder la main sur chaque appel et utiliser un orchestrateur pour l'ordonnancement.
Maintenance, versions et licence MIT
Le dépôt est actif : dernier push en septembre 2026, version 0.3.0 publiée en juin 2026, après 0.2.6 en décembre 2025 et 0.2.5 en août 2025. Le rythme est irrégulier, avec environ six mois entre 0.2.5 et 0.2.6, puis six mois jusqu'à 0.3.0. Une numérotation en 0.x signifie que des ruptures d'API restent possibles entre versions mineures, ce qui a un coût direct si vous figez un pipeline YAML ou un enchaînement Python. La licence est MIT, ce qui autorise l'usage commercial et la modification, avec l'obligation de conserver l'avis de copyright et le texte de la licence. Le README ne mentionne aucune clause additionnelle ni dépendance à licence restrictive, mais il ne détaille pas non plus les dépendances tierces : à vérifier dans le fichier de dépendances du dépôt si votre organisation filtre les licences. Le projet est rattaché à des publications académiques (VLDB 2025, UIST 2025, VLDB 2026), ce qui indique une trajectoire de recherche plutôt qu'un produit stabilisé.
Conclusion éditoriale
DocETL convient aux équipes qui traitent déjà des volumes de documents non structurés et qui veulent décrire leurs transformations en langage naturel plutôt que d'écrire chaque appel LLM à la main. Il ne convient pas si vous n'avez pas de clé de fournisseur LLM, si vos données tiennent dans un tableur, ou si vous avez besoin d'un débit déterministe sans coût variable. Avant d'adopter, vérifiez trois choses concrètes : que le pipeline tourne avec docetl run pipeline.yaml sur un échantillon de vos propres fichiers, que pipeline.total_cost reste dans votre budget après un pipeline.show() sur cinq documents, et que les opérateurs dont vous avez besoin figurent bien dans la liste documentée (map, filter, reduce, resolve, split, gather, extract).
Notes de la communauté