版本: 1.1 最后更新: 2026-06-11
标签系统提供三个核心能力:
{
"version": "1.0",
"exportedAt": "2026-06-11T12:00:00",
"groups": [ ... ]
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
version |
string | 是 | 格式版本号,当前为 "1.0" |
exportedAt |
string | 是 | ISO 8601 格式的导出时间 |
groups |
array | 是 | 标签组数组,见 2.2 |
{
"name": "标签组名称",
"description": "可选描述",
"sortOrder": 0,
"tags": [ ... ]
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name |
string | 是 | 标签组名称,作为导入时的唯一匹配键 |
description |
string | 否 | 标签组描述,可为 null 或省略 |
sortOrder |
integer | 否 | 排序序号,默认 0 |
tags |
array | 否 | 顶层标签节点数组,见 2.3 |
注意:tags 数组中的是标签组根节点下的直接子标签,不包含标签组同名的根节点本身。
标签节点采用递归嵌套结构,自然表达树形层级:
{
"name": "标签名称",
"sortOrder": 0,
"children": [
{
"name": "子标签",
"sortOrder": 0,
"children": []
}
]
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name |
string | 是 | 标签名称 |
sortOrder |
integer | 否 | 同级排序序号,默认 0 |
children |
array | 否 | 子标签数组,递归嵌套。无子节点时可省略或为空数组 |
{
"version": "1.0",
"exportedAt": "2026-06-11T14:30:00",
"groups": [
{
"name": "情感分类",
"description": "文本情感极性标签",
"sortOrder": 0,
"tags": [
{
"name": "正面",
"sortOrder": 0,
"children": [
{
"name": "喜悦",
"sortOrder": 0,
"children": [
{ "name": "狂喜", "sortOrder": 0 },
{ "name": "微笑", "sortOrder": 1 }
]
},
{ "name": "满意", "sortOrder": 1 }
]
},
{
"name": "负面",
"sortOrder": 1,
"children": [
{ "name": "愤怒", "sortOrder": 0 },
{ "name": "失望", "sortOrder": 1 }
]
},
{
"name": "中性",
"sortOrder": 2
}
]
},
{
"name": "主题分类",
"description": null,
"sortOrder": 1,
"tags": [
{
"name": "科技",
"sortOrder": 0,
"children": [
{
"name": "人工智能",
"sortOrder": 0,
"children": [
{ "name": "大语言模型", "sortOrder": 0 },
{ "name": "计算机视觉", "sortOrder": 1 }
]
},
{ "name": "云计算", "sortOrder": 1 }
]
},
{ "name": "财经", "sortOrder": 1 },
{ "name": "体育", "sortOrder": 2 }
]
}
]
}
tags-export-{YYYY-MM-DD}.json以标签组 名称 (name) 作为匹配键。若导入文件中的标签组名称与系统中已有标签组名称相同,则判定为冲突。
| 策略 | 值 | 说明 |
|---|---|---|
| 覆盖 | overwrite |
删除原有标签组及全部标签,用导入数据重新创建 |
| 合并 | merge |
逐层按名称匹配:同名标签保留,新标签追加。详见 4.4 |
| 跳过 | skip |
跳过该标签组,不做任何修改 |
| 新建 | create |
无冲突时的默认行为,直接创建新标签组 |
合并采用递归名称匹配算法:
对于导入标签树的每一层节点:
1. 在目标标签组的同级子节点中查找同名标签
2. 如果找到同名标签 → 保留该标签,递归处理其子节点
3. 如果未找到 → 创建新标签节点
示例(多级标签合并):
现有标签组 "情感分类":
正面
喜悦
微笑
负面
导入合并数据:
正面
喜悦
微笑 ← 同名,保留
感动 ← 新增
满意 ← 新增
负面
愤怒 ← 新增
合并结果:
正面
喜悦
微笑 ← 保留(三级同名匹配)
感动 ← 新增
满意 ← 新增
负面
愤怒 ← 新增
{
"data": {
"version": "1.0",
"exportedAt": "...",
"groups": [ ... ]
},
"strategies": {
"冲突标签组名称": "overwrite | merge | skip",
"另一个冲突标签组": "merge"
}
}
data:完整的导出数据strategies:仅冲突标签组需要指定策略,无冲突的标签组自动新建{
"created": 2,
"overwritten": 1,
"merged": 0,
"skipped": 1,
"details": [
"新建: 主题分类",
"新建: 行业分类",
"覆盖: 情感分类",
"跳过: 优先级"
]
}
GET /api/tags/export
响应:Result<TagExportDTO>
POST /api/tags/import
请求体:TagImportDTO(见 4.5)
响应:Result<TagImportResultDTO>(见 4.6)
POST /api/tags/assignments
请求体:
{
"entityType": "skill",
"entityId": "my-skill-folder",
"tagIds": [1, 5, 12]
}
行为:全量替换该实体的所有标签关联。tagIds 为空数组时清除所有标签。
GET /api/tags/assignments?entityType=skill&entityId=my-skill-folder
响应:Result<List<TagBriefVO>>
假设标签树结构如下:
情感分类
正面 ← tagId: 1
喜悦 ← tagId: 2
狂喜 ← tagId: 3
负面 ← tagId: 4
主题分类
科技 ← tagId: 10
人工智能 ← tagId: 11
大语言模型 ← tagId: 12
为一个 Skill 同时打上"正面"(非叶子节点)、"狂喜"(三级叶子)、"大语言模型"(三级叶子)的响应示例:
{
"data": [
{ "tagId": 1, "tagName": "正面", "groupId": 1, "groupName": "情感分类" },
{ "tagId": 3, "tagName": "狂喜", "groupId": 1, "groupName": "情感分类" },
{ "tagId": 12, "tagName": "大语言模型", "groupId": 2, "groupName": "主题分类" }
]
}
GET /api/tags/all-with-tags
响应:Result<List<{ id, name, tags: List<Tag> }>>
打标通过 tag_assignment 表实现多对多关联:
| 字段 | 类型 | 说明 |
|---|---|---|
id |
BIGINT | 主键 |
entity_type |
VARCHAR(32) | 业务对象类型,如 "skill" |
entity_id |
VARCHAR(128) | 业务对象标识,如 Skill 的 folderName |
tag_id |
BIGINT | 关联的标签 ID |
created_at |
TIMESTAMP | 创建时间 |
唯一约束:(entity_type, entity_id, tag_id) — 同一实体的同一标签不可重复关联。
| entityType | entityId 来源 | 说明 |
|---|---|---|
skill |
folderName | 技能 |
| (预留) | — | 未来可扩展智能体、工作流等 |
entityType + entityId 实现通用多对多关联,不与特定业务耦合