Как за один вечер разгрести 36 000 фотографий и почту с 2005 года, руками AI-агента и локальных моделей

от автора

Есть задачи, которые не делаются никогда. Не потому что сложные, а потому что объём убивает любое намерение на втором часу. У меня такой задачей был фотоархив: около 36 000 фото и видео, 222 ГБ, копившиеся 20 лет и размазанные вообще везде:

  • часть в OneDrive, разложенная по годам;

  • часть там же, но в свалках: дампы с телефонов, выгрузки из WhatsApp, папка буквально с названием «разобрать старые фото», которая ждала своего часа лет десять;

  • часть уже в Apple Photos, с iPhone, сама по себе и никак не связанная с остальным архивом;

  • часть вообще застряла в почте: приходила годами порциями, тяжёлыми письмами, и так и осела вложениями;

  • имена файлов: половина по-человечески, половина IMG_4348.JPG и DSCN0217.JPG;

  • EXIF: у части корректный, у части враньё, у части нет вовсе.

Разобрать это руками означало однажды сесть и просмотреть десятки тысяч файлов, то есть никогда.

А началось всё буднично. Пришло уведомление, что в почте кончается место, и сервис предложил очевидное: докупить квоту. Но я подумал, что за 20 лет ящик ни разу толком не чистил, и логичнее один раз разобрать. И сразу решил делать это не руками, а с агентом: выдал ему доступ к Gmail API, попросил проанализировать ящик. Он вернулся с раскладкой (сколько чего по отправителям, размерам, годам), и дальше почту мы разрулили целиком его руками. По дороге выяснилось, что куча фотографий осела в тяжёлых письмах, решил их вытащить и кинуть в Apple Photos. И тут вспомнил про старый неразобранный архив в OneDrive. И понеслось.

Исторически у такой задачи было ровно два исхода: «руками когда-нибудь» (то есть никогда) и «докупить квоту». Я решил попробовать третий: отдать рутину AI-агенту, а самому только принимать решения. Оркестратором был Claude Code / Opus 4.8, он сам писал одноразовые скрипты под каждый шаг и дёргал нужные инструменты.

С чего начали: почта

План, на котором сошлись с агентом, был простой: сначала вычистить спам, а фото-архивы, осевшие в письмах, вытащить и перенести в отдельный сервис, чтобы и место освободить, и снимки не потерять.

Около 9 500 явного мусора (реклама, уведомления) отправили в Корзину. И сразу урок, ради которого стоит держать страховку: в эту пачку уехала рассылка живого интернет-магазина (конструктор сайта, сервис рассылок, платёжные уведомления), формально спам-признаки, фактически рабочая история проекта. Спасло то, что удаляли только в Корзину: восстановили одной командой, отправителя занесли в исключения. Никаких «удалить насовсем», пока человек не подтвердил.

А вот дальше началось интересное. Тяжёлые письма оказались, по сути, непросмотренным фотоальбомом. Причём слали их порциями: одно событие нередко было раскидано по нескольким письмам («часть 1», «часть 2», и так далее). И тут агент сделал больше, чем тупо вытащил вложения: он проанализировал темы и содержание писем, выборочно посмотрел сами фотографии и предложил понятную структуру. Например, файлы, присланные четырьмя разными письмами, он объединил в одно событие. То есть не «папка на письмо», а «папка на реальное событие».

Эти альбомы перенесли в Apple Photos. С массовым импортом скриптом возникли проблемы (Apple Photos с таким дружит плохо), но вместе с агентом мы их порешали. Подробности скучные, важно другое.

Поворот: а давай заодно и OneDrive

Вот ровно в этот момент я задумался плотнее. Раз фотографии из почты уже едут в Apple Photos, логично причесать и старый архив в OneDrive, который лежал нетронутым годами, и тоже завести его в Apple Photos.

Зачем. Во-первых, альтернативная копия. Во-вторых, и это главное, появлялась реальная возможность вообще отказаться от подписки OneDrive и переехать в Apple целиком. Раньше об этом не было смысла даже думать: затащить 36 тысяч неразобранных файлов в Apple Photos означало просто перевезти бардак с места на место.

Так задача из «почистить почту» выросла в «разобрать весь фотоархив». А это уже 36 659 файлов и 222 ГБ.

Честный разговор про объём

Когда я попросил агента «разобрать 36 тысяч фотографий», он не бросился их смотреть. Он сказал прямо: гонять такой объём через меня саму (фронтир-модель) бессмысленно, это и в контекст не влезет, и по токенам разорит. Правильный путь, говорит, поднять локальные модели, которые сделают тяжёлую работу почти даром на твоём железе, а я возьму на себя оркестрацию и контроль качества.

Это и задало всю архитектуру. Сложилось разделение труда:

  • локальные модели перемалывают десятки тысяч файлов почти бесплатно;

  • фронтир-агент пишет под каждый шаг одноразовый скрипт, склеивает инструменты и сам проверяет результат, а не только показывает его мне;

  • человек принимает финальные решения и ловит то, что машина знать не может.

Связка человек, агент, локальные модели

Связка человек, агент, локальные модели

Источники из разных мест сходятся к агенту, тот раздаёт тяжёлую работу локальным моделям, а себе оставляет оркестрацию и контроль.

Дальше каждый узел покажу одинаково: в какую проблему уперлись, что предложил агент, как это выглядело технически, что значило по-человечески, и какое решение это позволило принять.

Шаг 1. Дедуп, до всего остального

Первое правило большого архива: сначала убрать дубли, потом всё остальное.

Проблема. Куча почти-одинаковых файлов: пересохранения, ресайзы, кадры серий. Точные дубли по хэшу их не ловят. Что предложил агент. Сравнивать не байты, а изображения. Технически. Перцептивный хэш, инструмент czkawka. По-человечески. «Вот 5 кадров, где одно и то же, разница только в сжатии: оставляем лучший по разрешению, остальные в карантин.» Какое решение позволило принять. Схлопнуть очевидные повторы, не глядя руками на 36 тысяч файлов. Обратимо, в карантин.

Поверх czkawka агент за 15 минут собрал маленькую браузерную страничку для ревью: группы похожих, миниатюры в ряд, лучший предвыбран. Удобнее любой готовой галереи.

Дедуп по содержимому

Дедуп по содержимому

Из почти одинаковых кадров остаётся лучший по разрешению, остальные в карантин (обратимо).

Шаг 2. «А что вообще на фото?», локальные модели

Свалки без имён и дат нельзя разложить по событиям, пока не поймёшь, что на снимках. Руками те же десятки тысяч. Поэтому модели, локально.

Грубые теги содержимого. CLIP (open_clip, ViT-B-32) для каждого фото выдаёт ближайшие теги из словаря (пляж, дети, еда, документ). По-человечески: «это похоже на праздник», «это скан документа, не память». Заодно отделили документы и скриншоты от снимков.

Имена событий.

Проблема. Тег «праздник» это не название альбома. Нужно «день рождения», «поездка», «корпоратив». Что предложил агент. Показать зрительной модели по паре кадров из каждого кластера и попросить описать. Технически. Qwen2.5-VL-7B через mlx-vlm, нативно на Apple Silicon. По-человечески. Модель выдавала «Дети на катке с маскотом в виде зайца», «Семья катается на коньках в тумане». Из этого уже собирается человеческое имя события.

Вот здесь и видна та самая экономика. Просить фронтир-модель «опиши все 4 000 фото» это и долго (около 17 секунд на кадр, итого часы), и дорого по токенам. Локальная VLM делает это почти даром, а агент только склеивает описания в имена событий.

Шаг 3. Лица, как диаризация в аудио

Самая красивая часть. Задача «найти, кто на фото» это ровно та же задача, что диаризация спикеров в аудио: разбить на «персона 1, персона 2», а человек потом называет их по разу.

Проблема. Хочется находить всех по человеку и подписывать события именами, но 74 тысячи лиц вручную не разметишь. Что предложил агент. Детектировать лица, посчитать эмбеддинги, кластеризовать, а человеку оставить только «назвать кластеры». Технически. InsightFace (ArcFace-эмбеддинги), затем kNN и union-find, получилось 2 153 кластера-персоны. По-человечески. «Вот один человек на 3 818 фото, вот другой на 3 200: назови их по разу, имена сами разойдутся по всем снимкам.»

И тут поучительный провал с порогом. При мягком пороге кластеризация схлопнула пол-архива в один мегакластер на 30 000 лиц, где разные люди вперемешку (эффект цепочки через «мостиковые» лица). Подняли порог строже, получили чистые кластеры.

Показательно, кто проверял качество. Не я глазами, а сам агент: вырезал по несколько лиц из крупнейших кластеров и смотрел (у фронтир-модели есть зрение), один это человек или каша. То есть оптический контроль, который обычно ложится на человека, агент во многом взял на себя.

Какое решение позволило принять. Назвать топ-персон по разу (это покрыло больше 15 тысяч фото), а их имена вписались тегами прямо в файлы (XMP/IPTC), так что ищутся в любом просмотрщике.

Диаризация лиц

Диаризация лиц

Лица бьются на персон автоматически, человек называет каждую один раз, имена расходятся по всем фото и видео.

Называл не всех, да это и не нужно. Персоны отсортированы по частоте: сверху те, кто чаще всего в кадре (по факту семья, друзья, родственники, коллеги), внизу случайные и малознакомые люди, попавшие в объектив на групповых и публичных снимках. Подписывать имеет смысл именно частых, у них и отдача максимальная.

Лейблер персон

Лейблер персон

Реальный экран лейблера: персоны по убыванию частоты, лица заблюрены, а имена я скрыл специально для публикации. Из 2 153 персон подписаны верхние несколько десятков, дальше хвост из случайных людей.

Шаг 4. Видео: тот же стек, в два прохода

Роликов в архиве 1 754, и бросать их не хотелось. Отдельный «видео-стек» не понадобился: ffmpeg достаёт из ролика несколько кадров, а дальше работают те же модели, что и для фото. Что в ролике, описывает та же VLM по кадрам. Кто в ролике, те же лица сверяются с уже названными персонами, и клип получает теги.

Видео кадры из ffmpeg в те же модели

Видео кадры из ffmpeg в те же модели

Видео разбирается тем же стеком: кадры из ffmpeg уходят в VLM (что в ролике) и в распознавание лиц (кто), результат тегами в файл.

С распознаванием людей в видео всплыл нюанс, который мы с агентом обсудили и решили в два прохода. Сначала прогнали все 1 754 ролика по 5 кадров, это дало людей в части роликов. Но 5 кадров легко пропускают человека, который мелькнул лишь в куске видео. Поэтому вторым проходом взяли только те ролики, где в первый раз никого не нашли, и прогнали их плотнее, по 12 кадров. Так добрали ещё заметную долю: итого из 1 754 людей распознали в 608 (470 в первом проходе плюс 138, всплывших во втором).

Логика та же, что и со всем остальным: сначала дёшево закрыть основной объём, потом точечно дожать остаток там, где это реально окупается.

Хозяйке на заметку. Этим же реестром лиц можно довольно точно вытащить все фото и видео с конкретным человеком и собрать на их основе, например, короткий коллаж-ролик к событию: дню рождения, юбилею, выпускному.

Шаг 5. Сортировка, и почему EXIF врёт

Целевая структура хронологическая: год, внутри ГГГГ-ММ-ДД, событие. Делали через манифест с предпросмотром и полным undo-логом (любой шаг обратим), сначала пилот на одном годе. И пилот тут же себя оправдал.

Проблема. Пачка фото с корпоратива 2008 года уехала в 2005. Почему. У старых камер с несбитыми часами EXIF по умолчанию 2005-01-01, а у сканов EXIF хранит дату оцифровки, а не съёмки. Что предложил агент. При расхождении года доверять имени папки, а не EXIF. Лежит в папке «2008-09 корпоратив», значит 2008, что бы ни говорил EXIF. По-человечески. Человек, который называл папку, знал год точно, камера нет.

Шаг 6. Гранулярность и финальная полировка

Первый автоматический результат смутил: одно событие дробилось на несколько папок по дням. Поправили в два прохода: день в месяц, а «папки-людей» и длящиеся истории (человек, ремонт) в год, потому что это субъекты, а не разовые события. Поездки и праздники остались помесячно. Для одного 2013 года это сократило около 200 папок-по-дням до 49.

Гранулярность до и после

Гранулярность до и после

Слева дробление по дням, справа: год для людей, месяц для разовых событий.

А дальше начинается то, что отличает «готово» от «вылизано». Проходя руками по уже разобранному архиву, замечаешь артефакты: где-то два почти одинаковых события стоит слить, где-то подправить имя. Но это уже не работа, а причёсывание. И сам факт, что осталась только полировка, говорит о главном: основной объём сделан, и сделан достойно.

Что в итоге

  • по всему OneDrive нашлось около 37 000 изображений и видео, разбросанных не только по фотоархиву, но и по самым разным папкам;

  • около 4 400 файлов лежали в свалках «разобрать», дампах с телефонов и старых бэкапах, к которым иначе не прикоснулись бы, все разобраны и разложены;

  • итог: примерно 36 000 фото и видео в ~490 папках-событиях за 26 лет, структура ГГГГ, человек или поездка плюс ГГГГ-ММ, событие;

  • люди тегами внутри файлов, и в фото, и в видео;

  • дубли в карантине, документы и нефото-материалы отдельно;

  • всё обратимо: каждое перемещение в undo-логе, удалённые письма в Корзине, дубли в карантине.

Стек: Claude Code (оркестратор), czkawka (дедуп), open_clip (теги), Qwen2.5-VL на MLX (описания событий), InsightFace (лица), exiftool (теги в файлы).

Полный импорт в Apple Photos я ещё не завершил. Но это уже дело техники: основная, тяжёлая работа (дедуп, события, лица, единая структура) сделана, и завести готовый архив в любую галерею теперь не страшно, бардак туда уже не переедет.

Итого

Активной работы пара часов. Несколько раз я просто оставлял машину молоть (распознавание лиц по всему архиву, описание событий) и уходил заниматься своими делами. Итог: задача, которую я не сделал бы никогда, закрылась за вечер. А началось всё с уведомления о паре гигабайт в почте.

И главное не в том, что «AI всё сделал сам», а в том что с этим инструментом я быстро собрал себе пайплайн решивший бытовой вопрос с 20 летней историей прокрастинации. Сработала именно связка:

  • тяжёлый перемол (десятки тысяч фото, лиц, хэшей) ушёл на бесплатные локальные модели;

  • фронтир-агент остался на оркестрации и контроле качества, причём проверку он во многом взял на себя;

  • человек на решениях, которые машина знать не может: что папка «разобрать» это не одно событие, что «по дням» плохо, что половина «фотографий» в одной свалке вообще не фото, а сохранённые из интернета референсы.

Те самые два исхода, «руками когда-нибудь» и «докупить квоту», наконец получили рабочую альтернативу. И обошлась она, за счёт локальных моделей, почти даром.

Именно это уже происходит и будет все больше происходить в работе. Будут решаться аналогичные nice to have вещи до которых никогда не дошли бы приоритеты и слот на ресурсы.

ссылка на оригинал статьи https://habr.com/ru/articles/1047274/