MarkItDown thường hay bị xếp lẫn với các web scraper, nhưng gọi vậy là sai. Công cụ này không có crawler, không có bộ máy JavaScript, và cũng không có cách nào lấy nội dung từ một URL rồi bỏ đi phần giao diện thừa. Điều MarkItDown làm là nhận những dữ liệu bạn đã có sẵn — PDF, tài liệu Word, bảng tính, bộ slide — rồi chuyển hết sang Markdown để mô hình ngôn ngữ có thể đọc được.
Tôi đã dành vài tuần thử Microsoft's MarkItDown trên nhiều tài liệu thực tế bằng đúng một chiếc Mac, chấm từng bảng theo danh sách tiêu chí tôi chuẩn bị trước khi chạy và đo thời gian của từng lần chuyển đổi. Nói ngắn gọn: với dữ liệu sạch, nó nhanh và giữ nội dung khá chuẩn; nhưng gói cài đặt lại âm thầm kéo theo một runtime máy học nặng 73 MB mà bạn chẳng hề yêu cầu, và các bảng của nó có thể hỏng theo kiểu vẫn qua được bài kiểm tra “văn bản còn nguyên không?” nhưng lại rớt bài “dữ liệu có nằm đúng cột không?”. Dưới đây là bức tranh đầy đủ, kèm số liệu.
MarkItDown thực chất là gì
MarkItDown là một tiện ích Python của Microsoft, dùng để chuyển file và tài liệu Office sang Markdown tối ưu cho LLM. Bạn có thể đưa cho nó một file PDF, .docx, .xlsx, .pptx, một ảnh, file HTML hoặc vài định dạng khác, và nó sẽ trả về Markdown. Công cụ này có ba cách dùng: CLI (markitdown file.pdf -o out.md hoặc nhận dữ liệu từ stdin), Python API (MarkItDown().convert(...)), và một MCP server tùy chọn cho các workflow tác nhân.

Điểm quan trọng nhất nằm ở chỗ nó không làm gì, vì README cũng không hề nhắc tới, và tôi đã xác nhận trong lúc thử nghiệm: không crawl, không render JS, không lần theo link, không xử lý phân trang, và cũng không trích xuất “nội dung chính” theo kiểu readability. Đây là công cụ chuyển đổi cả tài liệu. Bạn đưa bytes vào; nó chuẩn hóa chúng. Sự khác biệt này quyết định công cụ có hợp với stack của bạn hay không, nên tôi sẽ nhắc lại điểm này nhiều lần.
Bản thân repo này có chỉ số rất “khủng” theo kiểu GitHub khoe mẽ — 165,282 stars và 11,790 forks tính đến giữa tháng 7 năm 2026, giấy phép MIT, bản phát hành mới nhất (v0.1.6) ra ngày 2026-05-26. Nhưng số sao đó chủ yếu phản ánh repo của Microsoft đi cùng làn sóng quan tâm lớn đến tooling cho LLM, chứ không phải tín hiệu cho thấy lõi chuyển đổi đã thật sự trưởng thành. Hiện cũng có 833 issue đang mở, và vài trong số đó là thứ bạn nên biết trước khi cài (tôi sẽ nói rõ ở phần dưới).
HTML sang Markdown: nhanh, đủ, nhưng giữ luôn cả phần thừa
Vì phần còn lại của loạt bài đánh giá scraper của tôi đều dùng cùng bốn fixture web, tôi cũng đưa cho MarkItDown đúng các file HTML cục bộ đó — không phải để chấm nó như một scraper, mà để xem chất lượng chuyển HTML sang Markdown ra sao. Trên các trang được đánh dấu tốt, kết quả thực sự khá ổn.
Bốn trang đều chuyển được với bản cài đặt lõi, không cần thêm gói phụ nào, và mọi probe của phần nội dung đều còn nguyên. Bài Wikipedia về “Web scraping” (226 KB) cho ra cây tiêu đề được phản chiếu khá chuẩn — một h1, bảy h2, mười hai h3, khớp với cấu trúc mục thật của bài viết — và 418 link được giữ dưới dạng [text](url) đúng chuẩn. Bảng thống kê khúc côn cầu 26×9 trên trang Scrape This Site forms biến thành một bảng pipe GFM sạch sẽ 27 hàng (header + dòng phân tách + 26 hàng dữ liệu), kể cả ô trống. Tốc độ ở đây không phải vấn đề: median 48 ms cho trang quotes nhỏ nhất đến 352 ms cho trang Wikipedia 226 KB.
Nhưng có một điểm cần lưu ý, và đây là lựa chọn thiết kế chứ không phải bug. MarkItDown không cắt bỏ boilerplate. Nó chuyển toàn bộ <body>, nên phần giao diện của trang cũng đi theo — và lượng “rác” này tăng theo mức độ nặng giao diện của trang.
| Trang | Số ký tự đầu ra | Tiêu đề (h1/h2/h3) | Link | Dòng giao diện thừa |
|---|---|---|---|---|
| Books to Scrape | 10,478 | 1 / 0 / 0 | 94 | 0.6% (1/159) |
| Quotes to Scrape | 2,973 | 1 / 1 / 0 | 55 | 1.2% (1/86) |
| ScrapeThisSite forms | 3,385 | 1 / 0 / 0 | 31 | 6.7% (5/75) |
| Wikipedia Web scraping | 60,159 | 1 / 7 / 12 | 418 | 12.4% (42/338) |
Ở trang Books, vốn gần như không có phần giao diện thừa, chỉ 0.6% số dòng đầu ra là chrome. Còn trên Wikipedia, con số này lên đến 12.4% — 42 trong 338 dòng không rỗng là những thứ như “jump to content”, “toggle the table of contents”, “22 languages”, “retrieved from”, cùng footer về cookie và giấy phép. Những banner bảo trì của Wikipedia như “This article needs additional citations” còn được render trung thực thành các bảng pipe hai cột, và đó là nguồn của chín hàng bảng trên một trang vốn không hề có bảng dữ liệu thật.
Tuy nhiên, đó không phải là MarkItDown làm sai. Nó là bộ chuyển đổi cả tài liệu, không phải công cụ đọc dễ hiểu kiểu readability: chuyển HTML sang Markdown một cách trung thực là một bài toán khác với trích xuất bài viết sạch sẽ. Trafilatura và các công cụ kiểu Firecrawl hướng đến việc trả về chỉ nội dung chính; MarkItDown trả về cả trang. Bên trong, _html_converter.py của nó chỉ gỡ <script> và <style>, rồi đưa toàn bộ body sang thư viện markdownify — không hề có heuristic cho nội dung chính. Nếu bạn chỉ cần bài viết, đây là sai tầng xử lý.
Sân nhà của nó: PDF, DOCX, XLSX, PPTX
Tài liệu là thứ MarkItDown được sinh ra để xử lý. Tôi đã thử nó trên các file công khai thực tế — một bài arXiv có lớp text, whitepaper Bitcoin, một PDF scan chỉ có ảnh mà tôi tự render để không còn text layer, và các file DOCX/XLSX/PPTX từ chính bộ test của MarkItDown (được gắn UUID để tôi phát hiện mất nội dung âm thầm).
| Tài liệu | Kích thước đầu vào | Số ký tự đầu ra | Probe | Thời gian median | Ghi chú |
|---|---|---|---|---|---|
| arXiv 1706.03762 (PDF có text layer) | 2.2 MB | 40,174 | 7/7 | 3.7 s (warm) | title, “Transformer”, “BLEU”, “References” đều còn |
| Bitcoin whitepaper (PDF 9 trang) | 184 KB | 22,485 | 6/6 | 1.4 s | “Satoshi Nakamoto”, “proof-of-work”, “Conclusion” đều có |
| PDF scan (không có text layer) | 89 KB | 0 | 0/4 | 15 ms | đầu ra rỗng, không lỗi, không OCR |
| DOCX (test.docx) | 136 KB | 4,651 | — | 70 ms | heading + bảng GFM; UUID nhúng vẫn còn |
| DOCX có công thức | 15 KB | 240 | — | 101 ms | Office Math được giữ dưới dạng LaTeX |
| XLSX (test.xlsx) | 12 KB | 808 | — | 57 ms | mỗi sheet → ## SheetName + bảng GFM |
| PPTX (test.pptx) | 278 KB | 2,047 | — | 52 ms | có marker số slide, bảng, biểu đồ → bảng |
Khả năng nhớ lại văn bản trên PDF có text layer là rất tốt — 7/7 probe đã định nghĩa trước trên bài arXiv “Attention Is All You Need”, 6/6 trên Bitcoin whitepaper — và không file Office nào làm mất một UUID sentinel nào, tức là không có mất nội dung âm thầm trong các fixture regression của chính nhà phát triển. Một điểm cộng hẹp nhưng đáng giá: luồng DOCX (qua mammoth) giữ được công thức Office Math dưới dạng LaTeX, chuyển equations.docx thành math thực sự trong $$...$$. Nếu bạn đưa các tài liệu Word nặng công thức vào LLM, đây là một lợi thế rất thực tế, dù khá đặc thù.
Có hai phát hiện ở mảng này cần được nhấn mạnh riêng, vì chúng dễ gây rắc rối nhất.
PDF scan thì biến mất
Đưa cho MarkItDown một PDF chỉ có ảnh, không có text layer, và nó trả về chuỗi rỗng. Không có ký tự nào, không exception, không cảnh báo — chỉ chuyển xong trong khoảng 15 ms vì thực ra không có gì để trích xuất. Nhánh xử lý PDF của MarkItDown chỉ làm trích xuất text (dùng pdfminer và pdfplumber ở phía dưới), và bản cài đặt lõi cũng như các pip extra đều không có OCR.
Điều này rất đáng kể khi xử lý hàng loạt. Nếu một developer đưa vào cả thư mục PDF mà trong đó có file scan, những file đó sẽ âm thầm cho kết quả rỗng mà không hề có tín hiệu cho biết chúng đã bị bỏ qua. Tôi đã kiểm tra xem fixture có hỏng hay không bằng cách gọi trực tiếp extract_text của pdfminer lên file đó — đúng là zero ký tự sau khi strip, xác nhận không có text layer — nên đầu ra rỗng là hành vi thực của MarkItDown trên một file scan thật. Điều này tái hiện đúng khoảng trống OCR đã được báo lâu nay trong issue #1268. Cách xử lý được tài liệu hóa là dùng backend Azure Document Intelligence tùy chọn hoặc một plugin; cả hai đều không có trong bản cài đặt mặc định.
PDF ra text phẳng, không có cấu trúc
Trên cả hai PDF có text layer, MarkItDown không tạo ra bất kỳ marker heading Markdown nào. PDF vốn không mang thẻ heading ngữ nghĩa, và MarkItDown cũng không suy ra heading từ cỡ chữ, nên mọi dòng đều rơi xuống mức body. Khả năng nhớ text cao; còn cấu trúc thì phẳng.
Đây không chỉ là kết quả của tôi. Các benchmark công khai từ bên thứ ba chấm khả năng tái tạo thứ bậc heading của PDF của MarkItDown khoảng 0.0, và độ chính xác bảng vào khoảng 0.27, thấp hơn nhiều so với 0.88 của Docling nhờ TableFormer (xem so sánh MarkItDown vs Docling vs Marker và READoc benchmark). Fixture của tôi tái tạo đúng xu hướng đó, và đây là điểm mạnh của bằng chứng — số liệu của tôi khớp với nguồn bên ngoài. Cái giá mà cùng các benchmark đó nêu ra là MarkItDown nhanh hơn Docling khoảng 100 lần, phù hợp với việc tài liệu của tôi chạy trong vài giây thay vì vài phút như các công cụ dựa trên mô hình bố cục. Kết luận: MarkItDown cho bạn phần text của PDF nhanh và sạch; nó không cho bạn cấu trúc của PDF. Nếu heading và bảng phải giữ nguyên, bạn cần một công cụ ở tầng layout-model như Docling hoặc Marker.
Bảng: nội dung luôn sống, cấu trúc thì không phải lúc nào cũng vậy
Bảng là nơi câu hỏi “văn bản còn nguyên không?” và “dữ liệu còn dùng được không?” tách ra rõ nhất, nên tôi xây một ma trận 13 tình huống — mỗi case là một <table>, được chấm theo manifest viết trước khi chạy — để xác định chính xác dạng nào giữ được và dạng nào hỏng.

Kết luận chính: MarkItDown không làm mất nội dung bảng. Cả 13 case đều giữ lại 100% token đã định nghĩa trước. Nhưng độ trung thực về cấu trúc lại chia thành ba nhóm. Bảy trên mười ba case cho ra một lưới GFM chuẩn chỉnh (bảng thường, colspan ở header, bảng rộng 24 cột, không có header, ô trống, nội dung dạng block trong ô, và bảng tiếng Ả Rập từ phải sang trái). Bốn case bị méo, vì Markdown không có khái niệm ô gộp; nên rowspan, colspan và nguồn dữ liệu lỗi đều sinh ra các hàng ngắn. Và hai case thì hỏng hẳn.
Hai lỗi này đáng được nêu tên. Một bảng lồng nhau (một <table> nằm trong <td>) sẽ bị làm phẳng ngay trong dòng, đổ cả dấu pipe và hàng phân tách của nó vào ô cha, tạo ra một hàng rác “14 cột”. Và dấu | nguyên văn trong ô không được escape — text a | b bị hiểu thành hai cột, x || y thành ba cột — khiến một bảng hai cột xuất hiện các hàng hai, ba và bốn cột, và bất kỳ Markdown parser nào ở phía sau cũng sẽ đọc sai ranh giới. Thú vị là dấu * và backticks trong ô thì có được escape; chỉ có pipe là không. Nguyên nhân là nhánh HTML của MarkItDown dùng xử lý bảng mặc định của markdownify, còn subclass tùy biến của nó chỉ override link, image và heading chứ không chạm vào cell bảng. Cùng họ lỗi escape pipe này cũng đã được ghi nhận trong issue mở của bộ chuyển CSV (#2019), dù bản sửa đó không ảnh hưởng tới nhánh HTML tôi đã thử.
Điểm tinh tế nhất — phát hiện mà tôi muốn một data engineer chú ý nhất — là rowspan. Case t03 không chỉ bị méo; nó còn làm lệch dữ liệu một cách âm thầm. Nhãn rowspan=2 (“Fruit”) chỉ được xuất một lần, và dòng bên dưới trở thành hàng ngắn hai cột (| Banana | 8 |), nên “Banana” rơi vào cột Group thay vì Item. Tất cả token đều còn đó. Nhưng một người tiêu thụ dữ liệu theo kiểu ngây thơ “đọc cột thứ hai” sẽ lấy sai giá trị. Đây là kiểu lỗi vượt qua kiểm tra tồn tại văn bản nhưng âm thầm làm hỏng dữ liệu.
Bản thân hạn chế span là một ràng buộc thiết kế đã được biết và theo dõi (#1211, #1248) — một lưới GFM phẳng thật sự không thể biểu diễn span hay bảng lồng nhau, nên converter buộc phải đánh đổi cấu trúc để lấy sự đầy đủ của nội dung. Tuy vậy vẫn có những hành vi tốt: bảng không có header sẽ được tạo sẵn một hàng header trống, nên dữ liệu không bị đẩy âm thầm lên làm header; ô trống được giữ nguyên; và <caption> vẫn còn dưới dạng một dòng văn bản phía trên bảng.
Cài đặt và khởi động: cái “thuế” mà một tiện ích nhẹ nhàng không hề cảnh báo
Không có gì khiến tôi bất ngờ hơn phần này, và đây cũng là chỗ cách gọi “tiện ích Python nhẹ” bị phóng đại một cách kín đáo.

Đầu tiên, đừng dùng pip install 'markitdown[all]'. Trên Python 3.14, lệnh này lặng lẽ lùi về markitdown 0.0.2 — một bản phát hành từ hai năm trước — và tôi đã tái hiện trực tiếp trong một venv sạch. Khi cố ghim phiên bản, lý do lộ ra: pip install 'markitdown[all]==0.1.6' báo lỗi vì extra [all] ghim youtube-transcript-api~=1.0.0, trong khi trên PyPI hiện tại mọi build trong dải đó đều chỉ hỗ trợ Python <3.14, còn các build tương thích 3.14 duy nhất lại nằm ngoài ràng buộc ghim. Vì thế bộ resolver phải lùi hẳn về bản phát hành cũ nhất mà nó còn giải quyết được dependency. Điều này khớp với issue #2179. Cách sửa khá rõ: ghim phiên bản rồi cài từng extra riêng lẻ: pip install 'markitdown==0.1.6', sau đó pip install 'markitdown[pdf,docx,pptx,xlsx,xls]==0.1.6'. Mỗi lệnh đó đều chạy ổn; chỉ bundle [all] là có pin lỗi. (Bẫy này phụ thuộc phiên bản Python — trên Python 3.13 hoặc thấp hơn, rào cản có thể không xuất hiện, nên [all] có thể giải quyết khác đi.)
Thứ hai là footprint. Bản cài lõi nặng 161 MB (một venv trống 13 MB cộng thêm 148 MB). Trong số đó, onnxruntime (73 MB) và numpy (34 MB) cộng lại là 107 MB — chiếm 66% toàn bộ footprint lõi — và cả hai đều được kéo vào chỉ bởi một dependency cứng: magika, bộ phát hiện loại file bằng ML của Google. Nói cách khác, một công cụ chuyển text lại ship kèm một runtime suy luận ONNX 73 MB trong bản cài cơ bản trước khi bạn thêm bất kỳ gói tài liệu nào. Khi thêm các extra cho tài liệu, venv tăng lên 310 MB. Con số này vẫn nhẹ hơn nhiều so với stack trình duyệt headless, nhưng nếu bạn nghĩ đây là một tiện ích “pip install là xong” thật nhỏ gọn, thì bạn nên biết rằng nó có kéo theo ONNX runtime.
Thứ ba — và đây là phát hiện duy nhất trong toàn bộ bộ thử của tôi vượt qua mọi bài kiểm tra độ mới lạ mà tôi đã chạy — chỉ riêng việc import markitdown sau khi cài sạch đã tốn khoảng 3.35 giây trên máy này. Phần lớn chi phí nằm ở lúc import: markitdown._markitdown chủ động import toàn bộ registry converter (tổng cộng 2.56 giây, chiếm 76% tổng thời gian), kéo theo pandas (594 ms, qua converter XLSX), python-pptx (427 ms), magika (354 ms) và requests (270 ms) — bất kể bạn có convert định dạng đó hay không. Với dịch vụ chạy lâu, chi phí này được amortize và gần như không đáng kể. Nhưng với một lần gọi CLI hay cold start serverless, đó là mức “thuế” theo mỗi process mà nhãn “tiện ích nhẹ” không hề khiến bạn nghĩ đến. (Lưu ý công bằng: đây là một lần đo duy nhất, được xem như một quan sát, không phải phân phối nhiều lần.)

Quy mô lớn: không crash, nhưng phải chuẩn bị CPU cho PDF và RAM cho bảng tính
Tôi đẩy bốn đối tượng lớn qua công cụ, mỗi đối tượng chạy trong process riêng để mức RSS đỉnh không bị ảnh hưởng bởi lần chạy trước. Không có gì bị crash. Nhưng hồ sơ chi phí thì khá lệch.

| Đối tượng | Kích thước đầu vào | Số ký tự đầu ra | Thời gian median | Peak RSS Δ |
|---|---|---|---|---|
| NIST SP 800-53r5 (PDF 492 trang) | 5.9 MB | 1,625,365 | 192.5 s | +40 MB |
| XLSX 50,000 hàng × 8 cột | 2.1 MB | 3,722,955 | 62.1 s | +374 MB |
| arXiv 1706.03762 (~15 trang PDF) | 2.2 MB | 40,174 | 12.6 s | +25 MB |
| XLSX 200 hàng × 64 cột | 46 KB | 120,129 | 2.9 s | +22 MB |
PDF NIST 492 trang mất median 192.5 giây — khoảng 3.2 phút, hay 0.39 giây/trang — vì pdfplumber chạy phát hiện form theo vị trí từ trên mọi trang. Peak RSS chỉ tăng +40 MB, nên đây là bài toán CPU chứ không phải bộ nhớ. Ngay cả PDF arXiv 15 trang cũng mất 12.6 giây khi chạy trong process tách biệt, tức khoảng 3.4 lần so với mức 3.7 giây của cùng file khi chạy “warm” trong bộ tài liệu của tôi. Khoảng cách đó là chi phí của process lạnh, và nó xác nhận rằng khối lượng công việc theo từng trang mới là yếu tố chi phối, không phải kích thước byte thô. Nếu cần một con số duy nhất có thể mang đi, hãy dùng 12.6 giây của lần chạy cô lập.
Luồng xử lý bảng tính thì đảo ngược nút thắt. Một file XLSX 2.1 MB, 50,000 hàng tăng lên +374 MB RSS đỉnh (và 3.7 triệu ký tự đầu ra) vì converter nạp cả sheet vào bộ nhớ và dựng một chuỗi Markdown khổng lồ. Vì vậy lời khuyên thực tế rất thẳng: PDF lớn thì chuẩn bị vài phút CPU; bảng tính lớn thì chuẩn bị hàng trăm MB RAM. Đây là số liệu đo trên một máy macOS arm64 và Python 3.14, nên hằng số theo trang và theo hàng là đặc thù nền tảng — nhưng hình dạng chung (PDF chậm và ăn CPU, XLSX ngốn bộ nhớ, không có gì bị crash) là phần có thể mang sang môi trường khác.
Thunderbit phù hợp ở đâu — và không phù hợp ở đâu
Dùng thử Thunderbit để trích xuất dữ liệu web
Đây là điểm so sánh dễ bị nói quá nhất, nên tôi sẽ phân định thật rõ. MarkItDown và Thunderbit giải quyết các bài toán liên quan, nhưng không giống nhau.
MarkItDown chuyển đổi những file bạn đã có. Thunderbit lấy trang web trước đã. Endpoints /distill của Thunderbit biến một trang web đang sống thành Markdown sạch, sẵn cho LLM — xử lý phần render JS, chống bot và nội dung động mà MarkItDown không có công cụ nào đảm trách — còn endpoint /extract trả về JSON có cấu trúc khớp schema, chứ không chỉ Markdown thô. Với developer, các khả năng đó được mở ra qua API (POST /distill / POST /extract), một MCP server, và CLI (npx @thunderbit/thunderbit-cli) dùng chung một AI engine, cũng chính engine đứng sau extension có hơn 100,000 người dùng.
Vì thế chúng chỉ trùng nhau ở đúng một điểm — cả hai đều có thể xuất ra “Markdown sẵn cho LLM” — nhưng miền dữ liệu đầu vào thì khác: distill của Thunderbit nhận URL trên web công khai, còn MarkItDown nhận file cục bộ. Hai bên không phải lựa chọn thay thế trực tiếp cho nhau, và tôi cũng không định nói vậy. Stack thực tế là dùng cả hai: crawl và lấy dữ liệu web bằng Thunderbit (hoặc một dịch vụ kiểu Firecrawl), rồi chuẩn hóa những tài liệu cục bộ hỗn hợp mà bạn cũng có — PDF, slide, bảng tính — bằng MarkItDown. Một bên xử lý mạng; bên kia xử lý tủ hồ sơ.
Ưu và nhược điểm
Điểm mạnh
- Giữ nguyên gần như toàn bộ nội dung của HTML sạch (4/4 trang), heading tree và link đều được bảo toàn đúng
- Độ nhớ lại text của PDF/DOCX rất cao (arXiv 7/7 probe, Bitcoin 6/6) và không làm mất nội dung âm thầm trên fixture Office của chính dự án
- Công thức Office Math được giữ dưới dạng LaTeX — một điểm cộng rất cụ thể nhưng đáng giá
- Không hề crash ở bất kỳ dữ liệu quy mô nào, kể cả PDF 492 trang và XLSX 50k hàng
- Cách dùng rất đơn giản: CLI,
convert(), pipe từ stdin, và MCP server tùy chọn - Giấy phép MIT, được Microsoft duy trì tích cực, issue tracker phản hồi tốt
Điểm yếu
- Giữ luôn cả boilerplate — trên Wikipedia có thể đến 12.4% dòng là chrome; không phải công cụ đọc bài viết sạch
- Bảng dễ hỏng ở span, nesting và dấu pipe trong ô (2/13 case hỏng, 4/13 bị méo), và rowspan có thể làm lệch dữ liệu mà không báo
- PDF scan/chỉ có ảnh trả về đầu ra rỗng, không OCR và cũng không báo lỗi
- Đầu ra PDF hoàn toàn không có cấu trúc heading (đúng như benchmark công khai)
- Bản cài lõi 161 MB, kèm runtime ONNX 73 MB; import lạnh khoảng 3.35 giây
- Extra
[all]trên Python 3.14 âm thầm lùi về bản 0.0.2 đã hai năm tuổi
Ai nên dùng, và ai không nên dùng
Hãy chọn MarkItDown nếu bạn đang chuẩn hóa một đống tài liệu cục bộ hỗn hợp — Word, Excel, PowerPoint, PDF có text layer — sang Markdown cho một pipeline LLM, và bạn quan tâm nhiều hơn đến việc giữ đủ văn bản thay vì giữ nguyên cấu trúc. Ở bước chuyển cuối cùng của một batch job, đưa text sạch cho model, nó nhanh, chuẩn và miễn phí.
Hãy bỏ qua nó, hoặc ghép nó với công cụ khác, nếu công việc của bạn thuộc một trong các trường hợp sau: bạn chỉ cần bài viết chính từ một trang web (hãy dùng công cụ kiểu readability hoặc Firecrawl); bạn cần heading và bảng của PDF phải còn nguyên (đó là sân chơi của Docling hoặc Marker); hoặc đầu vào của bạn có các tài liệu scan cần OCR (bạn sẽ cần backend Azure hoặc một công cụ khác hoàn toàn). Và nếu bạn tưởng mình đang tìm một scraper — thứ có thể fetch và crawl — thì đây hoàn toàn không phải vậy.
Bảng chấm điểm tạm thời tôi chạy, dựa trên rubric giống scraper, đưa MarkItDown về mức 60/100, và tổng điểm thấp đó là hệ quả của việc chấm một converter bằng bài test của crawler. Ở đúng sân chơi của nó, điểm fidelity văn bản rất cao; các điểm yếu là về cấu trúc (bảng, heading PDF) và đóng gói (footprint, import, bẫy [all]), chứ không phải chất lượng text. Hãy đánh giá nó đúng bản chất — một công cụ chuyển file sang Markdown — thì đây là một công cụ tốt, được duy trì đàng hoàng, chỉ có vài cạnh sắc mà bạn nên biết trước khi đưa vào production.
Câu hỏi thường gặp
MarkItDown có phải là web scraper không?
Không. Nó không có crawler, không render JavaScript, không lần theo link và không xử lý phân trang. Nó chuyển các file và tài liệu bạn đã có sẵn — PDF, DOCX, XLSX, PPTX, ảnh, HTML — sang Markdown. Nếu bạn cần fetch và crawl trang web trực tiếp, hãy dùng một công cụ scraping như Thunderbit hoặc Firecrawl; MarkItDown là bước phía sau, biến file đã lấy hoặc file cục bộ thành Markdown sạch.
Vì sao pip install markitdown[all] lại cài bản cũ?
Trên Python 3.14, extra [all] ghim youtube-transcript-api~=1.0.0, trong khi mọi build trong dải đó đều chỉ hỗ trợ Python dưới 3.14. Resolver không thỏa được ràng buộc ghim nên lặng lẽ lùi về markitdown 0.0.2, một bản phát hành đã hai năm tuổi. Cách sửa là ghim phiên bản rồi cài các extra riêng lẻ: pip install 'markitdown==0.1.6', sau đó thêm 'markitdown[pdf,docx,pptx,xlsx,xls]==0.1.6'. Vấn đề này đang được theo dõi tại issue #2179.
MarkItDown có OCR cho PDF scan không?
Không trong bản cài mặc định. Nhánh xử lý PDF của nó chỉ làm trích xuất text, nên một PDF chỉ có ảnh và không có text layer sẽ trả về chuỗi rỗng — không báo lỗi, không cảnh báo. Muốn OCR thì phải dùng backend Azure Document Intelligence tùy chọn hoặc plugin, và cả hai đều không đi kèm mặc định. Đây là một khoảng trống đã được theo dõi từ lâu (issue #1268).
MarkItDown xử lý bảng tốt đến mức nào?
Về nội dung thì rất tốt — trong bài test 13 case của tôi, nó giữ lại 100% nội dung bảng ở mọi case. Nhưng về cấu trúc thì tùy dạng: bảng đơn giản, bảng rộng, không có header và có ô trống thì ra lưới GFM sạch sẽ; còn rowspan và colspan thì dễ méo (rowspan còn có thể làm lệch dữ liệu sang cột sai), bảng lồng nhau bị làm phẳng thành hàng rác, và dấu pipe nguyên văn trong ô không được escape. Định dạng bảng phẳng của Markdown vốn dĩ không thể biểu diễn span hay nesting.
MarkItDown có đủ nhanh cho tài liệu lớn không?
Nó không crash với file lớn, nhưng bạn cần tính tài nguyên theo từng loại. Một PDF 492 trang mất khoảng 3.2 phút (xấp xỉ 0.39 giây/trang) vì nó phát hiện form theo từng trang, nên bị ràng buộc bởi CPU. Một bảng tính 50,000 hàng xong trong khoảng một phút nhưng dùng thêm +374 MB RAM vì nó dựng cả chuỗi Markdown lớn trong bộ nhớ. Với PDF lớn, hãy chuẩn bị vài phút CPU; với bảng tính lớn, hãy chuẩn bị hàng trăm MB RAM.
Dùng thử Thunderbit để trích xuất dữ liệu web Get Started Free


