Skip to content

Repository files navigation

dsh-multimodal-skill · 慧眼

🌐 中文 · English README

给纯文本 LLM 一双慧眼。 一个 DeepSeek Harness(DSH)原生 skill + 零依赖 Python CLI, 为 DeepSeek 等纯文本模型补上图像理解文档解析(OCR、表格、公式、PDF → Markdown), 使用免费额度优先的三方多模态 API,国内网络直连、无需代理。

核心特色 —— 🔄 内容寻址缓存:相同文件 + 相同问题只调一次 API(sha256 指纹、磁盘落盘、 跨会话共享、TTL/LRU 自动淘汰),避免重复请求、浪费免费额度;再叠加零依赖 (纯 Python 标准库)与自愈 provider 链(模型下线 / 限流 / 坏 key 自动切换),开箱即用。

许可证 Python 零依赖 缓存 DSH

慧眼

《慧眼》,灵感源自 1993 年的流行歌曲《雾里看花》。 作者在使用 DeepSeek 的过程中,仿佛听到它发出这样的呼唤:“借我借我一双慧眼吧,让我把这纷扰看得清清楚楚……”。 如今有了“慧眼-skill”,我终于可以对 DeepSeek 说:“帮我把这张截图看清楚”—— 它会自动调用 mm_cli.py,把 OCR/解析结果读回上下文,再回答你。

dsh-multimodal-skill demo

为什么需要这个 skill?

DeepSeek(以及许多编码模型)是纯文本的——它们看不见。 当你把截图、PDF 或图表 交给 agent 时,模型无法理解。这个 skill 就是那座缺失的桥:

截图 / PDF / 图片
        │
        ▼
mm_cli.py(仅 Python 标准库 —— 无需 pip install、无需 venv)
        │
        ├─ 文档 → Markdown   (PaddleOCR-VL / MinerU / DeepSeek-OCR)
        └─ 图片 → 文本       (GLM-4V-Flash / Qwen3-VL / qwen-vl-max)
        │
        ▼
Markdown / 文本 → 回到 LLM 上下文

模型把提取出的 Markdown 当作自己的“视网膜”:忠实 OCR 与版面解析交给专用解析 API (一个 0.9B 的文档 VLM 在忠实解析上胜过前沿通用模型 —— OmniDocBench 基准), 语义理解由文本模型自己完成。

特性亮点

  • 零依赖 —— 只有一个 mm_cli.py,纯 Python 标准库(urllib/json/base64)。 无需 pip install、无需 requirements.txt、无需 venv。
  • 免费优先 —— 每个默认 provider 都有慷慨的免费额度: PaddleOCR 官方 API(每模型 3000 页/日)、MinerU(免 key)、智谱 GLM-4V-Flash(完全免费), 另有 SiliconFlow 与 DashScope 兜底。
  • 国内网络友好 —— 默认 providers 全部国内可达,无需代理 (Gemini / Mistral / HuggingFace 国内不可达 —— 已剔除)。
  • 自愈 —— 模型下线、限流(429)、队列满、key 失效全部自动处理: 候选模型轮换、provider 链切换、退避重试、短期失败记忆。 见 references/troubleshooting.md
  • 格式感知路由 —— txt/md/csv/tsv 与本地 HTML 零模型成本本地解析 (stdlib 编码探测、csv → Markdown 表格、html.parser → Markdown); docx/xlsx/pptx 自动路由到 MinerU 打头;PDF/图片走 PaddleOCR-first 链。 见 references/formats.md
  • 内容寻址缓存 —— sha256(文件 + prompt + 模型) 作 key,TTL(文档 30 天 / 图片 24 小时)、 LRU 淘汰(2000 条 / 2GB)。省配额,让重试免费。
  • 干净的输出纪律 —— 结果走 stdout、诊断走 stderr,退出码 0–6 供 agent 自动化。
  • 面向 LLM 的提取元数据 —— 每次 doc parse 结果都带事实性 <!-- mm-meta: {...} --> 头(format、mode、provider、model、pages、stats、over), 消费方 LLM 清楚知道是谁解析的,可自行决定信任与复核。绝不捏造置信度。
  • 输出护栏 —— 交给 LLM 的每个字符串都经过可配置上限检查 (字节 / 行数 / 单行 / 估算 token,默认 64K token)。超限时不输出全文: 写入 UTF-8 文件并返回路径,由 LLM 用自己的工具读取/grep。绝不静默截断。

文档格式路由

doc parse 自动探测文件类型(magic bytes 优先、扩展名兜底)并按表格路由。 手动 --provider 可绕过路由(仅调试)。

格式 探测 路由 / 链头 本地零模型解析 备注
PDF (.pdf) %PDF magic paddleocr → mineru → siliconflow PaddleOCR 擅长扫描件/版面;≤100 页/文件(PaddleOCR),≤20 页/10MB(MinerU flash)
图片 PNG/JPEG/WebP/GIF/BMP magic bytes paddleocr → mineru → siliconflow 可作为单页文档解析;问答走 image ask
TIFF (.tif/.tiff) II*\0 / MM\0* magic paddleocr → mineru → siliconflow 上游上报为 image/tiff
Word/Excel/PPT (.docx/.xlsx/.pptx) PK zip + [Content_Types].xml mineru(其他 provider 无此能力,自动过滤) MinerU 官方支持 Office;flash ≤10MB/20 页;大文件转 PDF
旧版 Office (.doc/.xls/.ppt) OLE2 D0CF11E0 magic 无 provider 支持 → 明确报错并提示转 docx/pdf 避免在不受支持的格式上浪费配额
纯文本 .txt/.md/.tsv/.log/.json/.yaml 无 magic + 非二进制启发式 本地读取(零配额、零延迟、数据不出本机) 编码自动探测:UTF-16(BOM/启发式)→ UTF-8 → GB18030 → Latin-1
CSV/TSV 文本 + 扩展名 本地 csv → Markdown 表格 csv.Sniffer 自动识别分隔符;处理带引号的逗号/换行
本地 HTML (.html/.htm) 文本 + 扩展名 本地 html.parser → Markdown 标题/列表/表格/链接/图片/代码块;JS 渲染页面提取过短时回退 mineru
未知 无 magic、无扩展名匹配 先文本探测(整文件可打印比例)→ 仍失败才报错 探测 报错信息列出所有支持格式

每次结果都带 <!-- mm-meta: {...} --> 头(--json 时为 meta 字段): format(分组)、modelocal = 本地确定性解析 / model = 厂商模型)、 provider/model(实际解析器)、pages(厂商上报时)、stats(字节/行/token 测量) 与 over(超限标记)。超限时 paths.result 指向导出的 UTF-8 文件 (paths.source 指向原始本地文件)。skill 只报告事实—— 置信度判断与是否建议人工复核,留给消费方 LLM。

环境要求

要求 检查
Python 3.8+ python3 --version
DeepSeek Harness(DSH) dsh --version(dsh web / dsh CLI 均可)
至少一个 API key 配置
网络 国内直连(默认 providers);无需代理

安装(DSH 原生 skill)

DSH 的 dsh-skill-filesystem 会自动扫描 ~/.dsh/skills/<name>/SKILL.md (另有项目级 .dsh/skills.agents/skillscustomSkillDirs 等根目录)。 目录名必须与 frontmatter 的 name 完全一致(kebab-case)。

方式一:软链接(推荐,单一事实来源)

mkdir -p ~/.dsh/skills
ln -sfn "$PWD" ~/.dsh/skills/dsh-multimodal-skill

方式二:git clone(更新走 git pull)

git clone https://github.com/v587d/dsh-multimodal-skill.git ~/.dsh/skills/dsh-multimodal-skill

方式三:项目级目录(仅当前项目可用)

SKILL.md(连同 scripts/references/)放进项目的 .dsh/skills/dsh-multimodal-skill/

装好后新开/重启一个 DSH 会话,skill 目录里就会出现 dsh-multimodal-skill; 加载时 DSH 会给出资源根目录(含 scripts/references/assets/), 下文 <skill_dir> 即该目录。

配置

1. API key(.env 或环境变量)

把 skill 目录下的 .env.example 复制为 .env(或直接导出环境变量)。 建议至少配一个文档 provider + 一个图片 provider。 CLI 读取优先级: 系统环境变量 > .env

变量 服务 用途 获取地址
PADDLEOCR_ACCESS_TOKEN PaddleOCR 官方 API 文档解析(默认) https://aistudio.baidu.com/index/accessToken
ZHIPUAI_API_KEY 智谱 GLM 图片理解(默认) https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys
MINERU_API_TOKEN MinerU 精准 API 文档解析(可选;flash 模式免 key) https://mineru.net/apiManage
SILICONFLOW_API_KEY SiliconFlow 图片 + 文档兜底 https://cloud.siliconflow.cn/account/ak
DASHSCOPE_API_KEY 阿里云百炼 DashScope 图片 + 文档(可选) https://bailian.console.aliyun.com/

2. 可选:config.json(付费模型 / 自定义链)

python3 <skill_dir>/scripts/mm_cli.py config open   # 创建并打开 ~/.config/multimodal-skill/config.json

除 provider 链与模型候选外,limits 段为交给 LLM 的每个字符串把关(默认值均可配置):

检查项 默认 用途
总字节 max_bytes 5 MB 整体大小上限
总行数 max_lines 20000 防止超大行数
单行字节 max_line_bytes 4096 防止压缩/Base64 大块
估算 token max_tokens 64K 上下文预算(CJK 加权估算器,小翻译表精确计数 —— 实测约 96ms @ 5MB)
输入硬上限 hard_max_bytes 20 MB 读文件前的 stat 预检

超限时不输出全文:CLI 写入 UTF-8 文件并返回路径(meta.paths.result; 本地文本输入还有 meta.paths.source),消费方 LLM 可用自己的工具读取/grep 片段。 cache clear 同时清理导出目录。

把付费/指定模型放在管线模型列表最前面即可优先使用 (如 "image_models": ["glm-4.5v", "glm-4v-flash"] —— 付费在前、免费兜底)。 完整模板见 config.example.json(JSONC 允许注释)。 快速查看:mm_cli.py providers

注:provider 列表在代码中固定(每个 provider 协议不同); 配置只能覆盖模型候选与默认链 —— 不能新增 provider。

快速开始

CLI=python3 <skill_dir>/scripts/mm_cli.py

# 0. 健康检查 —— 连通性、key、模型
$CLI doctor

# 1. 把截图粘贴到 DSH 对话 → 出现本地路径 → 提问
$CLI image ask /path/to/screenshot.png "这个报错是什么?"

# 2. 解析文档(PDF/扫描件/图片)为 Markdown
$CLI doc parse report.pdf --pages 1-20 --out report.md

# 3. 本地文本/CSV/HTML 本地解析 —— 零配额、零延迟
$CLI doc parse notes.csv          # → Markdown 表格
$CLI doc parse page.html          # → html.parser 转 Markdown

# 4. 零配置兜底(MinerU flash,免 key)
$CLI doc parse scan.pdf --provider mineru

# 5. 超限输出落盘;CLI 返回路径,由 LLM 自行 grep
$CLI doc parse huge.log           # → 输出超限,返回落盘路径,由 LLM 自行 grep

完整命令参考:references/api.md

Providers 与免费额度(2026-08 实测)

Provider 管线 免费额度 国内可达
PaddleOCR 官方 API 文档 每模型 3000 页/日(异步任务 API)
MinerU 文档 flash:免费、免 key、≤20 页/10MB;精准:1000 页/日高优
SiliconFlow DeepSeek-OCR 文档 免费额度实测零扣费
智谱 GLM-4V-Flash 图片 完全免费(GLM-4.6V-Flash 免费,高峰繁忙)
SiliconFlow Qwen3-VL 图片 按量计费(便宜)
DashScope qwen-vl-max/ocr 图片 + 文档 每模型约 100 万 token 免费(90 天)

安全

  • key 存放在 .env(权限 600)或环境变量 —— 绝不硬编码;.envconfig.json 已 gitignore。
  • 免费档可能用提交的数据训练(各 provider 通用政策)—— 不要把机密文档/截图发给免费档; 敏感材料请用付费模型(经 config.json)。
  • CLI 绝不自动执行 API 响应中的任何内容;输出为 stdout 上的纯文本/Markdown。
  • 报错信息可能回显 provider 响应 —— 不要把你发给解析 API 的文件里塞入机密。

缓存

缓存纯磁盘、文件化 —— 无内存状态、无守护进程、无加载/退出周期。 每次 CLI 调用都是全新进程,直接读写磁盘条目(写穿):

  • key = 内容寻址 sha256(文件字节 + 管线 + provider + 模型 + prompt + 参数);文件名即 key。
  • TTL 读取时惰性检查:文档 30 天、图片 24 小时(--ttl / --no-cache 覆盖)。
  • LRU 写入时目录扫描淘汰:2000 条 / 2GB 上限,最早访问的先丢。

简言之:一个 缓存风味的文件算子 —— 崩溃安全、跨会话共享 (一个会话里解析过的,下一个会话直接省配额)。

工作原理

两条管线(行业最佳实践:忠实解析与开放视觉分开):

  • doc parse —— 专用文档解析器 → Markdown(表格、LaTeX 公式、阅读顺序)。 PaddleOCR-VL-1.6 属 OmniDocBench SOTA 级别。
  • image ask —— OpenAI 兼容 VLM 对话,面向截图/照片/图表。

每次调用都走自适应链:按序尝试模型候选 → 模型下线/限流/鉴权失败时轮换或切换 provider → 聚合错误并给出有意义的退出码(2 用法 / 3 鉴权 / 4 限流 / 5 模型 / 6 网络)。

故障排查

常见问题(PaddleOCR 排队慢、GLM 429、MinerU 上传签名、中文输出乱码、缓存怪癖): references/troubleshooting.md

License

MIT


English

中文版(默认) · English

Give text-only LLMs eyes. A DeepSeek Harness (DSH) native skill + a zero-dependency Python CLI that adds image understanding and document parsing (OCR, tables, formulas, PDF → Markdown) to any text-only model such as DeepSeek, using free-tier-first third-party multimodal APIs. All default providers are reachable from mainland China without a proxy.

Key feature — 🔄 content-addressed caching: the same file + the same prompt hits the API only once (sha256 fingerprint, disk-backed, shared across sessions, auto-evicted via TTL/LRU) — no repeated requests, no wasted free quota — on top of zero dependencies (pure Python stdlib) and a self-healing provider chain (auto-rotation on model deprecation / rate limits / bad keys).

Why this skill?

DeepSeek (and many coding models) are text-only — they cannot see. When you paste a screenshot, a PDF, or a chart into your agent, the model has no way to understand it. This skill is that missing bridge:

screenshot / PDF / image
        │
        ▼
mm_cli.py (Python stdlib only — no pip install, no venv)
        │
        ├─ document → Markdown   (PaddleOCR-VL / MinerU / DeepSeek-OCR)
        └─ image    → text       (GLM-4V-Flash / Qwen3-VL / qwen-vl-max)
        │
        ▼
Markdown/text → back into the LLM's context

The model reads the extracted Markdown as its "retina": faithful OCR and layout parsing are delegated to specialist APIs (a 0.9B document VLM beats frontier models on faithful parsing — OmniDocBench), while the text model handles semantics.

Highlights

  • Zero dependencies — one mm_cli.py, pure Python standard library (urllib/json/base64). No pip install, no requirements.txt, no venv.
  • Free-first — every default provider has a generous free tier: PaddleOCR official API (3,000 pages/day/model), MinerU (free, no key), Zhipu GLM-4V-Flash (fully free), plus SiliconFlow & DashScope fallbacks.
  • China-network friendly — all default providers are mainland-reachable; no proxy required. (Gemini/Mistral/HuggingFace are blocked from CN — dropped.)
  • Self-healing — model deprecation, rate limits (429), queue-full, and bad keys are handled automatically: candidate-model rotation, provider fallback chains, backoff, and a short-lived failure memory. See references/troubleshooting.md.
  • Format-aware routing — txt/md/csv/tsv and local HTML are parsed locally with zero model cost (stdlib encoding detection, csv → Markdown tables, html.parser → Markdown); docx/xlsx/pptx auto-route to MinerU as chain head; PDF/images keep the PaddleOCR-first chain. See references/formats.md.
  • Content-addressed cachingsha256(file + prompt + model) keys, TTL (30d documents / 24h images), LRU eviction (2,000 entries / 2 GB). Saves quota, makes retries free.
  • Clean output discipline — results to stdout, diagnostics to stderr, exit codes 0–6 for agent automation.
  • LLM-facing extraction metadata — every doc parse result carries a factual <!-- mm-meta: {...} --> header (format, mode, provider, model, pages, stats, over) so the consuming LLM knows exactly who parsed the file and can decide trust/verification itself. Never fabricated confidence scores.
  • Output guardrails — every string handed to the LLM is checked against configurable limits (bytes / lines / single-line / estimated tokens, default 64K tokens). On over-limit the full text is not emitted: it is written to a UTF-8 file and the path is returned, so the LLM reads/greps snippets with its own harness tools. Never silently truncated.

Document format routing

doc parse auto-detects the file type (magic bytes first, extension fallback) and routes accordingly. Manual --provider bypasses routing (debug only).

Format Detection Route / chain head Local zero-model parse Notes
PDF (.pdf) %PDF magic paddleocr → mineru → siliconflow No PaddleOCR excels at scans/layout; ≤100 pages/file (PaddleOCR), ≤20 pages/10MB (MinerU flash)
Images PNG/JPEG/WebP/GIF/BMP magic bytes paddleocr → mineru → siliconflow No Parsable as single-page docs; Q&A via image ask
TIFF (.tif/.tiff) II*\0 / MM\0* magic paddleocr → mineru → siliconflow No Reported upstream as image/tiff
Word/Excel/PPT (.docx/.xlsx/.pptx) PK zip + [Content_Types].xml mineru (other providers lack this capability and are filtered out) No MinerU officially supports Office; flash ≤10MB/20 pages; convert large files to PDF
Legacy Office (.doc/.xls/.ppt) OLE2 D0CF11E0 magic No provider support → clear error with convert-to-docx/pdf hint No Avoid wasting quota on unsupported formats
Plain text .txt/.md/.tsv/.log/.json/.yaml etc. no magic + non-binary heuristic local read (zero quota, zero latency, data never leaves the machine) Encoding auto-detection: UTF-16 (BOM/heuristic) → UTF-8 → GB18030 → Latin-1
CSV/TSV text + extension local csv → Markdown table csv.Sniffer auto-detects delimiter; handles quoted commas/newlines
Local HTML (.html/.htm) text + extension local html.parser → Markdown Headings/lists/tables/links/images/code blocks; falls back to mineru when extraction is too short (JS-rendered pages)
Unknown no magic, no extension match text probe first (printable ratio over whole file) → error only if that fails probe Error message lists all supported formats

Every result carries a <!-- mm-meta: {...} --> header (meta field with --json): format (group), mode (local = deterministic local parse / model = vendor model), provider/model (actual parser), pages (when the vendor reports it), stats (bytes/lines/tokens measurements) and over (limit flags). When over-limit, paths.result points to the exported UTF-8 file (and paths.source to the original local file). The skill reports facts only — confidence judgment and whether to suggest manual verification are left to the consuming LLM.

Requirements

Requirement Check
Python 3.8+ python3 --version
DeepSeek Harness (DSH) dsh --version (dsh web or dsh CLI)
At least one API key see Configuration
Network mainland China OK (defaults); no proxy needed

Install (DSH native skill)

DSH's dsh-skill-filesystem automatically scans ~/.dsh/skills/<name>/SKILL.md (plus project-level .dsh/skills, .agents/skills, customSkillDirs, etc.). The directory name must exactly match the name in the frontmatter (kebab-case).

Option 1: symlink (recommended — single source of truth)

mkdir -p ~/.dsh/skills
ln -sfn "$PWD" ~/.dsh/skills/dsh-multimodal-skill

Option 2: git clone (updates via git pull)

git clone https://github.com/v587d/dsh-multimodal-skill.git ~/.dsh/skills/dsh-multimodal-skill

Option 3: project-level directory (this project only)

Put SKILL.md (with scripts/, references/) into your project's .dsh/skills/dsh-multimodal-skill/.

After installing, start/restart a DSH session and dsh-multimodal-skill will appear in the skill catalog. When loaded, DSH provides the resource base directory (containing scripts/, references/, assets/) — <skill_dir> below refers to that directory.

Configuration

1. API keys (.env or environment variables)

Copy .env.example to .env in the skill directory (or export the variables). At least one document provider + one image provider is recommended. The CLI reads keys with priority: system environment > .env.

Variable Service Used for Where to get it
PADDLEOCR_ACCESS_TOKEN PaddleOCR official API document parsing (default) https://aistudio.baidu.com/index/accessToken
ZHIPUAI_API_KEY Zhipu GLM image understanding (default) https://open.bigmodel.cn/usercenter/proj-mgmt/apikeys
MINERU_API_TOKEN MinerU precision API document parsing (optional; flash mode needs no key) https://mineru.net/apiManage
SILICONFLOW_API_KEY SiliconFlow image + document fallback https://cloud.siliconflow.cn/account/ak
DASHSCOPE_API_KEY Alibaba DashScope image + document (optional) https://bailian.console.aliyun.com/

2. Optional: config.json (paid models / custom chains)

python3 <skill_dir>/scripts/mm_cli.py config open   # creates & opens ~/.config/multimodal-skill/config.json

Beyond provider chains and model candidates, the limits section guards every string handed to the LLM (defaults; all configurable):

Check Key Default Purpose
Total bytes max_bytes 5 MB overall size cap
Total lines max_lines 20000 guards huge line counts
Single-line bytes max_line_bytes 4096 guards minified/base64 blobs
Estimated tokens max_tokens 64K context budget (CJK-weighted estimator, exact CJK count via small translate table — benchmarked ~96ms @ 5MB)
Input hard cap hard_max_bytes 20 MB stat pre-check before reading the file

On over-limit the full text is not emitted: the CLI writes it to a UTF-8 file and returns the path (meta.paths.result; plus meta.paths.source for local text inputs), so the consuming LLM can read/grep snippets with its own tools. cache clear also cleans the export directory.

Put paid/any model IDs first in a pipeline's model list to prefer them (e.g. "image_models": ["glm-4.5v", "glm-4v-flash"] — paid first, free fallback). See config.example.json for the full template (JSONC comments allowed). Quick look: mm_cli.py providers.

Note: the provider list is fixed in code (each provider speaks a different protocol); configuration can only override model candidates and default chains — it cannot add providers.

Quick start

CLI=python3 <skill_dir>/scripts/mm_cli.py

# 0. Health check — connectivity, keys, models
$CLI doctor

# 1. Paste a screenshot into the DSH chat → you get a local path → ask about it
$CLI image ask /path/to/screenshot.png "What error is shown here?"

# 2. Parse a document (PDF/scanned/image) into Markdown
$CLI doc parse report.pdf --pages 1-20 --out report.md

# 3. Local text/CSV/HTML is parsed locally — zero quota, zero latency
$CLI doc parse notes.csv          # → Markdown table
$CLI doc parse page.html          # → Markdown via html.parser

# 4. Zero-config fallback (MinerU flash, no key needed)
$CLI doc parse scan.pdf --provider mineru

# 5. Over-limit output is exported to disk; the CLI returns the path
$CLI doc parse huge.log           # → 输出超限,返回落盘路径,由 LLM 自行 grep

Full command reference: references/api.md.

Providers & free tiers (verified 2026-08)

Provider Pipeline Free tier Reachable from CN
PaddleOCR official API document 3,000 pages/day/model (async job API)
MinerU document flash: free, no key, ≤20 pages/10MB; precision: 1,000 pages/day high-priority
SiliconFlow DeepSeek-OCR document measured zero-cost on free credit
Zhipu GLM-4V-Flash image fully free (GLM-4.6V-Flash free, busy at peak)
SiliconFlow Qwen3-VL image pay-per-use (cheap)
DashScope qwen-vl-max/ocr image + document ~1M tokens/model free (90 days)

Security

  • Keys live in .env (permission 600) or environment variables — never hardcoded; .env and config.json are gitignored.
  • Free tiers may train on submitted data (a common policy across all providers) — do not send confidential documents/screenshots to free tiers. Use paid models (via config.json) for sensitive material.
  • The CLI never auto-executes anything from API responses; outputs are plain text/Markdown on stdout.
  • Error messages may echo provider responses — don't paste secrets into files you send to parsing APIs.

Caching

Cache is disk-only, file-backed — no memory state, no daemon, no load-on-start / flush-on-exit cycle. Every CLI invocation is a fresh process that reads and writes entries directly on disk (write-through):

  • Key = content-addressed sha256(file bytes + pipeline + provider + model + prompt + params); file name is the key.
  • TTL checked lazily on read: 30 days for documents, 24 h for images (--ttl / --no-cache to override).
  • LRU eviction by directory scan on write: 2,000 entries / 2 GB cap, oldest-accessed dropped first.

In short: a cache-flavored file operator — crash-safe, survives restarts, and shared across sessions (a parse cached in one session is a quota saved in the next).

How it works

Two pipelines (industry best practice: keep faithful parsing separate from open-ended vision):

  • doc parse — specialist document parsers → Markdown (tables, LaTeX formulas, reading order). PaddleOCR-VL-1.6 is OmniDocBench SOTA class.
  • image ask — OpenAI-compatible VLM chat for screenshots/photos/charts.

Every call runs through an adaptive chain: try model candidates in order → on model-deprecation/rate-limit/auth failure, rotate or switch provider → aggregate error with a meaningful exit code (2 usage / 3 auth / 4 rate / 5 model / 6 network).

Troubleshooting

Common issues (PaddleOCR slow queue, GLM 429s, MinerU upload signature, Chinese output garbling, cache quirks): references/troubleshooting.md.

License

MIT

About

给纯文本 LLM 一双慧眼。 一个 DeepSeek Harness(DSH)原生 skill + 零依赖 Python CLI, 为 DeepSeek 等纯文本模型补上图像理解与文档解析(OCR、表格、公式、PDF → Markdown), 使用免费额度优先的三方多模态 API,国内网络直连、无需代理。

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages