Label Studio List 标签实战指南:轻量列表展示、Ranker 排序标注与结果导出
【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio
List是 Label Studio 标签体系中用于展示"同类型条目集合"的对象标签,典型场景包括搜索结果、文章列表等。它比把多个Text标签塞进View分组更轻量,还能与Ranker标签组合实现拖拽排序、相关条目筛选,或配合Style标签定制界面外观。读完本文,你将掌握List的完整配置语法、任务数据结构要求、与Ranker/Bucket的协作模式、标注结果格式,以及对应的前端源码实现细节。
List 标签概述
在 Label Studio 的标注配置(Labeling Config)中,List标签用于展示一组同类型条目,例如文章、搜索结果、候选答案等。任务数据中value参数指向的字段应是一个对象数组,每个对象包含id、title、body、html字段。
官方文档与源码注释对它的定位很明确(见 List.jsx):
- 相比把多个
Text标签分组,List更加轻量,适合一次性展示大量同构条目; - 可以为列表附加分类标注(如
Choices等),提供关于该列表的额外信息; - 可与
Ranker标签配合,对列表条目进行排序或挑选相关条目; - 条目可以通过
Style标签中的.htx-ranker-item类进行样式定制。
List标签在标签体系中属于对象(Object)类型,通过Registry.addTag("list", ListModel, HtxList)注册,并同时注册为对象类型(Registry.addObjectType(ListModel)),因而可以作为toName的目标被其他控制标签(如Ranker、分类标签)引用。
参数详解
List标签支持以下参数(来源:文档 参数表 与源码 List.jsx):
| 参数 | 类型 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|---|
name | string | 是 | — | 元素名称,用于在标注结果中标识该列表,同时被toName引用 |
value | string | 是 | — | 任务数据字段名,其值应为 JSON 对象数组(每个对象含id、title、body、html字段),作为待展示/排序的条目 |
title | string | 否 | 空字符串 | 列表标题,会渲染为列标题文本 |
从源码模型定义看,List的 MobX State Tree 模型中还有内部字段_value(类型为 frozen 数组),它是在初始化时通过updateValue动作从任务数据解析填充的;title参数类型为types.optional(types.string, ""),即未提供时为空字符串。
任务数据结构要求
List标签的value指向的任务数据字段必须是对象数组,每个条目建议包含以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
id | string/number | 条目唯一标识;渲染时会被强制转为字符串,并作为拖拽与结果中的引用键 |
title | string | 条目标题,渲染为条目的标题行 |
body | string | 条目正文文本 |
html | string | 条目 HTML 内容,渲染前会经过sanitizeHtml净化(见 Item.tsx) |
官方文档给出的第一个示例是纯文本风格的列表数据:
{ "items": [ { "id": "blog", "title": "10 tips to write a better function", "body": "There is nothing worse than being left in the lurch when it comes to writing a function!" }, { "id": "mdn", "title": "Arrow function expressions", "body": "An arrow function expression is a compact alternative to a traditional function" }, { "id": "wiki", "title": "Arrow (computer science)", "body": "In computer science, arrows or bolts are a type class..." } ] }第二个示例展示如何使用html字段嵌入富媒体内容:
{ "items": [ { "id": "blog", "title": "Image 1", "html": "<img src='http://example.com/1.jpg'>" }, { "id": "mdn", "title": "Image 2", "html": "<img src='http://example.com/2.jpg'>" } ] }注意:html字段渲染时会经过sanitizeHtml净化处理,以降低 XSS 等安全风险;id字段在解析时会被统一转为字符串(见 List.jsx 的updateValue动作),以保证后续以 id 为键进行匹配和排序时的一致性。
纯展示模式:基本用法示例
当标注任务只需要展示列表而不需要标注者排序时,可直接使用List标签。此时它内部以只读方式渲染一个"看板"(board)组件,将所有条目平铺在标题为title参数的单列中:
<View> <Style> .htx-ranker-column { background: cornflowerblue; } .htx-ranker-item { background: lightgoldenrodyellow; } </Style> <List name="results" value="$items" title="Search Results" /> </View>上述示例同时演示了样式定制:.htx-ranker-column控制列表列容器背景,.htx-ranker-item控制每个条目的背景。配合上面的items任务数据,界面上会呈现一个标题为 "Search Results" 的列表,其中包含三个可折叠展示的条目(标题 + 正文)。
从源码实现看(List.jsx),HtxList组件从item.dataSource获取数据(包含items、columns、itemIds),然后渲染<Ranker inputData={data} readonly />。其中readonly为true,表示纯展示、禁止拖拽;同时如果该List已被某个Ranker标签关联(item.ranker非空),HtxList会直接返回null——交互渲染交给Ranker接管,避免双重渲染。
与 Ranker 标签配合:拖拽排序与结果格式
List与Ranker组合是最核心的用法。Ranker通过toName关联到List,此时列表变为可交互:标注者可以拖拽条目来调整顺序,或(在使用Bucket时)将条目分入不同分组。
<View> <Style> .htx-ranker-column { background: cornflowerblue; } .htx-ranker-item { background: lightgoldenrodyellow; } </Style> <List name="results" value="$items" title="Search Results" /> <Ranker name="rank" toName="results" /> </View>简单排序模式下,标注结果是一个以Ranker的name为键、值为按新顺序排列的条目 id 数组的字典:
{ "from_name": "rank", "to_name": "results", "type": "ranker", "value": { "ranker": { "rank": ["mdn", "wiki", "blog"] } } }也就是说,标注者将 "mdn" 拖到第一位后,导出的结果中rank数组即为["mdn", "wiki", "blog"]。
Ranker标签的参数如下(见 Ranker.jsx):
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | string | — | 元素名称,作为结果字典的键 |
toName | string | — | 关联的List标签名称 |
collapsible | boolean | true | 条目是否可折叠展开 |
排序与分组的交互逻辑位于 Ranker.tsx,底层基于react-beautiful-dnd的DragDropContext/Draggable/Droppable实现:拖动结束时,handleDragEnd根据source与destination判断是同列内重排还是跨列移动,更新itemIds状态并通过handleChange回调写入标注结果(对应Ranker模型中的updateResult/createResult动作)。排序结果会在每次拖拽后实时写入annotation.results。
使用 Bucket 分组:从列表中挑选相关条目
当需要标注者从列表中挑选条目并归入不同类别(而非整体排序)时,可在Ranker内嵌套Bucket子标签。每个Bucket对应一个目标列/分组:
<View> <List name="results" value="$items" title="Search Results" /> <Ranker name="rank" toName="results"> <Bucket name="best" title="Best results" /> <Bucket name="ads" title="Paid results" /> </Ranker> </View>Bucket标签参数(见 Ranker.jsx):
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | string | — | 列名,作为结果字典中的键 |
title | string | null | 列标题 |
default | boolean | false | 若为true,List中的条目默认全部放入该列;否则条目默认停留在原列表 |
不使用default参数时,默认所有条目停留在原List列(内部以_作为该列键),只有被拖入Bucket的条目才会被导出;结果按Bucket分组:
{ "from_name": "rank", "to_name": "results", "type": "ranker", "value": { "ranker": { "best": ["mdn"], "ads": ["blog"] } } }给某个Bucket设置default="true"后,所有条目默认落入该列,导出结果始终包含完整条目集合。从源码 Ranker.jsx 可以确认三种模式:
- rank 模式(无
Bucket):defaultBucket为Ranker自身name,单一可排序列; - pick 模式(有
Bucket但无default):defaultBucket为undefined,条目默认留在_原列表列,未被分组的条目不会进入结果中的命名分组; - group 模式(有
default="true"的Bucket):defaultBucket为对应Bucket的name,条目默认全部分组导出。
此外,beforeSend动作会在提交时兜底创建结果:若尚未产生任何结果,则以空列结构 + 全量条目 id 填充(默认落入defaultBucket或_列),保证导出数据完整(见 Ranker.jsx)。注意源码注释提示:未使用default参数时,_原列表列属于内部值,未来版本可能调整。
样式定制
List/Ranker的界面元素暴露了预定义 CSS 类,可在Style标签中定制:
| CSS 类 | 作用元素 | 源码位置 |
|---|---|---|
.htx-ranker-column | 每个列表列(含标题与条目容器) | Column.tsx |
.htx-ranker-item | 每个可拖拽条目卡片 | Item.tsx |
官方示例通过这两个类分别设置列背景色与条目背景色,实现"搜索结果"风格的视觉区分。除颜色外,也可以配合Style标签调整字号、内边距、边框等任意 CSS 属性。
源码实现要点
List标签的完整前端实现在 List.jsx,关键设计如下:
- 数据解析:
updateValue(store)通过parseValue(self.value, store.task.dataObj)从任务数据中取出数组,非数组直接忽略;随后将每个条目 id 转为字符串存入_value(List.jsx)。parseValue的定义见 data.js,它负责解析形如$items的字段引用。 - 数据源组装:
dataSource视图将_value映射为{ items, columns, itemIds }结构,其中columns为[{ id: name, title }],itemIds将该列与全部条目 id 关联(List.jsx),供看板组件消费。 - 渲染接管:
HtxList在存在关联Ranker时不渲染自身,避免与交互式Ranker重复显示(List.jsx)。 - 条目渲染:
Item组件负责渲染每个条目,title显示为标题行,html字段经sanitizeHtml净化后渲染,条目支持折叠展开(默认collapsible开启),并携带data-ranker-id便于测试与样式定位(Item.tsx)。
标签的 schema 定义(含参数描述与元信息)同时维护在 tags.json,供配置校验与文档生成使用;List、Ranker、Bucket三种标签均在其中登记。仓库内还提供了可直接加载运行的示例配置:ranker/config.xml(简单排序)与 ranker_buckets/config.xml(Bucket 分组),可作为快速上手的参考模板。
相关文件与进一步阅读
- 官方标签文档:List 标签、参数表
- 前端实现:List.jsx、Ranker.jsx
- 看板与拖拽组件:Ranker.tsx、Column.tsx、Item.tsx
- 示例配置:ranker/config.xml、ranker_buckets/config.xml
- 单元测试:Ranker.test.ts
- 相关标签文档:Ranker 标签、Style 标签、View 标签
在实际项目中,建议优先用List+Ranker处理"长列表排序/筛选"类任务(如搜索结果相关性标注、推荐候选排序),用List纯展示配合分类标签完成列表级分类任务;需要富媒体展示时使用html字段,需要分组导出时使用Bucket与default参数组合,并始终通过.htx-ranker-column/.htx-ranker-item类保持界面与业务视觉一致。
【免费下载链接】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),仅供参考