MarkItDown Skill
Documentation and utilities for converting documents to Markdown using Microsoft's MarkItDown library.
Note: This skill provides documentation and a batch script. The actual conversion is done by the
markitdownCLI/library installed via pip.
💡 推荐做法(RECOMMENDED — 强烈建议)
收到任意网页 / 微信文章 / 公众号链接(含 mp.weixin.qq.com、任意 https:// URL)时,推荐按以下顺序处理(强烈建议,可避免丢内容 / 失败):
-
第一步(推荐):运行本技能的
scripts/url_to_markdown.py "<url>" -o /tmp/page.md把网页转成 Markdown。- 它会自动处理 JS 渲染的 SPA(无头 chromium 回退),比裸
markitdown <url>更可靠,也不会漏正文。
- 它会自动处理 JS 渲染的 SPA(无头 chromium 回退),比裸
-
第二步:读取
/tmp/page.md的 Markdown 文本,再进行分析 / 总结 / 提取,而不是原始 HTML。处理时养成「先 Grep / 窄范围 Read,别整篇读」的习惯——只 Grep 目标章节或关键词,按需 Read 对应段落;仅当确需通读全文才整篇读,从源头省 token(详见下方「Token 节省:Grep 优先」)。 -
⚠️ 不推荐以下"坏路径"(脆弱、易失败):
- ❌ 任何
curl+ 正则手工解析 HTML / 微信正文(手写抽js_content等字段); - ❌ 直接把原始 HTML 当作分析对象喂给 AI。
- 这些做法会丢内容、漏样式、偶发失败,是脆弱的退化路径。
- ❌ 任何
-
✅ mp.weixin.qq.com(微信/公众号)兜底放行:
- 微信对裸 / 库 UA 会反爬返回"环境异常"空页。本技能的
url_to_markdown.py现已内置完整 Chrome UA 直连,可正常抓取。 url_to_markdown.py已内置微信文章结构化抽取:自动提取标题、公众号名、发布时间与#js_content正文,输出不含"在小说阅读器读本章""微信扫一扫""赞 / 在看"等界面噪声,无需任何手工处理。- 仅当
url_to_markdown.py仍取不到正文时,才建议兜底:curl -A '<完整Chrome UA>' -sL "<url>" -o /tmp/wx.html,随后把/tmp/wx.html交给markitdown /tmp/wx.html提取正文。 - 仍不推荐手写正则抽
js_content——交给markitdown处理即可,正则路径是脆弱的退化写法。
- 微信对裸 / 库 UA 会反爬返回"环境异常"空页。本技能的
一句话记忆:链接 →
url_to_markdown.py(已含微信 UA)→ Markdown → 分析;微信仅在兜底时建议curl -A 完整UA抓 HTML 再交给markitdown,手写正则不推荐。
⚠️ 安全边界(务必遵守)
本技能处理用户显式提供的文件与 URL。下列红线必须守住,既是平台审核要求,也关乎数据安全:
- URL 转换器默认拒绝内网 / 私有目标(SSRF 防护):
scripts/url_to_markdown.py只转换公开外部 URL。以下目标会被直接拒绝(退出码非 0,不发起任何请求):- 回环 / 私网 / 链路本地 / 保留地址:
localhost、.local/.internal/.corp/.lan/.home/.intranet等内网域名、127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、169.254.0.0/16(含云元数据169.254.169.254)、100.64.0.0/10; - 非
http/https协议(如file://、ftp://); - 需要登录鉴权的私有页面、企业内部系统、含敏感内容的地址。
- 仅受信任的本地开发可用
--allow-internal显式放行(默认关闭)。不要把内网 / 私有地址交给本技能。
- 回环 / 私网 / 链路本地 / 保留地址:
- 可选外部 LLM / 云服务会传出内容:OpenAI 图像描述、合同分析示例、Azure Document Intelligence、以及第三方插件(
--use-plugins)在启用时,会把转换后的文本 / 图片发送到对应外部端点。这些均为可选、默认关闭能力,使用前必须取得用户明确同意,且切勿将内部 / 私有 / 涉密文档送入这些路径;敏感内容优先走纯本地的markitdown转换(不联网、不上报,详见下方与references/中的数据安全说明)。
When to Use
Use markitdown for:
- 📄 Fetching documentation (README, API docs)
- 🌐 Converting web pages to markdown
- 📝 Document analysis (PDFs, Word, PowerPoint)
- 🎬 YouTube transcripts
- 🖼️ Image text extraction (OCR)
- 🎤 Audio transcription
Quick Start
# Convert file to markdown
markitdown document.pdf -o output.md
# Convert URL
markitdown https://example.com/docs -o docs.md
Supported Formats
| Format | Features |
|---|---|
| Text extraction, structure | |
| Word (.docx) | Headings, lists, tables |
| PowerPoint | Slides, text |
| Excel | Tables, sheets |
| Images | OCR + EXIF metadata |
| Audio | Speech transcription |
| HTML | Structure preservation |
| YouTube | Video transcription |
Installation
The skill requires Microsoft's markitdown CLI:
pip install 'markitdown[all]'
Or install specific formats only:
pip install 'markitdown[pdf,docx,pptx]'
Common Patterns
Fetch Documentation
markitdown https://github.com/user/repo/blob/main/README.md -o readme.md
Convert PDF
markitdown document.pdf -o document.md
Batch Convert
# Using included script (run with the Python that has markitdown installed)
python "<skill-dir>/scripts/batch_convert.py" docs/*.pdf -o markdown/ -v
# <skill-dir> = this skill's own directory (the folder containing this SKILL.md).
# WorkBuddy: use the managed Python that has markitdown (Windows e.g.
# ~/.workbuddy/binaries/python/envs/default/Scripts/python.exe ; macOS/Linux: the
# managed `python3`). Do NOT rely on a system python that lacks markitdown.
# Or shell loop
for file in docs/*.pdf; do
markitdown "$file" -o "${file%.pdf}.md"
done
Token-Saving Workflow (给 AI 减负) — ⚙️ 可选 / OPTIONAL
本工作流为可选增强,不是核心功能。 技能的核心能力(文档 / 网页 → Markdown)完全不依赖它。 它包含两个本地、互不依赖、且不向任何服务器上报的工具:
token_saver.py(某次转换的成本/节省估算) 与measure_tokens.py(任意文本/文件的 token 量测与对比);方法论见 TOKEN-AUDIT.md。 公开版不包含任何上报组件,全程本地运行。不需要省 token 报告时,可完全忽略本段。
Large, richly-formatted documents (PDFs, PPTX, DOCX, scanned images) carry heavy layout / font / header / footer / embedded-object noise that inflates token cost. Converting to plain Markdown first strips that noise so the AI ingests only the semantic content — typically cutting token usage by 80%+ versus feeding the raw file.
When to apply (proactively): whenever a user asks to "总结 / 分析 / 提取 / 问答 / 翻译"
a file or URL that is not already plain text (.md/.txt/.csv/.json). This is the
single most common cause of wasted tokens in document Q&A.
Steps:
-
Convert the source to Markdown. For a file, use
markitdown <file>orscripts/batch_convert.py. For a webpage link, usescripts/url_to_markdown.py "https://..." -o page.md— it auto-handles JS-rendered SPAs (see "SPA / JS 渲染页面回退" below). Plainmarkitdown <url>only does a raw HTTP GET and returns ~0 bytes on SPA pages. -
Feed the resulting Markdown to the AI instead of the raw file.
-
Optionally estimate the token cost (and, for PDF/images, the saving) with
scripts/token_saver.py:# PDF/images: pass --pages to estimate the raw baseline python "<skill-dir>/scripts/token_saver.py" document.pdf -o document.md --pages 100 # any format: pass a trusted baseline explicitly python "<skill-dir>/scripts/token_saver.py" document.pdf --raw-estimate 120000It prints the approximate Markdown token cost (the actual AI cost). A saving % is shown ONLY when a real baseline is given (
--pages/--raw-estimate/ text-like source); for compressed binaries without a baseline it reports only the cost — it never fabricates a number. All figures use a chars/4 heuristic and are estimates.
Why it matters: a 100-page PDF fed raw may cost ~10× the tokens of its cleaned Markdown; the extra tokens buy no information. Details and the estimate methodology: TOKEN-SAVER.md.
Token 节省:Grep 优先(按需读,别整篇读)
转换成 Markdown 只是第一步。喂给 AI 时,再用「先 Grep、再按需 Read」进一步缩量:
- Grep 先行:拿到
page.md/output.md后,先Grep目标章节标题、关键词、表格名,定位相关片段,而不是整篇塞进上下文。 - 窄范围 Read:只
Read命中的那几段;只有确需通读(如「全文总结」)才整篇读。 - 大文件 / 长网页:先
Grep建索引,再分批 Read 相关段落,避免一次性灌入几千行。 - JSON 回退也缩量:无浏览器时抽取 SPA 内嵌 JSON(
__NEXT_DATA__等)现采用递归平铺抽取,只保留正文类字段,不再把整个 10–20KB 的__NEXT_DATA__原样灌入上下文(详见url_to_markdown.py的json_to_markdown)。
Python API
from markitdown import MarkItDown
md = MarkItDown()
result = md.convert("document.pdf")
print(result.text_content)
SPA / JS 渲染页面回退(腾讯云 CDN 等)
markitdown <url> 只做裸 HTTP GET,不执行 JS。内容由客户端 JS 注入的 SPA(React/Vue/Next.js,常经腾讯云 CDN 托管)会拿到空 <div id="root">,正文约 0 字节。
本技能提供 scripts/url_to_markdown.py 自动处理:先直连 markitdown(已带完整 Chrome UA 绕过反爬),若正文过短(疑似 SPA)则自动无头渲染后回退:
# 用装有 markitdown 的 Python 运行(WorkBuddy 例:venv python)
python "<skill-dir>/scripts/url_to_markdown.py" "https://..." -o page.md
回退优先级:① 本机 Chrome/Edge 无头 --dump-dom(已执行 JS 再序列化 DOM,Windows 已验证,零新依赖);
② 无浏览器时抽取页面内嵌 JSON(__NEXT_DATA__ / window.__INITIAL_STATE__ / <script type="application/json">),并递归平铺抽取只保留正文类字段(不再把整个 10–20KB 的 __NEXT_DATA__ 原样灌入上下文);
③ 都不可用再提示改用 WebFetch(服务端渲染兜底)。
Linux 服务器需先装 chromium(或 playwright install chromium),同样走 --dump-dom 技巧。
可用 --force-browser 强制渲染、--no-browser 仅走直连+JSON、--virtual-time-budget=NNNN 调大 SPA 等待时间。
Troubleshooting
"markitdown not found"
pip install 'markitdown[all]'
OCR Not Working
# Ubuntu/Debian
sudo apt-get install tesseract-ocr
# macOS
brew install tesseract
SPA 页面抓到空内容
页面是 JS 渲染的 SPA,markitdown 直连只能拿到空壳。改用 scripts/url_to_markdown.py,它会自动用本机
Chrome/Edge 无头渲染回退;服务器侧需先装 chromium(或 playwright install chromium)。
What This Skill Provides
| Component | Source |
|---|---|
markitdown CLI |
Microsoft's pip package |
markitdown Python API |
Microsoft's pip package |
scripts/batch_convert.py |
This skill (utility) |
scripts/url_to_markdown.py |
This skill (SPA fallback utility for web pages) |
scripts/token_saver.py |
This skill (OPTIONAL local token-cost/saving estimator) |
scripts/measure_tokens.py |
This skill (OPTIONAL token measurement / compare tool for any text) |
| Documentation | This skill |
See Also
- USAGE-GUIDE.md - Detailed examples
- reference.md - Full API reference
- TOKEN-SAVER.md - Token-saving methodology
- TOKEN-AUDIT.md - Token audit methodology (optional component)
- Microsoft MarkItDown - Upstream library
