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
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 端把拖入的文件解析回真实路径。
为什么这样设计
这是经过验证后收敛出来的架构,几个关键取舍:
-
零
@deepseek-ai依赖:社区 bundle 会被dsh plugin add装进 profile 的node_modules,那里没有 DSH 内部包。因此 host 只用 Node 内置(node:fs/node:path+ 原生fetch),client 端拖入面板用纯 DOM(不 import React),只有设置卡片用 platform seed 里的react。 -
原生
fetch而非 Python:bundle 的 host 运行在真实 Node 进程里(不同于动态插件的受限沙箱),可以直接fetch调百度 API。相比早期的 Python 脚本方案,零外部依赖、更可分发。 -
Client ↔ Host 走 HTTP 路由(而非动态插件的
host.call):bundle 没有动态插件那种「Package 私有 RPC」,标准做法是 host 注册webServer路由、clientfetch调用。这是 dsh-drag-and-drop / modlens 等社区 bundle 的同一模式。 -
key 永不回传浏览器:设置页只读到
hasKey布尔值,真值只存在于${DSH_HOME:-~/.dsh}/baidu-ocr.json(0600权限),提交时留空 = 保留原值。参照 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(留空 = 保留) │
└─────────────────────────────────────────────────────────────────┘
能力一览
双引擎
| 引擎 | 接口 | 模式 | 适用 | 输出 |
|---|---|---|---|---|
paddleocr | qianfan.baidubce.com/v2/ocr/paddleocr | 同步 | 图片、PDF 通用识别 | markdown.text |
unlimited | aip.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
三种来源,优先级从高到低:
- 设置页(推荐):设置 → 插件 → 百度 OCR,填 key 保存 → 写入
${DSH_HOME:-~/.dsh}/baidu-ocr.json; - credentials 服务:
ctx.get('credentials').resolve('BAIDU_OCR_KEY'); - 环境变量:
export BAIDU_OCR_KEY="bce-v3/ALTAK-.../..."。
key 格式为百度 BCE IAM API Key(bce-v3/ALTAK-.../...),对两个引擎的 Bearer 鉴权都有效。
获取:https://console.bce.baidu.com/iam/#/iam/accesslist
使用
方式一:拖入
- 从 Finder(或文件管理器)拖文件到页面任意位置,全屏出现「松开以添加文件到 OCR」提示;
- 右下角「百度 OCR」面板弹出,文件变成可删除的 chip(hover 显示完整路径);
- 选引擎(自动 / PaddleOCR-VL / Unlimited-OCR),点「识别 N 个文件」;
- 结果卡片显示 markdown 预览 + 结果文件路径,
.md/.json落到源文件旁。
面板可拖动标题栏移动、收起成 OCR 圆钮(悬浮在输入框上方,不挡发送按钮)、支持粘贴绝对路径手动添加。
方式二:模型工具
在对话里直接说:
用 baidu_ocr 识别 /absolute/path/to/image.png
工具返回预览 + 文件路径;要拿完整文本,再让 Agent 用 read 读 markdownFile。
输出
每个文件在 <源目录>/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.json(0600权限),会话日志里不出现。 - 跨站写防护(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-list(file:// 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