Pourquoi vous devez connaître anydoc
Lorsqu'on alimente de grands modèles linguistiques avec des documents, la qualité de la conversion de format influence directement les résultats RAG. Des tableaux mal alignés dans Word, des hiérarchies perdues dans PPT, des paragraphes cassés dans PDF – chaque problème de format peut considérablement réduire la précision de la recherche vectorielle. Auparavant, nous devions combiner plusieurs outils comme pandoc, python-docx et LibreOffice pour couvrir tant bien que mal les formats Office courants, avec un coût de maintenance élevé et des sorties incohérentes.
anydoc est une bibliothèque de conversion de documents développée de zéro en Rust par l'équipe Firecrawl. Un seul appel API convertit 14 formats avec un temps de conversion médian de seulement 4,4 millisecondes. Le projet a déjà dépassé les 12 000 étoiles sur GitHub et devient le nouveau standard pour le prétraitement de documents dans les chaînes d'outils RAG/LLM.
Les 14 formats pris en charge
anydoc offre la couverture de formats la plus large parmi tous les outils de conversion open source :
| Catégorie de format | Extensions prises en charge |
|---|---|
| Documents Word | .doc, .docx, .docm |
| Présentations PowerPoint | .ppt, .pps, .pot, .pptx, .pptm, .ppsx, .ppsm |
| Tableaux Excel | .xls, .xlsx, .xlsm, .xlsb |
| OpenDocument | .odt, .ods, .odp |
| Texte enrichi | .rtf |
| Livres numériques | .epub |
| Fichiers de données | .csv |
.pdf |
Notez que .doc (ancien format binaire) et .docx (nouveau format XML) sont tous deux pris en charge – c'est très rare parmi les outils comparables. La plupart des outils ne prennent en charge que .docx et sont impuissants face aux anciens fichiers .doc.
Test de performance : le secret des 4,4ms
Le benchmark officiel d'anydoc a comparé 7 outils (y compris lui-même) sur 100 documents réels couvrant les 14 formats :
| Outil | Formats pris en charge | Temps médian | Score qualité | Complétude | Structure | Formatage | Propreté |
|---|---|---|---|---|---|---|---|
| anydoc | 14/14 | 4,4ms | 81 | 87 | 79 | 78 | 81 |
| libreoffice | 12/14 | 1129,5ms | 40 | 59 | 42 | 40 | 24 |
| unstructured | 8/14 | 572,9ms | 63 | 76 | 59 | 51 | 63 |
| markitdown | 6/14 | 134,8ms | 65 | 78 | 66 | 60 | 52 |
| pandoc | 5/14 | 102,1ms | 56 | 74 | 57 | 56 | 38 |
| docling | 4/14 | 513,6ms | 57 | 60 | 60 | 57 | 51 |
| mammoth | 1/14 | 52,5ms | 70 | 84 | 71 | 75 | 51 |
Constatations clés :
- Vitesse écrasante : Les 4,4ms d'anydoc représentent 1/23 du temps de pandoc (102,1ms) et 1/257 du temps de LibreOffice (1129,5ms)
- Meilleure qualité : Pour tous les formats évalués, anydoc a obtenu les scores les plus élevés
- Couverture la plus complète : Le seul outil qui prend en charge les 14 formats
- Avantage Rust : Implémentation purement en Rust, aucune dépendance aux modèles ML, aucun appel de service externe
Le score de qualité a été déterminé par Claude Sonnet 5 en tant que juge LLM, comparant deux sorties en aveugle (basé sur les 6 premières pages rendues avec LibreOffice). Chaque outil a été évalué deux fois pour chaque paire de comparaison afin d'éliminer les biais de position – total de 482 évaluations.
Comparaison format par format : anydoc en tête partout
Les données suivantes montrent la comparaison directe des outils sur les mêmes formats (score maximum 100) :
| Format | anydoc | libreoffice | unstructured | markitdown | pandoc | docling | mammoth |
|---|---|---|---|---|---|---|---|
| .doc | 87 | 57 | 67 | - | - | - | - |
| .docx | 88 | 56 | 53 | 71 | 68 | 71 | 70 |
| .pptx | 74 | 24 | - | 66 | - | 52 | - |
| .xlsx | 72 | 30 | 66 | 55 | - | 47 | - |
| .rtf | 88 | 53 | 46 | - | 45 | - | - |
| .odt | 80 | 51 | 68 | - | 60 | - | - |
| .epub | 77 | - | 72 | 72 | 52 | - | - |
mammoth obtient un score de 70 sur .docx, ce qui semble bon – mais il ne prend en charge qu'un seul format. Les 81 points d'anydoc sont la moyenne sur les 14 formats, ce qui a une toute autre signification.
Installation et démarrage rapide
anydoc fournit un noyau Rust avec des bindings Node.js/Python/WebAssembly, ainsi qu'une CLI prête à l'emploi.
CLI (installation zéro)
# Exécuter directement avec npx, téléchargement automatique des binaires précompilés au premier lancement
npx @firecrawl/anydoc report.docx # Sortie sur stdout
npx @firecrawl/anydoc slides.pptx -o slides.md # Sortie dans un fichier
npx @firecrawl/anydoc - --format csv < data.csv # Lecture depuis stdin
Intégration Python
pip install firecrawl-anydoc
import anydoc
# Conversion depuis un chemin de fichier
markdown = anydoc.to_markdown("report.docx")
print(markdown)
# Conversion depuis des bytes (détection automatique de format)
with open("report.docx", "rb") as f:
data = f.read()
markdown = anydoc.to_markdown_bytes(data)
# Spécifier le format (requis pour les formats sans magic bytes comme CSV)
markdown = anydoc.to_markdown_bytes(csv_data, "csv")
# Obtenir le modèle de document (contient les images intégrées et autres ressources)
document = anydoc.to_document(data)
Intégration Node.js
npm install @firecrawl/anydoc
import { toMarkdown, toMarkdownBytes, toDocument } from '@firecrawl/anydoc';
// Depuis un chemin de fichier
const md = await toMarkdown('report.docx');
// Depuis des bytes
const mdFromBytes = await toMarkdownBytes(bytes);
// Obtenir le modèle de document (avec ressources intégrées)
const doc = await toDocument(bytes);
Utilisation native Rust
cargo add anydoc
// Depuis un chemin de fichier
let markdown = anydoc::to_markdown("report.docx")?;
// Depuis des bytes (détection automatique de format)
let markdown = anydoc::to_markdown_bytes(&bytes, None)?;
// Spécifier le format
let markdown = anydoc::to_markdown_bytes(&bytes, anydoc::Format::Csv)?;
Utilisation pratique avec LangChain / LlamaIndex
Dans un pipeline RAG, anydoc est typiquement utilisé comme étape préalable de chargement de documents, convertissant uniformément divers formats en Markdown avant le découpage en chunks et la vectorisation.
Avec LangChain
import anydoc
from langchain.text_splitter import MarkdownTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
# 1. Conversion Markdown unifiée avec anydoc
def load_documents(file_paths):
docs = []
for path in file_paths:
md = anydoc.to_markdown(path)
docs.append({"content": md, "source": path})
return docs
# 2. Découpage Markdown
splitter = MarkdownTextSplitter(chunk_size=1000, chunk_overlap=100)
raw_docs = load_documents(["report.docx", "slides.pptx", "data.xlsx"])
chunks = []
for doc in raw_docs:
chunks.extend(splitter.split_text(doc["content"]))
# 3. Vectorisation et stockage
embeddings = OpenAIEmbeddings()
db = FAISS.from_texts(chunks, embeddings)
db.save_local("./faiss_index")
Avec LlamaIndex
import anydoc
from llama_index.core import Document, VectorStoreIndex
# Conversion anydoc
file_paths = ["contract.docx", "presentation.pptx", "budget.xlsx"]
documents = []
for path in file_paths:
md = anydoc.to_markdown(path)
documents.append(Document(text=md, metadata={"source": path}))
# Indexation LlamaIndex
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("Quelles sont les clauses de pénalité dans le contrat ?")
print(response)
Bonnes pratiques pour les scénarios RAG
1. Utiliser to_document() pour les ressources intégrées
Lorsque les documents contiennent des images, le modèle de document retourné par to_document() conserve les données en bytes et le type de média des images. Vous pouvez :
- Extraire le texte alternatif des images comme contenu textuel
- Envoyer les images séparément à un modèle multimodal (comme GPT-4V) pour l'OCR
- Conserver les références URL des images (si les images ont des liens externes)
2. Tirer parti de la détection automatique de format
anydoc détecte le format via les magic bytes dans le contenu du fichier, pas via l'extension de fichier. Cela signifie qu'anydoc reconnaît et convertit correctement même si un fichier est mal nommé (par exemple, un .pdf qui est en fait un .docx).
# Détecter le format
fmt = anydoc.format_from_bytes(data) # Retourne l'enum Format
print(fmt) # Format.DOCX
3. Attention au GIL lors du traitement par lots
Les bindings Python libèrent le GIL, donc la conversion par lots avec plusieurs threads ne se bloque pas mutuellement :
import concurrent.futures
import anydoc
def convert(path):
return anydoc.to_markdown(path)
with concurrent.futures.ThreadPoolExecutor(max_workers=8) as executor:
results = list(executor.map(convert, file_paths))
4. Traitement des PDF scannés
anydoc intègre pdf-inspector qui détecte automatiquement si un PDF est basé sur du texte ou scanné. Pour les PDF textuels, l'extraction se fait directement ; pour les PDF scannés, il est recommandé de combiner avec l'API Parse de Firecrawl (avec capacités OCR).
Limitations et considérations
- Capacités limitées pour les PDF scannés : anydoc ne fait pas d'OCR lui-même. Les PDF scannés nécessitent un service OCR externe. L'API Parse de Firecrawl peut compléter ce point.
- Les mises en page complexes peuvent diverger : Pour les mises en page multi-colonnes ou les documents complexes avec beaucoup de mélange image-texte, les résultats de conversion peuvent être moins précis qu'avec des outils de mise en page professionnels. anydoc vise un texte structuré lisible par les LLM, pas une reproduction au pixel près.
- Ancien format .doc : Bien que pris en charge, la complexité d'analyse de .doc (format binaire OLE2) est plus élevée que pour .docx, ce qui peut entraîner une qualité de conversion légèrement inférieure.
- Pas d'amélioration ML : anydoc renonce délibérément aux modèles ML. Cela signifie qu'il n'utilise pas le deep learning pour l'analyse de mise en page comme docling ou marker. Avantage : vitesse élevée, pas de dépendance GPU. Inconvénient : capacité limitée à comprendre les mises en page complexes.
- Version WASM pour navigateur : La version WebAssembly s'exécute localement dans le navigateur, les fichiers ne quittent pas l'appareil de l'utilisateur – idéal pour les scénarios sensibles à la confidentialité. Cependant, la conversion de gros fichiers peut être limitée par la mémoire du navigateur.
Conclusion et évaluation
anydoc résout un problème très pratique : dans les pipelines RAG/LLM, il remplace par un outil léger, rapide et couvrant tous les formats le travail qui nécessitait auparavant de combiner quatre ou cinq bibliothèques.
Avantages : - Couverture complète de 14 formats, unique parmi les outils open source - Vitesse de conversion médiane de 4,4ms, 23 fois plus rapide que le deuxième - Scores de qualité leaders avec une cohérence de sortie élevée - Implémentation purement en Rust, aucune dépendance externe, pas de GPU nécessaire - Bindings disponibles pour Python/Node.js/Rust/WASM
Convient pour : - Les développeurs qui construisent des pipelines RAG et doivent traiter divers formats de documents uploadés - Les équipes qui ont besoin d'un format de sortie de document uniforme - Les scénarios en temps réel avec des exigences de vitesse de conversion - Les développeurs qui ne veulent pas maintenir plusieurs dépendances d'outils de conversion
GitHub : firecrawl/anydoc (12 000+ étoiles)
Questions fréquemment posées (FAQ)
Q1 : Quelle est la différence entre anydoc et pandoc ? pandoc est un outil de conversion de documents universel qui prend en charge un nombre extrêmement large de formats d'entrée et de sortie, mais avec une profondeur limitée pour chaque format. anydoc se concentre sur la conversion de documents Office en Markdown compatible LLM et offre une meilleure qualité de conversion pour les 14 formats pris en charge, une vitesse 23 fois supérieure, et est spécifiquement optimisé pour les scénarios RAG.
Q2 : anydoc nécessite-t-il un GPU ou des services externes ? Non. anydoc est une implémentation purement en Rust sans dépendance aux modèles ML et sans appels API externes. Il s'exécute localement avec un temps de conversion médian de 4,4ms par fichier.
Q3 : anydoc peut-il traiter les PDF scannés ? anydoc contient un pdf-inspector intégré pour traiter les PDF textuels. Pour les PDF scannés (basés sur des images), il est recommandé de combiner avec l'API Parse de Firecrawl (avec capacités OCR).
Q4 : À quoi ressemble le format de sortie d'anydoc ? La sortie est uniformément en GitHub Flavored Markdown (GFM) avec des hiérarchies de titres, des tableaux, des listes, des blocs de code, des liens et d'autres structures. Les 14 formats produisent un style de sortie cohérent.
Q5 : anydoc peut-il être exécuté dans un navigateur ? Oui. anydoc fournit une version WebAssembly (@firecrawl/anydoc-wasm). Les fichiers sont convertis localement dans le navigateur, sans upload vers un serveur – idéal pour les scénarios sensibles à la confidentialité.