news 2026/9/13 19:30:51

Label Studio Document AI 界面模板:用 ReactCode 构建 PDF 文档理解标注界面

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Label Studio Document AI 界面模板:用 ReactCode 构建 PDF 文档理解标注界面

Label Studio Document AI 界面模板:用 ReactCode 构建 PDF 文档理解标注界面

【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio

Label Studio 的 Interfaces(可编程界面)体系允许你用 React 代码在标注平台内嵌入完全自定义的标注界面。本文基于仓库中的 Document AI 模板文档,完整讲解这个面向 PDF 与文档图片的“文档理解”界面:它如何组合区域框选、hOCR 词级文本选择、表格结构编辑、文档/页面级分类与字段抽取五大能力,以及其 React 代码中参数模式、颜色映射、项目配置和结果输出的定制要点,帮助你在企业版环境中快速搭建 layout、OCR 与字段抽取(field extraction)工作流。

这个界面解决什么问题

Document AI 模板创建一个文档理解标注界面,用于对 PDF 和文档图片进行如下标注:

  • 对文档区域(标题、作者、摘要、图表、表格、引用等)画边界框并打区域标签;
  • 基于 hOCR 词级坐标选择真实文本片段(text span),并捕获转录文本;
  • 用可拖拽的行列分隔线标注表格结构,支持合并单元格、逐格标签与自动提取的单元格转录;
  • 建立区域之间的关联(例如把图注链接到图、把引用链接到参考文献条目);
  • 对整个文档或逐页做类型分类。

产出的是结构化程度很高的标注结果,直接服务于 Document AI 团队的 layout 分析、OCR 训练与字段抽取场景。

两点使用前须知(来自模板文档的明确约束):

  • 仅限企业版:Interfaces 只能在 Label Studio Enterprise 和 Starter Cloud 中使用;
  • 必须复制后再编辑:从Interfaces > Templates进入,点击目标模板旁边的溢出菜单(overflow menu),选择Duplicate生成可编辑副本,然后才能修改。

该模板在仓库中的位置与入口:模板文档位于 docs/source/templates/interfaces-document-ai.md,并收录于 Interfaces 模板画廊 docs/source/templates/gallery_interfaces.ejs 的 “Document AI” 卡片中(分类为 Interfaces / Document AI)。

界面 UI 结构

整个界面分为三栏:左侧的工具/实体栏(tool/entity rail)、中间的文档视口(document viewport)、右侧的选项卡式检查器面板(inspector panel)。

工具与实体栏

左侧纵向栏分为两个堆叠区:

  • Tools(工具):Select(V)、Pan(H)、Bounding box(B)、Text span(T)、Words(P)、Table(R)。当前激活的工具决定在视口中“点击并拖拽”触发的动作。
  • Entity labels(实体标签)entityTypes中每一项对应一个按钮,前九个条目自动获得热键1-9。选中某个实体后,接下来创建的标注就会应用该标签。

文档视口

中间的阅读主区域,行为按文档来源区分:

  • PDF 场景:页面通过 PDF.js 渲染,支持连续滚动、当前页指示、缩放控件和跳页导航;
  • 图片场景:单页视口渲染任务数据中的image字段;
  • 提供了hocr字段时:会叠加词级位置信息,使Text spanWords工具能够选中真实文本;在文本上直接画的边界框还会自动捕获一份transcription
  • 已有标注渲染为彩色覆盖层,选中区域显示八个方向的缩放手柄;
  • 表格以可拖拽的行列分隔线呈现,右键点击单元格打开逐格标签菜单,并暴露 merge(合并)操作。

检查器面板

右侧栏提供五个选项卡:

选项卡作用
Annotations列出所有区域:实体标签、页码范围、转录预览,以及每行的删除控件
Transcription编辑所选区域的转录文本;当沙箱 bundle 提供documentAI.recognizeImage时显示 OCR 按钮
Classifications可切换的 chip:Document type(取自documentTypes)与逐页Page type(取自pageTypes
Links查看和创建区域间链接;每条链接以linkedTo: [targetId, ...]形式存储在源区域上
Extraction可配置的抽取模式(schema),把实体类型绑定到命名字段(例如Authors→ 所有标为Author的区域),保存前可预览结构化对象

面板顶部还有一个搜索栏,可按转录文本或实体标签过滤区域。

React 代码:四个最值得定制的模块

完整Screen.jsx源码约 9,400 行,模板文档挑选了日常定制最可能涉及的四部分:任务数据参数、实体颜色表、内部PROJECT_CONFIG块(工具、特性、抽取模式)、以及写回 Label Studio 的结果结构。

界面参数 paramsSchema

在 Interface 配置中设置或重命名参数,可以指向不同的任务字段,或替换三套标签集(区域标签、文档类型、页面类型)。默认值与下文示例输入对应:

const paramsSchema = { type: "object", title: "Document AI Parameters", properties: { pdfField: { type: "dataField", default: "pdf", description: "Task data field containing the PDF URL", }, entityTypes: { type: "labels", description: "Labels available for annotating document regions", default: [ { name: "Title", color: "#10b981" }, { name: "Author", color: "#8b5cf6" }, { name: "Abstract", color: "#06b6d4" }, { name: "Section Header", color: "#f59e0b" }, { name: "Paragraph", color: "#64748b" }, { name: "Figure", color: "#10b981" }, { name: "Table", color: "#f97316" }, { name: "Citation", color: "#6366f1" }, // ... ], }, documentTypes: { type: "labels", description: "Document-level classification labels", default: [ { name: "Research Paper", color: "#3b82f6" }, { name: "Review Article", color: "#8b5cf6" }, { name: "Technical Report", color: "#10b981" }, // ... ], }, pageTypes: { type: "labels", description: "Page-level classification labels", default: [ { name: "Title Page", color: "#10b981" }, { name: "Abstract", color: "#06b6d4" }, { name: "Content", color: "#3b82f6" }, { name: "Tables", color: "#f97316" }, // ... ], }, }, };

除了显式声明的pdfField,界面还会从输入 schema 中读取imageFieldhocrField,默认值分别为imagehocr。任务数据中pdfimage二者必须至少提供一个。

实体颜色映射 ENTITY_COLORS

ENTITY_COLORS是模块级颜色表,被getEntityColortoScreenRegionFromAnn以及视口覆盖层共同使用。如果重命名或新增标签,需要同步维护这张表——注意它使用实体的内部id(小写、snake_case),而不是面向用户的label

const ENTITY_COLORS = { title: "#10b981", author: "#8b5cf6", affiliation: "#a855f7", abstract: "#06b6d4", section: "#f59e0b", paragraph: "#64748b", figure: "#10b981", figure_caption: "#34d399", table: "#f97316", table_caption: "#fb923c", equation: "#ec4899", citation: "#6366f1", reference: "#818cf8", list: "#14b8a6", footnote: "#78716c", header: "#9ca3af", footer: "#6b7280", page_number: "#525252", classifications: "#94a3b8", classificationMetadata: "#94a3b8", }; function getEntityColor(entityType) { return ENTITY_COLORS[entityType] || "#94a3b8"; }

未命中的实体类型会回退到中性灰#94a3b8,这也是classifications/classificationMetadata两个元数据类实体使用的颜色。

PROJECT_CONFIG:工具、特性与抽取模式

DocumentLabelingInterface内部,PROJECT_CONFIG是工具面板、特性开关和默认字段抽取模式的唯一事实来源(single source of truth)。Interface 设置中的params只覆盖entityTypesdocumentTypespageTypes三项;其余内容(toolsfeaturesfields)都需要在这个代码块里修改:

const PROJECT_CONFIG = { name: "Scientific Paper Labeling", contentType: "pdf", tools: { select: true, // Selection tool (V) pan: true, // Pan/hand tool (H) box: true, // Bounding box tool (B) span: true, // Text span selection (T) words: true, // Word selection tool (P) table: true, // Table annotation (R) }, features: { documentClassification: true, pageClassification: true, linking: true, transcription: true, tableEditing: true, search: true, extraction: true, }, // entityTypes, documentTypes, pageTypes are seeded here but // are overridden by params when the Interface is configured. fields: [ { id: "paper_title", label: "Paper Title", type: "string" }, { id: "authors", label: "Authors", type: "string" }, { id: "venue", label: "Venue/Journal", type: "string" }, { id: "year", label: "Year", type: "string" }, ], };

features的七个开关与检查器面板的一一对应关系:documentClassification/pageClassification对应 Classifications 选项卡,linking对应 Links,transcription对应 Transcription,tableEditing对应表格分隔线编辑,search对应面板顶部搜索栏,extraction对应 Extraction 选项卡。要裁剪界面,直接关掉对应开关即可。

结果结构 getResults

getResults为每个区域输出一条 Label Studio result。所有 result 统一使用from_name: "documentai"type: "documentai",完整标注负载(包括各类型专有字段)整体序列化进value,再由value内的type字段区分四种形态:

function getResults(regions, _relations) { return regions .filter(r => r._documentAI) .map(r => ({ id: r.id, from_name: "documentai", to_name: "document", type: "documentai", value: { ...r._documentAI }, origin: "manual", })); }

value内的四种标注形态:

  • Bounding box{ type: "boundingBox", entityType, x, y, w, h, page, startPage, endPage, transcription, linkedTo? }
  • Text span{ type: "textSpan", entityType, x, y, w, h, highlightRects, selectedText, transcription, spans, page, startPage, endPage }
  • Table{ type: "table", entityType: "table", x, y, w, h, tableData: { rows, cols, headerRows, headerCols, cellLabels, mergedCells, cellTranscriptions } }
  • Classification metadata{ type: "classificationMetadata", entityType: "classifications", documentClassification, pageClassifications }

坐标xywh均为页内相对百分比(0–100),不是像素值——这与 Label Studio 其他图像标注的归一化坐标约定一致,便于跨分辨率复用标注。

示例输入:任务数据格式

界面期望的data对象包含一个文档来源——pdf(PDF URL)或image(图片 URL)——以及可选的hocr字符串(为 text span 和单词拾取提供词级坐标)。字段名可通过pdfFieldimageFieldhocrField配置。

{ "data": { "pdf": "https://example.com/papers/2026-05-attention-is-all-you-still-need.pdf", "hocr": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n <body>\n <div class=\"ocr_page\" id=\"page_1\" title=\"bbox 0 0 800 1000\">\n <span class=\"ocrx_word\" title=\"bbox 80 140 480 188\">Attention</span>\n <span class=\"ocrx_word\" title=\"bbox 490 140 560 188\">Is</span>\n <span class=\"ocrx_word\" title=\"bbox 570 140 670 188\">All</span>\n <!-- ... more ocrx_word entries ... -->\n </div>\n </body>\n</html>" } }

纯图片任务则用imageURL 替换pdf

{ "data": { "image": "https://example.com/scans/invoice-2026-05-13.png", "hocr": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> ... </html>" } }

hOCR 采用标准ocr_page/ocrx_word结构:每个词是一个spantitle属性携带bbox x1 y1 x2 y2(像素坐标,页内坐标系),界面据此把词级选择落到真实文本上。

示例输出:四种形态齐全的标注结果

保存后的标注中每个区域对应一条 result。下面的示例同时展示了全部四种形态:标题的 bounding box(带linkedTo引用)、摘要的 text span、第 3 页的表格,以及一条承载文档级与逐页级分类的 classification-metadata:

{ "result": [ { "id": "1747156800000", "from_name": "documentai", "to_name": "document", "type": "documentai", "value": { "id": 1747156800000, "type": "boundingBox", "entityType": "title", "x": 12.5, "y": 8.2, "w": 75.0, "h": 4.8, "page": 1, "startPage": 1, "endPage": 1, "transcription": "Attention Is All You Still Need", "linkedTo": [1747156800001] } }, { "id": "1747156800002", "from_name": "documentai", "to_name": "document", "type": "documentai", "value": { "id": 1747156800002, "type": "textSpan", "entityType": "abstract", "x": 12.4, "y": 18.6, "w": 75.3, "h": 11.2, "highlightRects": [ { "x": 12.4, "y": 18.6, "w": 75.3, "h": 1.6 }, { "x": 12.4, "y": 20.4, "w": 75.3, "h": 1.6 } ], "selectedText": "We revisit the original Transformer architecture and find that...", "transcription": "We revisit the original Transformer architecture and find that...", "spans": ["w_42", "w_43", "w_44", "w_45"], "page": 1, "startPage": 1, "endPage": 1 } }, { "id": "1747156800003", "from_name": "documentai", "to_name": "document", "type": "documentai", "value": { "id": 1747156800003, "type": "table", "entityType": "table", "x": 14.0, "y": 42.0, "w": 72.0, "h": 22.0, "page": 3, "startPage": 3, "endPage": 3, "tableData": { "rows": [0, 18, 36, 54, 72, 100], "cols": [0, 30, 55, 78, 100], "headerRows": [0], "headerCols": [0], "mergedCells": [], "cellLabels": { "0,0": "Model", "0,1": "Params", "0,2": "BLEU", "0,3": "Notes" }, "cellTranscriptions": { "1,0": "Baseline", "1,1": "65M", "1,2": "26.4", "2,0": "Ours", "2,1": "65M", "2,2": "27.9", "3,0": "Ours-Big", "3,1": "213M", "3,2": "29.1" } } } }, { "id": "1747156800004", "from_name": "documentai", "to_name": "document", "type": "documentai", "value": { "id": 1747156800004, "type": "classificationMetadata", "entityType": "classifications", "documentClassification": "research_paper", "pageClassifications": { "1": "title_page", "2": "abstract", "3": "tables", "4": "content", "5": "references" } } } ] }

几个值得注意的细节:

  • tableData.rows/cols边界百分比数组(示例中rows: [0, 18, 36, 54, 72, 100]表示 5 行),而不是行列计数;headerRows/headerCols指出哪些是表头行列;cellLabelscellTranscriptions"row,col"字符串为键;
  • text span 的highlightRects是逐行高亮矩形数组,spans记录被选中词的 hOCR 词 id;
  • pageClassifications以页码字符串为键,值是与pageTypes标签对应的 snake_case id(如title_page),与documentClassification的取值风格一致;
  • 跨页区域通过startPage/endPage表达,多页 bounding box 也依赖这两个字段。

实现佐证:Interfaces 在 Label Studio 中的承载方式

结合仓库源码与文档结构,可以确认该模板的运行载体是<ReactCode>标签(旧名 ReactApp):

  • 标签文档 docs/source/tags/reactcode.md 说明:<ReactCode>把自定义标注 UI 嵌入 Label Studio,同时把输出保存为常规的 Label Studio regions/results,从而继续复用平台的标注管理、审核工作流与数据导出能力;该标签同样标注为仅企业版可用。
  • 从源码结构看,web/libs/editor/src/tags/Custom.jsx 是标签的实际实现入口,文件头注释表明“标签已更名为 ReactCode,两个名称都受支持”。
  • 本文的getResults输出(from_name/to_name/value)正是ReactCode标签文档中“outputs 参数”约定下的结果序列化形式:from_name对应标签的namedocumentai),to_name对应任务数据来源字段(document)。
  • 更多 Interfaces 模板的总览见 docs/source/guide/interfaces.md,以及画廊文件 docs/source/templates/gallery_interfaces.ejs(与 Document AI 同列的还有 Doclang、LiDAR、Agent Evaluation 等模板)。

落地要点小结

  1. 前置条件:Label Studio Enterprise 或 Starter Cloud;从 Interfaces > Templates 中Duplicate出可编辑副本后再改代码。
  2. 数据接入:任务data至少提供pdfimage;强烈建议同时提供hocr,否则 text span / Words 工具失去词级定位能力,边界框也不会自动捕获转录。字段名可用pdfField/imageField/hocrField覆盖默认值。
  3. 定制路径:改标签集走 Interface 配置(paramsSchema);改工具、特性开关、抽取fields走代码中的PROJECT_CONFIG;改视口颜色必须同步ENTITY_COLORS且注意键是 snake_case 内部 id。
  4. 下游对接:导出的每条 result 都是type: "documentai",需按value.type分派处理四种形态;坐标是 0–100 的页内百分比,换算像素时需结合该页渲染尺寸。

【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 19:28:31

FOC算法实战指南:从磁场定向控制到SVPWM调机

你有没有遇到过这样的情况&#xff1a;同一块电机驱动板&#xff0c;别人跑起来顺滑、安静、加速跟脚&#xff0c;你跑起来要么嗡嗡响&#xff0c;要么低速一抖一抖&#xff0c;稍微一堵就过流报警。如果这种场面你很熟&#xff0c;那大概率是和FOC 算法还没磨合好。FOC&#x…

作者头像 李华
网站建设 2026/9/13 19:27:20

mootdx 0.8.7实战:A股行情与财务数据获取指南

简介&#xff1a;mootdx-0.8.7.tar.gz 是专注于 A 股市场的 Python 行情数据接口库&#xff0c;面向量化分析、金融数据挖掘及后端服务开发人员&#xff0c;用于解决通达信行情数据的获取、解析与本地化存储问题。包体体积仅 32KB&#xff0c;共含 38 个文件&#xff0c;其中 2…

作者头像 李华
网站建设 2026/9/13 19:25:42

秒杀系统实战:Spring Boot+Vue实现高并发库存扣减与消息队列削峰

简介&#xff1a;这是一份面向Java毕业设计或期末项目的完整秒杀系统源码包&#xff0c;基于Spring Boot与Vue实现前后端分离架构&#xff0c;覆盖用户登录、商品列表、秒杀下单、订单管理及高并发处理等核心模块&#xff0c;适合想深入掌握高并发场景、数据库优化与项目部署的…

作者头像 李华