anydoc: 14 Dokumentformate in Millisekunden nach Markdown konvertieren
Ein Blick auf anydoc von Firecrawl, geschrieben in Rust: wie schnell es docx, pptx, xlsx und PDF auf einem frischen Testset in Markdown umwandelt, was schiefgeht und wie man es einsetzt.
Firecrawl hat einen Dokumentkonverter namens anydoc als Open Source veröffentlicht, und die Zahlen dazu sind beeindruckend. Eine docx-Datei über LibreOffice umzuwandeln, bevor sie an ein Modell geht, kann pro Datei über eine Sekunde dauern, manuelle Schritte nicht mitgerechnet. anydoc drückt den Median über 14 gängige Formate auf 4,4 Millisekunden und liefert immer dieselbe Variante von Markdown im GitHub-Stil.
Was es ist
Das ist kein weiterer Konverter nach dem Motto „reicht schon“. Die gesamte Pipeline wurde in reinem Rust neu geschrieben. Word, PowerPoint, Excel, OpenDocument, RTF, EPUB, CSV und PDF werden auf ein gemeinsames Dokumentmodell abgebildet, und ein einziger Serializer schreibt die Ausgabe. Eine alte .doc von 2003 und eine gestern exportierte .pptx sehen deshalb gleich aus: Überschriftenebenen, verbundene Zellen, Fußnoten und Aufgabenlisten verhalten sich identisch. Alles läuft lokal, ruft keine externen Dienste auf und nutzt keine Machine-Learning-Modelle.
Verbreitet ist die Annahme, Dokumente zu parsen brauche eine Kette zusammengeflickter Tools oder einen Umweg über die Cloud. Diese Geschwindigkeit und Qualität sind aber auf dem eigenen Rechner erreichbar. anydoc treibt bereits den Parse-Endpunkt von Firecrawl selbst an, wo nur gescannte PDFs einen zusätzlichen OCR-Schritt brauchen. Textbasierte PDFs und Office-Dateien werden lokal in einem Durchgang verarbeitet.
Die Angaben an einem frischen Korpus prüfen
Der Benchmark des Herstellers lässt sich nicht nachstellen. Laut README dürfen die 100 Dateien nicht weitergegeben werden und liegen nicht im Repository. Also wurde ein neues Testset zusammengestellt: 40 Dateien pro Format, jede unter 25 MB.
Das ergab 206 Dateien, von denen 194 erfolgreich konvertiert wurden.
Das zentrale Versprechen eines Medians unter 5 ms gilt nur für csv und xlsx. Der Median für docx lag bei 6,4 ms, pptx und pdf kamen jeweils auf 22. Die langsamste pptx brauchte 346 ms, eine große Datei in einer Stichprobe, die auch Exemplare über zweihundert Megabyte enthielt. Die 5 ms sind ein Median über den gesamten gemischten Korpus, und zeilenorientierte Formate wie csv ziehen ihn nach unten.
Praktisch heißt das: Tausend docx-Dateien dauern etwa 6 Sekunden, tausend PowerPoint-Dateien über zwanzig. Beides ist schnell, aber planen sollte man mit den langsameren Werten.
Acht der zwölf Fehlschläge gingen nicht auf das Konto des Tools. Diese acht Dateien meldeten malformed, also wurde jede mit dem Befehl file untersucht. Zwei .docx-Dateien entpuppten sich als einmal data und einmal JSON data, zwei .xlsx- und vier .pptx-Dateien waren schlicht data. Echte Office-Dokumente waren nicht darunter. anydoc liest den Inhalt nach Format und nicht nach Dateiendung, deshalb ließ es sich nicht täuschen. Ohne die acht Fälschungen liegt die echte Erfolgsquote bei 194 von 198, also 98 %.
Dabei fällt ein ungeplanter Bonus ab. Lässt man es über eine Dokumentbibliothek laufen und sammelt alles, was malformed meldet, erhält man eine fertige Liste beschädigter oder falsch benannter Dateien. Dafür wurde es nicht gebaut, aber es funktioniert.
Warum das für LLM-Pipelines zählt
Übergibt man einem Modell einen Vertrag, muss man zuerst wissen, in welchem Format er tatsächlich vorliegt. Die Endung sagt .docx, der Inhalt kann aber ein verändertes ZIP sein. CSV hat keine Signatur und muss von Hand deklariert werden. Wechselt man das Tool, ändern sich auch die Ausgaberegeln: Tabellen werden manchmal zu Listen, Fußnoten verschwinden, und die Einrückung verschachtelter Listen geht kaputt.
Zum Vergleich: Der Median von LibreOffice liegt über 1100 Millisekunden, und es deckt nicht alle 14 Formate ab. unstructured, markitdown und pandoc beherrschen jeweils nur einen Teil des Spektrums, mit Qualitätswerten von höchstens etwa 65. Auf demselben Stapel von 100 echten Dokumenten erreichte anydoc insgesamt 81 Punkte, davon 87 für Vollständigkeit, 79 für Struktur, 78 für Formatierung und 81 für Sauberkeit. Und das etwa 250-mal schneller.
Das ist nicht nur ein Laborwert. 500 docx-Dateien sind in 1,7 Sekunden durch, schnell genug, um direkt in einer Agentenschleife zu sitzen. Früher hätte man eine asynchrone Queue gebaut und auf Callbacks gewartet. Jetzt fühlen sich selbst synchrone Aufrufe sofort an.
Alte .xls- und .odp-Dateien mit falschen Namen wurden trotzdem anhand des Dateiheaders erkannt. CSV braucht einen ausdrücklichen Hinweis, denn ohne Signatur überspringt das Tool die Datei sonst. Solche Details sollte man kennen, bevor man darauf aufbaut.
Wie es intern funktioniert
Jede Datei beginnt mit einer Inhaltserkennung: PDFs am Dateiheader, RTF an den Gruppen, ZIP-Container am mimetype. Nach der Identifikation füllt ein eigener Parser ein einheitliches Document-Modell mit Blöcken, Inline-Elementen, Tabellen, Fußnoten und eingebetteten Ressourcen. Ein einziger GitHub-Flavored-Markdown-Serializer erledigt den Rest.
Deshalb folgen verbundene Tabellenzellen, Überschriftenanker, Durchstreichungen, Codeblöcke und Sprechernotizen denselben Regeln. Bilder und Objekte werden zu Markdown mit Alt-Text, während die Rohbytes für einen späteren Abruf im Modell bleiben.
PDFs laufen durch pdf-inspector, der nur Dateien mit Textebene verarbeitet. Ein reiner Scan liefert Unsupported, statt so zu tun, als sei er gelesen worden, und eine verschlüsselte Datei erzeugt eine klare Fehlermeldung. Diese Ehrlichkeit ist jederzeit besser als eine „Best-Effort-Konvertierung“.
Weil es reines Rust ist, fällt kein Overhead durch einen Python-Interpreter an und es entstehen keine temporären Dateien auf der Platte. Das Node-Binding nutzt den Thread-Pool von libuv, sodass die Event Loop nicht blockiert, und das Python-Binding gibt die GIL frei. So wird ein Median von 4,4 ms möglich.
Manche werden einen Rust-Parser als Overengineering abtun. Andere verpacken ihn als Agent-Skill, damit Claude oder Cursor jede auftauchende Datei in Markdown verwandeln. Beide Lager haben Argumente.
So nutzt man es
Am direktesten geht es über die Kommandozeile:
npx @firecrawl/anydoc report.docx
Die Ausgabe landet im Terminal. Mit -o slides.md wird eine Datei geschrieben. CSV von stdin lesen:
npx @firecrawl/anydoc - --format csv < data.csv
In Node:
import { toMarkdown, toMarkdownBytes } from '@firecrawl/anydoc';
const md = await toMarkdown('report.docx');
const mdFromBytes = await toMarkdownBytes(bytes);
const mdCsv = await toMarkdownBytes(bytes, 'csv');
Die Python-Version sieht ähnlich aus:
import anydoc
md = anydoc.to_markdown("report.docx")
md_bytes = anydoc.to_markdown_bytes(data)
md_csv = anydoc.to_markdown_bytes(data, "csv")
Es gibt auch einen Browser-Build als @firecrawl/anydoc-wasm, sodass Dateien den Rechner nie verlassen. Für Rust genügt cargo add anydoc.
Mit Agenten ist es noch einfacher. Nach npx skills add firecrawl/anydoc ruft die Toolchain den Konverter automatisch auf, sobald ein Dokument auftaucht.
Erwarten Sie sauberes Markdown mit intakten Tabellen, Listen und Überschriften. Bei komplexen Dokumenten geht gelegentlich Formatierung in Randfällen verloren, ein Kompromiss des Parsers und kein Absturz.
Grenzen, mit denen man planen sollte
Das Projekt steht bei Version 0.1.x. Stark beschädigte Dateien oder übergroße eingebettete Objekte könnten theoretisch ResourceLimit auslösen. Behandeln Sie in Produktion die zurückgegebenen Fehler nach Kategorie und protokollieren Sie verschlüsselte und nicht unterstützte Dateien getrennt, damit eine einzige fehlerhafte Eingabe nicht die ganze Pipeline lahmlegt.
Wenn die Konvertierung lokal möglich ist, sparen Sie sich den Umweg über die Cloud und heben Sie gescannte Dokumente für Endpunkte mit OCR auf. Geschwindigkeit und Qualität stimmen bereits, offen bleibt nur, wie es in die eigene Pipeline passt. Das Projekt liegt unter github.com/firecrawl/anydoc.