Реализация AI-автоматического тегирования контента в мобильном приложении
Автотегирование — это автоматическое назначение меток контенту (фото, видео, документам, постам) без участия пользователя. Реализация зависит от типа контента: для изображений — Vision/ML Kit, для текста — NLP-модели, для видео — анализ ключевых кадров. Все три сценария встречаются в одном приложении.
Тегирование изображений on-device
Стандартная связка: VNClassifyImageRequest (iOS) + ImageLabeler (Android). Выдают метки вроде «Food», «Sky», «Cat», «Outdoor». Для большинства приложений достаточно.
Проблема встроенных меток: они на английском и универсальные. Для приложения с предметной спецификой (маркетплейс одежды, рецепты, недвижимость) нужна кастомная таксономия.
Кастомная классификация через CreateML:
// Обучение через CreateML (запускать на Mac, не на устройстве)
import CreateML
let trainingData = MLImageClassifier.DataSource.labeledDirectories(
at: URL(fileURLWithPath: "/training_data")
// Структура: /training_data/jacket/, /training_data/shoes/, /training_data/bag/
)
var params = MLImageClassifier.ModelParameters()
params.maxIterations = 25
params.validationData = .split(strategy: .automatic)
params.featureExtractor = .scenePrint(revision: 2) // Transfer learning от Apple
let model = try MLImageClassifier(trainingData: trainingData, parameters: params)
try model.write(to: URL(fileURLWithPath: "/model.mlmodel"), metadata: nil)
20–50 примеров на категорию, 15–30 минут обучения на MacBook Pro M2 — получаем .mlmodel для deployment. Core ML Model Deployment (API от Apple) позволяет обновлять модель без обновления приложения.
Тегирование текстового контента
Для текстовых постов, описаний, комментариев — NLP-классификация. Варианты:
On-device через Create ML NLP Classifier:
let classifier = try NLModel(mlModel: textClassifierModel)
let labels = classifier.predictedLabelHypotheses(
for: "Отличный рецепт пасты с томатным соусом и базиликом",
maximumCount: 3
)
// Результат: ["Food": 0.91, "Recipe": 0.78, "Italian": 0.45]
Модель весит 1–5 MB для 50–100 категорий. Работает полностью offline.
Серверно через OpenAI / Claude — для сложных таксономий или когда нужна высокая точность. Промпт: «Определи 3–5 тегов для следующего текста из списка: [список тегов]». JSON-ответ парсим на клиенте. Задержка — 0.5–2 секунды, подходит для контента, который создаётся пользователем, а не для real-time потока.
Иерархические теги
Простой список тегов — недостаточно. Нужна иерархия: «Еда → Итальянская кухня → Паста». Реализуем через дерево тегов:
// Android: TagTree
data class Tag(
val id: String,
val name: String,
val parentId: String?,
val synonyms: List<String> = emptyList()
)
// При тегировании: если назначен тег "Паста" — автоматически добавляем родительские
fun expandWithParents(tagId: String, tagTree: Map<String, Tag>): Set<String> {
val result = mutableSetOf(tagId)
var current = tagTree[tagId]
while (current?.parentId != null) {
current = tagTree[current.parentId]
current?.let { result.add(it.id) }
}
return result
}
Пользовательские теги vs автоматические
Автотеги — служебная информация для поиска и фильтрации. Пользовательские теги — они видны пользователю и редактируемы. В базе данных разделяем:
CREATE TABLE content_tags (
content_id UUID,
tag_id UUID,
source ENUM('auto', 'user', 'admin'),
confidence FLOAT, -- для auto: вероятность
created_at TIMESTAMP
);
В UI показываем только source = 'user'. Автотеги используются только в поиске/фильтрах. Пользователь может «принять» автотег, перевести его в user.
Тегирование видео
Видео тегируем по ключевым кадрам — каждые 2–5 секунд берём кадр, классифицируем как изображение, агрегируем теги:
func tagVideo(at url: URL) async throws -> Set<String> {
let asset = AVURLAsset(url: url)
let duration = asset.duration.seconds
let generator = AVAssetImageGenerator(asset: asset)
generator.maximumSize = CGSize(width: 224, height: 224)
var allTags = Set<String>()
var time = 0.0
while time < duration {
let cgImage = try generator.copyCGImage(at: CMTime(seconds: time, preferredTimescale: 600), actualTime: nil)
let frameTags = try await classifyImage(cgImage)
allTags.formUnion(frameTags)
time += 3.0 // каждые 3 секунды
}
return allTags
}
Для длинного видео (10+ минут) — запускаем через BackgroundTask или на backend.
Сроки
On-device тегирование изображений с готовыми моделями — 3–5 дней. Кастомная таксономия с обучением под домен, тегирование текста и видео, иерархические теги — 2–4 недели. Стоимость рассчитывается индивидуально.







