feat(annotation): 替换模板配置表单为树形编辑器组件

- 移除 TemplateConfigurationForm 组件并引入 TemplateConfigurationTreeEditor
- 使用 useTagConfig Hook 获取标签配置
- 将自定义XML状态 customXml 替换为 labelConfig
- 删除模板编辑标签页和选择模板状态管理
- 更新XML解析逻辑支持更多对象和标注控件类型
- 添加配置验证功能确保至少包含数据对象和标注控件
- 在模板详情页面使用树形编辑器显示配置详情
- 更新任务创建页面集成新的树形配置编辑器
- 调整预览数据生成功能适配新的XML解析方式
This commit is contained in:
2026-01-23 16:11:59 +08:00
parent 76d06b9809
commit 3f566a0b08
14 changed files with 1383 additions and 900 deletions

View File

@@ -15,8 +15,8 @@ CREATE TABLE IF NOT EXISTS t_dm_annotation_templates (
description VARCHAR(500) COMMENT '模板描述',
data_type VARCHAR(50) NOT NULL COMMENT '数据类型: text/image/audio/video/pdf/timeseries/chat/html/table',
labeling_type VARCHAR(50) NOT NULL COMMENT '标注类型',
configuration JSON NOT NULL COMMENT '标注配置(包含labels定义等',
label_config TEXT COMMENT 'Label Studio XML配置(内置模板预定义',
configuration JSON NULL COMMENT '标注配置(兼容字段,主配置为label_config',
label_config TEXT COMMENT 'Label Studio XML配置(模板主配置',
style VARCHAR(32) NOT NULL COMMENT '样式配置: horizontal/vertical',
category VARCHAR(50) DEFAULT 'custom' COMMENT '模板分类',
built_in BOOLEAN DEFAULT FALSE COMMENT '是否系统内置模板',
@@ -776,19 +776,17 @@ INSERT INTO t_dm_annotation_templates (
'对文本进行分类,适用于情感分析、主题分类、垃圾邮件检测等场景。关联模型:BERT、RoBERTa、DistilBERT',
'text',
'text-classification',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'sentiment', 'toName', 'text', 'type', 'Choices', 'options', JSON_ARRAY('Positive', 'Negative', 'Neutral'), 'required', true)
),
'objects', JSON_ARRAY(JSON_OBJECT('name', 'text', 'type', 'Text', 'value', '$text'))
),
NULL,
'<View>
<Text name="text" value="$text"/>
<Choices name="sentiment" toName="text" choice="single-radio" showInLine="true">
<Choice value="Positive"/>
<Choice value="Negative"/>
<Choice value="Neutral"/>
</Choices>
<View style="box-shadow: 2px 2px 5px #999; padding: 20px; margin-top: 2em; border-radius: 5px;">
<Header value="选择文本情感"/>
<Choices name="sentiment" toName="text" choice="single" showInline="true">
<Choice value="Positive"/>
<Choice value="Negative"/>
<Choice value="Neutral"/>
</Choices>
</View>
</View>',
'vertical',
'nlp',
@@ -806,12 +804,7 @@ INSERT INTO t_dm_annotation_templates (
'在文本中标注命名实体,适用于信息抽取、知识图谱构建、智能问答等场景。关联模型:BERT-NER、SpaCy、Flair',
'text',
'ner',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'label', 'toName', 'text', 'type', 'Labels', 'labels', JSON_ARRAY('PER', 'ORG', 'LOC', 'MISC'))
),
'objects', JSON_ARRAY(JSON_OBJECT('name', 'text', 'type', 'Text', 'value', '$text'))
),
NULL,
'<View>
<Labels name="label" toName="text">
<Label value="PER" background="red"/>
@@ -837,23 +830,16 @@ INSERT INTO t_dm_annotation_templates (
'标注实体间的关系,适用于知识图谱构建、信息抽取等场景。关联模型:BERT、GPT、OpenIE',
'text',
'relation-extraction',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'label', 'toName', 'text', 'type', 'Labels', 'labels', JSON_ARRAY('PER', 'ORG', 'LOC')),
JSON_OBJECT('fromName', 'relation', 'toName', 'text', 'type', 'Relations')
),
'objects', JSON_ARRAY(JSON_OBJECT('name', 'text', 'type', 'Text', 'value', '$text'))
),
NULL,
'<View>
<Relations>
<Relation value="works_for"/>
<Relation value="lives_in"/>
<Relation value="located_in"/>
<Relation value="org:founded_by"/>
<Relation value="org:founded"/>
</Relations>
<Labels name="label" toName="text">
<Label value="PER" background="red"/>
<Label value="ORG" background="darkorange"/>
<Label value="LOC" background="orange"/>
<Label value="Organization" background="orange"/>
<Label value="Person" background="green"/>
<Label value="Datetime" background="blue"/>
</Labels>
<Text name="text" value="$text"/>
</View>',
@@ -873,22 +859,15 @@ INSERT INTO t_dm_annotation_templates (
'翻译文本内容,适用于翻译质量评估、机器翻译后编辑等场景',
'text',
'machine-translation',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'translation', 'toName', 'text', 'type', 'TextArea', 'required', true)
),
'objects', JSON_ARRAY(JSON_OBJECT('name', 'text', 'type', 'Text', 'value', '$text'))
),
NULL,
'<View>
<View style="display: grid; grid-template-columns: 1fr 1fr; grid-column-gap: 1em">
<View>
<Header value="原文"/>
<Text name="text" value="$text"/>
</View>
<View>
<Header value="翻译"/>
<TextArea name="translation" toName="text" rows="5" editable="true" maxSubmissions="1"/>
</View>
<View style="display: grid; grid-template: auto/1fr 1fr; column-gap: 1em">
<Header value="原文" />
<Header value="翻译" />
<Text name="text" value="$text" />
<TextArea name="translation" toName="text"
showSubmitButton="true" maxSubmissions="1" editable="true"
required="true" />
</View>
</View>',
'vertical',
@@ -907,16 +886,14 @@ INSERT INTO t_dm_annotation_templates (
'编写文本摘要,适用于新闻摘要、文档摘要、会议纪要等场景',
'text',
'text-summarization',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'summary', 'toName', 'text', 'type', 'TextArea', 'required', true)
),
'objects', JSON_ARRAY(JSON_OBJECT('name', 'text', 'type', 'Text', 'value', '$text'))
),
NULL,
'<View>
<Text name="text" value="$text"/>
<Header value="编写摘要"/>
<TextArea name="summary" toName="text" rows="4" editable="true" maxSubmissions="1"/>
<Header value="请阅读文本" />
<Text name="text" value="$text" />
<Header value="提供一句话摘要" />
<TextArea name="summary" toName="text"
showSubmitButton="true" maxSubmissions="1" editable="true"
required="true" />
</View>',
'vertical',
'nlp',
@@ -934,21 +911,15 @@ INSERT INTO t_dm_annotation_templates (
'基于上下文回答问题或标注答案,适用于阅读理解、智能客服等场景',
'text',
'question-answering',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'answer', 'toName', 'text', 'type', 'Labels', 'labels', JSON_ARRAY('Answer'))
),
'objects', JSON_ARRAY(
JSON_OBJECT('name', 'text', 'type', 'Text', 'value', '$text'),
JSON_OBJECT('name', 'question', 'type', 'Text', 'value', '$question')
)
),
NULL,
'<View>
<Header value="请阅读文本" />
<Text name="text" value="$text" granularity="word"/>
<Header value="选择回答问题的文本片段" />
<Text name="question" value="$question"/>
<Labels name="answer" toName="text">
<Label value="Answer" background="green"/>
<Label value="Answer" maxUsage="1" background="red"/>
</Labels>
<Text name="text" value="$text"/>
</View>',
'vertical',
'nlp',
@@ -966,31 +937,16 @@ INSERT INTO t_dm_annotation_templates (
'使用层级分类法对文本进行分类,适用于电商商品分类、文档归档等场景',
'text',
'taxonomy',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'taxonomy', 'toName', 'text', 'type', 'Taxonomy')
),
'objects', JSON_ARRAY(JSON_OBJECT('name', 'text', 'type', 'Text', 'value', '$text'))
),
NULL,
'<View>
<Text name="text" value="$text"/>
<Taxonomy name="taxonomy" toName="text">
<Choice value="Archaea">
<Choice value="Euryarchaeota"/>
<Choice value="Crenarchaeota"/>
</Choice>
<Choice value="Bacteria">
<Choice value="Actinobacteria"/>
<Choice value="Proteobacteria"/>
</Choice>
<Choice value="Archaea" />
<Choice value="Bacteria" />
<Choice value="Eukarya">
<Choice value="Animalia">
<Choice value="Chordata">
<Choice value="Mammalia"/>
<Choice value="Aves"/>
</Choice>
</Choice>
<Choice value="Plantae"/>
<Choice value="Human" />
<Choice value="Oppossum" />
<Choice value="Extraterrestial" />
</Choice>
</Taxonomy>
</View>',
@@ -1014,16 +970,7 @@ INSERT INTO t_dm_annotation_templates (
'收集人类偏好用于RLHF训练,对两个LLM响应进行排名',
'text',
'rlhf-preference',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'preference', 'toName', 'prompt', 'type', 'Pairwise')
),
'objects', JSON_ARRAY(
JSON_OBJECT('name', 'prompt', 'type', 'Text', 'value', '$prompt'),
JSON_OBJECT('name', 'response1', 'type', 'Text', 'value', '$response1'),
JSON_OBJECT('name', 'response2', 'type', 'Text', 'value', '$response2')
)
),
NULL,
'<View>
<Style>
.prompt-box { background: #f5f5f5; padding: 15px; border-radius: 8px; margin-bottom: 20px; }
@@ -1060,17 +1007,7 @@ INSERT INTO t_dm_annotation_templates (
'对LLM生成的响应进行多维度评分',
'text',
'llm-grading',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'relevance', 'toName', 'response', 'type', 'Rating'),
JSON_OBJECT('fromName', 'coherence', 'toName', 'response', 'type', 'Rating'),
JSON_OBJECT('fromName', 'fluency', 'toName', 'response', 'type', 'Rating')
),
'objects', JSON_ARRAY(
JSON_OBJECT('name', 'prompt', 'type', 'Text', 'value', '$prompt'),
JSON_OBJECT('name', 'response', 'type', 'Text', 'value', '$response')
)
),
NULL,
'<View>
<Header value="Prompt"/>
<Text name="prompt" value="$prompt"/>
@@ -1099,12 +1036,7 @@ INSERT INTO t_dm_annotation_templates (
'为LLM监督微调收集高质量指令-响应对',
'text',
'sft',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'response', 'toName', 'instruction', 'type', 'TextArea', 'required', true)
),
'objects', JSON_ARRAY(JSON_OBJECT('name', 'instruction', 'type', 'Text', 'value', '$instruction'))
),
NULL,
'<View>
<Header value="指令"/>
<Text name="instruction" value="$instruction"/>
@@ -1131,16 +1063,7 @@ INSERT INTO t_dm_annotation_templates (
'对两个项目进行成对比较分类',
'text',
'pairwise-classification',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'comparison', 'toName', 'text', 'type', 'Pairwise')
),
'objects', JSON_ARRAY(
JSON_OBJECT('name', 'text', 'type', 'Text', 'value', '$prompt'),
JSON_OBJECT('name', 'option1', 'type', 'Text', 'value', '$option1'),
JSON_OBJECT('name', 'option2', 'type', 'Text', 'value', '$option2')
)
),
NULL,
'<View>
<Text name="text" value="$prompt"/>
<Pairwise name="comparison" toName="text" leftText="选项A" rightText="选项B">
@@ -1164,15 +1087,7 @@ INSERT INTO t_dm_annotation_templates (
'对搜索结果进行相关性排名,适用于搜索引擎优化、信息检索等场景',
'text',
'serp-ranking',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'relevance', 'toName', 'result', 'type', 'Rating')
),
'objects', JSON_ARRAY(
JSON_OBJECT('name', 'query', 'type', 'Text', 'value', '$query'),
JSON_OBJECT('name', 'result', 'type', 'Text', 'value', '$result')
)
),
NULL,
'<View>
<Header value="搜索查询"/>
<Text name="query" value="$query"/>
@@ -1438,12 +1353,7 @@ INSERT INTO t_dm_annotation_templates (
'在文本中标注共指关系和实体链接',
'text',
'coreference-resolution',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'label', 'toName', 'text', 'type', 'Labels', 'labels', JSON_ARRAY('Noun', 'Pronoun'))
),
'objects', JSON_ARRAY(JSON_OBJECT('name', 'text', 'type', 'Text', 'value', '$text'))
),
NULL,
'<View>
<Labels name="label" toName="text">
<Label value="Noun" background="red"/>
@@ -1467,13 +1377,7 @@ INSERT INTO t_dm_annotation_templates (
'构建任务导向对话系统,选择对话意图并提取槽实体',
'text',
'slot-filling',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'entity_slot', 'toName', 'dialogue', 'type', 'ParagraphLabels', 'labels', JSON_ARRAY('Person', 'Organization', 'Location', 'Datetime', 'Quantity')),
JSON_OBJECT('fromName', 'intent', 'toName', 'dialogue', 'type', 'Choices', 'options', JSON_ARRAY('Greeting', 'Customer request', 'Small talk'))
),
'objects', JSON_ARRAY(JSON_OBJECT('name', 'dialogue', 'type', 'Paragraphs', 'value', '$dialogue'))
),
NULL,
'<View>
<ParagraphLabels name="entity_slot" toName="dialogue">
<Label value="Person" />
@@ -1505,12 +1409,7 @@ INSERT INTO t_dm_annotation_templates (
'通过生成下一个对话响应来收集聊天机器人训练数据',
'text',
'response-generation',
JSON_OBJECT(
'labels', JSON_ARRAY(
JSON_OBJECT('fromName', 'response', 'toName', 'chat', 'type', 'TextArea', 'required', true)
),
'objects', JSON_ARRAY(JSON_OBJECT('name', 'chat', 'type', 'Paragraphs', 'value', '$dialogue'))
),
NULL,
'<View>
<Paragraphs name="chat" value="$dialogue" layout="dialogue" />
<Header value="提供响应" />