---
name: label-master
description: Авторазметка матчей Dota 2. LLM анализирует пики героев и создаёт аннотацию 'draft_advantage' — какая команда имела преимущество в пике на момент первой крови.
license: MIT
compatibility: opencode
metadata:
    category: data-engineering
    version: 1.0.0
---

# Label Master — Dota 2 Draft Advantage

Агент для создания аннотации `draft_advantage` — дополнительного признака, отражающего экспертную оценку преимущества в пике. Это дополняет числовой `winrate_delta` качественной оценкой синергий и контрпиков.

## Контекст задачи

В Dota 2 `radiant_win` — это факт. Но **почему** побеждает та или иная команда во многом определяется пиком до первой крови. Признак `draft_advantage` отвечает: "Кто имел сильнее пик на момент fb?"

Это полезно как:

- Дополнительный признак для модели
- Проверка: совпадает ли `draft_advantage` с итоговым `radiant_win`?

**Классы:**

- `radiant_advantage` — у Radiant сильнее пик
- `dire_advantage` — у Dire сильнее пик
- `balanced` — примерно равные пики

## ВАЖНО: Рабочая директория

**Вход:** `data/cleaned/cleaned.parquet`

**Выход:** `data/labeled/labeled.parquet`, `data/labeled/spec.md`, `data/labeled/quality.json`

---

## Workflow

### Шаг 0: Setup

```bash
.venv/bin/pip install openai python-dotenv pandas pyarrow
```

Проверить `.env`:

```
OPENAI_API_KEY=sk-...
```

---

### Шаг 1: Подготовить данные

```bash
.venv/bin/python -c "
import pandas as pd, json
df = pd.read_parquet('data/cleaned/cleaned.parquet')
print(f'Rows: {len(df)}')
print(f'Columns: {list(df.columns)}')
# Показать пример строки
row = df.iloc[0]
print(f'Example radiant_heroes: {row[\"radiant_heroes\"]}')
print(f'Example winrate_delta: {row[\"winrate_delta\"]:.3f}')
"
```

Показать пользователю:

```
## Параметры разметки

- Файл: data/cleaned/cleaned.parquet
- Строк: X
- Классы: radiant_advantage, dire_advantage, balanced
- Задача: оценка преимущества в пике до первой крови

Приступаем? [да]:
```

---

### Шаг 2: Запуск авторазметки

```bash
.venv/bin/python ~/.claude/skills/label-master/scripts/auto_labeler.py \
    --input data/cleaned/cleaned.parquet \
    --output data/labeled/labeled.parquet \
    --winrates data/raw/hero_winrates.json \
    --classes "radiant_advantage,dire_advantage,balanced" \
    --task "Оцени преимущество в пике Dota 2: какая команда сильнее на основе героев и их вратейтов" \
    --self-train \
    --unlabeled data/cleaned/cleaned.parquet \
    --review-threshold 0.80
```

**Что делает скрипт:**

Для каждой строки формирует промпт вида:

```
Radiant team heroes: Anti-Mage (wr: 51.2%), Earthshaker (wr: 52.8%), ...
Dire team heroes: Invoker (wr: 48.3%), Witch Doctor (wr: 54.1%), ...
First blood time: 412 sec, got by: radiant

Classify draft advantage: radiant_advantage | dire_advantage | balanced
Respond in JSON: {"label": "...", "confidence": 0.XX, "reason": "..."}
```

**Добавляет колонки:** `draft_advantage`, `da_confidence`, `da_reason`

---

### Шаг 3: Анализ результатов

После разметки вывести:

```
## Разметка завершена

- Размечено: X строк
- Средняя уверенность: Y%
- Флаги на ручную проверку (confidence < 0.65): Z строк → data/labeled/review_queue.csv

### Распределение draft_advantage:
| Класс | Количество | % |
|-------|------------|---|
| radiant_advantage | 3200 | 36.8% |
| balanced | 3100 | 35.7% |
| dire_advantage | 2391 | 27.5% |

### Согласованность с radiant_win:
| draft_advantage | Реальная победа Radiant | % |
|----------------|------------------------|---|
| radiant_advantage | 2048 / 3200 | 64.0% |
| balanced | 1612 / 3100 | 52.0% |
| dire_advantage | 812 / 2391 | 34.0% |
```

> Ожидаемое поведение: чем сильнее задекларированное преимущество, тем выше корреляция с реальной победой. Если нет — проблема с промптом или данными.

---

### Шаг 4: Human-in-the-loop

Низкоуверенные примеры (confidence < 0.65) сохраняются отдельно:

```
data/labeled/review_queue.csv создан: Z строк
Открой файл, проверь колонку 'draft_advantage', исправь при необходимости.
После проверки сохрани как review_queue_corrected.csv и сообщи.
```

---

### Шаг 5: Спецификация разметки

Создать `data/labeled/spec.md`:

```markdown
# Annotation Specification: Draft Advantage

## Задача

Классификация преимущества пика команды Dota 2 на момент первой крови.

## Классы

### radiant_advantage

Команда Radiant имеет синергию героев, выгодные контрпики или
статистически более сильных героев в текущем патче.

Примеры:

1. Radiant: AM + Earthshaker + Magnus | Dire: Invoker + Pudge + Sniper
   → radiant_advantage (AM ult + ES combo + Magnus synergy)
2. ...

### dire_advantage

...

### balanced

Вратейты команд отличаются менее чем на 2%, нет выраженных синергий.
...

## Граничные случаи

- winrate_delta < 0.02 → скорее всего balanced
- Один очень слабый герой (wr < 44%) → advantage для противника
```

---

### Шаг 6: Метрики качества

```bash
.venv/bin/python -c "
import pandas as pd, json
from sklearn.metrics import cohen_kappa_score

df = pd.read_parquet('data/labeled/labeled.parquet')
metrics = {
    'total_labeled': len(df),
    'confidence_mean': float(df['da_confidence'].mean()),
    'confidence_low': int((df['da_confidence'] < 0.65).sum()),
    'label_distribution': df['draft_advantage'].value_counts().to_dict(),
    'correlation_with_win': {
        cls: float((df[df['draft_advantage']==cls]['radiant_win']).mean())
        for cls in df['draft_advantage'].unique()
    }
}
with open('data/labeled/quality.json', 'w') as f:
    json.dump(metrics, f, indent=2)
print(json.dumps(metrics, indent=2))
"
```

---

## Файлы скилла

| Скрипт            | Назначение                                           |
| ----------------- | ---------------------------------------------------- |
| `auto_labeler.py` | LLM-разметка с батчингом и флагом низкой уверенности |

---

## Правила

1. **Использовать готовый скрипт** `auto_labeler.py`
2. **Обязательно** показывать корреляцию `draft_advantage` с `radiant_win`
3. **Флагать** примеры с confidence < 0.65 в `review_queue.csv`
4. **Rate limiting**: `--delay 0.3` по умолчанию
5. **НЕ перезаписывать** оригинальную колонку `radiant_win` — она остаётся основным таргетом
