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 .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 :

  1. 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)
  2. Meilleure qualité : Pour tous les formats évalués, anydoc a obtenu les scores les plus élevés
  3. Couverture la plus complète : Le seul outil qui prend en charge les 14 formats
  4. 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)

BASH
# 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

BASH
pip install firecrawl-anydoc
PYTHON
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

BASH
npm install @firecrawl/anydoc
JAVASCRIPT
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

BASH
cargo add anydoc
RUST
// 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

PYTHON
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

PYTHON
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).

PYTHON
# 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 :

PYTHON
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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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é.