ai-annotation-workflow
28
总安装量
3
周安装量
#13314
全站排名
安装命令
npx skills add https://github.com/dengineproblem/agents-monorepo --skill ai-annotation-workflow
Agent 安装分布
github-copilot
3
amp
2
claude-code
2
kimi-cli
2
gemini-cli
2
Skill 文档
AI Annotation Workflow Expert
ÐкÑпеÑÑ Ð¿Ð¾ пÑоекÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸ ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑоÑеÑÑами ÑазмеÑки даннÑÑ Ð´Ð»Ñ Ð¼Ð°Ñинного обÑÑениÑ.
ÐÑновнÑе пÑинÑипÑ
Цикл ÑазмеÑки даннÑÑ
- ÐланиÑование: ÐпÑеделение задаÑи, Ñоздание guidelines
- ÐилоÑ: ТеÑÑиÑование Ñ Ð¼Ð°Ð»Ð¾Ð¹ вÑбоÑкой
- ÐаÑÑÑабиÑование: РаÑÑиÑение на полнÑй даÑаÑеÑ
- ÐонÑÑÐ¾Ð»Ñ ÐºÐ°ÑеÑÑва: ÐоÑÑоÑннÑй мониÑоÑинг
- ÐÑеÑаÑиÑ: УлÑÑÑение на оÑнове обÑаÑной ÑвÑзи
Ð¢Ð¸Ð¿Ñ Ð·Ð°Ð´Ð°Ñ ÑазмеÑки
- ÐлаÑÑиÑикаÑиÑ: ÐаÑегоÑизаÑÐ¸Ñ Ð´Ð°Ð½Ð½ÑÑ
- ÐеÑекÑÐ¸Ñ Ð¾Ð±ÑекÑов: Bounding boxes
- СегменÑаÑиÑ: ÐикÑелÑÐ½Ð°Ñ ÑазмеÑка
- NER: Named Entity Recognition
- Sentiment: Ðнализ ÑоналÑноÑÑи
- ТÑанÑкÑипÑиÑ: ÐÑдио в ÑекÑÑ
Создание Guidelines
СÑÑÑкÑÑÑа докÑменÑа
# Annotation Guidelines v1.0
## ÐадаÑа
РазмеÑка изобÑажений ÑоваÑов Ð´Ð»Ñ e-commerce
## ÐаÑегоÑии
1. Ðдежда
- ÐеÑÑ
нÑÑ Ð¾Ð´ÐµÐ¶Ð´Ð°
- ÐижнÑÑ Ð¾Ð´ÐµÐ¶Ð´Ð°
- ÐкÑеÑÑÑаÑÑ
2. ÐлекÑÑоника
- СмаÑÑÑонÑ
- ÐоÑÑбÑки
- ÐкÑеÑÑÑаÑÑ
## ÐÑавила ÑазмеÑки
- ÐÑбиÑайÑе наиболее ÑпеÑиÑиÑнÑÑ ÐºÐ°ÑегоÑиÑ
- ÐÑи неопÑеделÑнноÑÑи иÑполÑзÑйÑе "ÐÑÑгое"
- Ðдин обÑÐµÐºÑ = одна каÑегоÑиÑ
## ÐÑимеÑÑ
[ÐÑимеÑÑ Ñ Ð¸Ð·Ð¾Ð±ÑажениÑми и пÑавилÑной ÑазмеÑкой]
## Edge Cases
- Ð¢Ð¾Ð²Ð°Ñ ÑаÑÑиÑно виден: ÑазмеÑайÑе еÑли >50% видно
- ÐеÑколÑко ÑоваÑов: ÑазмеÑайÑе каждÑй оÑделÑно
ÐеÑÑики каÑеÑÑва
Inter-Annotator Agreement (IAA)
from sklearn.metrics import cohen_kappa_score, fleiss_kappa
def calculate_agreement(annotations_a, annotations_b):
"""РаÑÑÑÑ ÑоглаÑованноÑÑи Ð¼ÐµÐ¶Ð´Ñ Ð°Ð½Ð½Ð¾ÑаÑоÑами"""
# Cohen's Kappa Ð´Ð»Ñ Ð´Ð²ÑÑ
анноÑаÑоÑов
kappa = cohen_kappa_score(annotations_a, annotations_b)
# ÐнÑеÑпÑеÑаÑиÑ
if kappa < 0.20:
interpretation = "Poor"
elif kappa < 0.40:
interpretation = "Fair"
elif kappa < 0.60:
interpretation = "Moderate"
elif kappa < 0.80:
interpretation = "Good"
else:
interpretation = "Excellent"
return {
'kappa': kappa,
'interpretation': interpretation
}
Quality Metrics
class AnnotationQualityMonitor:
def __init__(self):
self.metrics = []
def calculate_metrics(self, annotations, gold_standard):
"""РаÑÑÑÑ Ð¼ÐµÑÑик каÑеÑÑва оÑноÑиÑелÑно ÑÑалона"""
from sklearn.metrics import precision_score, recall_score, f1_score
precision = precision_score(gold_standard, annotations, average='weighted')
recall = recall_score(gold_standard, annotations, average='weighted')
f1 = f1_score(gold_standard, annotations, average='weighted')
return {
'precision': precision,
'recall': recall,
'f1': f1,
'accuracy': sum(a == g for a, g in zip(annotations, gold_standard)) / len(annotations)
}
def detect_drift(self, window_size=100):
"""ÐбнаÑÑжение дÑиÑÑа каÑеÑÑва"""
if len(self.metrics) < window_size * 2:
return False
recent = self.metrics[-window_size:]
previous = self.metrics[-window_size*2:-window_size]
recent_avg = sum(m['f1'] for m in recent) / len(recent)
previous_avg = sum(m['f1'] for m in previous) / len(previous)
# ÐÑиÑÑ ÐµÑли падение > 5%
return (previous_avg - recent_avg) / previous_avg > 0.05
Workflow авÑомаÑизаÑии
Label Studio инÑегÑаÑиÑ
from label_studio_sdk import Client
class AnnotationPipeline:
def __init__(self, api_key, url):
self.client = Client(url=url, api_key=api_key)
def create_project(self, name, label_config):
"""Создание пÑоекÑа ÑазмеÑки"""
project = self.client.create_project(
title=name,
label_config=label_config
)
return project
def import_tasks(self, project_id, data):
"""ÐмпоÑÑ Ð·Ð°Ð´Ð°Ñ Ð´Ð»Ñ ÑазмеÑки"""
project = self.client.get_project(project_id)
project.import_tasks(data)
def export_annotations(self, project_id, format='JSON'):
"""ÐкÑпоÑÑ Ð³Ð¾ÑовÑÑ
анноÑаÑий"""
project = self.client.get_project(project_id)
return project.export_tasks(format=format)
Active Learning Pipeline
class ActiveLearningAnnotation:
def __init__(self, model, unlabeled_pool):
self.model = model
self.unlabeled_pool = unlabeled_pool
self.labeled_data = []
def select_samples_for_annotation(self, n_samples=100, strategy='uncertainty'):
"""ÐÑÐ±Ð¾Ñ Ð¾Ð±ÑазÑов Ð´Ð»Ñ ÑазмеÑки"""
if strategy == 'uncertainty':
# ÐÑÐ±Ð¾Ñ Ð¾Ð±ÑазÑов Ñ Ð½Ð°Ð¸Ð±Ð¾Ð»ÑÑей неопÑеделÑнноÑÑÑÑ
predictions = self.model.predict_proba(self.unlabeled_pool)
uncertainties = -np.sum(predictions * np.log(predictions + 1e-10), axis=1)
indices = np.argsort(uncertainties)[-n_samples:]
elif strategy == 'diversity':
# ÐÑÐ±Ð¾Ñ ÑазнообÑазнÑÑ
обÑазÑов
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=n_samples)
kmeans.fit(self.unlabeled_pool)
indices = [
np.argmin(np.linalg.norm(self.unlabeled_pool - center, axis=1))
for center in kmeans.cluster_centers_
]
return self.unlabeled_pool[indices]
def update_model(self, new_annotations):
"""Ðбновление модели поÑле полÑÑÐµÐ½Ð¸Ñ Ð°Ð½Ð½Ð¾ÑаÑий"""
self.labeled_data.extend(new_annotations)
X = [item['features'] for item in self.labeled_data]
y = [item['label'] for item in self.labeled_data]
self.model.fit(X, y)
УпÑавление анноÑаÑоÑами
ÐнбоÑдинг
class AnnotatorOnboarding:
def __init__(self, gold_standard_samples):
self.gold_standard = gold_standard_samples
self.passing_threshold = 0.85
def run_qualification_test(self, annotator_id, annotations):
"""ÐвалиÑикаÑионнÑй ÑеÑÑ Ð´Ð»Ñ Ð½Ð¾Ð²ÑÑ
анноÑаÑоÑов"""
correct = sum(
a == g for a, g in zip(annotations, self.gold_standard)
)
accuracy = correct / len(self.gold_standard)
return {
'annotator_id': annotator_id,
'accuracy': accuracy,
'passed': accuracy >= self.passing_threshold,
'errors': [
{'index': i, 'expected': g, 'actual': a}
for i, (a, g) in enumerate(zip(annotations, self.gold_standard))
if a != g
]
}
ÐониÑоÑинг пÑоизводиÑелÑноÑÑи
class AnnotatorPerformanceTracker:
def __init__(self):
self.annotator_stats = {}
def log_annotation(self, annotator_id, task_id, time_spent, quality_score):
if annotator_id not in self.annotator_stats:
self.annotator_stats[annotator_id] = []
self.annotator_stats[annotator_id].append({
'task_id': task_id,
'time_spent': time_spent,
'quality_score': quality_score,
'timestamp': datetime.now()
})
def get_annotator_report(self, annotator_id):
stats = self.annotator_stats.get(annotator_id, [])
if not stats:
return None
return {
'total_tasks': len(stats),
'avg_time': sum(s['time_spent'] for s in stats) / len(stats),
'avg_quality': sum(s['quality_score'] for s in stats) / len(stats),
'tasks_per_hour': len(stats) / (
(stats[-1]['timestamp'] - stats[0]['timestamp']).total_seconds() / 3600
) if len(stats) > 1 else 0
}
ÐнÑÑÑÑменÑÑ ÑазмеÑки
ÐопÑлÑÑнÑе плаÑÑоÑмÑ
- Label Studio: Open-source, Ð³Ð¸Ð±ÐºÐ°Ñ ÐºÐ¾Ð½ÑигÑÑаÑиÑ
- Labelbox: Enterprise, ML-assisted labeling
- Scale AI: Managed workforce
- Amazon SageMaker Ground Truth: AWS инÑегÑаÑиÑ
- Prodigy: NLP-focused, active learning
ÐÑÐ±Ð¾Ñ Ð¸Ð½ÑÑÑÑменÑа
| ÐÑиÑеÑий | Label Studio | Labelbox | Scale AI |
|---|---|---|---|
| СÑоимоÑÑÑ | Free/Open | $$ | $$$ |
| Workforce | Self-managed | Optional | Included |
| ML Assist | Basic | Advanced | Advanced |
| Customization | High | Medium | Low |
ÐÑÑÑие пÑакÑики
- ÐаÑинайÑе Ñ Ð¿Ð¸Ð»Ð¾Ñа â 100-200 обÑазÑов Ð´Ð»Ñ ÐºÐ°Ð»Ð¸Ð±Ñовки
- ÐÑеÑиÑÑйÑе guidelines â обновлÑйÑе по меÑе обнаÑÑÐ¶ÐµÐ½Ð¸Ñ edge cases
- ÐÑполÑзÑйÑе gold standard â 5-10% даннÑÑ Ð´Ð»Ñ ÐºÐ¾Ð½ÑÑÐ¾Ð»Ñ ÐºÐ°ÑеÑÑва
- ÐаланÑиÑÑйÑе ÑкоÑоÑÑÑ Ð¸ каÑеÑÑво â не давиÑе на анноÑаÑоÑов
- ÐокÑменÑиÑÑйÑе ÑеÑÐµÐ½Ð¸Ñ â запиÑÑвайÑе вÑе ÑазÑÑÑнениÑ
- ÐвÑомаÑизиÑÑйÑе ÑÑо можно â pre-labeling, validation rules