Back to home@pipiwolve

dsh-baidu-ocr

Baidu cloud OCR bundle for DeepSeek Harness: drag images/PDFs in, OCR to Markdown with PaddleOCR-VL or Unlimited-OCR. 百度云 OCR 插件:拖入图片/PDF 识别为 Markdown 并写入本地文件。

Stars
0
Language
JavaScript
Created
Aug 25, 2026
Updated
Aug 26, 2026
GitHub repo

Introduction

dsh-baidu-ocr

百度云 OCR 的 DeepSeek Harness Web 插件(bundle)。把图片 / PDF / 办公文档拖进页面,用百度云 OCR 识别为 Markdown,并把结果写成本地文件

  • PaddleOCR-VL(同步):千帆平台 qianfan.baidubce.com 的通用文字识别,返回 markdown.text,支持版面分析、图表识别、方向/畸变矫正。
  • Unlimited-OCR(异步):aip.baidubce.com 的文档解析,公式 LaTeX、表格 HTML、多栏版面智能合并。

一句话:一个 key、两个引擎、拖入即识别、结果落盘、既能 GUI 也能当模型工具用。


目录


它是什么

这是一个符合 DeepSeek Harness bundle 规范的插件包,安装后同时提供:

界面形态说明
拖入面板浏览器右下角浮窗拖入文件 → 自动解析真实本地路径 → 选引擎 → 识别 → 结果卡片预览
模型工具baidu_ocr 工具对话里直接 用 baidu_ocr 识别 /path/to/img.png,Agent 可自动调用
设置卡片设置 → 插件 → 百度 OCR在 GUI 里填写 API key(不回显、不落日志)

它解决的核心痛点:浏览器无法把「拖进来的文件」直接交给本地 OCR 引擎——浏览器只给你 File 对象(没有真实路径),而 DSH 的工具需要真实路径来读文件。本插件在 Host 端读真实路径、调 API、写结果文件,在 Client 端把拖入的文件解析回真实路径。


为什么这样设计

这是经过验证后收敛出来的架构,几个关键取舍:

  1. @deepseek-ai 依赖:社区 bundle 会被 dsh plugin add 装进 profile 的 node_modules,那里没有 DSH 内部包。因此 host 只用 Node 内置(node:fs/node:path + 原生 fetch),client 端拖入面板用纯 DOM(不 import React),只有设置卡片用 platform seed 里的 react

  2. 原生 fetch 而非 Python:bundle 的 host 运行在真实 Node 进程里(不同于动态插件的受限沙箱),可以直接 fetch 调百度 API。相比早期的 Python 脚本方案,零外部依赖、更可分发。

  3. Client ↔ Host 走 HTTP 路由(而非动态插件的 host.call):bundle 没有动态插件那种「Package 私有 RPC」,标准做法是 host 注册 webServer 路由、client fetch 调用。这是 dsh-drag-and-drop / modlens 等社区 bundle 的同一模式。

  4. key 永不回传浏览器:设置页只读到 hasKey 布尔值,真值只存在于 ${DSH_HOME:-~/.dsh}/baidu-ocr.json0600 权限),提交时留空 = 保留原值。参照 modlens 的安全模型。


架构

┌─────────────────────────────────────────────────────────────────┐
│  Host (lib/index.js, Node 进程, inject: [tools, webServer])      │
│                                                                 │
│  baidu_ocr 工具 ──┐                                             │
│                   ├─ resolveKey(ctx)  ── 设置文件 > credentials > env
│                   │                                             │
│  /baidu-ocr/run ──┼─ runOcr(path, engine, key)                  │
│  (client 面板用)  │    ├─ paddleocr()   → qianfan 同步 POST       │
│                   │    └─ unlimited()   → aip 提交→轮询→下载      │
│                   │    └─ writeResults() → ocr_output/*.md/.json  │
│                   │                                             │
│  /baidu-ocr/config ─ writeSettingsFile() → ${DSH_HOME:-~/.dsh}/baidu-ocr.json │
│  (设置页用)         readSettingsFile() → { hasKey } (不回显 key)   │
└─────────────────────────────────────────────────────────────────┘
                              │ HTTP (同源 fetch)
┌─────────────────────────────────────────────────────────────────┐
│  Client (lib/client.js, window.__ModuleLoader__)                 │
│                                                                 │
│  拖入面板(纯 DOM):                                              │
│    drag/drop → 解析 file:// URI → 真实路径 chip → 选引擎          │
│    → POST /baidu-ocr/run → 结果卡片 (markdown 预览 + 文件路径)     │
│    · 可拖动 / 可收起 / FAB 跟随 composer 上方(不挡发送按钮)        │
│                                                                 │
│  设置卡片(React, settings.plugin.item):                         │
│    GET /baidu-ocr/config → hasKey 状态                           │
│    POST → 写 key(留空 = 保留)                                   │
└─────────────────────────────────────────────────────────────────┘

能力一览

双引擎

引擎接口模式适用输出
paddleocrqianfan.baidubce.com/v2/ocr/paddleocr同步图片、PDF 通用识别markdown.text
unlimitedaip.baidubce.com/.../unlimited-ocr-parser异步(提交→轮询→下载)文档解析、公式、表格、多栏markdown_url 内容

引擎选择:

  • auto(默认):按扩展名自动选 —— 图片(jpg/png/bmp/tif…)→ paddleocr;办公文档/PDF(pdf/ofd/doc/docx/ppt/pptx…)→ unlimited
  • 也可在面板下拉框或工具参数里显式指定。

支持格式

类型扩展名
图片.jpg .jpeg .png .bmp .tif .tiff
版式文档.pdf .ofd
流式文档.doc .docx .txt .wps .ppt .pptx

安装

dsh plugin --profile web add <本仓库路径或 git url>

dsh plugin 是 pnpm 转发器:它把包加进 profile 的依赖,然后扫描声明了 dsh.bundle.patch 的包,自动 reconcile 进 dsh.profile.bundles 层栈。无需手改 config。

然后重启 Web UI 并刷新浏览器

dsh web --host 127.0.0.1 --port 3080 --no-open

注意:请用与当前运行实例同一个 dsh 二进制重启(如果你机器上有多个 dsh 版本,旧版可能不认 --no-open)。

安装后:

  • Host 注册 baidu_ocr 工具 + /baidu-ocr/run + /baidu-ocr/config 路由;
  • Client 注册右下角拖入面板 + 设置页「百度 OCR」卡片;
  • 3080 直连与 5173 皮肤壳(iframe 代理 /plugins)都会自动加载,无需手动配置。

配置 API Key

三种来源,优先级从高到低:

  1. 设置页(推荐):设置 → 插件 → 百度 OCR,填 key 保存 → 写入 ${DSH_HOME:-~/.dsh}/baidu-ocr.json
  2. credentials 服务ctx.get('credentials').resolve('BAIDU_OCR_KEY')
  3. 环境变量export BAIDU_OCR_KEY="bce-v3/ALTAK-.../..."

key 格式为百度 BCE IAM API Keybce-v3/ALTAK-.../...),对两个引擎的 Bearer 鉴权都有效。

获取:https://console.bce.baidu.com/iam/#/iam/accesslist


使用

方式一:拖入

  1. 从 Finder(或文件管理器)拖文件到页面任意位置,全屏出现「松开以添加文件到 OCR」提示;
  2. 右下角「百度 OCR」面板弹出,文件变成可删除的 chip(hover 显示完整路径);
  3. 选引擎(自动 / PaddleOCR-VL / Unlimited-OCR),点「识别 N 个文件」;
  4. 结果卡片显示 markdown 预览 + 结果文件路径,.md/.json 落到源文件旁。

面板可拖动标题栏移动、收起OCR 圆钮(悬浮在输入框上方,不挡发送按钮)、支持粘贴绝对路径手动添加。

方式二:模型工具

在对话里直接说:

用 baidu_ocr 识别 /absolute/path/to/image.png

工具返回预览 + 文件路径;要拿完整文本,再让 Agent 用 readmarkdownFile


输出

每个文件在 <源目录>/ocr_output/ 下产出两个文件:

  • <文件名>.md — Markdown 识别结果(含公式 LaTeX、表格 HTML);
  • <文件名>.json — 元数据:
{
  "engine": "paddleocr",
  "source": "/abs/path/to/image.png",
  "markdownFile": "/abs/path/to/ocr_output/image.md",
  "charCount": 1234,
  "requestId": "as-xxx",
  "generatedAt": "2026-08-24T08:00:00.000Z"
}

目录结构

dsh-baidu-ocr/
├── package.json          # dsh.bundle.patch + dsh.client 声明、exports、files
├── cordis.patch.yml      # insert 插件行的 bundle patch
├── lib/
│   ├── index.js          # host:baidu_ocr 工具 + /run + /config + 双引擎(原生 fetch,零依赖)
│   └── client.js         # client:拖入面板(纯 DOM)+ 设置卡片(React)
├── test/
│   └── index.test.js     # fence / 路径校验等纯逻辑的单元测试(node --test)
├── .github/workflows/ci.yml  # CI:语法检查 + 单元测试
└── README.md

安全

  • key 不回显、不落日志:设置页只拿到 hasKey 布尔值;真值存 ${DSH_HOME:-~/.dsh}/baidu-ocr.json0600 权限),会话日志里不出现。
  • 跨站写防护(CSRF fence)/baidu-ocr/config/baidu-ocr/run 复刻 DSH 自身 /api 的信任模型——副作用请求只接受 application/json 的 POST,并校验 Origin 与请求 Host 同源;恶意网页的跨站请求会被强制进入本服务永不应答的 CORS preflight。只读的 GET 也做 Origin 校验。
  • OCR 目标路径校验/run 只接受绝对路径、扩展名在白名单(图片 / PDF / 办公文档)、且确认为普通文件的目标,防止任意本地文件被上传到百度云(路径遍历 / 数据外带加固)。unlimited 引擎的结果下载只允许 https:// 的 markdown_url。
  • 结果文件写源目录.md/.json 写到源文件旁的 ocr_output/,可预期、可追溯。
  • 零依赖:host 只用 Node 内置,client 拖入面板纯 DOM,攻击面最小。

安全模型参照:DSH 的 /api 代理在 dsh-host-apiproxy 中以「仅接受 application/json」实现跨站写 fence;bundle 路由注册在 webServer(loopback),浏览器与 host 同源。


开发与调试

验证 host 逻辑

# 起临时实例(独立端口,不打扰正式 3080)
node /path/to/dsh/lib/bin.js web --host 127.0.0.1 --port 3090 --no-open

# 探测 config 路由(GET 不回显 key,POST 写 key)
curl http://127.0.0.1:3090/baidu-ocr/config
curl -X POST http://127.0.0.1:3090/baidu-ocr/config \
  -H "content-type: application/json" -d '{"apiKey":"bce-v3/..."}'

# 跑一次 OCR
curl -X POST http://127.0.0.1:3090/baidu-ocr/run \
  -H "content-type: application/json" -d '{"path":"/tmp/test.png","engine":"auto"}'

改 client 后生效

  • pnpm run dev:web(HMR watcher):client 改动热更新;
  • 无 watcher:改 lib/client.js 后,serveBundle 实时读磁盘,浏览器硬刷新(Cmd+Shift+R)即可;若要 rev 缓存键也更新,重启 dsh web

语法校验

node --check lib/index.js
node --check lib/client.js

单元测试

npm test

覆盖 host 侧的 CSRF fence 与目标路径校验等纯逻辑(test/index.test.js)。CI(.github/workflows/ci.yml)在每次 push 自动运行语法检查与测试。


FAQ

Q:为什么拖入能拿到真实路径? A:浏览器对拖入文件只暴露 File 对象,但文件管理器会带 text/uri-listfile:// URI)。client 端解析这些 URI 还原成本地绝对路径(POSIX / Windows 盘符 / UNC),再交给 host 读文件。这复用了 dsh-drag-and-drop 的定位思路。

Q:两个引擎的 key 一样吗? A:是。同一个 BCE IAM API Key(bce-v3/ALTAK-...)对 PaddleOCR-VL(千帆 Bearer)和 Unlimited-OCR(aip Bearer)都有效,一个 key 通吃。

Q:结果能直接「拖出」到任意文件夹吗? A:浏览器标准不支持「拖出写文件」,但 DSH 是本地 Web UI,host 直接写本地文件更可靠——结果落在源文件旁 ocr_output/,会话里展示预览 + 路径。

Q:为什么 5173 皮肤壳也能看到? A:皮肤壳是 <iframe> 代理 /plugins/api 到 3080,bundle 的 client 走静态路由 /plugins/dsh-baidu-ocr/client.js,两个视图都代理到了,无需重复配置。


路线图

  • 批量目录识别 + 并发限流(QPS 控制)
  • 结果文件路径做成可再拖入的 chip
  • 更多引擎(PP-OCRv6 通用文字识别)
  • 打包成 npm 包发布(当前为本地 link: 安装)

License

MIT