Auto-built from https://github.com/helwod/docling-webui
580
https://github.com/helwod/docling-webui
批量文档 OCR + AI 表格整理,浏览器里拖进去就能用。
把一堆图片(发票、合同、身份证、截图……)或者 PDF / Office 文档拖进网页,剩下的交给它:
不用写代码,不用装前端构建工具,打开浏览器就能操作。
拖文件进来,起个名字,勾不勾 LLM 都行,点一下就开始。

所有批次一目了然:状态、进度条、处理了多少文件、LLM 有没有跑完。支持暂停、置顶、批量删除。

点进某个批次后,你会看到:

任务详情页底部有一个 LLM 会话面板,可以围绕本批次的汇总表直接和模型对话、按指令重做表格:

失败排查示例:当模型返回无法解析为 JSON 时,错误提示会附带模型原始回复,会话里也能继续按指令重试。例如下面这个失败批次:

Docling Serve 地址、LLM 模型和 Key、OCR 引擎、表格模式……都在这里配。改完点保存即时生效,还有连接测试按钮。

浏览器 ──→ WebUI (:8001) ──┬── Docling Serve (:5001) ← OCR 引擎(必需)
└── LLM API (可选) ← AI 整理表格
WebUI 本身不含任何 OCR 模型——它只是一个调度器 + 可视化界面。真正的识别工作全部交给 Docling Serve 完成。LLM 也是可选的,不配也能正常做 OCR。
前端是原生 HTML/CSS/JS,由 FastAPI 同一进程托管,不需要单独的前端构建步骤或 Node.js 环境。
WebUI 离不开它,必须先有一个能用的实例。两种方式任选:
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install "docling-serve[ui]"
docling-serve run
首次启动会自动下载模型权重,需要联网,等它出现 Application startup complete 就好了。之后访问 http://localhost:5001/health 返回 200 就说明就绪。
只有一个健康检查路径:
/health。不是/v1/health,也不是/,记这个就行。
# CPU 版本,开箱即用
docker run -p 5001:5001 quay.io/docling-project/docling-serve
# 有 NVIDIA GPU?用加速版
docker run --gpus all -p 5001:5001 quay.io/docling-project/docling-serve-cu128
git clone https://github.com/helwod/docling-webui.git
cd docling-webui/src
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # 编辑 .env,填上 Docling 地址和 LLM Key(如果要用的话)
uvicorn app.main:app --host 0.0.0.0 --port 8001
打开浏览器访问 http://localhost:8001 ,就是你在上面截图里看到的那个界面了。
.env 里最关键的就这几项:
| 配置 | 说明 | 示例 |
|---|---|---|
DOCLING_BASE_URL | Docling Serve 地址(必填,填到端口即可) | http://localhost:5001 |
LLM_BASE_URL | LLM API 地址(可选) | https://api.deepseek.com/v1 |
LLM_MODEL | 模型名 | deepseek-chat |
LLM_API_KEY | API Key | sk-xxxxx |
LLM_TIMEOUT | LLM 调用超时(秒,可选,默认 600) | 600 |
不想把文档内容发到云端?本项目兼容 OpenAI 接口,可直接对接本机运行的 Ollama,所有 OCR 后处理与表格整理都在本地完成,无需联网、无需云 Key。
安装并启动 Ollama(默认监听 11434 端口,桌面端打开即自动运行)。
拉取本地模型(本项目默认推荐如下模型):
ollama pull lukey03/qwen3.5-9b-abliterated:latest
在 .env 里把 LLM 指向 Ollama(注意 /v1 后缀不能省,Ollama 走的是 OpenAI 兼容接口):
| 配置 | 值 |
|---|---|
LLM_BASE_URL | http://localhost:11434/v1 |
LLM_MODEL | lukey03/qwen3.5-9b-abliterated:latest |
LLM_API_KEY | ollama(Ollama 不校验 Key,随便填即可,如 ollama) |
模型说明:默认推荐
lukey03/qwen3.5-9b-abliterated:latest,是一个经过 abliterated(去除安全限制)的 Qwen3.5-9B 本地模型,适合在本机跑中文表格抽取与信息整理。若本地显存不足,可在 Ollama 官网另选更小的模型(如qwen2.5:7b等),只需把LLM_MODEL换成对应名字即可,其余配置不变。 同样支持在网页「设置」页直接填入上述地址与模型名,改完即时生效(页面优先级高于.env,并写入数据库)。
本地模型很慢,请耐心等待:本地 9B 模型生成整张汇总表可能要 1~3 分钟甚至更久,这不是「没有回复」,而是正在等待模型生成。前端会显示「LLM 思考中…(本地/较慢模型可能需要更长时间,请耐心等待)」。服务端的 LLM 调用超时默认是
LLM_TIMEOUT=600秒(10 分钟),一般不会中途掐断;若你的模型仍偶发超时,把LLM_TIMEOUT调大(如1200)即可,也可在网页「设置」里存llm_timeout覆盖。
不想用 LLM?上传时取消勾选「启用 LLM 表格整理」就行,纯 OCR 功能完全不受影响。 设置页改的参数会写入数据库,优先级高于
.env——也就是说你可以在网页里直接改配置,不用重启服务。
项目自带 docker-compose.yml,一条命令同时拉起 WebUI 和 Docling Serve:
docker compose up -d
然后:
两个服务通过内部网络互通,WebUI 自动连上 Docling,不用手动填地址。
如果想只部署 WebUI(Docling Serve 已经在别处跑了):
docker build -t docling-webui .
docker run -d -p 8001:8001 \
-e DOCLING_BASE_URL=http://<你的docling地址>:5001 \
-e LLM_API_KEY=sk-xxx \
docling-webui
前端所有资源引用(CSS/JS)和接口调用(含 PDF 预览图片)都已经是相对路径了,所以可以挂在任意子路径下,比如 https://your-site.com/docling/。后端本身也做了兼容处理:子路径模式下会自动注入 <base href="/docling/">、并把 /docling(末尾无斜杠)重定向到 /docling/,避免资源 404。
启动必须绑定
0.0.0.0:当你把程序放在容器里、或用独立反向代理访问时,务必让服务监听0.0.0.0而不是默认的127.0.0.1,否则代理侧会连不上(表现为整个页面、CSS、JS、图片全打不开)。# 推荐:显式指定 uvicorn app.main:app --host 0.0.0.0 --port 8001 # 或者直接(内部已默认绑定 0.0.0.0:8001) python -m app.mainDocker 镜像的
CMD已经是--host 0.0.0.0,docker run -p 8001:8001 ...即可。
反向代理有两种配置,关键是让 APP_ROOT_PATH 与代理行为一致:
方式 A(推荐):Nginx 剥离前缀,后端照常以根路径启动
location /docling/ {
proxy_pass http://127.0.0.1:8001/; # 注意结尾的 /,它负责把 /docling 前缀去掉
}
此时后端不需要设 APP_ROOT_PATH(留空即可)。浏览器访问 /docling/... → 代理去掉 /docling → 后端收到 /...,相对路径自动拼回 /docling/...,一切正常。
方式 B:代理不剥离前缀,告诉后端自己的前缀
如果你的 proxy_pass 后面没有 /(即不剥离前缀),就必须让后端知道自己挂在哪个子路径下:
location /docling/ {
proxy_pass http://127.0.0.1:8001; # 注意:没有结尾的 /,/docling 会被原样转发
}
APP_ROOT_PATH=/docling uvicorn app.main:app --host 0.0.0.0 --port 8001
APP_ROOT_PATH 的值必须和代理里的子路径完全相同(这里是 /docling)。
⚠️ 最常见的坑:代理不剥离前缀(方式 B 的 nginx 写法)却没设
APP_ROOT_PATH。这时后端只在/上注册路由,收到/docling/...直接 404,于是页面、CSS、JS、图片全打不开——看起来就是"CSS 和 JS 都有问题"。解决办法二选一:要么改成方式 A(剥离前缀、不设变量),要么保持方式 B 并补上APP_ROOT_PATH=/docling。
新增页面或 JS 时记得保持相对路径引用,别写
/assets/...或/api/...这种绝对路径,否则子路径部署会断掉。
Docling 连不上 / OCR 一直转圈?
先确认 curl http://<你的docling地址>:5001/health 返回 200。再检查 .env 或设置页里的地址是否填对(到端口为止,不要带 /v1)。设置页有「测试 Docling」按钮,点一下就知道通不通。
LLM 汇总表生成失败?
先别急着重传。失败原因会直接暴露出来:错误提示会附带模型原始回复的前 800 字,批次的「原始回复」面板也保留完整模型输出——据此判断是模型回了散文、还是 JSON 形状不对。然后在任务详情的 LLM 会话里按指令重新生成(即使之前没生成过/失败过也能操作,会退化为基于 OCR 重新生成),把格式要求写清楚即可重试。建议在设置页先用「测试连接」按钮验证通过;汇总表对模型的 JSON 输出能力有要求,尽量用支持 structured output 的模型。本地/慢模型若报「Empty LLM response」,多半是超时(见上),把 LLM_TIMEOUT 调大即可。
想完全本地化、不联网?
用 Ollama(见上文「用本地大模型(Ollama)」):LLM_BASE_URL 填 http://localhost:11434/v1、LLM_MODEL 填 lukey03/qwen3.5-9b-abliterated:latest、LLM_API_KEY 随便填(如 ollama)。文档内容全程不出本机。
端口被占了?
默认用 8001(8000 太容易被系统服务占)。换端口:uvicorn app.main:app --port <新端口号>。
重启后正在处理的任务丢了? 不会丢。后端启动时会自动把中断中的批次重置回队列,去任务列表重新点「开始处理」就能续跑。
导出的 CSV 没有图片? CSV 本来就不带图片嘛。要带缩略图的直观版本,选「导出 HTML」格式。
PDF 预览怎么实现的? 后端用 PyMuPDF 把 PDF 每页渲染成 PNG 图片并缓存,前端按页展示。点击字段高亮时会自动跳到对应页并在原图上画框。第一次打开某 PDF 会稍慢(取决于页数),之后就走缓存了。
Docling 启动好慢 / 吃资源?
首次确实要下载模型权重。纯 CPU 能跑但偏慢,生产环境建议上 GPU 镜像(-cu128 / -cu130),速度差距很大。
删除批次会删干净吗?
会。删除批次时,除了磁盘上的上传文件,数据库里该批次的 files(含 OCR 全文、LLM 结果)和 batch_chats(聊天记录)也会通过外键级联一并硬删除,不可恢复。删除前请确认;目前没有「回收站」式软删除。
src/ # 应用主目录(后端 + 前端合在一起)
├── app/
│ ├── main.py # 入口:API 路由 + 静态页面托管
│ ├── config.py # 配置读取(.env)
│ ├── db/ # SQLite 数据库
│ ├── routers/ # API:batches / files / config
│ ├── services/ # 核心业务:docling / llm / export / queue_scheduler
│ ├── repositories/ # 数据访问层
│ ├── models/ # 数据模型与 schema
│ └── utils/
├── index.html # 首页:上传并解析
├── tasks.html # 任务列表
├── task.html # 任务详情(PDF 预览 + 字段高亮 + 汇总表)
├── settings.html # 设置页
├── assets/ # CSS / JS(由 /assets 挂载)
├── data/ # 数据库文件(gitignore)
├── uploads/ # 上传文件(gitignore)
├── requirements.txt
├── .env.example
└── .env # 本地配置(不入库)
Dockerfile # WebUI 镜像
docker-compose.yml # WebUI + Docling 一体编排
Content type
Image
Digest
sha256:02d40beed…
Size
86.8 MB
Last updated
27 days ago
docker pull helwod/docling-webui