Label Studio 嵌套分类指南:用 visibleWhen / whenTagName / whenChoiceValue 构建条件式与多级分类标注
【免费下载链接】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 的分类(Choices)标注模板支持“条件触发 + 多级嵌套”的进阶用法:只有标注者选中了某个选项后,才会显示下一级分类问题或补充文本样本。本文以 nested-classification.md 为核心骨架,结合仓库内 View、Choices、Text 等标签文档,以及前端编辑器对visibleWhen系列参数的源码实现(Visibility.js),系统讲解条件式分类、两级与三级嵌套分类的完整 XML 配置写法,并给出参数取值、运行前提与结果序列化说明,帮助你直接用这些模板改造自己的标注项目。
前置理解:分类模板里的三个关键条件参数
嵌套分类的所有玩法都建立在一组条件控制参数之上。它们既可以加在 View 容器标签上,也可以直接加在 Choices 控制标签上,作用是按标注者当前的选择状态动态显示/隐藏界面区块。
| 参数 | 可选值(以仓库文档为准) | 作用 |
|---|---|---|
visibleWhen | choice-selected/choice-unselected/region-selected/no-region-selected | 控制内容可见性;与下方when*参数组合可进一步收窄触发条件 |
whenTagName | 字符串 | 配合visibleWhen使用。对 choices 类,填对应Choices标签的name;对 regions 类,填对象标签的name |
whenChoiceValue | 字符串,多个值用英文逗号分隔 | 配合visibleWhen="choice-selected"或"choice-unselected"使用,且必须与whenTagName同时出现;按具体的选项值收窄可见性 |
以 docs/source/includes/tags/view.md 的参数表为准,补充说明两点约束:
whenLabelValue仅用于region-selected场景(按区域标签过滤);whenRole用于聊天类数据按角色(如 user / assistant)过滤,详见 chat.md;- 对 choices 场景,
whenChoiceValue支持逗号分隔的多值,例如whenChoiceValue="Positive,Negative"表示选中其中任意一个即显示,view.md 中就有这样的示例。
参数解析在哪发生?在前端编辑器的源码 Visibility.js 中,
visiblewhen、whentagname、whenchoicevalue、whenlabelvalue、whenrole五个属性被建模为可空字符串字段,而isVisible计算属性(Visibility.js)在每次标注状态变化时求值:choice-selected分支会先在annotation.names中定位whenTagName指向的 Choices 标签,再调用其hasChoiceSelection(choiceValue.split(","), tag.selectedValues())判断所选值是否命中(Visibility.js)。也就是说,多值逗号分隔是在运行时被split(",")逐个匹配的,而不是把整串字符串拿去比较。
场景一:条件式分类(在第二个样本上追加分类)
适用于“先对第一段文本做情感分类,再根据结果展示第二段文本及其专属分类问题”的流程。核心思路是:用visibleWhen="choice-selected"+whenTagName+whenChoiceValue把一段 View 容器“挂”在指定选项上。
第 1 步:定义数据对象标签
使用 Text 对象标签承载第一段文本,name与value(指向任务数据字段$text1)必须填写:
<Text name="text1" value="$text1" />同样的模板可以平移到图像或音频分类:把对象标签换成<Image name="..." value="$image"/>或<Audio name="..." value="$audio"/>即可,其他部分无需改动。
第 2 步:定义第一组分类选项
Choices 控制标签通过name标识选项组,toName关联到第 1 步的对象标签,showInline="true"让选项在同一行横向排布:
<Choices name="sentiment" toName="text1" showInline="true"> <Choice value="Positive" /> <Choice value="Negative" /> <Choice value="Neutral" /> </Choices>第 3 步:用条件 View 包裹第二段样本
只有标注者在sentiment中选中了Positive,下面的 View 才会出现。注意whenTagName="sentiment"必须与whenChoiceValue="Positive"成对使用:
<View visibleWhen="choice-selected" whenTagName="sentiment" whenChoiceValue="Positive"> <Header value="What about this text?" /> <Text name="text2" value="$text2" /> </View>Header 在这里充当给标注者的指令文案。
第 4 步:定义第二组分类选项(同样受条件控制)
第二组选项toName="text2"关联第二段文本,并复制与第 3 步相同的条件设置——三者必须一致,才能保证“文本出现的同时问题也出现”:
<Choices name="sentiment2" toName="text2" choice="single" showInline="true" visibleWhen="choice-selected" whenTagName="sentiment" whenChoiceValue="Positive"> <Choice value="Positive" /> <Choice value="Negative" /> <Choice value="Neutral" /> </Choices>完整配置
把四段代码按顺序放入同一个<View>(推荐在最外层再包一层<View>以符合标签语法要求)即为可用模板:
<View> <Text name="text1" value="$text1" /> <Choices name="sentiment" toName="text1" showInline="true"> <Choice value="Positive" /> <Choice value="Negative" /> <Choice value="Neutral" /> </Choices> <View visibleWhen="choice-selected" whenTagName="sentiment" whenChoiceValue="Positive"> <Header value="What about this text?" /> <Text name="text2" value="$text2" /> </View> <Choices name="sentiment2" toName="text2" choice="single" showInline="true" visibleWhen="choice-selected" whenTagName="sentiment" whenChoiceValue="Positive"> <Choice value="Positive" /> <Choice value="Negative" /> <Choice value="Neutral" /> </Choices> </View>代码库中的对应示例:编辑器示例 nested_choices/config.xml 展示了同类思路——第一组
sentiment选项与一个仅带visibleWhen="choice-selected"(不写whenTagName,即“任一选项被选中即显示”)的第二组选项联动。你可以对比两种写法理解“指定标签”与“不指定标签”的差别。
场景二:两级嵌套分类(同一数据上的追问)
与场景一不同,这里不引入第二份数据,而是在同一份数据(如图片)上做“先粗分类、再追问细节”的两级问题。第二组选项的触发条件是“第一组任意选项被选中”,因此只写visibleWhen="choice-selected"+whenTagName="content",不写whenChoiceValue。
第 1 步:定义图像对象
<Image name="image" value="$image"/>第 2 步:第一级粗分类
<Choices name="content" toName="image"> <Choice value="Adult content"/> <Choice value="Weapons" /> <Choice value="Violence" /> </Choices>第 3 步:第二级追问(任意选项触发)
whenTagName="content"限定监听第一组选项;不写whenChoiceValue表示第一组中任一选项被选中即显示。<Header>作为嵌套在 Choices 内部的问题文案:
<Choices name="other-props" toName="image" choice="single" showInline="true" visibleWhen="choice-selected" whenTagName="content"> <Header value="Are there people or animals?" /> <Choice value="Yes" /> <Choice value="No" /> </Choices>这一写法与源码中的判断逻辑完全吻合:choice-selected分支在whenTagName有值、choiceValue为空时,只要tag.hasChoiceSelection(undefined, tag.selectedValues())命中任一已选项即返回可见(Visibility.js)。
场景三:三级嵌套分类(基于特定选项继续追问)
当追问粒度需要超过两级时,可以继续叠层。以音频分类为例:第一级判断总体倾向,第二级收集音频本身属性,第三级仅当第二级选中Noisy时追问噪音类型。每一级的触发条件都可以用前文参数自由组合,复杂度由你掌控。
第 1 步:定义音频对象
<Audio name="audio" value="$audio" />第 2 步:第一级——总体倾向
<Choices name="intent" toName="audio" showInline="true"> <Choice value="Positive" /> <Choice value="Negative" /> <Choice value="Neutral" /> </Choices>第 3 步:第二级——音频属性(任一第一级选项触发)
<Choices name="other-props" toName="audio" choice="single" showInline="true" visibleWhen="choice-selected" whenTagName="intent"> <Header value="Other properties of the audio clip" /> <Choice value="Noisy" /> <Choice value="Clear" /> </Choices>第 4 步:第三级——噪音类型(选中 Noisy 时触发)
注意这里whenTagName="other-props"指向第二级Choices 的name,whenChoiceValue="Noisy"指定具体选项。whenChoiceValue必须与whenTagName成对使用。另外原文档示例中第三级 Choices 的toName="text"指向了文本对象,若你的任务数据中没有名为text的字段,请将其改为实际对象标签的name(本例为audio),否则配置校验会失败:
<Choices name="emotion" toName="audio" choice="single" showInline="true" visibleWhen="choice-selected" whenTagName="other-props" whenChoiceValue="Noisy"> <Header value="What type of noise?" /> <Choice value="Crowd" /> <Choice value="Machinery" /> <Choice value="Traffic" /> <Choice value="Unsure/Other" /> </Choices>触发链路总结
| 层级 | 标签 | 触发条件 | 效果 |
|---|---|---|---|
| 第一级 | intent | 无(始终可见) | 选择 Positive / Negative / Neutral |
| 第二级 | other-props | choice-selected+whenTagName="intent" | 任一第一级选项被选中即出现 |
| 第三级 | emotion | choice-selected+whenTagName="other-props"+whenChoiceValue="Noisy" | 第二级选中 Noisy 才出现 |
条件参数的其他组合与进阶用法
在 View 标签上使用(场景一已见),在 Choices 标签上同样可用
Visibility.js 的注释明确说明:该可见性机制可以应用在View和Choices两种标签上。场景二、三的示例正是在Choices上直接使用,此时连同<Header>一起随条件显隐。
choice-unselected:反条件显示
若希望“取消选中某选项时”才显示追问,可将visibleWhen改为choice-unselected。源码中该模式定义为!fns"choice-selected"(Visibility.js),即对选择条件取反。
region-selected与whenLabelValue:区域驱动的显隐
条件不仅可绑定“选项”,也可绑定“区域标注”。例如 view.md 的示例中,当标注者在label标签组选中了PER或ORG区域时,才显示附加的<Header>:
<View> <Labels name="label" toName="text"> <Label value="PER" background="red"/> <Label value="ORG" background="darkorange"/> <Label value="LOC" background="orange"/> <Label value="MISC" background="green"/> </Labels> <Text name="text" value="$text"/> <!-- Shown only when region PER or ORG is selected --> <View visibleWhen="region-selected" whenLabelValue="PER,ORG"> <Header value="yoho"/> </View> </View>多值匹配与动态选项
whenChoiceValue="Positive,Negative"可一次匹配多个选项(逗号分隔),运行时按逗号拆分逐一比对(Visibility.js);- 分类选项本身也支持从任务数据动态加载:
<Choices ... value="$variants">,且动态选项支持children嵌套(allowNested),相关参数见 includes/tags/choices.md 与 choices.md 的动态加载示例。
randomize:弱化位置偏差
若希望每次打开任务时打乱顶层<Choice>的展示顺序(例如情感分类避免“总是顺手选第一项”),可设置randomize="true"。注意:随机化是临时的,不影响序列化结果中value/alias的输出;热键提示按可见顺序编号;带显式hotkey的选项不受影响。细节见 includes/tags/choices.md。
常用参数速查
| 参数 | 适用标签 | 默认值 | 说明 |
|---|---|---|---|
name | Choices / View 内的控制标签 | — | 选项组或元素名;whenTagName据此引用 |
toName | Choices | — | 关联的对象标签name(Text / Image / Audio 等) |
choice | Choices | single | 单选 / 单选-radio / 多选(single、single-radio、multiple) |
showInline | Choices | false | 是否在同一行横向显示选项 |
required/requiredMessage | Choices | false/ — | 是否强制选择及校验失败提示 |
visibleWhen | View、Choices | — | 可见性触发模式(4 种取值见上文) |
whenTagName | View、Choices | — | 配合visibleWhen,按标签名收窄 |
whenChoiceValue | View、Choices | — | 配合choice-selected/choice-unselected与whenTagName使用,按选项值收窄,多值逗号分隔 |
whenLabelValue | View、Choices | — | 仅配合region-selected,按区域标签收窄,多值逗号分隔 |
layout | Choices | vertical | 选项布局:select(下拉)/inline(横向)/vertical(纵向) |
perRegion | Choices | — | 对某个区域而不是整任务做选择 |
value | Choices | — | 从任务数据字段动态加载选项列表 |
allowNested | Choices | — | 允许动态选项的children嵌套,结果序列化为数组的数组 |
适用前提与注意事项
- 参数配对约束:
whenChoiceValue必须与whenTagName同时使用(原文档明确强调,includes/tags/choices.md 的参数表亦标注两者均为必需)。 - 条件标签适用范围:
visibleWhen机制由前端编辑器统一实现(Visibility.js),可在View与Choices上使用;四种取值region-selected/choice-selected/no-region-selected/choice-unselected中,no-region-selected不能附加其他when*参数(Visibility.js)。 - 父级不可见会级联隐藏:源码中
isVisible首先检查父级可见性,父级不可见时直接返回不可见(Visibility.js),因此嵌套时触发条件要保持层级一致。 toName必须真实存在:条件显隐只控制“显示”,不改变数据关联。每个Choices的toName仍需指向配置中真实定义的对象标签(如image、audio),否则配置无法通过校验(文中三级示例已修正原文档的toName="text")。- 其他数据类型同样适用:条件式分类不限于文本,图像、音频乃至视频分类任务均可平移套用,只需替换对象标签与数据字段。
- 本文所有模板的运行前提:Label Studio 标注项目创建页面的“Labeling Setup”中粘贴 XML 配置并校验通过;任务数据需包含
$text1、$text2、$image、$audio等对应字段。社区版与商业版的配置语法一致,此能力属于通用标注模板能力。
结语
通过visibleWhen搭配whenTagName/whenChoiceValue,你可以把原本平铺的分类问题改造成“选择驱动”的多级问卷式标注流程:从“先分类再对第二段样本追问”的条件式分类,到同一数据上两级、三级的嵌套追问,再到基于区域标签的显隐控制,参数组合的复杂度完全由业务需要决定。理解 Visibility.js 的运行逻辑(按whenTagName定位标签、按逗号拆分匹配选项值、父级不可见级联),能帮助你在排查配置问题时快速定位是“参数拼写”还是“层级嵌套”导致的不显示。将本文三个场景的完整 XML 直接用于你的 项目标注配置,即可快速落地一套自适应的分类标注模板。
【免费下载链接】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),仅供参考