К содержанию
Yottis полный план работ · сентябрь 2026

Весь план целиком

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

Задач
450
Фаз и треков
10
На критическом пути
83
Человеко-недель
2681
Направлений работ
18

Фаза 0

Фундамент

Месяцы
1–3
Календарь
сен–ноя 2026
Команда
6 чел.
Индекс
1 млн
Бюджет
7.8 млн ₽
Задач
23
Недель работ
51

Доказать, что связка «свой обход → свой индекс → своё ранжирование» сходится по качеству на малом масштабе, и параллельно поставить площадку, без которой бота не пустят в веб. Всё написанное здесь будет переписано: цель фазы — не код, а снятие неопределённости.

Обработка 2

0.1

Разбор Common Crawl: корпус рунета

Обработкакритический путь1 ML + 1 инфраструктура2 нед.
Зачем

Обходить веб с нуля ради проверки гипотезы — это месяцы. Common Crawl отдаёт более 2 млрд страниц в каждом месячном срезе бесплатно, и из него за две недели получается корпус, на котором проверяется всё остальное.

Что делаем
  1. Скачиваем индекс последнего среза, около 250 ГБ в сжатом виде.
  2. Фильтруем по зонам .ru, .рф, .su, .by, .kz и по определённому языку.
  3. Выкачиваем WARC-сегменты только для отобранных URL, а не весь срез.
  4. Складываем в объектное хранилище, ведём учёт: сколько документов, сколько байт, сколько стоило.
Готово, когда

5 млн русскоязычных документов лежат в WARC в объектном хранилище, есть таблица «домен → число документов», известна фактическая стоимость обработки.

Как проверяем

Случайная выборка 100 документов открывается и читается — это действительно русскоязычные страницы, а не мусор и не дубликаты.

Риск

Обработка обойдётся дороже ожидаемого из-за исходящего трафика. Обрабатываем в том же облаке, где лежат данные; считаем счёт на первой неделе, а не в конце.

0.2

Извлечение текста: выбор конфигурации

Обработкакритический путь1 ML2 нед.зависит от 0.1
Зачем

Всё качество поиска стоит на качестве извлечённого текста. Если мы индексируем навигацию и подвалы вместо содержания, никакое ранжирование не спасёт, а ошибку на этом шаге не видно до самого конца.

Что делаем
  1. Прогоняем Resiliparse и Trafilatura на одной выборке в 1000 документов.
  2. Вручную размечаем эталон: для каждого документа человек отмечает, какой текст является основным.
  3. Считаем точность, полноту и F1 для обеих библиотек и для их комбинации.
  4. Отдельно смотрим типы страниц, где обе ошибаются: форумы, каталоги, лендинги.
  5. Фиксируем конфигурацию: что запускаем на всём корпусе, что на кандидатах.
Готово, когда

Есть отчёт с числами по обеим библиотекам и выбранная конфигурация с обоснованием.

Как проверяем

F1 выбранной конфигурации на русскоязычной выборке не ниже 0.80. Публичные бенчмарки дают Trafilatura около 0.859, но они на англоязычных данных — для рунета цифру нужно получить свою.

Риск

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

Индекс и поиск 1

0.3

Прототип индекса на Tantivy

Индекс и поисккритический путь2 backend3 нед.зависит от 0.2
Зачем

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

Что делаем
  1. Схема документа по разделу 4.5 документа об обходе и индексации: заголовок, словоформы, леммы, хост, язык, дата, быстрые поля под авторитет, качество и спам.
  2. Токенизаторы: словоформы и леммы отдельными полями. Морфология пока грубая, полноценная придёт в фазе 1.
  3. Индексация 1 млн документов, замер скорости и размера.
  4. Поиск в консоли: разбор простого запроса, выдача топ-10 с оценками.
  5. Прямой индекс для сниппетов в простейшем виде, без сжатия.
Готово, когда

Поиск по 1 млн документов работает в консоли, p95 не выше 200 мс на одной машине, размер индекса измерен и записан.

Как проверяем

50 контрольных запросов отрабатывают за отведённое время; размер индекса на документ сверяется с расчётом — ориентир около 6 КБ горячих данных.

Риск

Схема окажется неудобной для будущих признаков. В фазе 0 это не страшно: индекс пересобирается за часы.

Ранжирование 2

0.4

BM25F с весами полей

Ранжирование1 backend + 1 ML2 нед.зависит от 0.3
Зачем

Получить первую осмысленную формулу ранжирования и точку отсчёта, относительно которой измеряется всё дальнейшее улучшение.

Что делаем
  1. Реализуем BM25F так, чтобы взвешенная частота собиралась по всем полям до применения насыщения — именно это отличает BM25F от суммы независимых BM25 по полям.
  2. Стартовые веса: заголовок 8.0, якорные тексты 6.0, подзаголовки 3.0, адрес 2.5, словоформы 1.5, леммы 1.0.
  3. Ручная настройка на 50 запросах: смотрим глазами, двигаем веса.
  4. Фиксируем конфигурацию в файле, а не в коде — она будет меняться постоянно.
Готово, когда

Формула считается, веса вынесены в конфигурацию, есть baseline-замер.

Как проверяем

На 50 запросах вручную: результат с точным вхождением в заголовке стоит выше результата с вхождением только в тексте.

0.6

Веб-граф, PageRank и первый TrustRank

Ранжирование1 ML3 нед.зависит от 0.1
Зачем

Авторитет хоста — второй по важности сигнал после текстовой релевантности. Без него в топе оказываются сайты, где слова запроса встречаются чаще, а не те, которым можно доверять.

Что делаем
  1. Извлекаем рёбра из обойденного корпуса, строим хостовый и страничный граф.
  2. PageRank с затуханием 0.85, итеративно до сходимости.
  3. Ядро доверия: вручную отбираем 500 хостов — государственные ресурсы, вузы, крупные СМИ, известные энциклопедии, отраслевые авторитеты. В фазе 1 ядро расширится до 10 000.
  4. TrustRank: распространение доверия из ядра с затуханием.
  5. Выгрузка значений в таблицу признаков для индекса.
Готово, когда

Для каждого хоста в корпусе есть значения PageRank, авторитета хоста и TrustRank, и они подмешиваются в ранжирование.

Как проверяем

Ручная проверка топ-100 хостов по авторитету: там должны быть узнаваемые крупные ресурсы, а не сетки дорвеев. Незнакомый домен в топ-50 разбирается отдельно — это либо находка, либо ошибка.

Обход 3

0.5

Прототип краулера

Обходкритический путь1 backend4 нед.зависит от 0.1
Зачем

Собственный обход — один из трёх обязательных активов. Проверить нужно не производительность, её проверим в фазе 1, а корректность: соблюдение robots.txt, вежливость, устойчивость к ошибкам.

Что делаем
  1. Разбор robots.txt строго по RFC 9309 со сверкой поведения с открытой реализацией Google.
  2. Двухуровневые очереди фронтира: передние по приоритету, задние по хостам с меткой времени следующего разрешённого запроса.
  3. Политика вежливости: 1 запрос в секунду на хост, не более 2 соединений.
  4. Загрузка, запись в WARC, обработка редиректов и ошибок.
  5. Свой DNS-кэш: на будущих скоростях системный резолвер станет узким местом.
Готово, когда

Краулер обходит 100 сайтов со скоростью 10 стр/с, соблюдая все ограничения, и складывает результат в WARC.

Как проверяем

Набор из 30 синтетических robots.txt с крайними случаями — поведение совпадает с эталонной реализацией во всех случаях без исключения. Логи 100 обойденных сайтов: ни к одному не было больше одного запроса в секунду. Ни одной жалобы от владельцев сайтов за время теста.

Риск

Неверная трактовка robots.txt приведёт к обходу закрытых разделов — репутационный риск, который трудно исправить. Три места, где ошибаются чаще всего: выигрывает самое длинное совпадение пути, а не первое встреченное; Allow побеждает Disallow при равной длине; ответ 404 означает разрешено всё, а 5xx — запрещено всё временно. Сверка с эталоном обязательна и входит в критерий готовности.

0.16

Страница о боте

Обходкритический путьинфраструктура + фронтенд2 нед.зависит от 0.14
Зачем

Вебмастер, увидевший в логах неизвестного бота, ищет его имя в поиске. Если он не находит объяснения, он его банит. Забаненный бот означает пустой индекс, а вернуть доверие после массовых банов гораздо дороже, чем изначально всё объяснить.

Что делаем
  1. Страница /bot: кто мы, зачем ходим, какой User-Agent, с какой частотой.
  2. Публикация диапазонов IP краулера в машиночитаемом виде по фиксированному адресу.
  3. Инструкция, как ограничить или запретить обход через robots.txt.
  4. Контакт для жалоб с обязательством отвечать в течение суток.
  5. Инструмент проверки: по IP сказать, наш это бот или подделка.
Готово, когда

Страница опубликована до первого внешнего запроса краулера. Условие блокирующее: пока страницы нет, краулер не выходит за пределы тестовых доменов.

Как проверяем

Страница открывается даже при недоступности приложения — отдаётся статикой напрямую из веб-сервера.

0.17

Обратный DNS для краулера

Обходкритический путьинфраструктура2 нед.зависит от 0.13
Зачем

Вебмастер должен уметь отличить настоящего бота от подделки. Без этого любой спамер может представиться нашим ботом, а репутацию за чужие действия получим мы.

Что делаем
  1. Заказываем PTR-записи в поддержке провайдера для всех IP краулера.
  2. Настраиваем прямые записи на те же адреса.
  3. Документируем процедуру двусторонней проверки.
Готово, когда

Двусторонняя проверка «адрес → имя → адрес» проходит для всех IP краулера.

Как проверяем

Для каждого адреса из публикуемого диапазона: обратный запрос даёт имя в нашей зоне, прямой запрос по этому имени возвращает исходный адрес. Проверка автоматическая и повторяется при КАЖДОМ изменении диапазона: адрес, добавленный без записи, означает, что вебмастер примет нашего бота за подделку и заблокирует его вместе с настоящим.

Риск

Провайдер долго оформляет PTR. Заявка подаётся на неделе 5, запас три недели.

Качество 3

0.7

Разметка первой корзины запросов

Качествокритический путь1 ML + 5 асессоров4 нед.зависит от 0.4
Зачем

Без асессорских оценок качество поиска — вопрос вкуса. С ними — число, которое можно двигать. Это самая недооценённая задача фазы: её постоянно откладывают, а потом месяцами «улучшают поиск» без возможности проверить, стало ли лучше.

Что делаем
  1. Отбираем 300 запросов: 200 случайных по частотности, 60 сложных многословных и неоднозначных, 40 навигационных с известным правильным ответом.
  2. Пишем инструкцию асессора — первую версию на 10–15 страниц: шкала оценок, разбор пограничных случаев, примеры.
  3. Нанимаем 5 асессоров по договору на 3 недели, обучаем по инструкции.
  4. Для каждого запроса оцениваем топ-20 нашей выдачи и топ-10 конкурентов — последнее нужно для сравнения, а не для копирования.
  5. Перекрытие: каждую пару «запрос — документ» оценивают 3 асессора.
  6. Считаем согласие по каппе Коэна; при значении ниже 0.5 дорабатываем инструкцию и переоцениваем.
Готово, когда

Размечено 300 запросов по 20 документов, каппа Коэна не ниже 0.5, данные в базе.

Как проверяем

Каппа Коэна не ниже 0.5. Порог ниже целевого 0.6, потому что первая инструкция всегда сырая; в фазе 1 требование ужесточается.

Риск

Асессоры оценивают по своему вкусу, а не по инструкции. Смягчение — контрольные задания с заранее известным ответом, вкраплённые в поток.

0.8

Реализация метрик и панель замеров

Качество1 ML2 нед.зависит от 0.7
Зачем

Метрика, которую считают вручную раз в месяц, не влияет на решения. Метрика, которая считается автоматически и видна всем, влияет.

Что делаем
  1. Реализуем pFound с вероятностью прерывания 0.15 и шкалой отображения асессорских оценок в вероятность релевантности.
  2. Реализуем NDCG@10, MRR и Recall@100 для сопоставимости с литературой.
  3. Скрипт прогоняет корзину, считает метрики и пишет результат с отметкой версии кода.
  4. Простая страница с графиком: как менялся pFound от замера к замеру.
Готово, когда

Одна команда выдаёт pFound за пару минут, результат сохраняется в историю.

Как проверяем

Ручной пересчёт pFound на 5 запросах в таблице совпадает с выводом скрипта до четвёртого знака.

0.10

Замер разрыва в качестве и отчёт по фазе

Качествокритический путьтехнический лидер + ML2 нед.зависит от 0.8, 0.9
Зачем

Главный результат фазы 0 — не код, а честное понимание, где мы находимся. Отчёт нужен и команде, и инвестору, и он должен быть неприятным, если реальность неприятна.

Что делаем
  1. Прогоняем корзину, считаем pFound для нашей выдачи и для выдачи конкурентов.
  2. Разбираем 30 запросов с наибольшим разрывом и классифицируем причины: нет документа в индексе, документ есть но не находится, находится но низко.
  3. Считаем, какая доля разрыва объясняется полнотой индекса, а какая ранжированием — это ключевое разделение: первое лечится обходом, второе моделями.
  4. Пишем отчёт: где мы, почему, что делать в фазе 1.
Готово, когда

Отчёт написан, обсуждён, решение по фазе 1 принято.

Как проверяем

Отчёт содержит числа, а не оценки. Формулировка «выдача выглядит неплохо» в отчёт не попадает.

Продукт 1

0.9

Прототип страницы выдачи

Продукт1 фронтенд4 нед.зависит от 0.4
Зачем

Ранжирование, которое нельзя посмотреть глазами, невозможно отлаживать. Плюс это первая витрина проекта, которая понадобится для задачи 0.15.

Что делаем
  1. Серверный рендеринг с работой без JavaScript.
  2. Вёрстка по дизайн-системе: токены, типографика, компоненты.
  3. Генерация сниппетов под запрос: скользящее окно по плотности терминов, подсветка совпадений.
  4. Тёмная тема, доступность, работа на мобильных.
  5. Служебный режим отладки, показывающий вклад каждого признака в скор — без него отладка ранжирования превращается в гадание.
Готово, когда

Выдача открывается в браузере, работает без JavaScript, отладочный режим показывает признаки.

Как проверяем

Страница открывается с отключённым JavaScript и остаётся полностью работоспособной; контраст текста проходит проверку на 4.5:1.

Инфраструктура 8

0.11

Регистрация домена yottis.ru

Инфраструктураинфраструктура1 нед.
Зачем

Домен — первый актив проекта. Он должен отстояться в DNS и быть оформлен правильно с самого начала: перенос с физического лица на юридическое позже происходит с задержкой и риском.

Что делаем
  1. Регистрируем yottis.ru в Timeweb как у аккредитованного регистратора.
  2. Одновременно берём защитные yottis.рф и yottis.com.
  3. Включаем автопродление и запрет на смену владельца без подтверждения.
  4. Оформляем на юридическое лицо.
Готово, когда

Три домена во владении, автопродление включено.

Как проверяем

Запрос whois показывает верного владельца и дату продления.

Риск

Домен занят. Проверка в первый день; запасные варианты подготовлены заранее.

0.12

Подготовка VPS

Инфраструктураинфраструктура2 нед.
Зачем

Площадка для витрины, демо и служебных сервисов. Небезопасно настроенный сервер, торчащий в интернет, — это вопрос дней до компрометации.

Что делаем
  1. VPS Timeweb: 4 vCPU, 8 ГБ памяти, 80 ГБ NVMe.
  2. Отдельный пользователь вместо root, вход только по ключам, нестандартный порт SSH.
  3. Межсетевой экран с открытыми только 80, 443 и SSH.
  4. Защита от перебора паролей и автоматические обновления безопасности.
Готово, когда

Сервер поднят, укреплён, доступен только по ключу.

Как проверяем

Попытка входа по паролю и под root отклоняется; внешнее сканирование портов показывает только 80, 443 и SSH.

0.13

Настройка DNS

Инфраструктураинфраструктура1 нед.зависит от 0.11, 0.12
Зачем

Без корректных записей не работает ничего: ни сайт, ни почта, ни выпуск сертификатов.

Что делаем
  1. Делегирование на серверы имён Timeweb.
  2. Записи A и AAAA на VPS — IPv6 обязателен, часть сетей уже без IPv4.
  3. CNAME для www, записи A для поддоменов кабинета, API и бота.
  4. Запись CAA с запретом выпуска сертификатов другими удостоверяющими центрами.
  5. Записи SPF и DMARC.
  6. TTL 300 на боевых записях: переключение при аварии за 5 минут, а не за сутки.
Готово, когда

Запросы к DNS возвращают верные ответы по всем записям.

Как проверяем

Каждая запись проверяется с нескольких резолверов ВНЕ нашей сети — публичных и сервера в другой стране: ответы совпадают между собой и с ожидаемыми значениями. Отдельно проверяется запись CAA (запрос возвращает запрет для чужих удостоверяющих центров) и фактический TTL на боевых записях. Запись SPF проверяется дважды: при настройке и в день запуска почты — -all при работающей почте это авария, а не конфигурация.

Риск

Запись v=spf1 -all означает, что домен не отправляет почту вообще. В момент запуска почты её обязательно заменить, иначе собственные письма будут отвергаться — это ровно та ошибка, которая обнаруживается на третий день, когда пользователи уже не получили коды подтверждения.

0.14

TLS и веб-сервер

Инфраструктураинфраструктура2 нед.зависит от 0.13
Зачем

Без HTTPS сайт не воспринимается всерьёз ни браузерами, ни поисковыми системами, ни вебмастерами.

Что делаем
  1. Nginx: редирект с http, HTTP/2, сжатие.
  2. Сертификат Let's Encrypt сразу на четыре имени: корень, www, кабинет вебмастера, API.
  3. HSTS и заголовки безопасности.
  4. Автопродление сертификата по таймеру.
Готово, когда

HTTPS работает на всех именах, внешняя оценка не ниже A.

Как проверяем

Проверка SSL Labs не ниже A; принудительное продление сертификата проходит без ошибок.

Риск

Заявку в список HSTS preload подаём не раньше чем через месяц стабильной работы: отозвать её почти невозможно.

0.15

Витрина проекта и демо

Инфраструктурафронтенд + инфраструктура2 нед.зависит от 0.14, 0.9
Зачем

Проект должен быть виден снаружи до того, как понадобится доверие: вебмастера, кандидаты и партнёры будут искать, кто мы такие.

Что делаем
  1. Страница проекта: что строим, статус, контакты.
  2. Макеты по адресу /demo.
  3. Свой robots.txt — мы тоже сайт.
Готово, когда

Страницы открываются, демо работает.

Как проверяем

Все адреса витрины открываются с холодного кеша, включая /demo; проверка с мобильного устройства и на медленном канале, а не только с рабочей машины. Свой robots.txt отдаётся с кодом 200 и разрешает индексацию витрины — закрытая от индексации витрина не выполняет своей единственной задачи.

0.18

CI/CD на Forgejo Actions

Инфраструктураинфраструктура3 нед.зависит от 0.12
Зачем

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

Что делаем
  1. Второй VPS под сборочный агент.
  2. Пайплайн: сборка, тесты, выкатка по SSH.
  3. Откат через символическую ссылку на каталог релиза: возврат к предыдущей версии — одна команда.
  4. Проверка здоровья после выката; нет ответа за 30 секунд — шаг падает.
Готово, когда

Изменение в основной ветке приводит к выкатке, откат проверен на практике.

Как проверяем

Выкатываем заведомо сломанную версию — CI останавливает выкатку; откат возвращает рабочую за меньше чем минуту.

0.19

Внешний мониторинг

Инфраструктураинфраструктура2 нед.зависит от 0.14
Зачем

Мониторинг, стоящий рядом с сервисом, падает вместе с ним.

Что делаем
  1. Внешний монитор доступности на дешёвом VPS у другого провайдера.
  2. Проверки: доступность сайта, срок действия сертификата, ответ проверки здоровья.
  3. Оповещения в мессенджер.
Готово, когда

Проверки идут, оповещение приходит при остановке сервиса.

Как проверяем

Останавливаем сервис — оповещение приходит меньше чем за 2 минуты.

0.20

Резервное копирование с проверкой восстановления

Инфраструктураинфраструктура3 нед.зависит от 0.12
Зачем

Резервная копия, из которой ни разу не восстанавливались, резервной копией не является.

Что делаем
  1. Бэкап базы: журнал непрерывно, полный снимок раз в сутки, хранение 30 дней.
  2. Снимки VPS средствами провайдера.
  3. Конфигурация серверов — в репозитории на Repobase.
  4. Секреты не в репозитории.
Готово, когда

Бэкап снимается автоматически и восстановлен на отдельной машине.

Как проверяем

Полное восстановление на чистой машине, данные совпадают. Процедура записана и повторяется раз в квартал.

Продвижение 3

0.21

robots.txt и sitemap для yottis.ru

Продвижениеинфраструктура1 нед.зависит от 0.15
Зачем

Страницы выдачи в чужом индексе — это бесконечное пространство адресов и мусор. Это ещё и правило приличия между поисковыми системами: индексировать чужую выдачу не принято, и мы не создаём такой возможности у себя.

Что делаем
  1. Запрет обхода страниц выдачи, личных кабинетов и админки в robots.txt.
  2. Мета-тег noindex на самих страницах выдачи: robots.txt запрещает обход, но не гарантирует отсутствие в индексе при наличии внешних ссылок.
  3. Sitemap с документацией и инструментами.
Готово, когда

Индексируется то, что нужно; выдача закрыта двумя способами.

Как проверяем

Выдача закрыта двумя независимыми способами, и проверяются оба: Disallow в robots.txt и мета-тег noindex на самих страницах. Карта сайта не содержит ни одного закрытого адреса — расхождение между картой и robots.txt считается ошибкой сборки. Через неделю после публикации панели вебмастера не показывают страниц выдачи в индексе.

0.22

Подключение Вебмастера и Search Console

Продвижениеинфраструктура1 нед.зависит от 0.21
Зачем

Без панелей вебмастера мы не видим, как нас индексируют конкуренты, и узнаём о проблемах последними.

Что делаем
  1. Подтверждение прав в Яндекс.Вебмастере.
  2. Подтверждение прав в Google Search Console.
  3. Загрузка карты сайта в обе панели.
Готово, когда

Обе панели подключены и показывают данные.

Как проверяем

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

0.23

Разметка Organization и WebSite

Продвижениефронтенд1 нед.зависит от 0.15
Зачем

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

Что делаем
  1. Разметка Organization на главной: название, логотип, контакты.
  2. Разметка WebSite с описанием поиска по сайту.
  3. Проверка валидатором.
Готово, когда

Разметка на главной проходит валидацию без ошибок.

Как проверяем

Валидатор структурированных данных не выдаёт ни ошибок, ни предупреждений на главной. Отдельно поля организации сверяются с тем, что написано на странице «О проекте»: расхождение разметки и видимого текста считается ошибкой, а не мелочью — именно на таких расхождениях разметку и перестают учитывать.

Ворота фазы 0

Все критерии обязательны. Не пройдены — фаза продлевается, а не закрывается.

  • Поиск по 1 млн документов работает, p95 не выше 200 мс на одной машине
  • pFound@10 не ниже 0.35 на корзине из 300 запросов
  • F1 извлечения текста не ниже 0.80 на русскоязычной выборке
  • Краулер прошёл 100 сайтов без единого нарушения robots.txt
  • Каппа Коэна между асессорами не ниже 0.5
  • Сайт открывается по HTTPS, внешняя оценка не ниже A, демо доступно
  • Страница о боте опубликована, обратный DNS проверен в обе стороны
  • Выкатка одной командой из Repobase, откат проверен на практике
  • Бэкап восстановлен на отдельной машине
  • Отчёт о разрыве в качестве написан, с разделением на полноту и ранжирование

Фаза 1

Ядро

Месяцы
4–10
Календарь
дек 2026 – июн 2027
Команда
14 чел.
Индекс
50 млн
Бюджет
59.5 млн ₽
Задач
67
Недель работ
243

Превратить прототип в систему: распределённый индекс, непрерывный обход, кабинет вебмастера, аккаунты, закрытая альфа на 1000 пользователей. Главное отличие от фазы 0 — теперь код пишется надолго: схемы данных, контракты между сервисами и формат индекса, заложенные здесь, будут жить годами.

Обход 7

1.1

Промышленный фронтир

Обходкритический путь2 backend6 нед.зависит от 0.5
Зачем

Прототип держит очередь в памяти и теряет её при перезапуске. На 50 млн документов очередь — это десятки миллионов адресов, которые нельзя терять: их повторное открытие означает повторный обход всего.

Что делаем
  1. Персистентное хранилище очереди с восстановлением после перезапуска.
  2. Двухуровневая схема: передние очереди по приоритету — критично, высокий, обычный, хвост; задние очереди по одной на хост с меткой времени следующего разрешённого запроса.
  3. Формула приоритета: авторитет хоста, прогноз изменения, спрос на свежесть в теме, сигнал из выдачи, подсказки вебмастера, штрафы за недоступность и за спам.
  4. Метрики: длина очереди, лаг, распределение по приоритетам, доля отброшенных.
Готово, когда

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

Как проверяем

Убиваем процесс на полной очереди — после перезапуска очередь восстановлена, порядок сохранён, потерь нет.

Риск

Очередь станет узким местом по записи. Смягчение — батчинг записей и раздельные хранилища для передних и задних очередей.

1.2

Прогноз частоты изменения и расписание переобхода

Обходкритический путь1 backend + 1 ML4 нед.зависит от 1.1
Зачем

При индексе в 2 млрд документов и среднем интервале переобхода 14 суток нужно 1650 страниц в секунду только на поддержание свежести, до всякого роста. Переобход доминирует над первичным обходом, и без прогноза основной ресурс уходит на страницы, которые не меняются годами.

Что делаем
  1. Для каждого адреса храним ряд отпечатков содержимого и времён обхода.
  2. Экспоненциальное сглаживание интервалов между реальными изменениями.
  3. Расписание по непрерывной шкале: страница без изменений за год переобходится раз в месяц, лента новостей — раз в минуту.
  4. Отдельная обработка случая «сначала неизвестно»: новый адрес обходится через сутки, затем интервал уточняется.
Готово, когда

Средний интервал переобхода подстраивается под реальную частоту изменений документа.

Как проверяем

На выборке 10 000 адресов с известной историей доля переобходов, не давших изменений, ниже 40% против 75% при фиксированном расписании.

1.3

Условные запросы

Обход1 backend2 нед.зависит от 1.2
Зачем

Ответ «не изменилось» стоит нам почти ничего и экономит трафик сайта. Это одновременно вежливость и деньги: при 10 000 страниц в секунду разница в разы.

Что делаем
  1. Храним время последнего изменения и метку версии для каждого документа.
  2. Отправляем условные заголовки при каждом переобходе.
  3. Корректно обрабатываем ответ «не изменилось», не перезаписывая документ.
Готово, когда

Доля ответов «не изменилось» при переобходе не ниже 40%.

Как проверяем

Метрика доли таких ответов на панели обхода, разбивка по хостам.

1.4

Собственный DNS-резолвер с кэшем

Обход1 backend3 нед.
Зачем

На скорости 10 000 запросов в секунду системный резолвер становится узким местом: обращения к DNS начинают занимать больше времени, чем сама загрузка.

Что делаем
  1. Свой резолвер с кэшем по времени жизни записи, но не меньше 60 секунд.
  2. Пул вышестоящих серверов с распределением нагрузки.
  3. Обработка отказов и отрицательного кэширования.
  4. Метрики попаданий в кэш и времени разрешения.
Готово, когда

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

Как проверяем

Замер под нагрузкой 1000 запросов в секунду: время разрешения не превышает 5 мс на p99.

1.5

Пул рендеринга JavaScript

Обход1 backend5 нед.зависит от 1.1
Зачем

Половина современного веба без выполнения скриптов отдаёт пустой контейнер. Но рендеринг стоит в 50–100 раз дороже простой загрузки, поэтому применяется выборочно и по жёсткой квоте.

Что делаем
  1. Пул headless-браузеров с блокировкой изображений, шрифтов, медиа и рекламы.
  2. Эвристика необходимости: доля видимого текста в объёме разметки ниже 5%, маркеры одностраничного приложения, хост в списке известных, страница ранее показывалась в выдаче.
  3. Самообучающаяся экономия: если прирост текста после рендеринга меньше 20%, хост помечается как не требующий рендера на 30 дней.
  4. Жёсткая квота не более 8% обходимых страниц; при превышении приоритет отдаётся страницам с ненулевым сигналом из выдачи.
Готово, когда

Рендеринг работает, доля не превышает 8%, список «рендер не нужен» пополняется автоматически.

Как проверяем

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

Риск

Пул браузеров течёт по памяти. Смягчение — перезапуск процесса каждые N страниц и жёсткий лимит памяти на процесс.

1.6

Публикация диапазонов IP и верификация бота

Обход1 инфраструктура2 нед.зависит от 0.16, 0.17
Зачем

Продолжение задачи фазы 0. Теперь бот выходит в веб по-настоящему, и вебмастера должны иметь техническую возможность его проверить, а не верить на слово.

Что делаем
  1. Машиночитаемый список диапазонов IP по фиксированному адресу, обновляемый при изменении парка.
  2. Инструмент проверки по адресу на сайте.
  3. Документация процедуры двусторонней проверки DNS.
Готово, когда

Инструмент работает, диапазоны актуальны, документация опубликована.

Как проверяем

Внешняя проверка: адрес из списка проходит двустороннюю проверку, произвольный адрес — нет.

1.7

Приём sitemap и IndexNow

Обход1 backend3 нед.зависит от 1.1
Зачем

Это бесплатная свежесть: вебмастер сам сообщает, что изменилось, и нам не нужно это угадывать переобходом.

Что делаем
  1. Разбор директивы Sitemap из robots.txt, индексных карт и сжатых карт.
  2. Учёт даты изменения и приоритета из карты в приоритете фронтира.
  3. Эндпоинт приёма, совместимый с IndexNow, плюс собственный эндпоинт пуша.
  4. Защита от злоупотребления: квоты и проверка принадлежности адреса домену.
Готово, когда

Карты сайтов разбираются, пуш принимается, изменения попадают в приоритет обхода.

Как проверяем

Адрес, отправленный через пуш, обходится в течение часа.

Обработка 6

1.8

Промышленный конвейер экстракции

Обработка1 ML + 1 backend5 нед.зависит от 0.2
Зачем

Прототип обрабатывает документы по одному. На 300 страницах в секунду нужен конвейер с параллелизмом, устойчивостью к ошибкам и наблюдаемостью.

Что делаем
  1. Двенадцать шагов обработки в потоковом режиме: определение типа, разбор, удаление обвязки, язык, заголовки, структурные данные, ссылки, каноникализация, отпечаток, пассажи, морфология, классификаторы.
  2. Изоляция сбоев: падение на одном документе не роняет пачку.
  3. Метрики по каждому шагу: пропускная способность, доля ошибок, время.
Готово, когда

300 документов в секунду на узел, ошибки изолированы и посчитаны.

Как проверяем

Прогон 1 млн документов без остановки, доля необработанных ниже 0.5%.

1.9

Каноникализация адресов

Обработка1 backend2 нед.зависит от 1.8
Зачем

Один и тот же документ, доступный по пяти адресам, попадёт в индекс пять раз и будет пять раз конкурировать в выдаче сам с собой.

Что делаем
  1. Строгий порядок шагов: регистр схемы и хоста, порт по умолчанию, префикс www, декодирование экранированных символов, нормализация пути, сортировка параметров и удаление трекинговых, удаление фрагмента.
  2. Применение канонического адреса, объявленного страницей.
  3. Кросс-хостовые канонические адреса принимаются только для пар доменов, подтверждённых в кабинете вебмастера: указание канонического адреса на чужой хост — распространённый приём угона трафика.
  4. Хеш канонического адреса как идентификатор документа.
Готово, когда

Пять вариантов записи одного адреса дают один идентификатор документа.

Как проверяем

Набор из 200 пар «разный адрес — один документ» схлопывается верно, набор из 50 пар «похожие адреса — разные документы» не схлопывается.

1.10

Дедупликация по SimHash

Обработка1 backend4 нед.зависит от 1.8
Зачем

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

Что делаем
  1. SimHash на 64 бита по трёхсловным шинглам.
  2. Порог: расстояние Хэмминга не более 3 бит.
  3. Поиск кандидатов через разбиение отпечатка на четыре блока по 16 бит с индексацией по каждому — при расстоянии не более трёх хотя бы один блок совпадает точно.
  4. Дубли группируются, а не удаляются: в выдаче показывается представитель группы, остальные доступны по ссылке.
Готово, когда

Группы дублей строятся, представитель выбирается по авторитету хоста, при равенстве — по времени первого обхода, что даёт заодно сигнал первоисточника.

Как проверяем

На размеченной выборке из 5000 пар точность не ниже 0.95, полнота не ниже 0.85.

1.11

Морфология русского языка

Обработкакритический путь1 ML4 нед.зависит от 1.8
Зачем

Русский язык без лемматизации в поиске не работает: падежная система даёт до двенадцати форм на существительное, и запрос «купить холодильник» обязан находить документ про покупку холодильников. Но искать только по леммам тоже нельзя — теряются точные цитаты и имена собственные.

Что делаем
  1. Полная морфология на индексации через словарный анализатор и нейросетевой разбор.
  2. Быстрый стемминг там, где полная морфология избыточна.
  3. Два поля в индексе: словоформы и леммы, с разными весами в формуле.
  4. Обработка омонимии: при неоднозначности индексируем оба варианта.
Готово, когда

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

Как проверяем

Набор из 300 пар «запрос — документ в другой форме» находится; набор из 100 точных цитат находится дословно.

1.12

Определение языка и региона документа

Обработка1 ML2 нед.зависит от 1.8
Зачем

Язык нужен для выбора обработки и для фильтра выдачи, регион — для локальных запросов. Ошибка здесь портит и то, и другое.

Что делаем
  1. Определение языка с оценкой уверенности, отдельная обработка многоязычных страниц.
  2. Определение региона по доменной зоне, языку, адресам и телефонам в тексте, расположению хостинга.
  3. Пометка «регион не определён» как отдельное состояние, а не подстановка страны по умолчанию.
Готово, когда

Язык определяется с точностью не ниже 0.97 на контрольной выборке, регион проставлен там, где он определим, а доля ОШИБОЧНЫХ определений (в отличие от отказов) не выше 0.01.

Как проверяем

Размеченная выборка из 2000 документов, замер точности по каждому языку отдельно. Отдельно — доля отказов против доли ошибок: система, отказывающаяся в 10% случаев и не ошибающаяся, лучше системы с точностью 0.97 и 3% молчаливых ошибок.

1.13

Извлечение структурированных данных

Обработка1 backend3 нед.зависит от 1.8
Зачем

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

Что делаем
  1. Разбор JSON-LD, микроданных, RDFa и OpenGraph.
  2. Приоритет типов: статья, товар, организация, хлебные крошки, вопросы и ответы, рецепт, событие, видео.
  3. Валидация: битая разметка не должна ронять обработку документа.
  4. Журнал ошибок разметки для показа в кабинете вебмастера.
Готово, когда

Разметка извлекается, ошибки логируются и доступны владельцу сайта, а битая разметка НЕ приводит к потере документа: страница индексируется как обычная, просто без разметки.

Как проверяем

На выборке из 1000 страниц с известной разметкой извлекается не менее 95% объявленных типов. Отдельно — доля ложных записей в журнале ошибок: она обязана быть близка к нулю, иначе журнал не читают. Отдельно — прогон на страницах с намеренно испорченной разметкой: ни одна не теряется, а целые блоки не пропадают вместе с битым.

Индекс и поиск 7

1.14

Шардирование по хосту

Индекс и поисккритический путь2 backend5 нед.зависит от 0.3
Зачем

50 млн документов ещё помещаются на несколько машин, но схема шардирования — решение на годы: менять её позже означает переиндексацию всего корпуса.

Что делаем
  1. Ключ шардирования — хеш хоста, а не адреса. Это даёт три выигрыша: правило разнообразия сайтов применяется локально в шарде, хостовые признаки грузятся один раз, дедупликация внутри сайта не требует сети.
  2. Вторичное расщепление: хосты, превысившие один процент размера шарда, шардируются по хешу от хоста и корзины адреса.
  3. Реестр топологии шардов в системе координации.
Готово, когда

Индекс разложен по трём шардам, перекос между ними не превышает 15%, ключ шардирования устойчив между перезапусками, а число корзин расщеплённого хоста хранится в реестре и только растёт.

Как проверяем

Распределение документов по шардам и проверка, что крупные хосты действительно расщеплены. Отдельно — устойчивость ключа в отдельном процессе. Отдельно — добавление страницы к расщеплённому хосту не меняет шард ни одного из уже размещённых документов.

Риск

Перекос из-за гигантских сайтов. Вторичное расщепление закладывается сразу, а не «когда понадобится» — потом оно требует переиндексации.

1.15

Репликация и публикация версий индекса

Индекс и поиск1 backend + 1 инфраструктура4 нед.зависит от 1.14
Зачем

Без атомарной публикации версии выкатка индекса превращается в набор ручных операций, а откат становится невозможен.

Что делаем
  1. Репликация с двумя копиями каждого шарда в этой фазе.
  2. Публикация новой версии через систему координации, переключение шардов пореплично.
  3. Хранение предыдущей версии 72 часа.
  4. Откат как переключение указателя.
Готово, когда

Версия публикуется без простоя, откат проверен на практике.

Как проверяем

Выкатываем заведомо испорченную версию индекса, откатываем, замеряем время — не более 10 минут.

1.16

Смеситель: веерный опрос и деградация

Индекс и поиск1 backend4 нед.зависит от 1.14
Зачем

Один медленный шард не должен задерживать весь запрос. Неполный ответ за отведённое время лучше полного за две секунды.

Что делаем
  1. Веерный опрос всех шардов с таймаутом 80 мс на шард.
  2. Слияние результатов с сохранением порядка.
  3. Пометка неполного ответа и метрика доли таких выдач.
  4. Исключение систематически медленного шарда из веера до восстановления.
Готово, когда

При отключении одного шарда выдача формируется, доля неполных выдач считается с первого запроса и видна на панели, а исключённый шард возвращается в веер САМ после восстановления.

Как проверяем

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

1.17

BlockMax WAND

Индекс и поисккритический путь1 backend5 нед.зависит от 1.14
Зачем

Полный перебор постингов частого термина — это сотни миллионов записей на шард. Без отсечения бюджет задержки не выдержать никакими машинами.

Что делаем
  1. Нарезка постингов на блоки с хранением верхней границы вклада для каждого блока.
  2. Пропуск блока целиком без декодирования, если его граница не позволяет попасть в текущий топ.
  3. Сверка поведения с эталонными реализациями.
Готово, когда

Ускорение на частых терминах не менее чем в десять раз, отсечение отключается на запросах с фильтрами (иначе выдача пуста при существующих документах).

Как проверяем

Замер на 100 запросах с частыми словами до и после. Критично: результаты выдачи идентичны полному перебору — отсечение не должно менять топ ни на одну позицию. Сравнение оценок побитовое, а не с допуском. Отдельно — прогон на случайных индексах разной формы, включая вырожденный случай, где все списки стоят на одних и тех же документах.

1.18

Инкрементальная индексация

Индекс и поисккритический путь2 backend6 нед.зависит от 1.14, 1.15
Зачем

Пересборка всего индекса — путь, от которого Google отказался в 2010 году. Свежая новость должна попадать в индекс за минуты, а не ждать следующей полной сборки.

Что делаем
  1. Журнал изменений в шине сообщений с секционированием по шарду.
  2. Подход с журнально-структурированным слиянием внутри шарда: новые документы пишутся в малые сегменты, фоново сливаются.
  3. Удаления через битовую карту мёртвых идентификаторов, применяемую при слиянии.
  4. Отложенные производные: авторитет хоста и ссылочные признаки не пересчитываются на каждый документ, а обновляются пакетом раз в сутки и подмешиваются из отдельной таблицы. Свежий документ получает актуальный текст сразу, а актуальный авторитет — назавтра.
Готово, когда

Документ появляется в поиске в течение 10 минут после обхода.

Как проверяем

Публикуем документ на тестовом сайте, замеряем время до появления в выдаче — на выборке из 50 публикаций.

1.19

Прямой индекс и генерация сниппетов

Индекс и поиск1 backend4 нед.зависит от 1.14
Зачем

Сниппет — не аннотация страницы, а ответ на конкретный запрос. Чтобы собрать его за 35 мс, нужны позиции терминов рядом с шардом, а не поход в объектное хранилище.

Что делаем
  1. Колоночная структура «идентификатор документа → позиции терминов, краткий текст, признаки» со сжатием и словарём на сегмент.
  2. Алгоритм сниппета: скользящее окно 220 символов по плотности терминов запроса, расширение до границ предложений, склейка одного-двух лучших фрагментов, подсветка лемм.
  3. Мета-описание используется в последнюю очередь: его пишут маркетологи, и оно почти всегда хуже отвечает на конкретный запрос.
Готово, когда

Сниппет собирается за 35 мс на топ-10 и меняется вместе с запросом.

Как проверяем

Один документ по трём разным запросам даёт три разных сниппета, в каждом подсвечены слова соответствующего запроса.

1.20

Разбор языка запросов

Индекс и поиск1 backend3 нед.зависит от 1.16
Зачем

Операторы — это то, чем пользуется профессиональная аудитория, которая первой придёт в новый поиск и первой напишет о нём.

Что делаем
  1. Операторы: кавычки для точной фразы, минус для исключения, «или», ограничение сайтом и исключение сайта, поиск по адресу и в адресе, поиск в заголовке, тип файла, язык, диапазон дат, регион, любое слово, синонимы, отключение лемматизации.
  2. Синтаксис намеренно совместим с привычным по Яндексу — не переучивать пользователя.
  3. Понятные сообщения об ошибках разбора вместо пустой выдачи.
Готово, когда

Все операторы работают, на каждый есть тест.

Как проверяем

Набор из 60 запросов с операторами даёт ожидаемые результаты; 20 запросов с намеренно сломанным синтаксисом дают осмысленное сообщение.

Ранжирование 5

1.21

BM25F с обученными весами

Ранжирование1 ML3 нед.зависит от 0.4, 1.39
Зачем

Ручная настройка весов упирается в предел человеческого внимания: шесть полей дают пространство, которое глазами не обойти.

Что делаем
  1. Подбор весов по асессорской корзине координатным спуском или байесовской оптимизацией с целевой функцией pFound.
  2. Веса версионируются вместе с моделью.
  3. Отдельная проверка, что подобранные веса не деградируют на навигационных запросах.
Готово, когда

Подобранные веса дают прирост pFound не менее 0.03 относительно ручных.

Как проверяем

Замер на отложенной части корзины, не участвовавшей в подборе.

1.22

Линейная модель предранжирования

Ранжирование1 ML + 1 backend5 нед.зависит от 1.21
Зачем

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

Что делаем
  1. Около 40 дешёвых признаков: BM25F по полям, покрытие запроса, близость терминов, авторитет хоста, качество, свежесть, совпадение региона и языка.
  2. Обучение логистической регрессией на асессорских парах.
  3. Инференс внутри шарда без обращений наружу.
Готово, когда

Модель работает в шарде за 10 микросекунд на документ, отбор в топ-1000 не теряет релевантные документы.

Как проверяем

Полнота на топ-1000 после предранжирования не ниже 0.95 относительно полного ранжирования.

1.23

PageRank и TrustRank в продакшене

Ранжирование1 ML4 нед.зависит от 0.6
Зачем

Прототип считает граф разово. В продакшене нужен регулярный пересчёт, иначе новые сайты навсегда остаются без авторитета.

Что делаем
  1. Ежедневный пересчёт хостового графа, еженедельный — страничного.
  2. Расширение ядра доверия с 500 до 10 000 хостов.
  3. Компактное кодирование графа: разности идентификаторов и ссылки на похожие списки смежности.
  4. Выгрузка значений в таблицу признаков, доступную индексу.
Готово, когда

Пересчёт хостового графа укладывается в 4 часа, значения обновляются ежедневно.

Как проверяем

Новый сайт, появившийся в обходе, получает ненулевой авторитет в течение суток.

1.24

Первый классификатор качества

Ранжирование1 ML5 нед.зависит от 1.8
Зачем

Отделить содержательные страницы от пустых, шаблонных и сгенерированных без редактуры. Это признак, а не фильтр: жёсткое отсечение даёт ложные срабатывания, от которых страдают добросовестные сайты.

Что делаем
  1. Разметка 10 000 документов по качеству.
  2. Обучение градиентного бустинга на признаках: объём текста, отношение текста к разметке, доля рекламы в первом экране, наличие автора и даты, читаемость, структурированность, признаки машинной генерации.
  3. Калибровка оценки, чтобы она читалась как вероятность.
Готово, когда

Классификатор даёт оценку качества для каждого документа, площадь под ROC-кривой не ниже 0.85 на отложенной выборке, шкала не насыщается на верхнем дециле, а вклад каждого признака разложим и показывается владельцу сайта.

Как проверяем

Ручной просмотр 100 документов из нижнего и верхнего децилей: оценка соответствует впечатлению человека. Отдельно — проверка совета вебмастеру на страницах БЕЗ проблем: совет там обязан отсутствовать. Совет, выданный там, где проблемы нет, стоит дороже отсутствия совета: владелец идёт искать несуществующую неисправность и теряет доверие ко всем остальным советам заодно.

1.25

Дедупликация и разнообразие в выдаче

Ранжирование1 backend2 нед.зависит от 1.10, 1.16
Зачем

Пользователь, увидевший в топе три страницы одного сайта или два одинаковых текста, считает поиск сломанным независимо от их релевантности.

Что делаем
  1. Схлопывание групп дублей на выдаче с показом представителя.
  2. Правило «не более двух результатов с одного хоста в топ-10» с вытеснением третьего вниз, а не удалением.
  3. Ссылка «показать похожие» для схлопнутых групп.
Готово, когда

В топ-10 не бывает трёх результатов с одного сайта и двух почти одинаковых текстов ПРИ УСЛОВИИ, что было чем заменить; схлопнутые дубли доступны по ссылке «показать похожие», а не удалены.

Как проверяем

Прогон корзины из 3000 запросов с автоматической проверкой обоих правил. Проверка обязана отличать превышение, которого можно было избежать, от неизбежного: тревога там, где выбора не было, обесценивает весь отчёт.

Продукт 8

1.26

Главная страница и выдача

Продукт2 фронтенд6 нед.зависит от 1.19, 1.20
Зачем

Промышленная версия вместо отладочного прототипа. Скорость главной — витрина скорости всего продукта.

Что делаем
  1. Серверный рендеринг с полной работой без JavaScript: скрипты только улучшают.
  2. Ограничения: разметка не более 120 КБ, стили не более 20 КБ, скрипты не более 40 КБ с отложенной загрузкой.
  3. Колонка результатов не шире 652 пикселей: длинная строка хуже читается.
  4. Резервирование мест под блоки, чтобы не было сдвигов вёрстки.
Готово, когда

Отрисовка основного содержимого не дольше 1.2 секунды на мобильной сети, страница полностью работает без скриптов.

Как проверяем

Замер в автоматическом аудите на четырёх эталонных страницах в мобильном и десктопном профиле.

1.27

Саджест

Продукт1 backend + 1 фронтенд4 нед.зависит от 1.20
Зачем

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

Что делаем
  1. Префиксный автомат для автодополнения.
  2. Исправление опечаток за постоянное время через симметричное удаление.
  3. До восьми подсказок, задержка не более 60 мс.
  4. Персональные подсказки из истории с иконкой и крестиком удаления.
  5. Клавиатурная навигация: стрелки, дополнение табуляцией, закрытие по Esc.
Готово, когда

Подсказки появляются с первого символа, задержка на p99 не выше 60 мс.

Как проверяем

Нагрузочный замер на 500 запросах в секунду.

1.28

Колдунщики первой фазы

Продукт1 фронтенд + 1 backend4 нед.зависит от 1.26
Зачем

Блок с готовым ответом экономит клик. Плотность таких блоков — то, в чём Яндекс сильнее Google, и это заметное продуктовое отличие.

Что делаем
  1. Калькулятор, конвертер величин, время в городах, перевод.
  2. Правило вытеснения: колдунщик показывается, только если не отодвигает первый органический результат ниже 600 пикселей от верха окна.
  3. Не более двух колдунщиков одновременно.
Готово, когда

Четыре колдунщика работают, правило вытеснения соблюдается на всех размерах экрана.

Как проверяем

Автоматическая проверка положения первого органического результата на трёх разрешениях.

1.29

Yottis ID: аккаунты

Продукт1 backend + 1 фронтенд6 нед.
Зачем

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

Что делаем
  1. Регистрация через ключ доступа как способ по умолчанию и через почту с паролем как запасной.
  2. Пароли через современную функцию хеширования, проверка по базам утечек методом k-анонимности.
  3. Двухфакторная аутентификация: одноразовые коды по времени, ключи доступа, резервные коды.
  4. Сессии: короткоживущий токен плюс ротируемый токен обновления в защищённой cookie.
  5. Журнал входов, список устройств, выход на всех устройствах.
Готово, когда

Регистрация, вход, двухфакторная аутентификация и управление сессиями работают.

Как проверяем

Аудит безопасности: перебор паролей блокируется, сессии инвалидируются при смене пароля, токены не попадают в логи.

1.30

Кабинет вебмастера — базовая версия

Продукткритический путь1 backend + 1 фронтенд7 нед.зависит от 1.7, 1.29
Зачем

Блокирующая задача фазы. Без кабинета бот не будет принят вебом, а без обхода нет продукта.

Что делаем
  1. Подтверждение прав тремя способами: файл в корне, мета-тег, запись в DNS. Перепроверка раз в сутки.
  2. Раздел индексирования: страницы в поиске и исключённые страницы с конкретной причиной из закрытого списка — запрет в robots.txt, мета-тег noindex, канонический адрес на другую страницу, дубликат, мало текста, мягкая ошибка «не найдено», ошибка HTTP, редирект, низкое качество, нарушение правил, не дошла очередь обхода.
  3. Статистика обхода: запросы бота, коды ответов, время ответа, объём скачанного.
  4. Загрузка карты сайта, ручная отправка на переобход с квотой 20 адресов в сутки.
  5. Настройка скорости обхода.
Готово, когда

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

Как проверяем

50 внешних сайтов подтвердили права и пользуются кабинетом.

Риск

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

1.31

Тёмная тема и доступность

Продукт1 фронтенд3 нед.зависит от 1.26
Зачем

Поиском пользуются по сто раз в день, в том числе люди со слабым зрением и с клавиатурной навигацией. Доступность здесь не благотворительность, а условие пригодности.

Что делаем
  1. Тёмная тема через системное предпочтение плюс явный переключатель с тремя состояниями: светлая, тёмная, как в системе.
  2. Аудит по стандарту доступности уровня AA: контраст, клавиатурная навигация, видимый фокус, роли ориентиров, объявление изменений выдачи.
  3. Работа при двукратном увеличении и при отключённых стилях.
  4. Учёт предпочтения уменьшенного движения.
Готово, когда

Аудит пройден, замечаний уровней A и AA нет.

Как проверяем

Автоматическая проверка контраста в сборке плюс ручной проход всей выдачи с клавиатуры и со скринридером.

1.46

Публичный инструмент «Проверка адреса»

Продукт1 backend + 1 фронтенд3 нед.зависит от 1.8
Зачем

Вебмастеру нужно видеть страницу нашими глазами. Это и снимает поток вопросов в поддержку, и собирает ссылки как полезная утилита.

Что делаем
  1. По адресу показываем: заголовки ответа, цепочку редиректов, извлечённый текст, найденную разметку, определённые язык и регион, статус в индексе.
  2. Работает без регистрации.
  3. Ограничение частоты, чтобы инструмент не превратился в чужой краулер.
Готово, когда

Инструмент открыт публично и показывает всё перечисленное.

Как проверяем

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

1.47

Публичный анализатор robots.txt

Продукт1 backend + 1 фронтенд2 нед.зависит от 0.5
Зачем

Самая частая причина отсутствия страниц в индексе — неверный robots.txt, и вебмастер обычно не понимает, какое правило сработало.

Что делаем
  1. Проверка синтаксиса с указанием номера строки.
  2. Проверка конкретного адреса против правил с показом сработавшего правила дословно.
  3. Работает без регистрации.
Готово, когда

Инструмент открыт, его вывод совпадает с реальным поведением краулера.

Как проверяем

На наборе из 30 крайних случаев вывод анализатора совпадает с поведением бота во всех случаях.

Инфраструктура 6

1.32

Переезд на выделенные серверы

Инфраструктура2 инфраструктура4 нед.
Зачем

VPS не держит поисковый индекс: ему нужны локальные NVMe и предсказуемая память без соседей по гипервизору. VPS остаются под фронт, шлюз API и служебные сервисы.

Что делаем
  1. Заказ и приёмка выделенных серверов по расчётной конфигурации.
  2. Приёмочные тесты дисков и сети до ввода в эксплуатацию.
  3. Схема размещения ролей по машинам.
Готово, когда

Парк принят, тесты пройдены, серверы в строю.

Как проверяем

Замер последовательного и случайного чтения дисков, пропускной способности сети между узлами; отклонение от заявленного больше 15% — основание для замены.

1.33

Развёртывание парка и инфраструктура как код

Инфраструктура2 инфраструктура6 нед.зависит от 1.32
Зачем

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

Что делаем
  1. Вся конфигурация в коде в репозитории на Repobase.
  2. Разворачивание нового узла одной командой.
  3. Запрет ручных настроек на серверах как правило, а не пожелание.
Готово, когда

Новый узел вводится в строй за 30 минут одной командой.

Как проверяем

Разворачиваем узел с нуля на чистой машине, засекаем время.

1.34

ClickHouse и шина событий

Инфраструктура1 инфраструктура4 нед.зависит от 1.33
Зачем

Без хранилища событий не работают ни метрики качества, ни аналитика, ни будущее обучение на кликах.

Что делаем
  1. Кластер аналитической базы.
  2. Приём событий через шину по канонической схеме: топик, таблица-приёмник, материализованное представление, реплицируемое хранилище.
  3. Реестр схем событий с обязательной обратной совместимостью.
Готово, когда

События выдачи и обхода пишутся, аналитические запросы к ним отрабатывают.

Как проверяем

Нагрузочный тест на 20 000 событий в секунду в течение часа без потерь.

1.35

Наблюдаемость

Инфраструктура1 инфраструктура5 нед.зависит от 1.34
Зачем

Систему, в которой не видно, где именно уходит время, невозможно ускорять — можно только гадать.

Что делаем
  1. Метрики и панели по каждому сервису: частота, ошибки, длительность.
  2. Сквозная трассировка с единым идентификатором запроса через все сервисы.
  3. Структурированные логи в аналитическом хранилище.
  4. Панели: обход, индекс, выдача, железо.
Готово, когда

Полный путь запроса виден в трассировке с разбивкой по этапам бюджета задержек.

Как проверяем

Берём произвольный медленный запрос из логов и находим по трассировке, какой именно этап его задержал.

1.36

CI/CD с канареечной выкаткой

Инфраструктура1 инфраструктура4 нед.зависит от 0.18, 1.35
Зачем

Выкатка сразу на весь трафик означает, что ошибка достаётся всем пользователям одновременно.

Что делаем
  1. Канареечная выкатка ступенями: один процент, десять, пятьдесят, сто.
  2. Автоматический откат по метрикам ошибок и задержки.
  3. Пауза между ступенями, достаточная для накопления статистики.
Готово, когда

Канареечная выкатка работает, автооткат срабатывает на искусственно внесённой ошибке.

Как проверяем

Выкатываем версию с намеренно увеличенной задержкой — откат происходит автоматически до перехода на следующую ступень.

1.37

Регресс-тесты производительности

Инфраструктура1 backend3 нед.зависит от 1.36
Зачем

Производительность деградирует незаметно, по одному проценту за релиз, и обнаруживается через полгода, когда причин уже десяток.

Что делаем
  1. Замер скорости индексации и поиска на каждой сборке на фиксированном наборе данных.
  2. Сравнение с предыдущей сборкой и с эталоном.
  3. Падение сборки при деградации больше 10%.
  4. История замеров с графиком.
Готово, когда

Тест в непрерывной интеграции, история замеров сохраняется.

Как проверяем

Вносим намеренную деградацию — сборка падает.

Качество 3

1.38

Пул асессоров и руководство

Качество1 качество5 нед.зависит от 0.7
Зачем

Пять асессоров фазы 0 не покрывают корзину из трёх тысяч запросов. Плюс инструкция после первого применения всегда требует переработки.

Что делаем
  1. Набор 20 асессоров по договору.
  2. Переработка инструкции в полноценное руководство асессора, которое мы планируем опубликовать: открытая инструкция дисциплинирует прежде всего нас.
  3. Обучение и аттестация с проходным баллом.
  4. Контрольные задания с известным ответом в потоке.
Готово, когда

20 асессоров работают, каппа Коэна не ниже 0.6.

Как проверяем

Замер согласия на пересекающихся заданиях еженедельно; падение ниже 0.6 — повод для переобучения.

1.39

Регресс-корзина на 3000 запросов

Качество1 качество + 20 асессоров8 нед.зависит от 1.38
Зачем

Корзина фиксируется и не меняется между релизами: иначе цифры несравнимы, и любое «улучшение» может оказаться сменой выборки.

Что делаем
  1. Состав: 2000 случайных по частотности, 700 сложных, 300 навигационных с известным ответом.
  2. Разметка топ-20 с перекрытием три асессора.
  3. Версионирование корзины; изменения только с явным решением и пересчётом истории.
Готово, когда

Корзина размечена, зафиксирована и версионируется.

Как проверяем

Повторная разметка случайных 100 пар через месяц даёт согласие с исходной не ниже 0.85.

1.40

Ежедневный автозамер качества

Качество1 качество3 нед.зависит от 1.39
Зачем

Падение качества, замеченное через неделю, уже нельзя связать с конкретным изменением.

Что делаем
  1. Прогон корзины по расписанию с привязкой к версии кода и версии индекса.
  2. Панель с графиком истории.
  3. Оповещение при падении больше 0.01.
Готово, когда

Замер идёт ежедневно, падение качества замечается в тот же день.

Как проверяем

Вносим намеренное ухудшение формулы — оповещение приходит на следующем замере.

Регион и гео 5

1.43

Определение региона посетителя

Регион и геокритический путь1 backend2 нед.зависит от 1.26
Зачем

Локальные запросы бессмысленны без города: «шиномонтаж» в Москве и Омске — это разные запросы. Плюс регион нужен аналитике и определению применимой юрисдикции.

Что делаем
  1. База соответствия адреса и региона с возможностью замены поставщика одним файлом.
  2. Явный выбор пользователя как высший приоритет, сохраняемый на год.
  3. Оператор региона в запросе — только для этого запроса.
  4. Геолокация браузера только на локальных запросах, с объяснением зачем и с запоминанием отказа.
  5. Запасной вариант по языку браузера и доменной зоне.
  6. Разрешение конфликтов между источниками по строгому приоритету.
Готово, когда

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

Как проверяем

Набор из 500 адресов с известным городом: точность определения города не ниже 75%, страны — не ниже 95%.

Риск

Потолок точности на уровне города — около 85%, и это ограничение самих данных, а не поставщика. Поэтому регион всегда виден пользователю и меняется одним кликом, а ранжирование не ломается при неверном регионе: региональный признак влияет, но не отсекает.

1.44

Региональный признак в ранжировании

Регион и гео1 ML3 нед.зависит от 1.43, 1.22
Зачем

Определить регион мало — его нужно использовать. Без признака локальные запросы отвечают одинаково по всей стране.

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

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

Как проверяем

Корзина из 200 локальных запросов с замером по пяти городам; контрольная корзина информационных запросов не деградирует.

1.45

Справочник регионов

Регион и гео1 backend2 нед.
Зачем

Единая сущность для поиска, аналитики, кабинета вебмастера и будущего локального поиска. Без неё каждый сервис заводит свой список городов, и они расходятся.

Что делаем
  1. Иерархия: страна, федеральный округ, регион, город.
  2. Синонимы для распознавания в запросе: «Питер», «СПб», «Мск».
  3. Координаты, радиус, часовой пояс, язык по умолчанию.
  4. Расстояние между регионами считается по иерархии, а не по прямой: Химки ближе к Москве, чем Тверь, потому что в той же агломерации.
Готово, когда

Справочник заполнен для России и стран СНГ, есть программный интерфейс.

Как проверяем

Проверка на 200 названиях городов и их разговорных форм: все распознаются.

1.48

Плашка региона на главной и в выдаче

Регион и гео1 фронтенд2 нед.зависит от 1.43, 1.45
Зачем

Пользователь, получивший результаты не своего города и не понимающий почему, уходит и не возвращается. Скрывать регион нельзя.

Что делаем
  1. Плашка с иконкой места и названием города рядом со строкой поиска на главной.
  2. Клик открывает выбор региона с поиском по справочнику и кнопкой автоматического определения.
  3. В выдаче — тем же компонентом в панели инструментов.
  4. На локальных запросах — подсказка «результаты для города такого-то» с указанием источника определения.
Готово, когда

Регион виден на главной и в выдаче и меняется одним кликом.

Как проверяем

Клавиатурная доступность выбора региона и сохранение выбора между сессиями.

1.49

Приватность геоданных

Регион и гео1 backend + юрист2 нед.зависит от 1.43
Зачем

Местоположение — самая чувствительная часть аналитики, и ошибка здесь юридическая, а не техническая.

Что делаем
  1. Обрезка адреса до подсети через 24 часа.
  2. Точное местоположение из браузера не сохраняется: используется в момент запроса, в лог пишется только город.
  3. Отключаемое определение по адресу в настройках.
  4. Регион не связывается с аккаунтом при выключенной истории.
Готово, когда

Требования выполнены и проверены юристом.

Как проверяем

Аудит логов: адресов старше суток в полном виде нет.

Админ-часть 3

1.50

Каркас админ-части

Админ-часть1 backend + 1 фронтенд5 нед.зависит от 1.29
Зачем

Основа, на которую наращиваются разделы. Заводится рано по одной причине: журнал действий нельзя дописать задним числом, а без него первые полгода работы останутся непрослеживаемыми.

Что делаем
  1. Роли с раздельными правами, а не единая роль администратора.
  2. Вход через Yottis ID с обязательной двухфакторной аутентификацией.
  3. Журнал действий: кто, что, когда, зачем, с какого адреса, что было и что стало.
  4. Неизменяемость журнала на уровне хранилища.
Готово, когда

Админка открывается, роли работают, все изменения состояния пишутся в журнал.

Как проверяем

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

1.51

Раздел «Индекс» в админке

Админ-часть1 backend + 1 фронтенд4 нед.зависит от 1.50, 1.15
Зачем

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

Что делаем
  1. Состояние: размер, свежесть, шарды, возраст сегментов.
  2. Обход: скорость, очередь, проблемные хосты.
  3. Ручная переиндексация по хосту и по разделу.
  4. Исключения: что и почему не в индексе.
Готово, когда

Оператор управляет индексом из интерфейса, каждое действие в журнале.

Как проверяем

Сквозной сценарий: находим хост с проблемой, запускаем переиндексацию, видим результат.

1.52

Раздел «Сайты» и ручные санкции

Админ-часть1 backend + 1 фронтенд4 нед.зависит от 1.50
Зачем

Санкции появятся раньше автоматического антиспама, и нужен механизм с обоснованием и обратимостью с самого начала.

Что делаем
  1. Реестр хостов с признаками: страниц, авторитет, качество, спам, кабинет.
  2. Наложение санкции только с обязательным текстовым обоснованием.
  3. Отображение санкции владельцу в кабинете вебмастера с описанием пути выхода.
  4. Снятие санкции с обоснованием, всё в журнале.
Готово, когда

Санкции накладываются и снимаются, владелец сайта их видит.

Как проверяем

Тестовая санкция на свой домен: она появляется в кабинете с понятным текстом и снимается без остатка.

Риск

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

ИИ-структура 3

1.53

Заготовки под ИИ в схемах данных

ИИ-структуракритический путь1 backend2 нед.
Зачем

Добавление поля в индекс на 10 млрд документов — это полная переиндексация, недели работы. Пустое поле, заведённое сейчас, стоит почти ничего.

Что делаем
  1. Поля для вектора документа, векторов пассажей и оценок моделей в схеме документа.
  2. Поле оценок моделей в контрактах ответа шарда и ранжировщика.
  3. Правило: потребители обязаны игнорировать неизвестные ключи — это делает добавление модели неломающим изменением.
Готово, когда

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

Как проверяем

Добавляем в ответ шарда фиктивный ключ — ни один потребитель не падает, и ключ виден в списке неизвестных.

1.54

Реестр флагов функций

ИИ-структура1 backend2 нед.
Зачем

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

Что делаем
  1. Реестр флагов с значением «выключено» по умолчанию для всех будущих точек ИИ.
  2. Изменение флага без релиза.
  3. Журналирование изменений флагов.
Готово, когда

Флаг переключается за минуту без выкатки, изменение попадает в журнал.

Как проверяем

Переключение флага в продакшене занимает меньше минуты от решения до эффекта.

1.55

Резерв в бюджете задержек

ИИ-структуратехнический лидер1 нед.
Зачем

Модель съедает от 50 до 150 мс. Если бюджет распределён без резерва, добавление модели означает пересмотр всей архитектуры обслуживания.

Что делаем
  1. Резервируем 70 мс на слот нейросетевого реранкера.
  2. Резервируем 60 мс на параллельные ИИ-функции.
  3. Резерв не расходуется, пока функции выключены, но и не занимается другими этапами.
Готово, когда

Бюджет пересчитан, зафиксирован и проверяется автоматически; последовательная и параллельная части резерва разведены; принято решение по превышению медианы.

Как проверяем

Регресс-тест бюджета в двух состояниях — с выключенными моделями и с включёнными: сумма последовательных этапов не превышает цель ни там, ни там. Проверка записана точным числом, а не допуском: допуск покроет и следующее превышение.

Хранилища 4

1.56

Абстракция доступа к базе обхода

Хранилища1 backend2 нед.
Зачем

Миграция базы обхода на другое хранилище в фазе 3 не должна переписывать краулер. Абстракция сейчас стоит день, а потом — квартал.

Что делаем
  1. Интерфейс доступа к состоянию адресов с операциями чтения, записи, пакетного обновления и обхода диапазона.
  2. Реализация на встроенном хранилище.
  3. Краулер работает только через интерфейс, прямых обращений нет.
Готово, когда

Интерфейс введён, реализация подменяется в конфигурации.

Как проверяем

Тесты интерфейса проходят на двух реализациях: боевой и на упрощённой в памяти.

1.57

Транзакционный слой

Хранилища1 инфраструктура3 нед.зависит от 1.33
Зачем

Аккаунты, права на сайты, роли и обращения — данные реляционные по природе, и хранить их в чём-то другом означает писать соединения таблиц руками.

Что делаем
  1. Реляционная база с автоматическим переключением при отказе.
  2. Схема аккаунтов, прав и ролей.
  3. Миграции в репозитории с обязательной обратимостью.
  4. Резервное копирование с журналом транзакций.
Готово, когда

Транзакционный слой работает, переключение при отказе проверено.

Как проверяем

Учение: гасим основной узел, замеряем время переключения — не более 30 секунд.

1.58

Объектное хранилище для документов

Хранилища1 инфраструктура3 нед.зависит от 1.33
Зачем

Архив обхода растёт быстрее всего остального, и держать его на дорогих дисках бессмысленно: он пишется один раз и читается редко.

Что делаем
  1. Кластер объектного хранилища с совместимым интерфейсом.
  2. Политики жизненного цикла: перевод старых данных в холодный класс.
  3. Проверка целостности по контрольным суммам.
Готово, когда

Архив обхода пишется и читается, политики жизненного цикла работают.

Как проверяем

Запись и чтение терабайта с проверкой контрольных сумм.

1.59

Реестр схем событий

Хранилища1 backend2 нед.зависит от 1.34
Зачем

Изменение схемы события ломает всех потребителей одновременно, и обнаруживается это в проде.

Что делаем
  1. Реестр схем с версионированием.
  2. Правило обратной совместимости: поле удаляется не раньше двух релизов после прекращения записи.
  3. Проверка совместимости в непрерывной интеграции.
Готово, когда

Несовместимое изменение схемы не проходит сборку.

Как проверяем

Вносим ломающее изменение — сборка падает с понятным сообщением.

Продвижение 6

1.60

Скрипт: генератор карты сайта

Продвижение1 backend2 нед.зависит от 0.21
Зачем

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

Что делаем
  1. Обход собственной структуры: документация из файлов, инструменты из реестра маршрутов, статьи из индекса.
  2. Дата изменения берётся из системы контроля версий — это точнее любой ручной даты.
  3. Приоритет и частота изменений по фактической истории, а не по догадке.
  4. Разбиение на файлы по 50 000 адресов с индексной картой.
  5. Исключение всего, что запрещено в robots.txt: противоречие между картой и запретом вызывает предупреждения в обеих панелях.
Готово, когда

Карта пересобирается автоматически при каждой выкатке.

Как проверяем

Число адресов в карте совпадает с числом открытых к индексации страниц; расхождение — ошибка сборки.

1.61

Скрипт: аудит технического SEO в сборке

Продвижение1 фронтенд3 нед.зависит от 1.26
Зачем

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

Что делаем
  1. Автоматический аудит эталонных страниц в мобильном и десктопном профиле.
  2. Пороги: отрисовка основного содержимого, отзывчивость, сдвиги вёрстки, размеры разметки, стилей и скриптов.
  3. Валидация структурированных данных на каждой странице-образце.
  4. Проверка канонических адресов, заголовков, описаний, единственности главного заголовка.
  5. Проверка, что запрещённые разделы не встречаются во внутренних ссылках.
  6. Нарушение любого порога роняет сборку.
Готово, когда

Аудит в непрерывной интеграции, регрессии не проходят.

Как проверяем

Вносим намеренное замедление — сборка падает с указанием нарушенного порога.

1.62

Публикация документации и правил для сайтов

Продвижениепродукт + фронтенд4 нед.зависит от 1.41
Зачем

Документация — главный источник органического трафика для нового поиска: на запросы вроде «как работает поисковая система» мы можем отвечать авторитетнее большинства.

Что делаем
  1. Публичная документация о том, как работает поиск.
  2. Правила для сайтов с примерами нарушений.
  3. Разметка технических статей и раздела вопросов и ответов — но только там, где вопросы реально есть на странице.
Готово, когда

Документация опубликована, разметка проходит валидацию.

Как проверяем

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

1.63

Публичные инструменты как посадочные страницы

Продвижениефронтенд2 нед.зависит от 1.46, 1.47
Зачем

На инструменты ссылаются как на утилиту, а не как на мнение, поэтому они собирают ссылки лучше статей.

Что делаем
  1. Отдельная страница под каждый инструмент с описанием и примерами.
  2. Общий раздел инструментов с перелинковкой.
  3. Разметка инструкций.
Готово, когда

Инструменты доступны по осмысленным адресам и связаны между собой.

Как проверяем

Каждый инструмент достижим не более чем в два клика от главной.

1.64

Скрипт: пуш об изменениях

Продвижение1 backend2 нед.зависит от 1.60
Зачем

Ускоряет индексацию наших изменений конкурентами и заодно проверяет на себе нашу же реализацию приёма пуша.

Что делаем
  1. Сравнение новой карты сайта со старой после выкатки.
  2. Отправка изменившихся адресов через открытый протокол пуша.
  3. Отправка в панель второй системы через её программный интерфейс с учётом квот.
  4. Запись факта отправки и отслеживание появления в индексе.
Готово, когда

Пуш уходит автоматически после каждой выкатки.

Как проверяем

Новая страница появляется в индексе конкурента быстрее, чем при обычном обходе, на выборке из 20 публикаций.

1.65

Регистрация в третьей панели вебмастера

Продвижениеинфраструктура1 нед.зависит от 0.22
Зачем

Разные панели показывают разные проблемы, и третий источник данных стоит недели работы.

Что делаем
  1. Подтверждение прав в панели третьей поисковой системы.
  2. Загрузка карты сайта.
  3. Подключение к общему монитору индексации.
Готово, когда

Панель подключена и показывает данные.

Как проверяем

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

Ворота фазы 1

Все критерии обязательны. Не пройдены — фаза продлевается, а не закрывается.

  • 50 млн документов в индексе, обход 300 страниц в секунду непрерывно
  • pFound@10 не ниже 0.48 на корзине из 3000 запросов
  • Доля запросов без релевантных результатов не выше 12%
  • Задержка выдачи на p99 не выше 400 мс при 50 запросах в секунду
  • Каппа Коэна между асессорами не ниже 0.6
  • Кабинет вебмастера работает, 50 внешних сайтов подтвердили права
  • Закрытая альфа: 1000 пользователей, удовлетворённость замерена
  • Ни одного инцидента с нарушением robots.txt или превышением нагрузки на сайты
  • Документ появляется в поиске в течение 10 минут после обхода
  • Правовые документы опубликованы, форма обращений работает
  • Регион определяется и виден пользователю, точность по городу не ниже 75%

Фаза 2

Качество

Месяцы
11–17
Календарь
июл 2027 – янв 2028
Команда
26 чел.
Индекс
300 млн
Бюджет
129.5 млн ₽
Задач
66
Недель работ
320

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

Ранжирование 10

2.1

Реестр признаков с жизненным циклом

Ранжирование1 ML3 нед.
Зачем

Утечка кода конкурента вскрыла около 1922 именованных фактора ранжирования, из которых больше трети оказались неиспользуемыми или устаревшими. Без дисциплины жизненного цикла реестр превращается в свалку, где никто не решается ничего удалить, потому что неизвестно, на что это повлияет.

Что делаем
  1. Каждый признак — запись с именем, владельцем, версией, описанием смысла, стоимостью вычисления, зависимостями и тестами.
  2. Метрика важности, пересчитываемая при каждом обучении.
  3. Дата протухания: признак без подтверждения владельца после этой даты автоматически исключается из обучения.
  4. Автоматический отчёт о неиспользуемых признаках.
Готово, когда

Реестр работает, все существующие признаки в нём, отчёт о неиспользуемых строится автоматически.

Как проверяем

Признак с истёкшей датой действительно выпадает из следующего обучения без ручного вмешательства.

2.2

Расширение до 350 признаков

Ранжирование2 ML10 нед.зависит от 2.1
Зачем

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

Что делаем
  1. Группа текстовой релевантности: BM25F по полям, покрытие запроса, близость терминов, порядок слов, точная фраза, позиция первого вхождения, языковые модели с двумя видами сглаживания, пассажный максимум.
  2. Группа семантики: косинус запроса с документом и с лучшим пассажем, расхождение тематик.
  3. Группа ссылок: авторитет документа и хоста, доверие, число и разнообразие ссылающихся хостов и подсетей, возраст домена, доля закрытых ссылок, тематическое соответствие доноров, глубина от главной.
  4. Группа качества: объём текста, отношение текста к разметке, доля рекламы, грамматичность, оригинальность, наличие автора и даты, читаемость, структурированность.
  5. Группа свежести: возраст документа и последнего изменения, частота обновления, всплеск запросов по теме.
  6. Группа региона и языка: совпадение и расстояние, качество языка.
Готово, когда

350 признаков вычисляются, важность каждого измерена и записана в реестр.

Как проверяем

Признак, дающий нулевой вклад в трёх обучениях подряд, помечается кандидатом на удаление.

2.3

CatBoost YetiRank как основная формула

Ранжированиекритический путь2 ML8 нед.зависит от 2.2
Зачем

Основная формула ранжирования. Выбранная библиотека — открытый наследник промышленной формулы конкурента, с listwise-функцией потерь, спроектированной именно под поисковое ранжирование, и нативной работой с категориальными признаками без ручного кодирования, что при тысячах доменов принципиально.

Что делаем
  1. Обучение на асессорских оценках с обязательной группировкой по запросу.
  2. Метрика на валидации — pFound@10; NDCG как вторичная.
  3. Около 2000 деревьев глубины 6.
  4. Инференс через нативный рантайм, батчами, с целевыми 20 микросекундами на документ.
  5. Версионирование модели вместе с реестром признаков.
Готово, когда

Модель в продакшене, прирост pFound не менее 0.06 относительно линейной модели.

Как проверяем

Интерливинг против линейной модели: победа со значимостью выше 99%.

Риск

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

2.4

Классификатор намерения и семейство моделей

Ранжирование1 ML6 нед.зависит от 2.3
Зачем

У навигационного и описательного запросов признаки работают принципиально по-разному: на первом решает точное совпадение хоста, на втором — семантика. Одна формула на всё теряет качество на обоих краях.

Что делаем
  1. Классификатор на шесть классов: навигационный, информационный, транзакционный, локальный, свежий, мультимедийный.
  2. Классификатор отдаёт распределение вероятностей, а не жёсткую метку.
  3. Отдельная модель ранжирования на каждый класс.
  4. Итоговый скор — взвешенная смесь предсказаний по вероятностям классов. Смесь, а не выбор, потому что запросы часто пограничные, и жёсткий выбор даёт скачки качества на границе.
Готово, когда

Шесть моделей обучены, смесь работает, прирост pFound не менее 0.02.

Как проверяем

Отдельный замер качества по каждому классу запросов: ни один класс не деградировал.

2.5

Плотные векторы

Ранжированиекритический путь2 ML + 1 backend9 нед.зависит от 2.2
Зачем

Только текстовый поиск даёт полноту около 65%, гибрид — около 91%. Строить оба ретривера надо сразу: ретроспективное добавление второго ломает всю калибровку основной модели.

Что делаем
  1. Обучение би-энкодера для русского на парах «запрос — кликнутый документ» и асессорских оценках.
  2. Векторы размерности 256 с квантованием в один байт на измерение.
  3. Индекс приближённого поиска соседей внутри тех же шардов, что и постинги, а не в отдельной базе.
  4. Офлайн-вычисление векторов документов на этапе индексации.
Готово, когда

Плотный поиск работает, полнота по нему на топ-1000 не ниже 0.70.

Как проверяем

Замер полноты на корзине отдельно для плотного, разреженного и гибридного поиска. Отдельно — проверка обобщения на корпусе-мосте: цель, содержащая синоним, но ни одного слова запроса.

2.6

Обучаемое разреженное представление

Ранжирование1 ML6 нед.зависит от 2.5
Зачем

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

Что делаем
  1. Обучение модели расширения терминов с весами.
  2. Индексация расширенных терминов в отдельное поле того же индекса.
  3. Контроль размера индекса: агрессивное расширение раздувает постинги.
Готово, когда

Третий ретривер работает, рост размера индекса не превышает 30%.

Как проверяем

Замер прироста полноты против роста размера индекса; при неблагоприятном соотношении расширение урезается.

2.7

Слияние трёх ретриверов

Ранжирование1 ML4 нед.зависит от 2.5, 2.6, 2.4
Зачем

Три списка кандидатов надо объединить, не требуя калибровки разномасштабных оценок.

Что делаем
  1. Слияние по обратным рангам с отраслевой константой.
  2. Веса ретриверов зависят от класса запроса: на навигационном доминирует текстовый поиск и точное совпадение, на описательном — плотный.
  3. Подбор весов по корзине отдельно для каждого класса.
  4. Проверка, что развёртка веса имеет внутренний максимум. Если качество растёт монотонно до насыщения на значении «только один ретривер», корзина слишком мала или однородна, чтобы выбрать вес, и выбирать его по ней нельзя.
Готово, когда

Гибрид даёт полноту на топ-10 не ниже 0.88, а выбранные веса лежат во внутреннем максимуме развёртки, а не на её границе.

Как проверяем

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

2.8

Пассажное разбиение и признаки

Ранжирование1 ML5 нед.зависит от 2.2
Зачем

Ответ часто находится в середине длинной статьи, и документная оценка его не видит: релевантный абзац растворяется в тысячах нерелевантных слов.

Что делаем
  1. Разбиение документа на окна по 512 токенов с перекрытием 128.
  2. Оценка каждого окна.
  3. Признаки документа: максимум по окнам, число окон выше порога, позиция лучшего окна.
Готово, когда

Ответ находится в середине длинной статьи; прирост качества на длинных документах измерен.

Как проверяем

Отдельная корзина из 300 запросов, ответ на которые лежит в середине длинных страниц.

2.9

Нейросетевой реранкер

Ранжирование2 ML8 нед.зависит от 2.8, 2.53
Зачем

Кросс-энкодер обрабатывает пару «запрос — пассаж» совместно, что принципиально точнее раздельного кодирования, но применимо только к десяткам кандидатов.

Что делаем
  1. Компактная предобученная модель для русского как основа.
  2. Дообучение дистилляцией из большой модели-учителя плюс клики с коррекцией смещения.
  3. Инференс в едином рантайме с квантованием, батчами по 50.
  4. Обязательная отбрасываемость по таймауту: без реранкера отдаём порядок предыдущего уровня.
Готово, когда

Реранкер в продакшене, прирост pFound не менее 0.04, бюджет 70 мс на p99 соблюдён.

Как проверяем

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

2.34

Поведенческие признаки из Метрики в обучение

Ранжирование1 ML5 нед.зависит от 2.31, 2.3
Зачем

Ради этого счётчик и строился: данные о том, что человек делал после перехода из поиска.

Что делаем
  1. Агрегация обезличенных признаков: время на странице после перехода из поиска, доля возвратов, глубина просмотра.
  2. Признаки уровня хоста и раздела, а не отдельного пользователя.
  3. Включение в основную модель ранжирования.
  4. Полное разделение с историей поиска: связывания с аккаунтом нет.
Готово, когда

Признаки в модели, прирост качества измерен.

Как проверяем

Интерливинг модели с новыми признаками против модели без них.

Риск

Сайты со счётчиком получат преимущество, и это превратится в вымогательство установки. Смягчение — признаки нормализуются по тематике и не могут повышать позицию сами по себе, только уточнять оценку уже релевантного документа.

Качество 1

2.10

Инфраструктура интерливинга и A/B

Качествокритический путь1 ML + 1 backend6 нед.зависит от 1.34
Зачем

Интерливинг требует на порядок меньше трафика для статистической значимости, чем обычный A/B-тест, потому что сравнение идёт внутри одного пользователя и одного запроса. При нашем трафике это разница между «проверим за неделю» и «проверим за квартал».

Что делаем
  1. Смешивание двух выдач по схеме командного набора: монетка решает, кто добавляет документ первым, затем по очереди.
  2. Клик засчитывается той формуле, которая добавила документ.
  3. Накопление статистики и биномиальный тест.
  4. Панель с результатами и историей экспериментов.
  5. A/B-тест как подтверждающий инструмент перед выкаткой на весь трафик.
Готово, когда

Эксперимент запускается за 10 минут, значимость считается автоматически.

Как проверяем

Заведомо худшая формула проигрывает в интерливинге со значимостью выше 99% на ожидаемом объёме трафика.

Антиспам 5

2.11

Разметка спам-корпуса

Антиспам2 антиспам + асессоры8 нед.
Зачем

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

Что делаем
  1. Отбор 50 000 хостов-кандидатов по эвристикам и по жалобам.
  2. Разметка по типам нарушений: клоакинг, дорвеи, скрапинг, ссылочные схемы, скрытый текст, автогенерация, взлом, паразитный хостинг, накрутка поведения, домены под запрос.
  3. Отдельная разметка добросовестных сайтов, похожих на спам: это самая ценная часть выборки.
  4. Перекрытие и контроль согласия.
Готово, когда

50 000 хостов размечены, доля добросовестных сайтов в выборке не ниже 40%.

Как проверяем

Согласие разметчиков по каппе Коэна не ниже 0.7 — для спама требование выше, чем для релевантности.

2.12

Классификатор антиспама

Антиспамкритический путь2 антиспам7 нед.зависит от 2.11
Зачем

Единый ML-классификатор, а не набор отдельных фильтров. Google тринадцать лет шёл от отдельных подсистем к сигналам внутри ядра, и повторять этот путь незачем.

Что делаем
  1. Градиентный бустинг на признаках корпуса.
  2. Теневой режим на семь дней: оценка считается, но не применяется, ложные срабатывания разбираются вручную.
  3. Три порога: ниже 0.3 — признак без действий, от 0.3 до 0.8 — понижение и метка для ручной проверки, выше 0.8 — исключение из индекса.
  4. Ежемесячное переобучение на новых данных.
Готово, когда

Точность не ниже 0.95 при полноте не ниже 0.70 на отложенной выборке.

Как проверяем

Разбор всех ложных срабатываний за неделю теневого режима; выкатка только при доле ложных срабатываний ниже 5%.

Риск

Ложное срабатывание бьёт по добросовестному сайту и по нашей репутации сильнее, чем пропущенный спам. Отсюда порог точности выше порога полноты и обязательный теневой режим.

2.13

Специализированные детекторы

Антиспам2 антиспам8 нед.зависит от 2.12
Зачем

Общий классификатор ловит типичное, но пропускает приёмы, требующие специальной проверки — например, показ роботу и человеку разного содержимого.

Что делаем
  1. Детектор клоакинга: выборочная сверка страницы, полученной ботом и полученной с браузерным User-Agent.
  2. Детектор дорвеев: шаблонность плюс редирект плюс отсутствие добавленной ценности.
  3. Детектор скрытого текста: анализ стилей при рендеринге.
  4. Детектор скрапинга: определение первоисточника по времени первого обхода.
Готово, когда

Все четыре детектора работают, их сигналы входят в общий классификатор как признаки.

Как проверяем

Каждый детектор проверяется на своей размеченной выборке из тысячи случаев.

2.14

Кластеризация ссылочных сетей

Антиспам1 антиспам6 нед.зависит от 1.23
Зачем

Сетки сайтов и обмен ссылками видны структурно: плотный подграф с высокой взаимной связностью и низкой связностью с остальным вебом.

Что делаем
  1. Поиск плотных подграфов в веб-графе.
  2. Признаки кластера: доля взаимных ссылок, общность владельцев по данным регистратора, общность подсетей, схожесть шаблонов.
  3. Оценка кластера как признак каждого его участника.
Готово, когда

Кластеры находятся, их оценка входит в классификатор.

Как проверяем

Известные сетки из размеченного корпуса обнаруживаются с полнотой не ниже 0.8.

2.15

Ручные санкции и пересмотр

Антиспам1 антиспам + 1 фронтенд4 нед.зависит от 1.52
Зачем

Автоматика ошибается, и у владельца сайта должен быть понятный путь исправления. Непрозрачные санкции — то, за что справедливо ругают крупные поисковики.

Что делаем
  1. Наложение санкции только оператором, всегда с указанием типа нарушения.
  2. Отображение санкции владельцу в кабинете с описанием пути выхода.
  3. Кнопка отправки на пересмотр с очередью и сроком ответа.
  4. История санкций по хосту.
Готово, когда

Санкции видны владельцам, пересмотр работает, срок ответа соблюдается.

Как проверяем

Сквозной прогон: наложение, отображение, заявка на пересмотр, снятие — всё в журнале.

Продукт 13

2.16

Вкладка «Картинки» в выдаче

Продукт2 вертикали4 нед.зависит от I1.16
Зачем

Саму вертикаль строит отдельный трек «Картинки» (docs/plan/track-images.md): у неё свой индекс, своё ранжирование и свой правовой режим. В основном плане остаётся то, что принадлежит выдаче, а не вертикали, — вкладка, общее состояние запроса и общие настройки. Описание одной и той же работы в двух местах разошлось бы на первой же правке.

Что делаем
  1. Вкладка в переключателе вертикалей с сохранением запроса, региона и языка при переходе.
  2. Разбор операторов вертикали (size:, ratio:, color:, imagetype:, license:, imagesite:) общим разборщиком языка запросов.
  3. Единая настройка безопасного поиска на продукт, а не отдельная для картинок, — стык с 2.25.
  4. Переход из веб-выдачи в вертикаль и обратно без потери фильтров времени и языка.
  5. Замер доли переходов между вкладками как входные данные для колдунщика «картинки в строку» (I3.3).
Готово, когда

Переход между «Всё» и «Картинки» сохраняет запрос, регион, язык и фильтр времени; операторы вертикали разбираются общим разборщиком; настройка безопасного поиска одна на весь продукт.

Как проверяем

Сценарный тест из десяти переходов между вкладками с проверкой сохранения каждого параметра; сверка выдачи по оператору size:large и по фильтру «Большие» — списки совпадают.

Риск

Вкладка появляется раньше содержимого под ней, и пустая вертикаль читается как поломка всего поиска. Смягчение: вкладка включается флагом функции и открывается только после ворот I1.

2.17

Вертикаль «Новости»

Продукт2 вертикали9 нед.
Зачем

Свежесть — то, по чему новый поиск проверяют в первую очередь. Новость крупного СМИ обязана появляться в индексе за минуты.

Что делаем
  1. Отдельный быстрый индекс с обновлением не реже чем раз в десять минут.
  2. Определение новостных источников и приоритетный обход их лент.
  3. Кластеризация публикаций в сюжеты.
  4. Обязательная плюрализация источников внутри сюжета: не более двух материалов одного издания.
  5. Хронология сюжета.
Готово, когда

Новость крупного СМИ появляется в индексе за 10 минут, сюжеты собираются.

Как проверяем

Замер задержки на 100 публикациях; проверка, что в сюжете представлено не менее трёх изданий.

Риск

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

2.18

Вертикаль «Видео»

Продукт1 вертикали6 нед.зависит от 1.13
Зачем

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

Что делаем
  1. Индексация по структурированной разметке видео.
  2. Извлечение превью, длительности, автора, даты.
  3. Транскрипты там, где они доступны на странице.
  4. Карточки с превью в общей выдаче и отдельная вертикаль.
Готово, когда

Видео находится, карточки показываются с превью и длительностью.

Как проверяем

Корзина из 300 видеозапросов с замером доли, где нужное видео попало в топ-3. Отдельно проверяется полнота карточки: превью, длительность и дата на месте. Карточка без превью проигрывает обычному текстовому результату — показывать её вместо ссылки значит ухудшить выдачу ради формального наличия вертикали.

2.19

Вертикаль «Файлы»

Продукт1 вертикали5 нед.зависит от 1.8
Зачем

Документы, таблицы и презентации содержат ответы, которых нет в веб-страницах: стандарты, отчёты, инструкции.

Что делаем
  1. Извлечение текста из документов, таблиц и презентаций.
  2. Ограничения на размер и время обработки.
  3. Оператор фильтрации по типу файла в интерфейсе.
  4. Отображение типа и размера в результате.
Готово, когда

Документы индексируются, фильтр по типу работает.

Как проверяем

Корзина из 200 запросов, ответ на которые лежит в документах.

2.20

Колдунщики второй фазы

Продукт1 фронтенд + 1 backend8 нед.зависит от 1.28
Зачем

Плотность блоков с готовым ответом — заметное продуктовое отличие, и она реально экономит клики на самых частых запросах.

Что делаем
  1. Погода по партнёрскому источнику.
  2. Курсы валют по данным центрального банка и биржи.
  3. Определения по открытым данным и собственному корпусу.
  4. Быстрый ответ на фактоидный вопрос с проверкой согласованности между тремя источниками.
  5. Соблюдение правила вытеснения и лимита в два блока.
Готово, когда

Четыре новых колдунщика работают, правило вытеснения соблюдается.

Как проверяем

Быстрый ответ показывается только при согласии источников; при расхождении блок не показывается вообще.

2.21

Панель инструментов выдачи

Продукт1 фронтенд4 нед.зависит от 1.26
Зачем

Фильтры нужны меньшинству пользователей, но это меньшинство самое лояльное и самое громкое.

Что делаем
  1. Фильтры по времени, региону, языку, типу файла, уровню безопасного поиска.
  2. Сортировка по релевантности и по дате.
  3. Фильтры применяются без перезагрузки страницы.
  4. Состояние фильтров отражается в адресе страницы, чтобы им можно было поделиться.
Готово, когда

Фильтры работают, состояние сохраняется в адресе.

Как проверяем

Ссылка с фильтрами, открытая в другом браузере, даёт ту же выдачу.

2.22

Приватность и управление данными

Продукт1 backend + 1 фронтенд7 нед.зависит от 1.29
Зачем

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

Что делаем
  1. Раздел «Мои данные»: всё, что известно о пользователе.
  2. Показ выведенных интересов с возможностью удалить любой и запретить выведение — обычно такие данные скрывают, мы показываем.
  3. Экспорт в архив с машиночитаемыми форматами, готовится асинхронно.
  4. Удаление аккаунта с тридцатидневной корзиной и подтверждением по почте.
  5. История поиска выключена по умолчанию; включение — осознанное действие с объяснением.
Готово, когда

Раздел работает, экспорт и удаление проходят полный цикл.

Как проверяем

Экспорт содержит все категории данных, перечисленные в политике конфиденциальности; после удаления данных в базах не остаётся.

2.23

Коллекции и подписки

Продукт1 фронтенд + 1 backend8 нед.зависит от 1.29
Зачем

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

Что делаем
  1. Сохранение страниц с папками, заметками и тегами.
  2. Приватность коллекции: личная, по ссылке, публичная.
  3. Подписки на новые результаты по запросу с выбором частоты и канала.
  4. Расширение для браузера для сохранения любой страницы.
Готово, когда

Коллекции и подписки работают, уведомления доходят.

Как проверяем

Новый результат по подписке приводит к уведомлению в течение заявленного интервала.

2.24

Кабинет вебмастера: отчёты и диагностика

Продукт1 backend + 1 фронтенд9 нед.зависит от 1.30
Зачем

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

Что делаем
  1. Отчёт по запросам: показы, клики, отношение, средняя позиция с разрезами по запросу, странице, региону, устройству, вертикали.
  2. Сравнение периодов и выгрузка данных.
  3. Диагностика: ошибки обхода, дубли и канонические адреса, проверка структурированных данных, мобильная пригодность.
  4. Внешние и внутренние ссылки с якорными текстами.
  5. Работа с картами сайта: статус разбора, ошибки.
Готово, когда

Все разделы работают, данные сходятся с логами выдачи.

Как проверяем

Сверка отчёта по запросам с сырыми логами на выборке из десяти сайтов: расхождение не более 1%.

2.25

Безопасный поиск и детский режим

Продукт1 фронтенд + 1 ML5 нед.зависит от 1.24
Зачем

Требование законодательства о защите детей и базовое ожидание семейной аудитории.

Что делаем
  1. Классификатор возрастного рейтинга на этапе индексации.
  2. Три уровня фильтрации: выключен, умеренный, строгий.
  3. Детский режим со строгим фильтром и невозможностью отключения без кода.
  4. Умеренный уровень по умолчанию.
Готово, когда

Три уровня работают, детский режим не отключается без кода.

Как проверяем

Корзина проверочных запросов: на строгом уровне доля нежелательного содержимого ниже 0.5%.

2.36

Проверка сайтов на вредоносный код

Продукт1 антиспам + 1 backend5 нед.зависит от 1.5
Зачем

Взломанный сайт вредит пользователям и не знает об этом сам. Уведомление владельца — то, за что вебмастера благодарны и остаются.

Что делаем
  1. Проверка страниц на признаки вредоносного кода при рендеринге.
  2. Сверка со списками известных угроз.
  3. Уведомление владельца с указанием затронутых адресов.
  4. Предупреждение в выдаче при подтверждённом заражении.
Готово, когда

Проверка работает, владелец получает уведомление в течение суток.

Как проверяем

Тестовый сайт с известным образцом обнаруживается; ложных срабатываний на выборке из тысячи чистых сайтов нет.

2.37

Голосовой ввод

Продукт1 фронтенд3 нед.зависит от 1.26
Зачем

На мобильных устройствах голосовой ввод — заметная доля запросов, а реализация через браузерный интерфейс почти бесплатна.

Что делаем
  1. Голосовой ввод через браузерный интерфейс распознавания речи.
  2. Корректная деградация при отсутствии поддержки: кнопка просто не показывается.
  3. Визуальная обратная связь во время записи.
Готово, когда

Голосовой ввод работает в поддерживающих браузерах, в остальных ничего не ломается.

Как проверяем

Проверка в четырёх браузерах, включая один без поддержки.

2.39

Языковые версии интерфейса

Продукт1 фронтенд3 нед.зависит от 1.26
Зачем

Подготовка к английскому сегменту следующей фазы: перевод интерфейса задним числом всегда дороже, чем закладка механизма заранее.

Что делаем
  1. Вынесение всех строк интерфейса в файлы переводов.
  2. Русская и английская версии.
  3. Указание языковых версий страниц для поисковых систем.
  4. Выбор языка независимо от региона.
Готово, когда

Интерфейс работает на двух языках, языковые версии размечены.

Как проверяем

Проверка на отсутствие захардкоженных строк в разметке.

Инфраструктура 4

2.26

Рост парка до 300 млн документов

Инфраструктура2 инфраструктура6 нед.зависит от 1.33
Зачем

Шестикратный рост индекса требует и роста парка, и пересмотра схемы репликации.

Что делаем
  1. Расширение до примерно 120 машин.
  2. Переход на три копии каждого шарда.
  3. Перебалансировка шардов без остановки поиска.
Готово, когда

300 млн документов в индексе с тройной репликацией, поиск не прерывался.

Как проверяем

Учение: гасим целую реплику-группу — выдача продолжает работать.

2.27

Второй дата-центр

Инфраструктура2 инфраструктура8 нед.зависит от 2.26
Зачем

Один дата-центр — единая точка отказа. Плюс подготовка к режиму, когда оба центра обслуживают трафик.

Что делаем
  1. Развёртывание второй площадки.
  2. Репликация индекса и транзакционных данных.
  3. Резервное копирование в другую площадку.
  4. Регламент переключения.
Готово, когда

Второй центр развёрнут, данные реплицируются, регламент проверен учением.

Как проверяем

Учебное переключение трафика на второй центр с замером времени и потерь.

2.28

Парк ускорителей для моделей

Инфраструктура1 инфраструктура5 нед.
Зачем

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

Что делаем
  1. Закупка и развёртывание узлов с ускорителями.
  2. Разделение на обучение и инференс.
  3. Планировщик заданий обучения с очередью.
  4. Мониторинг утилизации: простаивающий ускоритель — прямые потери.
Готово, когда

Обучение и инференс идут на ускорителях, утилизация видна на панели.

Как проверяем

Средняя утилизация парка не ниже 60% за месяц.

2.29

Панель «Здоровье выдачи»

Инфраструктура1 инфраструктура3 нед.зависит от 1.35
Зачем

Четыре числа, которые первыми показывают деградацию качества — раньше, чем пожалуются пользователи.

Что делаем
  1. Доля выдач с нулём результатов.
  2. Доля неполных выдач.
  3. Доля выдач без единого клика.
  4. Средняя позиция первого клика.
  5. Обновление каждые пять минут, оповещения по порогам.
Готово, когда

Панель обновляется каждые пять минут, оповещения настроены.

Как проверяем

Искусственное ухудшение выдачи на одном шарде приводит к оповещению в течение десяти минут.

Админ-часть 9

2.30

Приём событий и счётчик

Админ-частькритический путь2 backend + 1 фронтенд9 нед.
Зачем

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

Что делаем
  1. Счётчик на скриптах размером не более 6 килобайт: тяжёлый счётчик портит скорость чужого сайта, и его снимают.
  2. Асинхронная загрузка и отправка событий фоновым каналом, не блокирующим выгрузку страницы.
  3. Приём событий в аналитическое хранилище через шину.
  4. События: просмотр, глубина прокрутки, время на странице, переходы, источник, устройство.
  5. Режим без cookie по умолчанию: идентификация сессии без межсайтовых идентификаторов.
Готово, когда

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

Как проверяем

Замер отрисовки основного содержимого на сайте до и после установки счётчика: разница в пределах погрешности.

Риск

Счётчик тормозит чужой сайт, и его снимают. Жёсткий лимит размера проверяется в сборке; отправка через фоновый канал; отсутствие синхронных запросов.

2.31

Отчёты Метрики

Админ-часть1 backend + 1 фронтенд7 нед.зависит от 2.30
Зачем

Счётчик без отчётов не имеет ценности для владельца сайта, а без ценности его не установят.

Что делаем
  1. Посещаемость, источники, глубина, время на странице, отказы.
  2. Устройства, браузеры, разрешения.
  3. География по справочнику регионов.
  4. Страницы входа и выхода, популярные страницы.
  5. Сравнение периодов и выгрузка.
Готово, когда

Отчёты работают, данные сходятся с сырыми событиями.

Как проверяем

Сверка отчёта с сырыми событиями на тестовом сайте: расхождение не более 0.5%.

2.32

Приватность Метрики

Админ-часть1 backend + юрист4 нед.зависит от 2.30
Зачем

Счётчик, собирающий всё подряд, юридически токсичен и подрывает нашу же позицию по приватности. Это ещё и рыночное отличие: аналитика, которая не следит.

Что делаем
  1. Обрезка адреса до подсети через 24 часа.
  2. Отсутствие межсайтовых идентификаторов.
  3. Публичное описание того, что именно собирается.
  4. Режим полного отказа от cookie.
  5. Возможность владельца сайта отключить сбор отдельных категорий.
Готово, когда

Требования выполнены, описание опубликовано, юридическая проверка пройдена.

Как проверяем

Аудит: в хранилище нет данных, позволяющих связать посетителя между двумя сайтами.

2.33

Единое подтверждение прав

Админ-часть1 backend3 нед.зависит от 2.30, 1.30
Зачем

Владелец сайта не должен подтверждать права дважды — для кабинета вебмастера и для аналитики.

Что делаем
  1. Общая сущность подтверждённого сайта.
  2. Единый интерфейс переключения между кабинетом и аналитикой.
  3. Общие роли доступа.
Готово, когда

Одно подтверждение даёт доступ к обоим сервисам.

Как проверяем

Новый сайт, подтверждённый в кабинете, сразу доступен в аналитике.

2.47

Раздел «Аудитория»

Админ-часть1 фронтенд4 нед.зависит от 1.50
Зачем

Продуктовые решения без данных об аудитории принимаются по интуиции, и она обычно ошибается.

Что делаем
  1. Пользователи: новые, вернувшиеся, активные.
  2. Устройства и браузеры.
  3. Удержание по когортам.
  4. Источники прихода.
Готово, когда

Раздел работает, когортный анализ строится.

Как проверяем

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

2.48

Раздел «Поиск → Запросы»

Админ-часть1 backend + 1 фронтенд5 нед.зависит от 1.50, 1.34
Зачем

Нулевые выдачи — самый короткий путь к пониманию, чего не хватает в индексе.

Что делаем
  1. Топ запросов, растущие запросы, нулевые выдачи, переформулировки.
  2. Разбор конкретного запроса: выдача глазами пользователя выбранного региона.
  3. Вклад каждого признака по каждому документу в разборе.
  4. Кнопка заведения запроса в регресс-корзину.
Готово, когда

Сценарий разбора запроса проходится целиком из интерфейса.

Как проверяем

Разобранный запрос попадает в корзину и появляется в следующем автозамере.

2.49

Раздел «Поиск → Качество»

Админ-часть1 фронтенд3 нед.зависит от 1.40
Зачем

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

Что делаем
  1. pFound по срезам: класс запроса, регион, вертикаль, длина запроса.
  2. История с привязкой к версиям кода и индекса.
  3. Отметки выкаток на графике.
Готово, когда

Панель показывает качество по срезам с историей.

Как проверяем

По графику можно найти выкатку, после которой качество упало.

2.50

Раздел «Модерация»

Админ-часть1 backend + 1 фронтенд5 нед.зависит от 1.50, 2.12
Зачем

Спам-кандидаты от классификатора требуют ручной проверки, и без очереди с приоритетами эта работа не масштабируется.

Что делаем
  1. Очередь жалоб с приоритетом и сроком реакции.
  2. Спам-кандидаты из среднего диапазона оценки на ручную проверку.
  3. Решение с обоснованием, всё в журнале.
  4. Обратная связь в обучающую выборку классификатора.
Готово, когда

Очередь работает, решения модератора пополняют обучающую выборку.

Как проверяем

Замер: срок реакции на жалобу не превышает заявленный в 95% случаев.

2.52

Красный список и роль аудитора

Админ-часть1 backend3 нед.зависит от 1.50
Зачем

Администратор, который видит всё и ни перед кем не отчитывается, — это уязвимость, а не роль.

Что делаем
  1. Красный список действий, требующих второго подтверждающего: просмотр истории конкретного пользователя, выгрузка персональных данных, санкция на крупный хост, изменение реестра скрытия, изменение ролей, отключение антиспама.
  2. Роль аудитора: доступ только к журналу, включая действия администратора, без права что-либо менять.
  3. Оповещение аудитора о действиях из красного списка.
Готово, когда

Действия из красного списка невозможны без второго подтверждающего, аудитор видит всё.

Как проверяем

Попытка выполнить действие из красного списка в одиночку отклоняется.

Регион и гео 6

2.35

Указание региона сайта в кабинете

Регион и гео1 backend + 1 фронтенд3 нед.зависит от 1.30, 1.45
Зачем

Мы определяем регион сайта эвристикой и ошибаемся. Владелец знает точно, и ему проще сказать, чем спорить.

Что делаем
  1. Указание одного или нескольких регионов сайта.
  2. Автоматическое предложение по контактам, найденным на сайте.
  3. Модерация подозрительных заявок: указание всех регионов сразу — типичный приём.
Готово, когда

Регион указывается и влияет на выдачу в течение суток.

Как проверяем

Изменение региона тестового сайта отражается в локальной выдаче.

2.38

Доработка выбора региона

Регион и гео1 фронтенд2 нед.зависит от 1.48
Зачем

Первая версия плашки показывает регион, но выбор из длинного списка неудобен.

Что делаем
  1. Поиск по справочнику регионов с распознаванием разговорных форм.
  2. Недавно выбранные регионы.
  3. Кнопка возврата к автоматическому определению.
  4. Клавиатурная доступность всего диалога.
Готово, когда

Регион выбирается за два действия из любого состояния.

Как проверяем

Клавиатурный проход всего диалога без мыши.

2.43

Раздел «География»

Регион и геокритический путь1 backend + 1 фронтенд5 нед.зависит от 1.50, 1.43
Зачем

Первый раздел, который открывают утром: где растём, где падаем, откуда идёт накрутка.

Что делаем
  1. Карта посетителей с размером точки по числу сессий.
  2. Таблицы по странам, регионам и городам с динамикой.
  3. Разбивка по источнику определения региона: явный выбор, база адресов, браузер, не определён.
  4. Доля ручных смен региона как прямая оценка ошибок определения.
  5. Разрезы по устройствам, языку интерфейса, новым и вернувшимся.
  6. Города с посещаемостью ниже пятидесяти сессий схлопываются в «прочие»: по городу с одним посетителем регион перестаёт быть агрегатом.
Готово, когда

География видна, доля ручных смен считается по каждому городу.

Как проверяем

Целевое значение доли ручных смен не выше 4%; превышение по конкретному региону заводится как задача на исправление данных.

2.44

Запрос геолокации на локальных запросах

Регион и гео1 фронтенд2 нед.зависит от 1.43
Зачем

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

Что делаем
  1. Запрос только после классификации запроса как локального.
  2. Объяснение зачем: «чтобы показать ближайшие».
  3. Запоминание отказа: повторно не спрашиваем.
Готово, когда

Запрос показывается только на локальных запросах, отказ запоминается.

Как проверяем

Доля согласий на запрос геолокации не ниже 40% — при неуместном запросе она была бы втрое ниже.

2.45

Регионы в отчётах кабинета вебмастера

Регион и гео1 backend3 нед.зависит от 2.24, 1.45
Зачем

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

Что делаем
  1. Разрез отчёта по запросам с фильтром по региону.
  2. Карта показов по регионам.
  3. Сравнение позиций между регионами.
Готово, когда

Разрез работает, данные сходятся с общим отчётом.

Как проверяем

Сумма показов по регионам совпадает с общим числом показов в отчёте; расхождение допускается только на долю «регион не определён», и она выводится явно, а не молча списывается. Дополнительно — проверка на сайте с заведомо известной географией: разрез обязан повторять реальное распределение, а не давать ровную картину по стране.

2.46

Порог агрегации в аналитике

Регион и гео1 backend + юрист2 нед.зависит от 2.43
Зачем

По городу с одним посетителем «регион» перестаёт быть агрегатом и становится персональными данными.

Что делаем
  1. Порог: города ниже пятидесяти сессий за период схлопываются.
  2. Порог применяется во всех отчётах, включая выгрузки и программный интерфейс.
  3. Проверка порога тестами, а не соглашением.
Готово, когда

Порог применяется везде, обход через выгрузку невозможен.

Как проверяем

Попытка получить данные по городу ниже порога через любой интерфейс возвращает агрегат «прочие».

Многоязычие 3

2.40

Языковые кластеры как сущность

Многоязычие1 backend3 нед.
Зачем

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

Что делаем
  1. Справочник кластеров: кириллица, западная латиница, восточная латиница, иероглифика, письмо справа налево, индийские письменности.
  2. Привязка языков к кластерам.
  3. Поле кластера в схеме документа и в контрактах.
Готово, когда

Поле есть в схеме, заполняется при индексации, доступно как фильтр.

Как проверяем

Все документы корпуса имеют непустой кластер.

2.41

Определение языка запроса

Многоязычие1 ML4 нед.зависит от 1.12
Зачем

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

Что делаем
  1. Модель на коротких строках с учётом алфавита, частотности и структуры.
  2. Обработка запросов без языка: цифры, артикулы, имена собственные.
  3. Отдельное состояние «язык не определён» вместо подстановки языка интерфейса.
Готово, когда

Точность не ниже 0.95 на запросах от двух слов.

Как проверяем

Размеченная выборка из 5000 запросов на пяти языках.

2.42

Английская ветка обработки

Многоязычие1 ML4 нед.зависит от 2.40
Зачем

Готовность к волне английского сегмента следующей фазы. Строить её в момент, когда уже идёт обход восьми миллиардов страниц, поздно.

Что делаем
  1. Токенизация и нормализация для английского.
  2. Стемминг и обработка сокращений.
  3. Стоп-слова с проверкой, что их удаление не ломает фразовый поиск.
  4. Проверка на подмножестве англоязычных документов из текущего корпуса.
Готово, когда

Английские документы обрабатываются корректно, качество на англоязычной подвыборке измерено.

Как проверяем

Корзина из 500 английских запросов на текущем корпусе.

ИИ-структура 5

2.53

Шлюз моделей

ИИ-структуракритический путь1 backend5 нед.зависит от 1.53, 1.54
Зачем

Единая точка журналирования, политики данных, учёта стоимости, подмены модели и — главное — выключения. Прямых вызовов моделей из других сервисов не существует.

Что делаем
  1. Контракт запроса с обязательными полями: имя функции, срок ожидания, поведение при отказе, потолок стоимости, класс допустимых данных.
  2. Контракт ответа: результат, использованная модель и версия, время, стоимость, уверенность, факт деградации.
  3. Единственная реализация на старте: «функция выключена» с нулевой стоимостью.
  4. Потребители пишутся против настоящего интерфейса с первого дня.
Готово, когда

Шлюз в продакшене, потребители ходят через него, выключенная функция не ломает вызывающий код.

Как проверяем

Отключение шлюза целиком не приводит к отказу ни одного сервиса.

2.54

Реестр моделей

ИИ-структура1 ML3 нед.зависит от 2.53
Зачем

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

Что делаем
  1. Запись на модель: идентификатор, версия, владелец, задача, среда исполнения.
  2. Метрики качества на эталонном наборе с датой замера.
  3. Задержка и стоимость на тысячу вызовов.
  4. Класс данных, который модели разрешено передавать.
  5. Дата протухания и запасная модель при отказе.
Готово, когда

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

Как проверяем

Модель с истёкшей датой действительно перестаёт вызываться.

2.55

Журнал вызовов моделей

ИИ-структура1 backend2 нед.зависит от 2.53
Зачем

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

Что делаем
  1. Запись каждого вызова: функция, модель, версия, время, стоимость, уверенность, деградация.
  2. Содержимое входа и выхода — по классу данных, с обезличиванием.
  3. Панель по стоимости и задержке в разрезе функций и моделей.
Готово, когда

Журнал пишется с первого включённого вызова, панель строится.

Как проверяем

Модель включается на одном проценте трафика: каждый вызов виден в журнале со входом, выходом и временем, а число записей совпадает с числом вызовов по метрике. Отдельно проверяется, что ДЕГРАДАЦИИ пишутся так же, как успешные вызовы: журнал, где видны только успехи, показывает не работу модели, а её лучшую половину.

2.56

Политика данных для моделей в коде

ИИ-структура1 backend + юрист3 нед.зависит от 2.53
Зачем

Отправка пользовательских данных в модель без описанной политики — юридический инцидент, а не техническая задача. Регламент здесь не работает: нужна техническая невозможность.

Что делаем
  1. Классы данных: публичные страницы, текст запроса, запрос с историей, содержимое писем, персональные данные.
  2. Класс проверяется шлюзом при каждом вызове.
  3. Нарушение — отказ вызова, а не предупреждение в логе.
  4. Содержимое писем — только локальным моделям, внешние интерфейсы запрещены категорически.
  5. Персональные данные не передаются моделям ни при каких условиях.
Готово, когда

Политика проверяется технически, нарушение невозможно.

Как проверяем

Попытка вызвать внешнюю модель с классом данных выше публичного отклоняется на уровне шлюза.

2.57

Первые функции через шлюз

ИИ-структура1 ML3 нед.зависит от 2.53, 2.5, 2.9
Зачем

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

Что делаем
  1. Вычисление эмбеддингов документов через шлюз.
  2. Нейросетевой реранкер через шлюз.
  3. Замер накладных расходов шлюза: они не должны превышать 2 мс.
Готово, когда

Обе функции работают через шлюз, накладные расходы измерены и приемлемы.

Как проверяем

Сравнение задержки прямого вызова и вызова через шлюз.

Хранилища 3

2.58

Разделение кластеров аналитики

Хранилища1 инфраструктура4 нед.зависит от 1.34
Зачем

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

Что делаем
  1. Отдельный кластер для истории поиска с отдельными учётными данными.
  2. Общий кластер для технической аналитики и метрик.
  3. Отдельный кластер для событий Метрики.
  4. Аудит доступа к кластеру истории.
Готово, когда

Кластеры разделены, у сервисов ранжирования нет доступа к истории.

Как проверяем

Попытка обращения к кластеру истории с учётными данными сервиса ранжирования отклоняется.

2.59

Нагрузочное тестирование базы обхода

Хранилища1 backend3 нед.зависит от 1.56
Зачем

Решение о смене хранилища для базы обхода в фазе 3 должно приниматься по данным, а не по предположениям о том, что «встроенное хранилище не потянет».

Что делаем
  1. Замер реальной скорости записи и чтения на текущем объёме.
  2. Экстраполяция на объёмы фазы 3.
  3. Пробное развёртывание кандидата на замену с тем же нагрузочным профилем.
  4. Отчёт с решением.
Готово, когда

Решение о хранилище для фазы 3 принято и записано с обоснованием.

Как проверяем

Замеры воспроизводимы: повторный прогон даёт те же числа в пределах 10%.

2.60

Регламент проверки восстановления

Хранилища1 инфраструктура2 нед.зависит от 0.20, 1.57
Зачем

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

Что делаем
  1. Регламент ежеквартальной проверки восстановления по каждому хранилищу.
  2. Первое реальное восстановление всех баз на отдельной площадке.
  3. Замер времени восстановления и фиксация как показателя.
Готово, когда

Все хранилища восстановлены хотя бы раз, регламент утверждён, время восстановления известно.

Как проверяем

Восстановленная копия проходит проверки целостности данных.

Продвижение 6

2.61

Скрипт: монитор индексации

Продвижение1 backend3 нед.зависит от 1.60, 0.22
Зачем

Понять, сколько наших страниц реально в индексе конкурентов и что оттуда выпало. Без монитора это выясняется через месяцы падения трафика.

Что делаем
  1. Ежесуточная выгрузка из панелей вебмастера: страницы в поиске, исключённые с причинами, ошибки обхода.
  2. Сопоставление с собственной картой сайта.
  3. Для отсутствующих страниц — автоматическая проверка доступности, запретов, канонических адресов, объёма содержания.
  4. Оповещение при отклонении больше 5% от предыдущего дня.
  5. История в аналитическом хранилище.
Готово, когда

Монитор работает, выпадение страниц замечается за сутки.

Как проверяем

Намеренно закрываем страницу от индексации — монитор сообщает об этом на следующий день.

2.62

Скрипт: монитор видимости

Продвижение1 аналитик4 нед.зависит от 2.61
Зачем

Позиции по ядру запросов — единственный способ увидеть, растёт ли органический канал, до того как это отразится на трафике.

Что делаем
  1. Ядро: 300 брендовых, 500 информационных, 200 инструментальных запросов.
  2. Еженедельный съём позиций по десктопу и мобильным, по пяти регионам.
  3. Показатель видимости как взвешенная сумма по кривой кликабельности.
  4. Выявление страниц, потерявших позиции.
Готово, когда

Монитор работает, динамика видна на панели.

Как проверяем

Данные съёма воспроизводимы при повторном замере в тот же день.

Риск

Снятие позиций делается только через официальные программные интерфейсы и разрешённые методы. Компания, строящая поисковую систему, не может нарушать чужие условия использования: это и юридический риск, и репутационный.

2.63

Скрипт: валидатор структурированных данных

Продвижение1 backend3 нед.зависит от 1.13
Зачем

Одна работа, два применения: валидатор нужен нам в сборке и вебмастерам как публичный инструмент.

Что делаем
  1. Извлечение разметки — переиспользуется код нашего же экстрактора.
  2. Проверка по схемам: обязательные поля, типы значений.
  3. Проверка соответствия видимому содержимому: заявленные вопросы реально присутствуют на странице.
  4. Отчёт с указанием строки.
  5. Публикация как инструмента для вебмастеров.
Готово, когда

Валидатор работает в сборке и открыт публично.

Как проверяем

На выборке из 200 страниц с известными ошибками разметки находит не менее 95% из них.

2.64

Инженерный блог

Продвижениепродукт + инженеры4 нед.
Зачем

Ссылки от технической аудитории и канал найма. Разборы реальных задач читают и цитируют, в отличие от маркетинговых текстов.

Что делаем
  1. Раздел блога с разметкой статей.
  2. Первые десять материалов о реальных инженерных решениях.
  3. Регулярность не реже двух материалов в месяц.
  4. Лента для подписки.
Готово, когда

Блог запущен, десять материалов опубликованы.

Как проверяем

Материалы индексируются и получают внешние ссылки в течение месяца.

2.65

Публикация руководства асессора

Продвижениекачество + юрист3 нед.зависит от 1.38
Зачем

Открытая публикация инструкции — редкость в отрасли, поэтому она гарантированно вызовет резонанс. И она дисциплинирует прежде всего нас: инструкцию, которую увидят все, невозможно писать небрежно.

Что делаем
  1. Подготовка публичной версии руководства.
  2. Юридическая проверка на отсутствие раскрытия чувствительных деталей формулы.
  3. Публикация с версионированием и историей изменений.
Готово, когда

Руководство опубликовано и версионируется.

Как проверяем

Публичная версия не содержит информации, позволяющей манипулировать ранжированием.

2.66

Машиночитаемая карта содержания для языковых моделей

Продвижение1 фронтенд1 нед.зависит от 1.62
Зачем

Складывающийся стандарт для языковых моделей: карта содержания сайта в машиночитаемом виде, отдельная от карты сайта для краулеров.

Что делаем
  1. Файл в корне с иерархией разделов и ключевыми фактами о проекте.
  2. Однозначные формулировки о себе, повторяющиеся везде одинаково.
  3. Обновление при изменении структуры сайта.
Готово, когда

Файл опубликован и обновляется автоматически вместе с картой сайта.

Как проверяем

Файл валиден по схеме и обновляется вместе с картой сайта: изменение раздела появляется в обоих файлах за один цикл сборки. Расхождение проверяется автоматически — раздел, попавший в карту сайта, но не в карту содержания, считается ошибкой сборки, а не допустимой рассинхронизацией.

Ворота фазы 2

Все критерии обязательны. Не пройдены — фаза продлевается, а не закрывается.

  • 300 млн документов, обход 2000 страниц в секунду
  • pFound@10 не ниже 0.58
  • Доля запросов без релевантных результатов не выше 6%
  • Задержка на p99 не выше 320 мс при 300 запросах в секунду
  • Доступность 99.9% за квартал
  • Интерливинг показывает победу новой формулы над предыдущей со значимостью выше 99%
  • Антиспам: точность не ниже 0.95 при полноте не ниже 0.70
  • Yottis Метрика установлена не менее чем на 2000 внешних сайтов
  • Открытая бета: 100 000 пользователей в месяц, доля возвращающихся не ниже 30%
  • Админ-часть: сценарии разбора запроса, обращения по праву на забвение и проверки спам-кандидата проходятся целиком
  • Шлюз моделей в продакшене, обе первые функции идут через него
  • 1500 наших страниц в индексе конкурентов, 400 ссылающихся доменов

Фаза 3

Масштаб

Месяцы
18–26
Календарь
фев – окт 2028
Команда
45 чел.
Индекс
2 млрд
Бюджет
405 млн ₽
Задач
57
Недель работ
417

Публичный запуск. Два миллиарда документов, английский сегмент, генеративный ответ, публичный программный интерфейс, каналы дистрибуции, круглосуточная эксплуатация. Это главная веха программы: на выходе из фазы 3 проект либо является поисковой системой, которой пользуются, либо не является ничем.

Индекс и поиск 3

3.1

Индекс до 2 млрд документов

Индекс и поисккритический путь3 backend14 нед.зависит от 2.26
Зачем

Семикратный рост корпуса. На этом объёме перестают работать приёмы, достаточные для трёхсот миллионов: перебалансировка занимает сутки, полная пересборка — неделю.

Что делаем
  1. Сорок шардов с тройной репликацией.
  2. Переиндексация с новым ключом шардирования, учитывающим языковой кластер.
  3. Перебалансировка без остановки поиска.
  4. Проверка, что время полной пересборки остаётся в пределах трёх суток.
Готово, когда

2 млрд документов в индексе, перекос между шардами не более 15%, поиск не прерывался.

Как проверяем

Замер времени полной пересборки и времени добавления нового шарда.

3.2

Трёхслойный индекс

Индекс и поиск2 backend10 нед.зависит от 3.1
Зачем

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

Что делаем
  1. Горячий слой: примерно два процента документов по трафику и авторитету плюс всё свежее за двое суток, полностью в памяти и на быстрых дисках.
  2. Тёплый слой: основной корпус на быстрых дисках.
  3. Холодный слой: длинный хвост и архив на объектном хранилище.
  4. Автоматическое перемещение документов между слоями по трафику.
  5. Разная стратегия обновления для каждого слоя.
Готово, когда

Слои работают, восемьдесят пять процентов запросов обслуживаются горячим слоем.

Как проверяем

Распределение запросов по слоям на реальном трафике за неделю.

3.4

Векторный индекс на диске

Индекс и поиск2 ML + 1 backend10 нед.зависит от 2.5, 3.2
Зачем

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

Что делаем
  1. Построение графа соседства на быстрых дисках.
  2. Сжатое представление в памяти для навигации.
  3. Раздельные стратегии для горячего слоя, где вектора остаются в памяти, и тёплого.
  4. Инкрементальное добавление векторов без полной перестройки графа.
Готово, когда

Векторный поиск работает на всём корпусе, полнота на первом результате не ниже 0.95, средняя задержка не выше 5 мс.

Как проверяем

Замер полноты и задержки на контрольном наборе из миллиона запросов.

Обход 2

3.3

Обход 10 000 страниц в секунду

Обход3 backend + 2 инфраструктура12 нед.зависит от 1.1, 1.2
Зачем

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

Что делаем
  1. Шестьдесят узлов загрузки, восемьдесят узлов обработки.
  2. Распределение фронтира между узлами с сохранением вежливости: суммарная нагрузка на хост считается глобально, а не по узлам.
  3. Адаптивное снижение скорости при росте времени ответа хоста.
  4. Мониторинг по каждому крупному хосту отдельно.
Готово, когда

Обход идёт на десяти тысячах страниц в секунду непрерывно, ни один хост не получает больше разрешённого.

Как проверяем

Учение: искусственно замедляем крупный хост — скорость обхода по нему падает автоматически в течение минуты.

Риск

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

3.36

Обход англоязычного сегмента

Обход2 backend + 2 инфраструктура16 нед.зависит от 3.3, 3.34
Зачем

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

Что делаем
  1. Начальный набор доменов из открытого корпуса и из ссылочного окружения уже известных.
  2. Приоритизация по авторитету и по спросу из логов запросов.
  3. Рост индекса до восьми миллиардов документов.
  4. Отдельный контроль вежливости: чужой сегмент, чужие ожидания.
Готово, когда

Восемь миллиардов англоязычных документов в индексе.

Как проверяем

Покрытие: для девяноста процентов англоязычных запросов корзины в индексе есть страница из топ-3 конкурента.

Ранжирование 4

3.5

Компактное кодирование веб-графа

Ранжирование1 ML7 нед.зависит от 1.23
Зачем

Граф на десятки миллиардов рёбер в наивном представлении не помещается в память ни одной машины, а пересчёт авторитета с диска занимает сутки.

Что делаем
  1. Кодирование разностями идентификаторов вместо самих идентификаторов.
  2. Ссылки на похожие списки смежности: у страниц одного сайта они почти совпадают.
  3. Проверка, что распаковка не становится узким местом пересчёта.
Готово, когда

Граф помещается в память узла пересчёта, ежедневный пересчёт хостового графа укладывается в четыре часа.

Как проверяем

Замер объёма и времени пересчёта на полном графе.

3.7

Поведенческие признаки с коррекцией смещения

Ранжированиекритический путь3 ML10 нед.зависит от 2.3
Зачем

Клики — самый сильный сигнал релевантности и самый опасный: они смещены позицией и уязвимы к накрутке. Использовать их обязательно, использовать наивно — гибельно.

Что делаем
  1. Кликстрим в обучение с коррекцией позиционного смещения; вероятность просмотра позиции оценивается на трафике исследования.
  2. Признаки: кликабельность с поправкой на позицию, доля длинных кликов, доля быстрых возвратов, последний клик в сессии.
  3. В инференсе используются только сглаженные агрегаты с окном не менее тридцати дней.
  4. Лаг не менее семи дней между сбором и применением.
  5. Байесовское сглаживание к среднему по позиции: редкие пары не двигаются вообще.
Готово, когда

Поведенческие признаки в основной модели, прирост pFound не менее 0.03.

Как проверяем

Проверка на устойчивость: искусственный всплеск кликов по паре не меняет её позицию раньше чем через неделю.

Риск

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

3.8

Трафик исследования и обучение без смещения

Ранжированиекритический путь2 ML8 нед.зависит от 3.7
Зачем

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

Что делаем
  1. Один-два процента запросов получают выдачу с внедрённым случайным документом из позиций с одиннадцатой по пятидесятую.
  2. Оценка вероятности показа на этом трафике.
  3. Обучение с обратным взвешиванием по этой вероятности.
  4. Отдельная холодная корзина запросов, по которым мы намеренно не обучаемся: только замер.
Готово, когда

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

Как проверяем

Рост качества на холодной корзине не отстаёт от роста на обучающей — расхождение означает переобучение на собственную выдачу.

3.11

Расширение до 600 признаков

Ранжирование2 ML12 нед.зависит от 2.2, 3.7
Зачем

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

Что делаем
  1. Группа поведения полностью.
  2. Признаки истории документа: динамика позиций, стабильность содержания.
  3. Признаки хоста из аналитики.
  4. Ревизия реестра: признаки с нулевым вкладом в трёх обучениях удаляются.
Готово, когда

Около шестисот признаков в модели, реестр очищен от мёртвых.

Как проверяем

Доля признаков с нулевой важностью не выше десяти процентов.

Инфраструктура 2

3.6

Работа из двух дата-центров одновременно

Инфраструктура3 инфраструктура12 нед.зависит от 2.27
Зачем

Онлайн-контур должен переживать потерю целого дата-центра с деградацией задержки, но без отказа. Офлайн-контур при этом может лежать сутки — это осознанное решение, экономящее половину стоимости резервирования.

Что делаем
  1. Полный онлайн-контур в обоих центрах.
  2. Маршрутизация трафика по географии с быстрым переключением.
  3. Репликация индекса между центрами.
  4. Офлайн-контур остаётся в одном центре.
  5. Регулярные учения по переключению.
Готово, когда

Потеря центра не приводит к отказу поиска, только к росту задержки.

Как проверяем

Учение с реальным отключением одного центра под нагрузкой.

3.20

Круглосуточное дежурство

Инфраструктура3 инженера эксплуатации8 нед.зависит от 1.35
Зачем

Публичный запуск означает, что авария ночью — это авария для пользователей, а не строчка в утреннем отчёте.

Что делаем
  1. График дежурств с ротацией.
  2. Регламенты реагирования по типам инцидентов.
  3. Эскалация и разбор инцидентов без поиска виновных.
  4. Бюджет ошибок: при исчерпании выкатки останавливаются до конца периода.
Готово, когда

Дежурство работает, регламенты написаны, первые разборы проведены.

Как проверяем

Учебный инцидент ночью: время до реакции не больше пятнадцати минут.

Хранилища 3

3.50

Миграция базы обхода

Хранилища2 backend + 1 инфраструктура10 нед.зависит от 1.56, 2.59
Зачем

Тридцать миллиардов ключей и сто тысяч записей в секунду. Встроенное хранилище на таком объёме перестаёт справляться, а транзакции здесь не нужны: обновление статуса адреса идемпотентно.

Что делаем
  1. Развёртывание кластера распределённого хранилища.
  2. Реализация интерфейса доступа поверх него.
  3. Двойная запись в старое и новое хранилище с постоянной сверкой.
  4. Переключение чтения после схождения данных.
  5. Всё без остановки обхода.
Готово, когда

База обхода на новом хранилище, обход не прерывался.

Как проверяем

Абстракция, введённая в первой фазе, сделала миграцию заменой реализации, а не переписыванием краулера — это проверяется по объёму изменений в коде краулера: он должен быть нулевым.

3.51

Холодный слой на объектном хранилище

Хранилища1 backend + 1 инфраструктура8 нед.зависит от 3.2
Зачем

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

Что делаем
  1. Формат самодостаточных сегментов индекса на объектном хранилище.
  2. Поисковые узлы без состояния, читающие сегменты напрямую.
  3. Кэширование горячих участков сегментов.
  4. Пометка выдачи как обслуженной холодным слоем для отдельного замера задержки.
Готово, когда

Холодный слой работает, доля обслуживаемых им запросов не превышает одного процента.

Как проверяем

Задержка холодного слоя может достигать секунды — это приемлемо для одного процента запросов и неприемлемо для остальных, поэтому доля контролируется отдельной метрикой с оповещением.

3.52

Региональные реплики транзакционного слоя

Хранилища1 инфраструктура6 нед.зависит от 1.57, 3.6
Зачем

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

Что делаем
  1. Реплики только для чтения в каждом регионе присутствия.
  2. Запись остаётся в основном центре.
  3. Обработка задержки репликации в интерфейсе: после изменения показываем своё же изменение.
Готово, когда

Чтение обслуживается локально, задержка кабинета в удалённом регионе не выше 300 мс.

Как проверяем

Замер задержки кабинета из удалённого региона с реального канала, а не из соседнего дата-центра. Отдельно — проверка расхождения реплик: запись в центре видна в реплике за оговорённое время, и это время измеряется, а не предполагается. Сценарий с отставшей репликой проверяется явно: пользователь обязан увидеть свои собственные изменения сразу, даже если реплика ещё не догнала.

Антиспам 1

3.9

Защита от накрутки поведенческих факторов

Антиспамкритический путь2 антиспам7 нед.зависит от 3.7
Зачем

Поведенческие признаки — самый уязвимый слой ранжирования, и рынок накрутки существует ровно потому, что они работают.

Что делаем
  1. Учёт кликов только от сессий с историей не менее семи дней и человеческим профилем поведения.
  2. Детектор аномалий: всплеск кликабельности по паре относительно исторической базы.
  3. Ограничение вклада одной сессии, одного адреса и одной подсети в агрегат.
  4. Сглаживание к среднему по позиции.
  5. Лаг применения не менее семи дней, делающий быструю накрутку бессмысленной.
Готово, когда

Все пять мер работают, детектор аномалий находит искусственные всплески.

Как проверяем

Учение: имитируем накрутку на тестовом запросе — позиция не меняется, аномалия попадает в очередь модерации.

ИИ-структура 5

3.10

Собственная предобученная модель для реранкера

ИИ-структура3 ML14 нед.зависит от 2.9
Зачем

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

Что делаем
  1. Предобучение на собственном корпусе, русский и английский.
  2. Дообучение под задачу ранжирования на кликах и асессорских оценках.
  3. Дистилляция в компактную версию для инференса.
  4. Квантование и замер задержки.
Готово, когда

Собственная модель заменила готовую, прирост pFound не менее 0.02 при том же бюджете задержки.

Как проверяем

Сравнение на корзине и замер задержки под нагрузкой.

3.13

Генеративный ответ

ИИ-структуракритический путь3 ML + 1 фронтенд14 нед.зависит от 2.53, 3.10
Зачем

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

Что делаем
  1. Классификатор пригодности запроса. На чувствительных темах — медицина, право, финансы, политика, безопасность — блок не показывается вообще.
  2. Берём топ-8 после реранкера.
  3. Семантическая фильтрация до трёх-пяти действительно отвечающих документов.
  4. Извлечение релевантных пассажей точным экстрактором.
  5. Генерация с обязательной ссылкой на каждое утверждение.
  6. Проверка обоснованности каждого предложения отдельной моделью; неподтверждённое вырезается.
  7. Если после проверки осталось меньше двух предложений — блок не показывается.
Готово, когда

Доля утверждений без подтверждения источником не выше одного процента на аудите.

Как проверяем

Ручной аудит двухсот сгенерированных ответов асессорами с проверкой каждого утверждения по источнику.

Риск

Блок подрывает трафик сайтов, которые нас наполняют. Жёсткие ограничения: не более шестидесяти слов, не более двадцати пяти слов подряд из одного источника, блок сворачивается с запоминанием выбора навсегда, занимает не более сорока процентов первого экрана, явная плашка об автоматической генерации.

3.46

Генеративный ответ через шлюз моделей

ИИ-структура1 ML4 нед.зависит от 3.13, 2.53
Зачем

Первая пользовательская функция на моделях обязана идти через общий шлюз — иначе смысл шлюза теряется на первой же реальной задаче.

Что делаем
  1. Перенос вызовов на шлюз.
  2. Настройка срока ожидания и поведения при отказе.
  3. Флаг с долей трафика.
  4. Учёт стоимости.
Готово, когда

Функция работает через шлюз, выключается флагом за минуту.

Как проверяем

Отключение шлюза приводит к исчезновению блока, а не к отказу выдачи.

3.48

Учёт стоимости инференса

ИИ-структура1 backend3 нед.зависит от 2.55
Зачем

Без учёта в разрезе функций инференс внезапно оказывается крупнейшей статьёй расходов, и непонятно, какая функция её создала.

Что делаем
  1. Панель стоимости по функциям, моделям и долям трафика.
  2. Прогноз стоимости при увеличении доли трафика.
  3. Оповещение при превышении бюджета функции.
Готово, когда

Стоимость видна по каждой функции, прогноз строится.

Как проверяем

Прогноз при удвоении доли трафика сходится с фактом в пределах двадцати процентов.

3.49

Учёт машиночитаемых карт при обходе

ИИ-структура1 backend3 нед.зависит от 2.66
Зачем

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

Что делаем
  1. Разбор файла при обходе как подсказки о структуре сайта.
  2. Использование в приоритизации обхода.
  3. Отсутствие доверия к содержимому файла как к факту: это подсказка, а не источник истины.
Готово, когда

Файл разбирается и учитывается в приоритете.

Как проверяем

Сайт с корректной картой обходится в правильном порядке; сайт с ложной картой не получает преимущества.

Регион и гео 1

3.12

Региональное ранжирование по городам

Регион и гео1 ML8 нед.зависит от 1.44, 2.35
Зачем

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

Что делаем
  1. Отдельные модели или поправки для крупных городов.
  2. Учёт расстояния и агломерации.
  3. Обработка запросов без региональной привязки: региональные признаки не должны портить информационную выдачу.
Готово, когда

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

Как проверяем

Замер по пяти городам на локальной корзине и контрольный замер на информационной.

Качество 6

3.24

Платформа краудсорсинга разметки

Качествокритический путь2 backend + 1 качество9 нед.
Зачем

Определяющая задача фазы: пропускная способность оценки — узкое место всей программы начиная отсюда.

Что делаем
  1. Платформа на базе открытого инструмента разметки, чтобы не изобретать интерфейсы заново.
  2. Типы заданий: оценка релевантности по шкале, попарное сравнение документов, сравнение выдач целиком.
  3. Ловушки-контрольки с заранее известным ответом, вкраплённые в поток.
  4. Расчёт согласия исполнителей и рейтинга качества.
  5. Своё пишем только там, где специфика поиска: шкала, сравнение выдач, контроль согласия.
Готово, когда

Платформа выдаёт задания, оценки собираются, согласие считается.

Как проверяем

Согласие по каппе Коэна не ниже 0.6 на пересекающихся заданиях.

3.25

Пул исполнителей

Качество1 качество8 нед.зависит от 3.24
Зачем

Платформа без людей бесполезна, а люди без обучения дают шум вместо данных.

Что делаем
  1. Набор и обучение по опубликованному руководству асессора.
  2. Аттестация с проходным баллом.
  3. Рейтинг качества по контролькам, влияющий на доступ к заданиям и на оплату.
  4. Выплаты и документооборот.
Готово, когда

Пул набран, десять тысяч оценок в неделю выдаются стабильно.

Как проверяем

Замер пропускной способности за четыре недели подряд.

3.26

Конвейер от гипотезы до переобучения

Качество1 ML6 нед.зависит от 3.24, 3.25
Зачем

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

Что делаем
  1. Автоматическое формирование задания на разметку из гипотезы.
  2. Сбор оценок и включение в обучающую выборку.
  3. Переобучение и офлайн-замер.
  4. Автоматический запуск интерливинга при прохождении офлайн-порога.
Готово, когда

Полный цикл занимает не более пяти дней.

Как проверяем

Замер на десяти реальных гипотезах подряд.

3.37

Английская корзина и асессоры

Качество1 качество10 нед.зависит от 3.25
Зачем

Качество на языке, для которого нет корзины и асессоров, не измеряется, а значит, не управляется.

Что делаем
  1. Пять тысяч английских запросов по той же методике отбора.
  2. Пул англоязычных асессоров и перевод руководства.
  3. Отдельный автозамер по английской корзине.
Готово, когда

Корзина размечена, автозамер идёт ежедневно.

Как проверяем

Согласие англоязычных асессоров не ниже 0.6.

3.40

Оценка на открытом многоязычном наборе

Качество1 ML4 нед.зависит от 3.38
Зачем

Внутренние метрики на собственной корзине не позволяют сравнить себя с миром. Публичный набор позволяет.

Что делаем
  1. Прогон на многоязычном наборе для оценки поиска.
  2. Сравнение с опубликованными результатами базовых методов.
  3. Включение в регулярный замер.
Готово, когда

Наши результаты сопоставимы с опубликованными для сильных базовых методов.

Как проверяем

Прогон на публичном наборе по опубликованной методике, без единой правки под него — подгонка под открытый набор обесценивает единственное, ради чего он берётся. Результаты сравниваются с опубликованными для сильных базовых методов и печатаются вместе с ними, включая случаи, где мы проигрываем.

3.22

Публикация руководства асессора

Качествокачество3 нед.зависит от 2.65
Зачем

Снимает спекуляции о секретных критериях и даёт вебмастерам понятную рамку.

Что делаем
  1. Публикация полного руководства асессора в открытом доступе, тем же текстом, по которому работают наши асессоры, — сокращённая «версия для внешних» обесценивает всю затею. 2. История изменений с датами и пояснением, что именно поменялось и почему. 3. Раздел с примерами оценок: страница, оценка, обоснование. Правила без примеров каждый понимает по-своему. 4. Форма обратной связи для вебмастеров с обязательным ответом на содержательные замечания.
Готово, когда

Актуальная версия руководства опубликована с историей изменений.

Как проверяем

Внутренние асессоры работают по опубликованной версии, а не по внутренней: расхождение между текстом на сайте и инструкцией в работе означает, что опубликовано не руководство, а его изложение. Проверяется выборочной сверкой и тем, что каппа Коэна между асессорами не падает после публикации.

Многоязычие 4

3.34

Шардирование по паре «кластер и хост»

Многоязычиекритический путь2 backend10 нед.зависит от 2.40, 3.1
Зачем

Расхожий совет «один индекс на язык» верен для коллекций до миллиона документов и вреден для веба: многоязычные страницы попадают не туда, кросс-языковые запросы не работают, а число индексов растёт вместе с числом языков.

Что делаем
  1. Ключ шардирования — хеш от пары «языковой кластер и хост».
  2. Внутри кластера сохраняется хостовая локальность, между кластерами появляется возможность отсечения.
  3. Переиндексация корпуса с новым ключом.
  4. Обработка многоязычных сайтов: документы одного хоста могут попасть в разные шарды, и хостовые признаки должны быть доступны в каждом.
Готово, когда

Языковое отсечение шардов работает, русский запрос читает часть шардов вместо всех.

Как проверяем

Замер числа опрошенных шардов до и после на корзине русских запросов.

3.35

Маршрутизация запроса по кластерам

Многоязычие1 backend5 нед.зависит от 3.34, 2.41
Зачем

Отсечение по языку даёт выигрыш, но неаккуратное отсечение теряет лучший ответ.

Что делаем
  1. Определение языка запроса и региона пользователя.
  2. Правило: свой кластер плюс западная латиница всегда. Русскоязычный пользователь на технический запрос почти всегда хочет видеть и англоязычные результаты.
  3. Язык не определён — опрашиваются все кластеры региона.
  4. Явный оператор языка — только указанный кластер.
Готово, когда

Маршрутизация работает, выигрыш по задержке измерен, качество не упало.

Как проверяем

Контрольный замер на корзине: доля запросов, где полезный англоязычный результат исчез из топ-10, равна нулю.

3.38

Многоязычные эмбеддинги

Многоязычие2 ML12 нед.зависит от 2.5, 3.36
Зачем

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

Что делаем
  1. Дообучение многоязычной модели на собственных данных.
  2. Использование английского как языка-моста: модели, дообученные под поиск, выигрывают именно в такой схеме.
  3. Общее векторное пространство для всех кластеров.
  4. Пометка результата на другом языке в выдаче с кнопкой перевода.
Готово, когда

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

Как проверяем

Оценка на открытом многоязычном наборе, чтобы цифры были сопоставимы с литературой, а не сами с собой.

3.39

Перевод запроса как дополнительная ветвь

Многоязычие1 ML6 нед.зависит от 3.38
Зачем

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

Что делаем
  1. Включение ветви при малом числе результатов на языке запроса.
  2. Перевод запроса на английский и поиск дополнительной ветвью.
  3. Слияние результатов с понижением веса переведённой ветви.
  4. Прозрачность: пользователь видит, что часть результатов найдена по переводу.
Готово, когда

Ветвь включается по условию, результаты помечены.

Как проверяем

На корзине узких технических запросов доля пустых выдач снижается.

Продукт 14

3.14

Панель знаний

Продукт2 backend + 1 ML12 нед.зависит от 1.13
Зачем

Запрос-сущность — заметная доля трафика, и на него правильный ответ не список ссылок, а карточка с фактами.

Что делаем
  1. Собственный граф сущностей с начальным наполнением из открытых данных.
  2. Связывание сущностей с документами индекса.
  3. Извлечение фактов из структурированной разметки.
  4. Карточка с изображением, фактами и ссылками.
  5. Механизм исправления фактов через кабинет вебмастера.
Готово, когда

Панель показывается на запросах-сущностях, факты верны.

Как проверяем

Асессорская проверка ста карточек: доля неверных фактов ниже двух процентов.

3.15

Блок «Люди также спрашивают»

Продукт1 backend + 1 фронтенд5 нед.зависит от 1.34
Зачем

Помогает пользователю уточнить запрос и даёт нам сигнал о том, какие формулировки работают лучше.

Что делаем
  1. Кластеризация связанных запросов из логов.
  2. Отбор вопросов, на которые есть хороший ответ в индексе.
  3. Раскрытие ответа без ухода со страницы: блок не должен конкурировать с выдачей.
Готово, когда

Блок показывается на информационных запросах, раскрытие не уводит со страницы.

Как проверяем

Замер на живом трафике: доля раскрытий блока и доля уходов со страницы после раскрытия. Блок засчитывается работающим, только если раскрытие НЕ уводит пользователя со страницы чаще, чем обычный результат: блок, отправляющий людей дальше искать, ухудшает выдачу, как бы охотно его ни раскрывали.

3.16

Колдунщики третьей фазы

Продукт1 фронтенд + 1 backend8 нед.зависит от 2.20
Зачем

Продолжение линии на плотность блоков с готовым ответом.

Что делаем
  1. Картинки в строку на визуальных запросах.
  2. Новости в строку при всплеске темы.
  3. Факты и определения из графа сущностей.
  4. Соблюдение общего лимита в два блока.
Готово, когда

Колдунщики работают, лимит соблюдается.

Как проверяем

Замер доли запросов с колдунщиком и соблюдения лимита на их число в выдаче. Отдельно — контрольная корзина обычных запросов: она не должна деградировать. Колдунщик, вытеснивший верный органический результат, считается ошибкой, а не удачным блоком.

3.17

Публичный программный интерфейс

Продукткритический путь2 backend10 нед.зависит от 1.29
Зачем

Первая понятная монетизация: не нужен отдел продаж и рекламодатели, актив уже построен.

Что делаем
  1. Эндпоинты: веб-поиск, картинки, новости, подсказки, исправление опечаток, проверка адреса.
  2. Ключи доступа с квотами по алгоритму токенного ведра и заголовками остатка.
  3. Тарифные планы от бесплатного для разработчиков до корпоративного.
  4. Документация с примерами на нескольких языках.
  5. Правила использования: запрет на построение конкурирующего индекса из выдачи, обязательная атрибуция, ограничение кэширования.
Готово, когда

Интерфейс работает, первые платящие клиенты подключены.

Как проверяем

Нагрузочный тест на заявленных лимитах; превышение квоты корректно отклоняется.

3.18

Расширения для браузеров

Продукт2 фронтенд8 нед.зависит от 2.23
Зачем

Самый дешёвый канал дистрибуции: одна кодовая база на три браузера.

Что делаем
  1. Установка поиском по умолчанию с честным диалогом, а не подменой настроек.
  2. Сохранение страницы в коллекции.
  3. Быстрый доступ к поиску по выделенному тексту.
  4. Публикация в магазинах трёх браузеров.
Готово, когда

Расширения опубликованы, не менее пятидесяти тысяч установок.

Как проверяем

Доля удалений в первую неделю ниже двадцати процентов — выше означает, что расширение навязчиво.

3.19

Персонализация выдачи

Продукт2 ML9 нед.зависит от 2.22, 3.7
Зачем

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

Что делаем
  1. Включается только явным действием пользователя.
  2. Переупорядочивает топ-30, но не меняет состав кандидатов.
  3. Максимальный сдвиг документа — пять позиций.
  4. Сигналы: посещённые ранее хосты, повтор запроса, вектор интересов.
  5. Пометка в выдаче и ссылка «показать без персонализации» одним кликом.
  6. Сервис персонализации отдаёт производный вектор интересов, а не историю.
Готово, когда

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

Как проверяем

Замер: ни один документ не сдвинулся больше чем на пять позиций; состав топ-30 без персонализации и с ней совпадает.

3.23

Маркетинг запуска

Продуктпродукт8 нед.зависит от 3.18
Зачем

Продукт, о котором никто не знает, не получает пользователей независимо от качества.

Что делаем
  1. Пресс-материалы и работа с отраслевыми изданиями.
  2. Выступления на профильных конференциях.
  3. Работа с техническими сообществами.
  4. Кампания в момент открытого запуска.
Готово, когда

Запуск состоялся, охват замерен.

Как проверяем

Замер охвата и переходов по каждому каналу отдельно, с разделением платного и органического. Главная проверка — не охват, а удержание: доля вернувшихся на второй неделе. Запуск, давший миллион визитов и нулевое удержание, считается несостоявшимся, потому что второй раз тех же людей не привести.

3.27

Расширение как канал дистрибуции

Продукткритический путь1 фронтенд4 нед.зависит от 3.18
Зачем

Опубликовать расширение мало — нужно, чтобы его находили и устанавливали.

Что делаем
  1. Оптимизация страниц в магазинах расширений.
  2. Промо-страница на сайте.
  3. Отслеживание установок и удалений как отдельной метрики.
Готово, когда

Не менее пятидесяти тысяч установок, воронка отслеживается.

Как проверяем

Воронка прослеживается целиком: показ в каталоге, переход, установка, первый запрос, запрос на седьмой день. Число установок само по себе ничего не значит — засчитывается доля дошедших до седьмого дня, потому что расширение, удалённое через неделю, не канал дистрибуции, а строчка в отчёте.

3.28

Поиск по сайту для вебмастеров

Продукт2 backend + 1 фронтенд7 нед.зависит от 3.17
Зачем

Бесплатно для владельца сайта; для нас — дистрибуция, брендинг и данные о тематических запросах, которых иначе неоткуда взять.

Что делаем
  1. Встраиваемая форма поиска по сайту.
  2. Настройка внешнего вида в кабинете вебмастера.
  3. Обязательная видимая атрибуция.
  4. Отчёт по запросам внутри сайта для владельца.
Готово, когда

Форма встраивается, работает и даёт владельцу отчёт.

Как проверяем

Внедрение на десяти внешних сайтах с замером нагрузки.

3.29

Виджет поиска и стартовая страница

Продукт1 фронтенд4 нед.зависит от 3.18
Зачем

Дешёвые каналы дистрибуции, которые стоит занять до того, как о нас узнают.

Что делаем
  1. Встраиваемый виджет поиска.
  2. Настраиваемая стартовая страница.
  3. Инструкции по установке для распространённых браузеров.
Готово, когда

Оба канала доступны и документированы.

Как проверяем

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

3.31

Оригинальные тексты

Продукт1 backend + 1 фронтенд6 нед.зависит от 1.30, 1.10
Зачем

Сильнейший сигнал первоисточника против воровства контента: автор отправляет текст до публикации, и мы фиксируем время.

Что делаем
  1. Форма отправки текста в кабинете вебмастера с квотой.
  2. Фиксация времени и отпечатка текста.
  3. Использование как признака первоисточника при обнаружении дубля.
  4. Защита от злоупотребления: отправка чужого текста ничего не даёт, если он уже зафиксирован.
Готово, когда

Механизм работает, зафиксированный текст выигрывает у копии в выдаче.

Как проверяем

Учение: фиксируем текст, публикуем копию на другом сайте — оригинал остаётся выше.

3.32

Управление быстрыми ссылками

Продукт1 фронтенд3 нед.зависит от 2.24
Зачем

Быстрые ссылки формируются автоматически и иногда ведут не туда, куда владелец сайта хотел бы.

Что делаем
  1. Просмотр сформированных быстрых ссылок.
  2. Скрытие ненужных.
  3. Объяснение, почему выбраны именно эти.
Готово, когда

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

Как проверяем

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

3.33

Вертикаль поиска по документам в интерфейсе

Продукт1 фронтенд4 нед.зависит от 2.19
Зачем

Индексация документов сделана в предыдущей фазе, но без отдельной вертикали пользователи о ней не знают.

Что делаем
  1. Отдельная вкладка с фильтрами по типу файла.
  2. Отображение типа, размера и числа страниц.
  3. Предпросмотр первой страницы, где это возможно.
Готово, когда

Вертикаль работает, фильтры применяются.

Как проверяем

Корзина запросов по документам с замером полноты: доля запросов, где нужный документ найден. Фильтры проверяются на согласованность — сумма по типам файлов совпадает с общим числом, а фильтр по типу не теряет документы с нераспознанным типом молча.

3.47

Переключатель для вебмастера по генеративным ответам

Продукт1 backend + 1 фронтенд3 нед.зависит от 3.13, 1.30
Зачем

Честный ответ на главную претензию издателей к генеративному поиску: возможность быть в индексе, но не в генеративных ответах.

Что делаем
  1. Переключатель в кабинете вебмастера.
  2. Учёт при отборе источников для ответа.
  3. Учёт директив на уровне страницы.
Готово, когда

Переключатель работает, исключённые сайты не используются в ответах.

Как проверяем

Сайт с включённым запретом не появляется среди источников ни в одном из ста проверенных ответов.

Продвижение 6

3.30

Публичная статистика рынка

Продвижение1 фронтенд + 1 аналитик5 нед.зависит от 2.31
Зачем

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

Что делаем
  1. Расчёт долей поисковых систем и браузеров на агрегированных данных Метрики.
  2. Публичная страница с историей и выгрузкой.
  3. Прозрачная методика расчёта.
  4. Соблюдение порогов агрегации.
Готово, когда

Страница опубликована, данные обновляются автоматически.

Как проверяем

Методика воспроизводима третьей стороной по опубликованному описанию.

3.53

Отчёт о прозрачности как публичная страница

Продвижение1 фронтенд3 нед.зависит от 3.21
Зачем

Отчёт в формате документа читают единицы; страница с данными и выгрузкой цитируется годами.

Что делаем
  1. Публичная страница с графиками и таблицами.
  2. Выгрузка данных в машиночитаемом виде.
  3. Разметка набора данных.
  4. История отчётов.
Готово, когда

Страница опубликована, данные выгружаются.

Как проверяем

Данные на странице сходятся с внутренним учётом обращений и удалений — расхождение в отчёте о прозрачности стоит дороже отсутствия отчёта. Выгрузка открывается в табличном редакторе без правки руками, и её структура не меняется между выпусками: менять формат отчёта, который цитируют, значит обесценивать прошлые ссылки.

3.54

Публичная страница статистики рынка

Продвижение1 фронтенд2 нед.зависит от 3.30
Зачем

Постоянный источник ссылок и доказательство того, что у нас есть собственные данные.

Что делаем
  1. Страница с агрегированной статистикой по индексу: сколько сайтов, на каких языках, в каких зонах, как менялось за год. 2. Данные обезличены и агрегированы до уровня, на котором ни один отдельный сайт не опознаётся, — иначе страница превращается в инструмент конкурентной разведки. 3. Автоматическое обновление и выгрузка в машиночитаемом виде с явной лицензией на использование со ссылкой. 4. Методика расчёта опубликована рядом: цифра без методики не цитируется, а оспаривается.
Готово, когда

Страница опубликована и обновляется автоматически.

Как проверяем

Цифры на странице воспроизводятся из индекса независимым запросом и совпадают. Проверка обезличивания: по опубликованным агрегатам нельзя восстановить показатели отдельного сайта — это проверяется попыткой, а не декларацией. Обновление идёт автоматически, и устаревшая на месяц страница считается сломанной.

3.55

Исследования веба на собственных данных

Продвижениеаналитика8 нед.зависит от 3.1
Зачем

Никто, кроме владельца индекса, не может посчитать долю сайтов рунета на защищённом протоколе, средний вес страницы или долю мёртвых ссылок. На такие данные принято ссылаться, и такие ссылки невозможно купить.

Что делаем
  1. Четыре исследования в год на собственном индексе.
  2. Публикация методики и наборов данных.
  3. Разметка наборов данных.
  4. Работа с профильными изданиями.
Готово, когда

Первое исследование опубликовано и процитировано внешними источниками.

Как проверяем

Не менее десяти ссылающихся доменов на исследование в течение месяца.

3.56

Языковые версии для поисковых систем

Продвижение1 фронтенд2 нед.зависит от 2.39
Зачем

Без разметки языковых версий поисковые системы показывают английскому пользователю русскую страницу и наоборот.

Что делаем
  1. Взаимная разметка языковых версий всех публичных страниц.
  2. Указание версии по умолчанию.
  3. Проверка корректности в аудите сборки.
Готово, когда

Разметка на всех публичных страницах, аудит проходит.

Как проверяем

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

3.57

Программа партнёрских внедрений

Продвижениепродукт6 нед.зависит от 3.28
Зачем

Внедрение поиска по сайту даёт нам одновременно ссылки, брендинг и данные о тематических запросах.

Что делаем
  1. Условия партнёрства с обязательной атрибуцией.
  2. Пакет материалов для внедрения.
  3. Приоритетная поддержка партнёров.
  4. Отслеживание внедрений.
Готово, когда

Не менее пятидесяти внешних сайтов используют поиск по сайту с видимой атрибуцией.

Как проверяем

Считаются не подписанные соглашения, а работающие внедрения с видимой атрибуцией: проверяется автоматически обходом сайтов-партнёров. Отдельно замеряется, что даёт программа на деле — переходы и запросы, — потому что внедрение без трафика не отличается от отсутствующего.

Админ-часть 5

3.41

Раздел «Эксперименты»

Админ-часть1 backend + 1 фронтенд6 нед.зависит от 2.10, 1.50
Зачем

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

Что делаем
  1. Список экспериментов со статусом и владельцем.
  2. Запуск интерливинга и A/B из интерфейса.
  3. Расчёт значимости и достаточности накопленной статистики.
  4. Откат одной кнопкой.
  5. История всех экспериментов с результатами, включая неудачные.
Готово, когда

Эксперимент запускается и откатывается из интерфейса, история сохраняется.

Как проверяем

Любой прошлый эксперимент воспроизводим по записи в истории.

3.42

Флаги функций

Админ-часть1 backend5 нед.зависит от 1.54
Зачем

Выкатка без релиза: включение по долям трафика, регионам и языкам.

Что делаем
  1. Управление флагами из интерфейса с журналированием.
  2. Условия: доля трафика, регион, язык, класс запроса, тип аккаунта.
  3. Постепенное включение с автоматическим откатом по метрикам.
Готово, когда

Флаги управляются из интерфейса, условия работают.

Как проверяем

Включение функции на пять процентов трафика в одном регионе действительно затрагивает только его.

3.43

Раздел «Аккаунты» с процедурой доступа

Админ-часть1 backend5 нед.зависит от 2.52
Зачем

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

Что делаем
  1. Поиск аккаунта, статус, устройства, журнал входов — без содержимого истории.
  2. Процедура доступа к истории: обоснование, второй подтверждающий, ограниченное время доступа.
  3. Уведомление пользователя о факте доступа, если это не запрещено законом.
  4. Всё в журнале с оповещением аудитора.
Готово, когда

Процедура работает, доступ без обоснования невозможен.

Как проверяем

Попытка открыть историю без процедуры отклоняется.

3.44

Раздел «Контент»

Админ-часть1 фронтенд6 нед.зависит от 3.14, 3.16
Зачем

Колдунщики, панель знаний и справочники требуют продуктового управления, а не правки конфигов в репозитории.

Что делаем
  1. Управление колдунщиками: включение, пороги, источники данных.
  2. Редактирование сущностей панели знаний и исправление фактов.
  3. Управление справочниками регионов и категорий.
Готово, когда

Продуктовая команда управляет содержимым без участия разработчиков.

Как проверяем

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

3.45

Управление ключами программного интерфейса

Админ-часть1 backend3 нед.зависит от 3.17
Зачем

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

Что делаем
  1. Список ключей с тарифом, потреблением и остатком квоты.
  2. Блокировка и разблокировка с обоснованием.
  3. Оповещения о всплесках потребления.
Готово, когда

Ключи управляются из интерфейса, всплески видны.

Как проверяем

Всплеск потребления по ключу виден в интерфейсе в течение пяти минут, а не в конце месяца по счёту за трафик. Проверяется искусственным всплеском на тестовом ключе. Блокировка ключа вступает в силу немедленно и проверяется тем, что следующий запрос получает отказ, а не тем, что запись изменилась в базе.

Ворота фазы 3

Все критерии обязательны. Не пройдены — фаза продлевается, а не закрывается.

  • 2 млрд документов, обход 10 000 страниц в секунду
  • pFound@10 не ниже 0.62 на русском — целевой уровень программы
  • pFound@10 не ниже 0.58 на английском
  • Доля запросов без релевантных результатов не выше 3%
  • Задержка на p99 не выше 300 мс при 1500 запросах в секунду
  • Доступность 99.95% за квартал
  • Генеративный ответ: доля утверждений без подтверждения источником не выше 1%
  • Платформа заданий выдаёт не менее 10 000 оценок в неделю при согласии не ниже 0.6
  • Расширение для браузера: не менее 50 000 установок
  • 1 млн пользователей в месяц
  • 500 внешних сайтов в кабинете вебмастера, Метрика на 20 000 сайтов
  • Публичный программный интерфейс работает, есть платящие клиенты
  • 6000 наших страниц в индексе конкурентов, 2000 ссылающихся доменов

Фаза 4

Полнота

Месяцы
27–38
Календарь
ноя 2028 – окт 2029
Команда
70 чел.
Индекс
10 млрд
Бюджет
1.12 млрд ₽
Задач
27
Недель работ
372

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

Индекс и поиск 1

4.1

Индекс до 10 млрд документов

Индекс и поисккритический путь3 backend + 2 инфраструктура20 нед.зависит от 3.1
Зачем

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

Что делаем
  1. Расширение до примерно двухсот шардов с тройной репликацией.
  2. Переход векторного слоя на схему с кластеризацией поверх графа в памяти: по опубликованным замерам она вдвое быстрее предыдущей при той же полноте и той же памяти на трёхмиллиардных наборах.
  3. Пересмотр порогов между слоями индекса: доля горячего слоя при росте корпуса падает.
  4. Проверка, что время полной пересборки остаётся управляемым.
Готово, когда

10 млрд документов в индексе, задержка на p99 не выше 300 мс при шести тысячах запросов в секунду.

Как проверяем

Нагрузочный тест на целевом объёме и целевой нагрузке в течение суток.

Хранилища 2

4.26

Шардирование транзакционного слоя

Хранилища2 инфраструктура12 нед.зависит от 1.57, 3.52
Зачем

Один узел реляционной базы перестаёт справляться при миллионах аккаунтов и десятках тысяч сайтов в кабинете вебмастера.

Что делаем
  1. Замер реальной нагрузки и определение ключа шардирования: по пользователю или по организации.
  2. Выбор между шардированием текущей базы и переходом на распределённую транзакционную систему — решение принимается по данным фазы 3.
  3. Миграция без простоя с двойной записью и сверкой.
Готово, когда

Транзакционный слой выдерживает целевую нагрузку с запасом в три раза.

Как проверяем

Нагрузочный тест на утроенной от текущей нагрузке.

4.27

Переход на промышленное объектное хранилище

Хранилища2 инфраструктура10 нед.зависит от 1.58
Зачем

За пределами пятисот терабайт эксплуатационные свойства становятся важнее простоты: нужны предсказуемое восстановление, управление размещением и работа с деградированным кластером.

Что делаем
  1. Оценка текущего решения на целевых объёмах.
  2. Пробное развёртывание более зрелой альтернативы.
  3. Решение по данным, а не по репутации систем.
  4. Миграция при положительном решении.
Готово, когда

Решение принято и записано; при переходе миграция завершена без потерь.

Как проверяем

Проверка целостности всех объектов по контрольным суммам после миграции.

Продукт 12

4.2

Вертикаль «Товары»

Продукт4 вертикали20 нед.зависит от 1.13
Зачем

Транзакционные запросы — заметная доля трафика и почти вся коммерческая ценность поиска. Без товарной вертикали пользователь с намерением купить уходит целиком.

Что делаем
  1. Приём товарных фидов от магазинов через кабинет вебмастера.
  2. Извлечение товаров из структурированной разметки для тех, кто фид не даёт.
  3. Сопоставление одинаковых товаров разных продавцов.
  4. Карточка товара: цена, наличие, доставка, продавцы.
  5. Фильтры по цене, характеристикам, продавцу.
  6. Явное разделение органических карточек и рекламных предложений.
Готово, когда

Вертикаль работает, товары сопоставляются между продавцами.

Как проверяем

Асессорская проверка сопоставления на тысяче товаров: доля ошибочных объединений ниже двух процентов.

4.3

Вертикаль «Карты» на партнёрской картографии

Продукт3 вертикали18 нед.зависит от 1.45
Зачем

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

Что делаем
  1. Открытая картографическая подложка как основа, коммерческий фид как дополнение.
  2. Слой организаций строим свой — это и есть наша часть работы.
  3. Поиск организаций с фильтрами по категории, часам работы, рейтингу.
  4. Построение маршрутов через партнёрский сервис.
  5. Карточка организации в веб-выдаче на локальных запросах.
Готово, когда

Локальный поиск работает, организации находятся с картой.

Как проверяем

Корзина из пятисот локальных запросов по десяти городам.

4.13

Справочник организаций

Продукт3 вертикали16 нед.зависит от 4.3
Зачем

Основа локального поиска. Карточка с адресом, часами работы и телефоном отвечает на запрос полностью, без перехода на сайт.

Что делаем
  1. Сбор данных из открытых источников, разметки сайтов и заявок владельцев.
  2. Подтверждение владения организацией по телефону или почте на домене.
  3. Кабинет владельца: адрес, часы, телефон, фото, услуги.
  4. Разрешение конфликтов между источниками.
  5. Обнаружение закрывшихся организаций: устаревшая карточка хуже отсутствующей.
Готово, когда

Справочник наполнен по крупным городам, владельцы могут править свои карточки.

Как проверяем

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

4.14

Отзывы с рейтингом внутри категории

Продукт2 вертикали + 1 антиспам14 нед.зависит от 4.13
Зачем

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

Что делаем
  1. Отзывы только от подтверждённых аккаунтов с историей.
  2. Рейтинг считается внутри категории: иначе кафе сравниваются с автосервисами, и сравнение бессмысленно.
  3. Порог: рейтинг показывается от трёх оценок.
  4. Обязательное право владельца на публичный ответ.
  5. Публикация с задержкой и антинакруточные проверки.
  6. Процедура удаления отзыва по обоснованной жалобе.
Готово, когда

Отзывы работают, рейтинг считается внутри категории, накрутка обнаруживается.

Как проверяем

Учение: имитация накрутки на тестовой организации обнаруживается до публикации.

Риск

Отзывы — источник юридических претензий. Процедура рассмотрения жалоб и удаления должна быть готова и проверена юристом до запуска, а не после первой претензии.

4.6

Поиск по изображению как отдельный сценарий

Продукт2 вертикали + 1 ML8 нед.зависит от 2.16, I2.5, I4.1
Зачем

В вертикали картинок поиск по изображению — способ ввода (I2.4, I2.5). Как отдельный сценарий он решает другие задачи: узнать объект, найти товар, найти источник — и потому имеет собственную точку входа с главной и из мобильного приложения, а не только вкладку.

Что делаем
  1. Отдельная точка входа с главной страницы и из приложения, с загрузкой, перетаскиванием и вставкой из буфера.
  2. Ответ, собранный вокруг объекта: что это, похожие изображения, товар, источник и более крупные версии.
  3. Связь с распознаванием объектов (I4.1) и с товарной вертикалью (4.2).
  4. Поиск источника изображения: первоисточник и все известные носители (I2.9).
  5. Единое состояние с вертикалью: сценарий и вкладка не расходятся в результатах на одном и том же файле.
Готово, когда

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

Как проверяем

Корзина из трёхсот изображений с известным ожидаемым результатом: доля непустых верных ответов по каждому из четырёх блоков измеряется отдельно.

Риск

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

4.9

Колдунщики четвёртой фазы

Продукт2 вертикали10 нед.зависит от 4.2, 4.3
Зачем

Продолжение линии на плотность блоков с готовым ответом, теперь на данных партнёрских фидов.

Что делаем
  1. Спортивные результаты и расписания матчей.
  2. Расписания транспорта.
  3. Товарные предложения на транзакционных запросах.
  4. Карта и организации на локальных запросах.
  5. Соблюдение общего лимита блоков.
Готово, когда

Колдунщики работают на партнёрских данных, лимит соблюдается.

Как проверяем

Проверка актуальности данных партнёрских фидов: колдунщик на устаревших данных хуже отсутствующего, потому что показывает неверную цену или расписание с нашей подписью. Замеряется задержка от изменения у партнёра до изменения в выдаче, и она входит в критерий приёмки наравне с долей покрытия.

4.4

Мобильные приложения

Продукткритический путь6 мобильная разработка24 нед.зависит от 3.17
Зачем

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

Что делаем
  1. Приложения для двух платформ с общей логикой и нативными интерфейсами.
  2. Поиск, вертикали, аккаунт, коллекции.
  3. Голосовой ввод и поиск по камере.
  4. Виджет на домашнем экране.
  5. Возможность установки поиском по умолчанию там, где платформа это позволяет.
  6. Работа в офлайне для сохранённого содержимого.
Готово, когда

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

Как проверяем

Оценка в магазинах не ниже 4.3; доля удалений в первую неделю ниже двадцати пяти процентов.

4.16

Озвучивание ответов

Продукт1 мобильная разработка6 нед.зависит от 4.5
Зачем

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

Что делаем
  1. Синтез речи для быстрых ответов и генеративного блока.
  2. Управление воспроизведением.
  3. Отключаемость в настройках.
Готово, когда

Ответы озвучиваются в мобильных приложениях.

Как проверяем

Разборчивость проверяется на записях: слушатели, не видевшие текста, воспроизводят факты из ответа. Отдельно — обработка того, что произносится плохо: адреса, номера, сокращения и иноязычные названия проверяются списком, а не выборочно, потому что именно на них озвучивание и ломается.

4.7

Организации в Yottis ID

Продукт2 backend + 1 фронтенд14 нед.зависит от 1.29, 2.24
Зачем

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

Что делаем
  1. Организация как контейнер для сайтов, ключей и участников.
  2. Единый вход через корпоративные системы аутентификации.
  3. Роли внутри организации с раздельными правами.
  4. Журнал действий участников.
  5. Централизованная оплата.
Готово, когда

Организации работают, единый вход подключается.

Как проверяем

Сквозной сценарий: создание организации, приглашение участников, передача сайта, отзыв доступа.

4.8

Программный интерфейс кабинета вебмастера

Продукт2 backend12 нед.зависит от 3.17, 2.24
Зачем

Агентства и крупные сайты работают с данными программно; ручная выгрузка для них неприемлема.

Что делаем
  1. Эндпоинты: список сайтов, отчёт по запросам, статус индексации, ссылки, отправка на переобход.
  2. Приём пуша об изменениях в промышленном режиме с квотами по правам.
  3. Аутентификация и разграничение по ролям организации.
  4. Документация и примеры.
Готово, когда

Интерфейс работает, квоты соблюдаются.

Как проверяем

Внешняя интеграция от партнёрского агентства проходит без правок с нашей стороны.

4.11

Рекламная система

Продукт4 продукт + 2 backend24 нед.зависит от 3.17
Зачем

Основная монетизация поиска. Ставится последней сознательно: реклама создаёт конфликт интересов с качеством выдачи, и запускать её до того, как качество набрано, — значит подменить цель.

Что делаем
  1. Отдельный сервис показа рекламы, не смешанный с органикой ни в коде, ни в логах.
  2. Явная маркировка каждого объявления и указание рекламодателя.
  3. Не более трёх блоков сверху; первый органический результат не уходит за первый экран.
  4. Аукцион и кабинет рекламодателя.
  5. Регистрация креативов в учётной системе согласно требованиям законодательства.
  6. Отдельный контроль: доля кликов по органике не должна падать после запуска.
Готово, когда

Реклама работает, маркировка соблюдается, требования законодательства выполнены.

Как проверяем

Замер доли органических кликов до и после запуска: падение больше пяти процентов означает, что реклама вытесняет органику, и объём блоков сокращается.

Риск

Реклама подменяет цель: команда начинает оптимизировать доход вместо качества. Смягчение — метрики качества остаются главными в системе целей, а доля органических кликов контролируется отдельно.

4.17

Тарифные планы и биллинг

Продукт2 backend10 нед.зависит от 3.17, 4.7
Зачем

Программный интерфейс без биллинга не приносит денег, а ручное выставление счетов не масштабируется.

Что делаем
  1. Тарифные планы с квотами и лимитами.
  2. Учёт потребления и выставление счетов.
  3. Оплата и документы для юридических лиц.
  4. Уведомления о приближении к лимиту.
Готово, когда

Биллинг работает, счета выставляются автоматически.

Как проверяем

Сверка счёта с фактическим потреблением на выборке аккаунтов — расхождение в биллинге обнаруживается клиентом раньше, чем нами, и стоит доверия. Отдельно проверяются пограничные случаи: переход между тарифами в середине периода, возврат, частичный месяц. Именно они и ломаются, а не обычное списание.

Регион и гео 3

4.15

Локальные признаки в ранжировании

Регион и гео2 ML10 нед.зависит от 4.13, 3.12
Зачем

Наличие карточек мало — нужно, чтобы на локальном запросе поднимались ближайшие и работающие сейчас организации.

Что делаем
  1. Признаки: расстояние, рейтинг, полнота карточки, актуальность часов, наличие сайта.
  2. Учёт времени запроса: закрытая сейчас организация понижается.
  3. Отдельная модель для локального класса запросов.
Готово, когда

Локальные запросы отвечают ближайшими работающими организациями.

Как проверяем

Асессорская корзина локальных запросов с оценкой по расстоянию и актуальности.

4.21

Собственная база соответствия адресов и регионов

Регион и гео2 ML + 1 backend14 нед.зависит от 2.30, 2.43
Зачем

Потолок точности покупных баз на уровне города — около восьмидесяти пяти процентов, и это предел их данных. У нас появляются собственные данные из аналитики и обхода, и на домашнем рынке они точнее.

Что делаем
  1. Сбор соответствий из явных выборов региона пользователями.
  2. Сбор из данных аналитики на сайтах с известной географией.
  3. Обучение модели соответствия подсети и региона.
  4. Гибрид: своя база для России и стран СНГ, покупная для остального мира.
  5. Постоянная проверка по доле ручных смен региона.
Готово, когда

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

Как проверяем

Сравнение доли ручных смен региона до и после по каждому городу.

4.22

Районы городов в справочнике

Регион и гео1 backend8 нед.зависит от 1.45, 4.13
Зачем

В крупных городах город как единица слишком крупный: «шиномонтаж» в Москве без уточнения района отвечает бесполезно.

Что делаем
  1. Иерархия районов для городов свыше миллиона жителей.
  2. Распознавание районов и станций транспорта в запросе.
  3. Учёт района в локальном ранжировании.
Готово, когда

Районы в справочнике, распознаются в запросе, влияют на выдачу.

Как проверяем

Корзина локальных запросов с указанием района: результат своего района поднимается, результат соседнего не отсекается — район уточняет, но не ограничивает. Отдельно проверяется распознавание разговорных названий районов, которых нет в официальном справочнике, но которыми пользуются все.

ИИ-структура 4

4.5

Собственное распознавание речи

ИИ-структура2 ML14 нед.зависит от 2.37
Зачем

Браузерный интерфейс распознавания зависит от платформы, работает не везде и передаёт голос третьей стороне. Своё распознавание снимает все три проблемы.

Что делаем
  1. Модель распознавания для русского и английского.
  2. Инференс на устройстве там, где это возможно, на сервере в остальных случаях.
  3. Адаптация под поисковые запросы: они короткие и содержат имена собственные.
  4. Голос не сохраняется после распознавания.
Готово, когда

Своё распознавание заменило браузерное, доля ошибок на словах не выше пятнадцати процентов.

Как проверяем

Замер на размеченном наборе голосовых запросов.

4.23

Слот реранкинга большой моделью

ИИ-структура2 ML12 нед.зависит от 1.55, 2.53, 3.10
Зачем

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

Что делаем
  1. Классификатор сложности запроса: модель вызывается только там, где она нужна.
  2. Реранкинг топ-10 большой моделью.
  3. Доля трафика не выше двух процентов — параметр управляемый, а не следствие.
  4. Жёсткий бюджет стоимости с автоматическим отключением при превышении.
Готово, когда

Слот работает на выбранной доле трафика, прирост качества на сложных запросах измерен.

Как проверяем

Отдельный замер на корзине сложных запросов; общая стоимость в пределах бюджета.

4.24

Абстрактивные сниппеты

ИИ-структура2 ML12 нед.зависит от 2.53, 3.10
Зачем

Извлечённый фрагмент иногда плохо отвечает на запрос: ответ разбросан по странице или сформулирован иначе. Сгенерированный сниппет решает это, но требует той же строгости, что и генеративный ответ.

Что делаем
  1. Классификатор: где извлечённый сниппет плох.
  2. Генерация сниппета строго по содержимому страницы.
  3. Проверка обоснованности: сниппет не может утверждать того, чего на странице нет.
  4. Пометка сгенерированных сниппетов.
  5. Отбрасываемость по таймауту с возвратом к извлечённому.
Готово, когда

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

Как проверяем

Асессорская проверка двухсот сгенерированных сниппетов на соответствие странице.

4.25

Помощник в админ-части

ИИ-структура1 ML + 1 фронтенд10 нед.зависит от 2.53, 2.48
Зачем

Аналитик тратит часы на составление запросов к логам. Запрос на естественном языке сокращает это до минут и снимает зависимость от знания схемы данных.

Что делаем
  1. Перевод вопроса на естественном языке в запрос к аналитическому хранилищу.
  2. Показ сгенерированного запроса перед выполнением: доверять, но проверять.
  3. Ограничение прав: помощник не может обращаться к персональным данным.
  4. Журналирование всех запросов.
Готово, когда

Помощник отвечает на типовые вопросы, сгенерированный запрос виден до выполнения.

Как проверяем

На пятидесяти типовых вопросах доля корректных запросов не ниже восьмидесяти процентов.

Многоязычие 2

4.10

Кластеры западной и восточной латиницы

Многоязычие4 многоязычие20 нед.зависит от 3.34, 3.36
Зачем

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

Что делаем
  1. Токенизация и нормализация с учётом диакритики.
  2. Стемминг по каждому языку.
  3. Разбиение сложных слов для немецкого: без него половина запросов не находится.
  4. Обработка агглютинации для турецкого и венгерского.
  5. Обход соответствующих сегментов веба.
Готово, когда

Одиннадцать языков в индексе с работающей обработкой.

Как проверяем

Корзина из тысячи запросов на язык с локальными асессорами.

4.20

Правило регионального размещения кластеров

Многоязычие1 backend + 1 инфраструктура8 нед.зависит от 4.19
Зачем

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

Что делаем
  1. Расчёт спроса на языковые кластеры по регионам из логов.
  2. Автоматическое решение о размещении кластера в регионе.
  3. Обслуживание редких для региона запросов из центрального дата-центра с повышенной задержкой.
  4. Метрика доли запросов, ушедших в центр.
Готово, когда

Правило работает, экономия на дисках измерена.

Как проверяем

Доля запросов, обслуженных из центра, не выше двух процентов в каждом регионе.

Качество 1

4.18

Корзины и асессоры по новым языкам

Качество2 качество16 нед.зависит от 4.10, 3.25
Зачем

Качество на языке без корзины не измеряется, а значит, не управляется. Заявлять поддержку языка без замера — обман.

Что делаем
  1. По тысяче запросов на каждый новый язык.
  2. Пул асессоров-носителей через платформу заданий.
  3. Перевод и адаптация руководства асессора.
  4. Отдельный автозамер по каждому языку.
Готово, когда

По каждому языку есть корзина, асессоры и ежедневный замер.

Как проверяем

Согласие асессоров по каждому языку не ниже 0.6.

Инфраструктура 1

4.19

Точка присутствия в Европе

Инфраструктура2 инфраструктура14 нед.зависит от 3.6, 4.10
Зачем

Скорость — это ещё и физика: сигнал из Москвы во Франкфурт и обратно занимает заметную долю бюджета задержки.

Что делаем
  1. Развёртывание полного онлайн-контура в европейской точке.
  2. Маршрутизация европейского трафика по географии.
  3. Размещение горячего и тёплого слоёв только для кластеров, которые в этом регионе спрашивают.
  4. Соблюдение требований европейского законодательства к данным.
Готово, когда

Европейский трафик обслуживается локально, задержка на p99 не выше 300 мс.

Как проверяем

Замер задержки из европейских точек мониторинга.

Ранжирование 1

4.12

Расширение до 1000 признаков с автоматическим отсевом

Ранжирование3 ML16 нед.зависит от 3.11, 2.1
Зачем

Реестр признаков растёт, и ручная ревизия перестаёт справляться. Урок из утечки кода конкурента прямой: без автоматики треть признаков мертва в любой момент.

Что делаем
  1. Новые группы признаков: товарные, локальные, многоязычные, поведенческие второго порядка.
  2. Автоматический расчёт важности при каждом обучении.
  3. Автоматический перевод признака в кандидаты на удаление после трёх обучений с нулевым вкладом.
  4. Автоматическое отключение по дате протухания.
Готово, когда

Около тысячи признаков, доля мёртвых не выше десяти процентов.

Как проверяем

Ежемесячный отчёт реестра: число активных, кандидатов на удаление, отключённых.

Ворота фазы 4

Все критерии обязательны. Не пройдены — фаза продлевается, а не закрывается.

  • 10 млрд документов, обход 40 000 страниц в секунду
  • pFound@10 не ниже 0.66 на русском, не ниже 0.62 на английском
  • Задержка на p99 не выше 300 мс при 6000 запросах в секунду
  • 5 млн пользователей в месяц, доля мобильного трафика не ниже 50%
  • Одиннадцать языков в индексе с измеренным качеством по каждому
  • Метрика установлена на 100 000 внешних сайтов
  • Справочник организаций наполнен по городам свыше пятисот тысяч жителей
  • Доля неактуальных карточек организаций ниже 5%
  • Мобильные приложения: оценка в магазинах не ниже 4.3
  • Доля органических кликов не упала после запуска рекламы больше чем на 5%

Фаза 5

Зрелость

Месяцы
39–50
Календарь
ноя 2029 – окт 2030
Команда
100 чел.
Индекс
30 млрд
Бюджет
2.0 млрд ₽
Задач
16
Недель работ
276

Паритет качества с лидерами на целевых сегментах и выход за пределы домашнего рынка. К этому моменту продукт работает и им пользуются; задача фазы — перестать быть локальным решением.

Индекс и поиск 1

5.1

Индекс до 30 млрд документов

Индекс и поисккритический путь4 backend + 3 инфраструктура24 нед.зависит от 4.1
Зачем

Трёхкратный рост корпуса и переход к по-настоящему многоязычному индексу. На этом объёме стоимость становится определяющим фактором архитектурных решений.

Что делаем
  1. Расширение парка и числа шардов.
  2. Пересмотр соотношения слоёв индекса: горячий слой в долях от корпуса продолжает уменьшаться.
  3. Оптимизация стоимости запроса как самостоятельная задача: она определяет юнит-экономику.
  4. Проверка, что операции обслуживания — пересборка, перебалансировка, восстановление — остаются выполнимыми.
Готово, когда

30 млрд документов, задержка на p99 не выше 280 мс при двадцати тысячах запросов в секунду.

Как проверяем

Нагрузочный тест на целевой нагрузке; замер стоимости обслуживания одного запроса.

Многоязычие 3

5.9

Сегментация иероглифических языков

Многоязычиекритический путь6 отдельная команда24 нед.зависит от 3.34
Зачем

Самая дорогая часть всемирного поиска. Без сегментации иероглифический текст невозможно ни проиндексировать, ни найти.

Что делаем
  1. Словарные и статистические сегментаторы для китайского, японского и корейского.
  2. Индексация биграмм как страховка на случаях, где сегментатор ошибся: это удваивает размер постингов для кластера, и в расчёте ёмкости учтено.
  3. Обработка смешанного текста: иероглифика вперемешку с латиницей встречается постоянно.
  4. Традиционное и упрощённое письмо как варианты одного языка.
Готово, когда

Три языка индексируются, поиск работает.

Как проверяем

Корзина из тысячи запросов на язык с носителями-асессорами.

Риск

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

5.10

Модели эмбеддингов для иероглифических языков

Многоязычие4 отдельная команда18 нед.зависит от 5.9, 3.38
Зачем

Общая многоязычная модель на иероглифике работает заметно хуже, чем на латинице и кириллице: слишком велика разница в структуре языка.

Что делаем
  1. Отдельная модель эмбеддингов для кластера.
  2. Связывание с общим пространством через язык-мост для кросс-языкового поиска.
  3. Дообучение на собственных данных по мере накопления.
Готово, когда

Семантический поиск на иероглифических языках работает.

Как проверяем

Замер на открытых многоязычных наборах для этих языков.

5.12

Кластер письма справа налево

Многоязычие3 многоязычие16 нед.зависит от 3.34
Зачем

Арабский и иврит требуют не только обработки текста, но и перестройки интерфейса: направление письма меняет всю вёрстку.

Что делаем
  1. Нормализация огласовок и вариантов написания.
  2. Корневая морфология для арабского.
  3. Зеркальная вёрстка интерфейса и корректная подсветка в сниппетах.
  4. Обработка смешанного текста с латиницей.
Готово, когда

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

Как проверяем

Проверка носителями: вёрстка, подсветка, порядок элементов.

Инфраструктура 2

5.11

Точка присутствия в Азии

Инфраструктура3 инфраструктура16 нед.зависит от 4.19, 5.9
Зачем

Задержка из Европы в Азию перекрывает весь бюджет: без локальной точки присутствия поиск для азиатского пользователя непригоден.

Что делаем
  1. Развёртывание полного онлайн-контура.
  2. Размещение иероглифического кластера локально.
  3. Маршрутизация трафика по географии.
  4. Соблюдение местных требований к данным.
Готово, когда

Азиатский трафик обслуживается локально, задержка на p99 не выше 300 мс.

Как проверяем

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

5.5

Третий дата-центр и международная инфраструктура

Инфраструктура4 инфраструктура20 нед.зависит от 4.19, 5.11
Зачем

Три площадки дают устойчивость к потере любой одной без деградации и покрывают три часовых пояса дежурством.

Что делаем
  1. Развёртывание третьей площадки.
  2. Пересмотр схемы репликации под три центра.
  3. Дежурство по принципу следования за солнцем.
  4. Регулярные учения по отказу каждой площадки.
Готово, когда

Три центра работают, потеря любого не приводит к деградации.

Как проверяем

Учения по отказу каждой площадки по очереди.

Качество 2

5.13

Корзины и асессоры по языкам пятой волны

Качество3 качество20 нед.зависит от 5.9, 5.12, 3.25
Зачем

Тот же принцип: язык без корзины и асессоров не измеряется, а значит, поддержка его заявлена, но не подтверждена.

Что делаем
  1. По тысяче запросов на язык.
  2. Пул асессоров-носителей через платформу заданий.
  3. Адаптация руководства с учётом культурной специфики: понятие релевантности в разных культурах различается сильнее, чем кажется.
  4. Отдельный автозамер.
Готово, когда

По каждому языку есть корзина, асессоры и замер.

Как проверяем

Согласие асессоров не ниже 0.6 по каждому языку.

5.7

Автоматизация цикла улучшения качества

Качество3 ML16 нед.зависит от 3.26, 3.41
Зачем

Признак зрелости организации — не размер индекса, а время от гипотезы до выката. Организация, у которой этот цикл занимает квартал, проигрывает независимо от качества инженеров.

Что делаем
  1. Автоматизация всех шагов цикла: задание на разметку, сбор оценок, переобучение, офлайн-замер, интерливинг, выкатка через флаг.
  2. Автоматический переход между шагами при прохождении порогов.
  3. Ручное вмешательство только на принятии решения о выкатке на весь трафик.
  4. Замер длительности цикла как отдельного показателя.
Готово, когда

Полный цикл от гипотезы до выката на весь трафик занимает не более трёх недель.

Как проверяем

Замер на двадцати последовательных гипотезах.

ИИ-структура 2

5.2

Мультимодальный поиск

ИИ-структура4 ML20 нед.зависит от 4.6, 3.38
Зачем

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

Что делаем
  1. Общее пространство представлений для текста и изображений.
  2. Комбинированный запрос: изображение плюс уточнение текстом.
  3. Интерфейс уточнения в мобильных приложениях и вебе.
Готово, когда

Комбинированный запрос работает, качество измерено.

Как проверяем

Корзина из пятисот комбинированных запросов.

5.3

Диалоговое уточнение запроса

ИИ-структура3 ML + 2 фронтенд18 нед.зависит от 3.13
Зачем

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

Что делаем
  1. Определение неоднозначности запроса.
  2. Уточняющий вопрос с вариантами, а не свободным полем.
  3. Сохранение контекста в пределах сессии.
  4. Полная отключаемость: пользователь может никогда этого не видеть.
Готово, когда

Уточнение работает на неоднозначных запросах, отключается в настройках.

Как проверяем

Доля успешных сессий на неоднозначных запросах растёт; на однозначных уточнение не появляется.

Продукт 2

5.4

Вертикаль научных публикаций

Продукт3 вертикали16 нед.зависит от 2.19
Зачем

Научный поиск — узкая, но лояльная аудитория, и он даёт ссылки из академической среды, которые невозможно получить иначе.

Что делаем
  1. Приём открытых научных метаданных.
  2. Связывание версий: препринт, публикация, издательская версия.
  3. Индекс цитирований.
  4. Фильтры по году, журналу, автору, доступности полного текста.
Готово, когда

Вертикаль работает, версии связаны.

Как проверяем

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

5.14

Диалоговое уточнение в выдаче

Продукт2 фронтенд10 нед.зависит от 5.3
Зачем

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

Что делаем
  1. Компактный блок уточнения над выдачей, не вытесняющий результаты.
  2. Уточнение одним кликом, без ввода текста.
  3. Возможность игнорировать: выдача полноценна и без уточнения.
  4. Запоминание отказа от уточнений.
Готово, когда

Блок работает, отключается, не вытесняет органику.

Как проверяем

Доля кликов по органике не падает после включения блока.

Ранжирование 1

5.8

Реестр признаков с полным автоматическим циклом

Ранжирование2 ML12 нед.зависит от 4.12
Зачем

Полторы тысячи признаков вручную не сопровождаются: любая ручная процедура на таком объёме превращается в формальность.

Что делаем
  1. Автоматическое добавление признака в реестр при первом использовании.
  2. Автоматический расчёт важности, стоимости и корреляции с существующими.
  3. Автоматическое предупреждение владельцу о приближении даты протухания.
  4. Автоматическое отключение и удаление по регламенту.
Готово, когда

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

Как проверяем

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

Почта 1

5.15

Суммаризация в почте локальными моделями

Почта2 ML12 нед.зависит от 2.56
Зачем

Пересказ длинной переписки — заметная экономия времени. Но содержимое писем не покидает почтовый контур ни при каких условиях, поэтому только локальные модели.

Что делаем
  1. Компактная модель суммаризации, работающая внутри почтового контура.
  2. Пересказ длинного письма и пересказ треда.
  3. Полная отключаемость.
  4. Техническая невозможность передачи содержимого во внешние интерфейсы, проверяемая шлюзом моделей.
Готово, когда

Суммаризация работает, содержимое не покидает контур.

Как проверяем

Аудит сетевых обращений почтового контура: обращений к внешним интерфейсам моделей нет.

Ворота фазы 5

Все критерии обязательны. Не пройдены — фаза продлевается, а не закрывается.

  • 30 млрд документов, обход 100 000 страниц в секунду
  • pFound@10 не ниже 0.70 на русском, 0.65 на английском, 0.50 на иероглифических языках
  • Задержка на p99 не выше 280 мс при 20 000 запросах в секунду
  • 20 млн пользователей в месяц
  • Положительная юнит-экономика
  • Соответствие европейскому регулированию подтверждено внешним аудитом
  • Цикл от гипотезы до выката не более трёх недель
  • Потеря любого из трёх дата-центров не приводит к деградации

Фаза 6

Развитие

Месяцы
51+
Календарь
с ноя 2030
Команда
120 чел.
Задач
10
Недель работ
0

Непрерывный цикл без фиксированного конца. Фаза 6 отличается от предыдущих принципиально: у неё нет ворот выхода, потому что выходить некуда — есть только поддержание и улучшение.

Ранжирование 1

6.1

Непрерывное улучшение ранжирования

Ранжирование12 MLзависит от 5.7
Зачем

Качество поиска не имеет предела и не сохраняется само: веб меняется, запросы меняются, конкуренты улучшаются.

Что делаем
  1. Ежеквартальные обновления ядра ранжирования.
  2. Постоянный поток гипотез из разбора запросов и обратной связи.
  3. Обновление моделей по мере появления новых архитектур.
  4. Строгое соблюдение порогов: изменение, ухудшающее любую метрику ворот, не выкатывается.
Готово, когда

Показатель непрерывный: pFound растёт или удерживается каждый квартал.

Как проверяем

Квартальный отчёт по качеству с разбивкой по классам запросов и языкам.

Индекс и поиск 1

6.2

Рост индекса и добавление языков

Индекс и поиск8 backendзависит от 5.1
Зачем

Покрытие — половина качества: документ, которого нет в индексе, нельзя показать никаким ранжированием.

Что делаем
  1. Рост корпуса по мере роста веба.
  2. Добавление языков по мере появления спроса, а не по списку.
  3. Каждый новый язык проходит полный цикл: обработка, корзина, асессоры, замер.
Готово, когда

Показатель непрерывный: покрытие топ-3 конкурента не ниже девяноста пяти процентов на каждом заявленном языке.

Как проверяем

Ежеквартальный замер покрытия по каждому языку.

Обход 1

6.3

Сокращение задержки индексации

Обход6 backendзависит от 1.18, 3.3
Зачем

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

Что делаем
  1. Сокращение задержки от публикации до появления в индексе.
  2. Расширение пуш-механизмов и партнёрских каналов уведомлений.
  3. Приоритизация источников с высокой частотой публикаций.
Готово, когда

Показатель непрерывный: задержка индексации новости не растёт при росте корпуса.

Как проверяем

Ежемесячный замер на ста публикациях крупных изданий.

Антиспам 1

6.4

Антиспам как непрерывная гонка

Антиспам8 антиспамзависит от 2.12, 3.9
Зачем

Единственное направление, где противник адаптируется в ответ на наши действия. Здесь не бывает состояния «сделано»: любое улучшение антиспама порождает новый обходной приём.

Что делаем
  1. Постоянный мониторинг новых приёмов манипуляции.
  2. Ежемесячное переобучение классификаторов.
  3. Теневой режим перед каждым изменением порогов.
  4. Разбор каждого случая массового пропуска и каждого ложного срабатывания.
Готово, когда

Показатель непрерывный: точность и полнота не деградируют квартал к кварталу.

Как проверяем

Квартальный замер на обновляемой тестовой выборке, включающей новые приёмы.

Продукт 2

6.5

Развитие продукта по данным о запросах

Продукт10 продуктзависит от 2.48
Зачем

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

Что делаем
  1. Регулярный анализ запросов без хорошего ответа.
  2. Приоритизация новых блоков и вертикалей по объёму такого спроса.
  3. Отказ от блоков с низкой пользой: колдунщик, которым не пользуются, занимает место.
Готово, когда

Показатель непрерывный: доля запросов без хорошего ответа снижается.

Как проверяем

Ежеквартальный разбор топ-1000 запросов с плохой выдачей.

6.9

Развитие каналов дистрибуции

Продукт6 продуктзависит от 3.18, 4.4
Зачем

Каналы дистрибуции устаревают: магазины расширений меняют правила, платформы меняют политику поиска по умолчанию.

Что делаем
  1. Поддержание существующих каналов при изменении правил платформ.
  2. Поиск новых каналов по мере их появления.
  3. Партнёрские интеграции.
  4. Отслеживание источников новых пользователей.
Готово, когда

Показатель непрерывный: приток новых пользователей не зависит критически от одного канала.

Как проверяем

Доля крупнейшего канала в притоке не выше сорока процентов.

Инфраструктура 2

6.6

Снижение стоимости запроса

Инфраструктура8 инфраструктуразависит от 5.1
Зачем

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

Что делаем
  1. Стоимость запроса как отслеживаемый показатель наравне с задержкой.
  2. Оптимизация самых дорогих этапов по данным профилирования.
  3. Пересмотр долей трафика для дорогих функций.
  4. Обновление парка с расчётом окупаемости.
Готово, когда

Показатель непрерывный: стоимость запроса снижается год к году при росте качества.

Как проверяем

Ежеквартальный расчёт полной стоимости обслуживания запроса.

6.10

Поддержание эксплуатационной надёжности

Инфраструктура6 эксплуатациязависит от 3.20, 5.5
Зачем

Надёжность деградирует сама по себе: система усложняется, люди меняются, знания теряются.

Что делаем
  1. Регулярные учения по отказам, включая неожиданные для дежурных.
  2. Разбор каждого инцидента без поиска виновных, с обязательными действиями по итогам.
  3. Актуализация регламентов и документации.
  4. Соблюдение бюджета ошибок: при исчерпании выкатки останавливаются.
Готово, когда

Показатель непрерывный: доступность не ниже целевой каждый квартал.

Как проверяем

Квартальный отчёт по доступности и по выполнению действий из разборов инцидентов.

ИИ-структура 1

6.8

Развитие структуры под ИИ

ИИ-структура6 MLзависит от 2.53, 4.23
Зачем

Архитектура шлюза и слотов рассчитана на добавление функций, но сами модели устаревают быстро, и реестр требует постоянного обновления.

Что делаем
  1. Замена моделей на более качественные по мере их появления.
  2. Включение зарезервированных слотов по мере созревания технологии и экономики.
  3. Ревизия реестра моделей: отключение устаревших.
  4. Пересмотр политики данных при появлении новых классов задач.
Готово, когда

Показатель непрерывный: ни одна модель в проде не старше двух лет без обоснования.

Как проверяем

Ежеквартальная ревизия реестра моделей.

Параллельный трек

Почта

Месяцы
трек
Календарь
с фазы 2
Команда
22 чел.
Бюджет
470 млн ₽
Задач
56
Недель работ
386

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

Почта 50

M0.4

Подготовка почтовых записей домена

Почтаинфраструктура2 нед.зависит от 0.13
Зачем

Записи домена нужно спланировать до запуска, а одну существующую — обязательно заменить.

Что делаем
  1. Проверка домена как почтового: не был ли он ранее в чёрных списках.
  2. План записей: обмен почтой, подписи, политики, транспортная безопасность.
  3. Резервирование адресов для приёмников и отправителей.
  4. План замены существующей записи политики отправки: сейчас она означает, что домен почту не отправляет, и с запуском почты собственные письма начнут отвергаться.
Готово, когда

План записей готов, домен проверен на историю в чёрных списках.

Как проверяем

Проверка домена по основным чёрным спискам: записей нет.

M1.1

Приём почты

Почтакритический путь2 backend6 нед.зависит от M0.6
Зачем

Основная точка входа. Ошибка здесь означает потерянные письма, а потерянное письмо разрушает доверие навсегда.

Что делаем
  1. Приём на стандартном порту с корректной обработкой всех кодов ответа.
  2. Лимиты по отправителю, по соединению, по числу получателей.
  3. Отложенный первый приём для новых отправителей как дешёвый фильтр массовых рассылок.
  4. Отказ на этапе приёма для явного спама: это дешевле, чем принять и удалить.
  5. Заимствование решений из открытого сервера с подходящей лицензией.
Готово, когда

Приём работает, лимиты соблюдаются, коды ответов корректны.

Как проверяем

Внешние проверочные сервисы не находят замечаний к поведению приёмника.

M1.2

Аутентификация отправителя на приёме

Почтакритический путь2 backend7 нед.зависит от M1.1
Зачем

Без проверки подлинности отправителя невозможно ни отличить фишинг от настоящего письма, ни защитить своих пользователей.

Что делаем
  1. Проверка политики отправки домена.
  2. Проверка цифровой подписи письма.
  3. Проверка согласованности домена в видимом поле отправителя с прошедшим проверку — это отдельное требование, и его чаще всего нарушают.
  4. Цепочка проверок для пересланных писем: без неё письма из списков рассылки ломают проверку подлинности.
  5. Отчёты о результатах проверок отправителям.
Готово, когда

Все четыре проверки работают, отчёты отправляются.

Как проверяем

Тестовые письма с корректной и с подделанной аутентификацией обрабатываются верно во всех комбинациях.

M1.3

Отправка почты

Почтакритический путь2 backend8 нед.зависит от M0.6
Зачем

Отправка сложнее приёма: нужны очереди, повторы, управление репутацией адресов и обработка отказов принимающих сторон.

Что делаем
  1. Очереди с повторами и растущими интервалами.
  2. Разбор отказов: временный отказ и постоянный обрабатываются по-разному.
  3. Пулы адресов отправки.
  4. Раздельные пулы для транзакционных писем и рассылок: проблема с рассылкой не должна ронять доставку кодов входа.
  5. Подпись всех исходящих писем.
Готово, когда

Отправка работает, очереди не растут неограниченно, отказы разбираются.

Как проверяем

Учение: недоступный принимающий сервер — письма не теряются и уходят после восстановления.

M1.4

Транспортная безопасность

Почта1 backend5 нед.зависит от M1.1, M1.3
Зачем

Без обязательного шифрования транспорта письмо можно перехватить и подменить по пути. Крупные провайдеры это учитывают при оценке отправителя.

Что делаем
  1. Политика обязательного шифрования при передаче.
  2. Привязка сертификатов к записям домена там, где это возможно.
  3. Отчёты о проблемах с шифрованием.
  4. Приём и разбор таких отчётов от других серверов.
Готово, когда

Политики опубликованы, отчёты принимаются и отправляются.

Как проверяем

Внешние проверочные сервисы подтверждают корректность всех политик.

M1.5

Отправка от пользователей

Почта1 backend4 нед.зависит от M1.3, 1.29
Зачем

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

Что делаем
  1. Приём на портах отправки с обязательной аутентификацией через Yottis ID.
  2. Лимиты отправки по аккаунту с учётом возраста аккаунта.
  3. Подпись писем от имени пользователя.
  4. Проверка, что пользователь отправляет от своего адреса.
Готово, когда

Отправка из внешних клиентов работает, лимиты соблюдаются.

Как проверяем

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

M1.6

Доступ по протоколу почтовых ящиков

Почтакритический путь2 backend8 нед.зависит от M1.8
Зачем

Без поддержки стандартного протокола доступа люди не переезжают: они не готовы менять привычный клиент вместе с почтой.

Что делаем
  1. Полная реализация современной версии протокола.
  2. Поддержка папок, флагов, поиска, частичной загрузки.
  3. Уведомления об изменениях без опроса.
  4. Проверка совместимости с распространёнными клиентами.
Готово, когда

Протокол работает, проверен на пяти распространённых клиентах.

Как проверяем

Переезд ящика в сто тысяч писем из внешнего сервиса проходит без потерь.

M1.7

Совместимость со старым протоколом

Почта1 backend3 нед.зависит от M1.8
Зачем

Часть корпоративных клиентов и устройств поддерживает только его.

Что делаем
  1. Реализация протокола на стандартных портах с обязательным шифрованием канала. 2. Ограничения по умолчанию: протокол не поддерживает папки и синхронизацию, и это надо показывать пользователю при включении, а не оставлять на его догадливость. 3. Отключение по умолчанию для новых аккаунтов: включает тот, кому он действительно нужен. 4. Отдельные лимиты и отдельный журнал — старые протоколы чаще становятся вектором подбора паролей, чем современные.
Готово, когда

Протокол работает, проверен на трёх клиентах.

Как проверяем

Проверка на трёх реальных клиентах разных поколений, включая устройство без обновлений, ради которого протокол и поддерживается. Отдельно — попытка подбора пароля через этот протокол обязана упираться в те же ограничения, что и через основной вход: старый протокол не должен быть обходным путём вокруг защиты аккаунта.

M1.8

Хранилище метаданных

Почтакритический путь2 backend7 нед.зависит от M0.6
Зачем

Метаданные — заголовки, флаги, папки, треды, размеры — читаются постоянно мелкими порциями: открытие списка писем это сотни строк. Нужна база с быстрым произвольным чтением и транзакциями.

Что делаем
  1. Реляционное хранилище с шардированием по ящику.
  2. Схема: письма, папки, флаги, треды, вложения по ссылке.
  3. Транзакционность операций перемещения и удаления.
  4. Индексы по времени: у ящиков свыше десяти тысяч писем обращения идут почти только к свежему.
Готово, когда

Метаданные хранятся, шардирование работает, операции транзакционны.

Как проверяем

Нагрузочный тест на ящике в миллион писем: открытие списка не дольше 200 мс.

M1.9

Хранилище тел писем и вложений

Почта2 backend6 нед.зависит от M1.8
Зачем

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

Что делаем
  1. Объектное хранилище для тел и вложений.
  2. Дедупликация вложений по содержимому: одна презентация на пятьсот адресов при наивном хранении займёт место пятьсот раз.
  3. Счётчик ссылок на объект и безопасное удаление.
  4. Шифрование в покое.
Готово, когда

Тела хранятся отдельно, дедупликация работает.

Как проверяем

На корпоративном потоке дедупликация экономит не менее тридцати процентов объёма.

M1.10

Треды

Почта1 backend4 нед.зависит от M1.8
Зачем

Переписка из двадцати писем, разбросанная по списку, нечитаема. Группировка в тред — базовое ожидание.

Что делаем
  1. Группировка по заголовкам связей между письмами.
  2. Запасной вариант по теме и участникам, когда заголовки отсутствуют или сломаны.
  3. Обработка ветвлений переписки.
  4. Отображение свёрнутого треда с числом писем.
Готово, когда

Треды собираются по заголовкам связей между письмами, а при их отсутствии или порче — по теме и участникам; доля неверных объединений на контрольной выборке ниже одного процента.

Как проверяем

На выборке из тысячи реальных переписок доля неверных объединений ниже одного процента.

M1.11

Индекс поиска по почте

Почта2 backend8 нед.зависит от M1.8, 1.11
Зачем

Главное продуктовое преимущество почты внутри поисковой компании: поиск по ящику не разрабатывается заново, он уже есть.

Что делаем
  1. То же ядро индекса, что и в веб-поиске.
  2. Отдельный шард на каждый ящик: полная изоляция, письма пользователей физически не смешиваются.
  3. Та же морфология: два поля, словоформы и леммы.
  4. Временные корзины для ящиков свыше десяти тысяч писем.
  5. Индексация вложений распространённых форматов.
Готово, когда

Поиск по ящику работает, изоляция обеспечена архитектурой.

Как проверяем

Поиск по ящику в пятьдесят тысяч писем не дольше 200 мс на p95.

M1.13

Базовый антиспам

Почта2 backend6 нед.зависит от M1.1
Зачем

Основа фильтрации. Берём зрелое открытое решение с подходящей лицензией: оно обрабатывает примерно вдесятеро больше сообщений, чем классическая альтернатива, на тех же правилах.

Что делаем
  1. Развёртывание и настройка.
  2. Байесовский классификатор на нашем потоке.
  3. Нечёткие хеши для обнаружения повторов.
  4. Настройка порогов с приоритетом точности над полнотой.
Готово, когда

Базовый антиспам работает, отсев не ниже восьмидесяти пяти процентов.

Как проверяем

Замер на размеченном потоке: отсев не ниже 85% при доле ложных срабатываний ниже 0.1%. Приоритет у второго числа: пропущенный спам раздражает, потерянное письмо теряет пользователя. Отдельно проверяется, что письмо, помеченное как спам ошибочно, находится поиском и восстанавливается пользователем за одно действие.

M1.14

Репутация ссылок из веб-индекса

Почтакритический путь2 ML8 нед.зависит от M1.13, 1.23
Зачем

Наше преимущество, которого нет ни у одного отдельно стоящего почтового сервиса. Другие проверяют ссылки через внешние сервисы репутации; мы сами обошли эти сайты и знаем о них всё.

Что делаем
  1. Извлечение всех ссылок из письма.
  2. Проверка каждой по собственному индексу: авторитет хоста, доверие, оценка спама, возраст домена.
  3. Признак «домен не обойдён вообще» — для трёхдневного домена это сильнейший сигнал.
  4. Расхождение видимого текста ссылки и фактического адреса.
  5. Признаки идут в общий классификатор с высоким весом.
Готово, когда

Слой работает, фишинг со ссылкой на новый домен без входящих ссылок отсекается.

Как проверяем

На корпусе известных фишинговых писем полнота обнаружения по одному этому слою не ниже семидесяти процентов.

M1.15

Детектор массовых рассылок

Почта1 backend5 нед.зависит от M1.13
Зачем

Массовая рассылка видна по повторению тела у сотен получателей за минуты — это сигнал, недоступный при анализе одного письма.

Что делаем
  1. Нечёткий хеш тела письма.
  2. Подсчёт повторов в скользящем окне по всему потоку.
  3. Отделение легитимных рассылок от спама по репутации отправителя и наличию отписки.
Готово, когда

Детектор работает, легитимные рассылки не путаются со спамом.

Как проверяем

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

M1.16

Персональное обучение антиспама

Почта1 ML5 нед.зависит от M1.13
Зачем

Кнопка «это спам», которая ничего не меняет, хуже её отсутствия: она обещает контроль, которого нет.

Что делаем
  1. Персональный классификатор поверх общего.
  2. Обучение на действиях пользователя с эффектом в течение часа.
  3. Персональные белый и чёрный списки.
  4. Немедленный возврат письма во входящие при нажатии «это не спам».
Готово, когда

Обучение работает, эффект наступает в течение часа.

Как проверяем

После пометки трёх похожих писем четвёртое попадает в спам автоматически.

M1.17

Объяснение причины попадания в спам

Почта1 фронтенд4 нед.зависит от M1.14, M1.15
Зачем

Непрозрачная папка спама — то, за что справедливо ругают крупные почтовые сервисы. Пользователь должен видеть, почему письмо там оказалось, и уметь это отменить.

Что делаем
  1. Конкретная причина из закрытого списка по каждому письму в спаме.
  2. Показ результатов проверки подлинности.
  3. Для причины по ссылке — конкретика: возраст домена, оценка спама.
  4. Кнопки «это не спам» и «заблокировать отправителя».
Готово, когда

По каждому письму в спаме видна конкретная причина.

Как проверяем

Асессорская проверка ста писем: причина соответствует фактическому основанию решения.

M1.18

Веб-интерфейс почты

Почта2 фронтенд10 нед.зависит от M1.8, M1.10
Зачем

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

Что делаем
  1. Три колонки: папки, список, письмо.
  2. Чтение, написание, ответ, пересылка, вложения.
  3. Треды со сворачиванием.
  4. Базовый режим работает без скриптов.
  5. Клавиатурные сокращения, привычные по другим сервисам.
Готово, когда

Интерфейс работает, базовый режим доступен без скриптов.

Как проверяем

Прохождение основных сценариев с клавиатуры без мыши.

M1.19

Поиск по почте в интерфейсе

Почта1 backend + 1 фронтенд7 нед.зависит от M1.11
Зачем

Главное продуктовое преимущество нужно сделать видимым: без операторов и подсказок пользователь не узнает, что поиск умеет больше привычного.

Что делаем
  1. Операторы: отправитель, получатель, тема, наличие вложения, диапазон дат, размер, точная фраза.
  2. Подсказки по операторам прямо в строке.
  3. Поиск по всем папкам сразу: пользователь ищет письмо, а не папку.
  4. Подсветка найденного в списке и в письме.
Готово, когда

Все операторы работают, подсказки помогают их найти.

Как проверяем

Пользовательское тестирование: без документации человек находит письмо по отправителю и дате.

M1.20

Интеграция с Yottis ID

Почта1 backend4 нед.зависит от 1.29, M1.5
Зачем

Единый аккаунт — смысл всей затеи с почтой. Отдельный вход в почту обесценивает идею.

Что делаем
  1. Единый вход с двухфакторной аутентификацией и ключами доступа.
  2. Единый список устройств и сессий.
  3. Пароли приложений для внешних почтовых клиентов, не поддерживающих современную аутентификацию.
Готово, когда

Вход единый, пароли приложений работают.

Как проверяем

Смена пароля в Yottis ID немедленно закрывает сессии почты — это и есть проверка единства аккаунта, а не наличие общей формы входа. Пароли приложений проверяются на клиенте без поддержки современной аутентификации, ради которого они и заведены, и отзываются по одному, не затрагивая остальные.

M1.21

Экспорт и импорт почты

Почта1 backend4 нед.зависит от M1.8
Зачем

Возможность уйти — условие доверия. Сервис, из которого нельзя забрать данные, не заслуживает того, чтобы в него приходить.

Что делаем
  1. Экспорт в стандартные форматы, полный, без ограничений.
  2. Импорт из тех же форматов.
  3. Асинхронная подготовка с уведомлением.
Готово, когда

Экспорт и импорт работают на ящиках любого размера.

Как проверяем

Экспорт ящика в сто тысяч писем и импорт обратно: содержимое совпадает полностью.

M1.22

Тёмная тема и доступность почты

Почта1 фронтенд3 нед.зависит от M1.18
Зачем

Те же требования, что и в поиске: почтой пользуются ежедневно, в том числе люди с ограничениями.

Что делаем
  1. Тёмная тема с сохранением читаемости писем в чужой вёрстке — письмо приходит со своими цветами, и инвертировать его целиком нельзя. 2. Полная работа с клавиатуры: чтение, ответ, перемещение, поиск — без мыши. 3. Разметка для экранных дикторов на списке писем, чтении и составлении. 4. Контрастность и размеры по нормам уровня AA, включая состояния фокуса.
Готово, когда

Аудит доступности пройден, замечаний уровней A и AA нет.

Как проверяем

Аудит доступности проходят без замечаний уровней A и AA. Отдельно — сценарий «прочитать, ответить, отправить» выполняется полностью с клавиатуры и полностью через экранный диктор, и проверяется это прохождением сценария, а не проверкой разметки: разметка бывает формально верной при непроходимом сценарии.

M1.23

Почтовые записи домена и обратный DNS

Почта1 инфраструктура3 нед.зависит от M0.4
Зачем

Без корректных записей письма не доходят, а без обратного разрешения имён принимающие серверы понижают доверие.

Что делаем
  1. Записи обмена почтой с двумя приёмниками разного приоритета.
  2. Замена записи политики отправки: обязательно, иначе собственные письма отвергаются.
  3. Публикация открытых ключей подписи.
  4. Обратное разрешение имён для всех отправляющих адресов.
Готово, когда

Все записи опубликованы, обратное разрешение работает.

Как проверяем

Внешние проверочные сервисы не находят замечаний.

M1.24

Прогрев адресов отправки

Почтакритический путь1 инфраструктура8 нед.зависит от M1.23, M1.3
Зачем

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

Что делаем
  1. Восьминедельная схема наращивания объёма по каждому крупному провайдеру.
  2. Отслеживание доли доставки и жалоб на каждой неделе.
  3. Остановка наращивания при росте жалоб.
  4. Раздельный прогрев пулов транзакционных писем и рассылок.
Готово, когда

Прогрев завершён, доля доставки во входящие не ниже девяноста восьми процентов.

Как проверяем

Замер по каждому крупному провайдеру отдельно.

Риск

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

M1.25

Регистрация в панелях почтовых провайдеров

Почта1 инфраструктура2 нед.зависит от M1.23
Зачем

Панели провайдеров — единственный источник данных о том, как они видят нашу репутацию.

Что делаем
  1. Регистрация во всех крупных панелях провайдеров и подтверждение владения доменом. 2. Настройка отчётов о доставке и жалобах на общий адрес команды. 3. Подписка на петли обратной связи: жалоба пользователя провайдеру должна доходить до нас. 4. Регламент реакции: кто смотрит отчёты, с какой частотой и что делает при росте жалоб.
Готово, когда

Регистрация во всех крупных панелях выполнена, данные поступают.

Как проверяем

Тестовая рассылка на ящики в каждой панели: письма доходят до входящих, а не в спам, и это видно в самой панели. Петля обратной связи проверяется отправкой жалобы на собственное письмо — она обязана дойти до нас. Регламент проверяется тем, что отчёт за первую неделю действительно прочитан и разобран, а не просто поступает.

M1.26

Мониторинг доставляемости

Почта1 backend4 нед.зависит от M1.25
Зачем

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

Что делаем
  1. Доля доставки, доля попаданий в спам, доля жалоб по каждому провайдеру.
  2. Оповещения при выходе за пороги.
  3. Отслеживание отчётов о проверках подлинности.
  4. Панель с историей.
Готово, когда

Мониторинг работает, оповещения настроены.

Как проверяем

Искусственное ухудшение отправки приводит к оповещению в течение суток.

M2.1

Фильтры и правила

Почта2 backend + 1 фронтенд8 нед.зависит от M1.18
Зачем

Автоматическая сортировка — то, ради чего опытные пользователи выбирают почтовый сервис.

Что делаем
  1. Условия по отправителю, теме, содержимому, вложениям, заголовкам.
  2. Действия: переместить, пометить, переслать, удалить, отметить прочитанным.
  3. Тестирование правила на прошлых письмах до применения: правило, применённое вслепую, может перемешать весь ящик.
  4. Порядок применения правил и остановка обработки.
Готово, когда

Правила работают, тестирование на прошлых письмах доступно.

Как проверяем

Правило, протестированное на выборке, при применении даёт тот же результат.

M2.2

Метки

Почта1 фронтенд4 нед.зависит от M1.18
Зачем

Папки предполагают, что письмо лежит в одном месте; метки позволяют нескольким классификациям сосуществовать.

Что делаем
  1. Метки с цветом и иерархией, произвольное число на письме. 2. Автоматическое назначение по правилам фильтрации. 3. Фильтрация и поиск по меткам, в том числе по сочетанию нескольких. 4. Метки применяются к переписке целиком или к отдельному письму — выбор за пользователем, потому что оба сценария встречаются.
Готово, когда

Метки создаются, назначаются, фильтруются, видны в списке.

Как проверяем

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

M2.3

Отложенная отправка и напоминания

Почта1 backend + 1 фронтенд5 нед.зависит от M1.3
Зачем

Отправка письма в рабочее время и напоминание об отсутствии ответа — простые функции с высокой оценкой пользователями.

Что делаем
  1. Отправка по расписанию с возможностью отмены до момента отправки.
  2. Напоминание, если на письмо не ответили за указанный срок.
  3. Отложенное чтение: убрать письмо из входящих до срока.
Готово, когда

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

Как проверяем

Отложенное письмо уходит точно в указанное время с учётом часового пояса пользователя, а не сервера. Отмена до момента отправки проверяется в том числе за секунду до срока. Напоминание не срабатывает, если ответ пришёл, — включая случай, когда ответ пришёл не на само письмо, а в ту же переписку.

M2.4

Сборщик писем с других сервисов

Почтакритический путь2 backend9 нед.зависит от M1.6, M1.8
Зачем

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

Что делаем
  1. Подключение внешнего ящика по стандартному протоколу.
  2. Однократный перенос архива и постоянная синхронизация.
  3. Сохранение структуры папок и флагов.
  4. Возможность отправлять от адреса внешнего ящика.
  5. Обработка больших ящиков без блокировки интерфейса.
Готово, когда

Сборщик переносит ящики крупных сервисов без потерь.

Как проверяем

Перенос ящика в сто тысяч писем: содержимое, структура и флаги совпадают.

M2.5

Алиасы и одноразовые адреса

Почта1 backend + 1 фронтенд5 нед.зависит от M1.8
Зачем

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

Что делаем
  1. Постоянные алиасы для разных целей.
  2. Одноразовые адреса с указанием, для какого сервиса созданы.
  3. Отключение адреса одним действием.
  4. Показ, на какой адрес пришло письмо.
Готово, когда

Алиасы и одноразовые адреса работают.

Как проверяем

Отключённый одноразовый адрес перестаёт принимать почту немедленно, а отправитель получает отказ, а не молчание: молчаливое поглощение писем создаёт у отправителя ложную уверенность в доставке. Отдельно проверяется, что в списке писем видно, на какой именно адрес пришло письмо — иначе весь смысл одноразовых адресов теряется.

M2.6

Отдельная папка для рассылок

Почта1 ML + 1 фронтенд5 нед.зависит от M1.15
Зачем

Легитимные рассылки — не спам, но и не входящие. Смешивание с личной перепиской обесценивает и то, и другое.

Что делаем
  1. Классификатор рассылок отдельно от классификатора спама.
  2. Отдельная папка с группировкой по отправителю.
  3. Отписка в один клик прямо из интерфейса.
  4. Возможность вернуть отправителя во входящие.
Готово, когда

Папка работает, отписка в один клик доступна.

Как проверяем

Доля личных писем, ошибочно попавших в рассылки, ниже половины процента.

M2.7

Современный протокол доступа

Почта2 backend8 нед.зависит от M1.8
Зачем

Современная замена старому протоколу: один интерфейс поверх обычных веб-технологий вместо протокола с состоянием, дешёвая синхронизация и уведомления без опроса.

Что делаем
  1. Реализация протокола для почты.
  2. Уведомления об изменениях.
  3. Собственные клиенты переводятся на него; старый протокол остаётся для совместимости.
Готово, когда

Протокол работает, есть внешний клиент, который его использует.

Как проверяем

Внешний клиент, реализующий протокол, работает с нашим сервером без правок на его стороне — это и есть проверка соответствия стандарту. Отдельно замеряется то, ради чего протокол берётся: объём трафика при синхронизации большого ящика сравнивается со старым протоколом на том же ящике.

M2.8

Шаблоны и подписи

Почта1 фронтенд3 нед.зависит от M1.18
Зачем

Подпись и шаблон — это то, что человек иначе набирает по десять раз в день. Экономия кажется мелкой ровно до подсчёта: у сотрудника поддержки на шаблонных ответах уходит больше времени, чем на содержательные письма. Подписи по адресам отправки нужны отдельно: с одного ящика пишут и от себя, и от организации, и путать эти две подписи неловко перед адресатом.

Что делаем
  1. Шаблоны с подстановкой полей: имя адресата, дата, ссылка на переписку.
  2. Подписи, привязанные к адресу отправки, включая алиасы, с автоматическим выбором.
  3. Общие шаблоны организации, доступные всем сотрудникам, и личные.
  4. Вставка шаблона в существующее письмо, а не только создание из шаблона.
Готово, когда

Шаблоны сохраняются и подставляются, подписи настраиваются по адресам отправки.

Как проверяем

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

M2.9

Уведомления

Почта1 фронтенд3 нед.зависит от M1.18
Зачем

Без уведомлений веб-почта требует постоянной проверки вкладки.

Что делаем
  1. Уведомления в браузере с настройкой по важности.
  2. Правила: уведомлять только о письмах из входящих, только от избранных отправителей.
  3. Тихие часы.
Готово, когда

Уведомления работают и настраиваются.

Как проверяем

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

M2.10

Расширенный поиск и сохранённые запросы

Почта1 фронтенд4 нед.зависит от M1.19
Зачем

Часто повторяющийся поиск удобнее сохранить, чем набирать заново.

Что делаем
  1. Сохранённые поиски как виртуальные папки.
  2. Поиск внутри вложений.
  3. История поисков по ящику.
Готово, когда

Сохранённые поиски работают как папки.

Как проверяем

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

M3.1

Почта для домена

Почтакритический путь3 backend + 2 фронтенд12 нед.зависит от M1.23, M2.4
Зачем

Основная монетизация почтового направления: понятная подписка для бизнеса с предсказуемой выручкой.

Что делаем
  1. Подключение собственного домена с проверкой прав.
  2. Мастер настройки записей домена с проверкой корректности.
  3. Управление почтовыми ящиками домена.
  4. Настройка политик безопасности для домена.
  5. Тарификация по числу ящиков и объёму.
Готово, когда

Домен подключается за десять минут, записи проверяются автоматически.

Как проверяем

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

M3.2

Организации и совместная работа

Почта2 backend + 1 фронтенд10 нед.зависит от M3.1, 4.7
Зачем

Компании работают с общими ящиками и делегированием, и без этого почта для домена не покрывает их сценарии.

Что делаем
  1. Общие ящики с разграничением доступа.
  2. Делегирование доступа к своему ящику.
  3. Журнал действий участников.
  4. Политики организации: обязательная двухфакторная аутентификация, ограничения на пересылку.
Готово, когда

Общие ящики и делегирование работают.

Как проверяем

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

M3.3

Календарь

Почта2 backend + 2 фронтенд12 нед.зависит от M3.1
Зачем

Календарь неотделим от рабочей почты: приглашения приходят письмами, и обрабатывать их вне почты неудобно.

Что делаем
  1. Стандартный протокол синхронизации календарей.
  2. Приглашения и ответы на них прямо из письма.
  3. Общие календари в организации.
  4. Поиск свободного времени участников.
Готово, когда

Календарь работает, синхронизируется со стандартными клиентами.

Как проверяем

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

M3.4

Контакты

Почта1 backend + 1 фронтенд8 нед.зависит от M3.1
Зачем

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

Что делаем
  1. Стандартный протокол синхронизации контактов.
  2. Автоматическое пополнение из переписки.
  3. Группы контактов и общие адресные книги организации.
Готово, когда

Контакты синхронизируются со стандартными клиентами.

Как проверяем

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

M3.5

Тарифные планы и оплата

Почта2 backend8 нед.зависит от M3.1, 4.17
Зачем

Почтовое хранилище растёт монотонно и не сжимается — платные тарифы нужны с первого дня, а не «когда наберём аудиторию».

Что делаем
  1. Тарифы: бесплатный объём, расширенное хранилище, почта для домена, корпоративный план.
  2. Учёт объёма и числа ящиков.
  3. Оплата и документы для юридических лиц.
  4. Уведомления о приближении к лимиту и мягкая деградация вместо резкого отключения.
Готово, когда

Тарифы работают, оплата проходит, документы формируются.

Как проверяем

Сверка счёта с фактическим объёмом хранилища и числом ящиков на выборке организаций. Отдельно проверяются пограничные случаи: добавление ящика в середине периода, превышение квоты, переход между тарифами. Документы для юридических лиц проверяются бухгалтером, а не разработчиком — формально верный документ бывает непригодным для учёта.

M3.6

Панель администратора организации

Почта2 фронтенд8 нед.зависит от M3.2
Зачем

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

Что делаем
  1. Управление сотрудниками, ящиками и квотами.
  2. Политики безопасности и правила на уровне домена.
  3. Журнал действий и отчёты.
  4. Передача ящика уволившегося сотрудника.
Готово, когда

Администратор организации управляет всем без обращения в поддержку.

Как проверяем

Сценарии «завести сотрудника», «изменить квоту», «передать ящик уволившегося» и «включить политику для домена» проходятся администратором без обращения в поддержку и без правки конфигураций. Проверка проводится наблюдением за реальным администратором, а не прохождением сценария разработчиком, который знает, куда нажимать.

M3.7

Миграция с корпоративных решений

Почта2 backend10 нед.зависит от M2.4, M3.3
Зачем

Компания переезжает целиком или не переезжает вовсе: почта без календаря и контактов её не устраивает.

Что делаем
  1. Импорт почты, календарей и контактов из распространённых корпоративных систем.
  2. Перенос структуры организации и групп.
  3. Поэтапный переезд с параллельной работой двух систем.
Готово, когда

Миграция проходит на тестовой организации в сто ящиков без потерь.

Как проверяем

Миграция тестовой организации в сто ящиков: сверяется число писем, вложений, событий календаря и контактов до и после, включая структуру папок и меток. Потеря даже одного письма считается провалом: компания, потерявшая переписку при переезде, не остаётся. Отдельно проверяется параллельная работа во время переезда.

M3.8

Соглашение об уровне обслуживания и поддержка

Почта2 поддержка6 нед.зависит от M3.5
Зачем

Бизнес платит не только за функции, но и за гарантии. Без соглашения об уровне обслуживания корпоративные клиенты не приходят.

Что делаем
  1. Гарантии доступности и времени реакции по тарифам.
  2. Приоритетная поддержка для платных планов.
  3. Компенсации при нарушении гарантий.
  4. Публичная страница статуса сервиса.
Готово, когда

Соглашение опубликовано, поддержка укомплектована, статус публикуется.

Как проверяем

Гарантии доступности проверяются по фактическим замерам за квартал, а не по обещаниям: публичная страница статуса показывает то же, что внутренний мониторинг. Компенсация при нарушении начисляется автоматически — компенсация по заявлению клиента не является гарантией, а является формальностью.

M4.1

Мобильные приложения почты

Почта4 мобильная разработка20 нед.зависит от M2.7, 4.4
Зачем

Почту читают с телефона чаще, чем с компьютера, и веб-версия на мобильном проигрывает нативному приложению по всем параметрам.

Что делаем
  1. Приложения для двух платформ.
  2. Уведомления с настройкой по важности.
  3. Работа в офлайне с синхронизацией.
  4. Быстрые действия по свайпу.
  5. Единый аккаунт с поиском.
Готово, когда

Приложения опубликованы, оценка не ниже 4.3.

Как проверяем

Работа в офлайне проверяется в режиме полёта: письма читаются, ответы составляются и уходят при появлении сети — без дублей, что и есть главная ошибка офлайн-синхронизации. Оценка не ниже 4.3 замеряется через месяц после публикации, а не в день выхода.

M4.2

Сквозное шифрование

Почта2 backend + 1 фронтенд14 нед.зависит от M1.18
Зачем

Для части аудитории это обязательное требование, а не удобство.

Что делаем
  1. Поддержка распространённых стандартов шифрования писем.
  2. Управление ключами на стороне пользователя.
  3. Понятная индикация состояния шифрования.
  4. Честное объяснение ограничений: зашифрованные письма не участвуют в поиске по содержимому.
Готово, когда

Шифрование работает, состояние понятно из интерфейса.

Как проверяем

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

M4.3

Хранение файлов

Почта2 backend + 2 фронтенд16 нед.зависит от M1.9
Зачем

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

Что делаем
  1. Хранилище файлов с квотой по тарифу.
  2. Отправка крупных вложений ссылкой.
  3. Автоматическое сохранение вложений из писем.
  4. Общий доступ по ссылке с ограничением срока.
Готово, когда

Хранилище работает, крупные вложения отправляются ссылкой.

Как проверяем

Крупное вложение отправляется ссылкой и открывается у получателя без регистрации. Ограничения доступа по ссылке проверяются попыткой обойти их: срок действия и пароль обязаны действительно закрывать доступ. Отдельно — что происходит с уже отправленной ссылкой при исчерпании квоты отправителя.

M4.4

Продвинутый антифишинг

Почта2 ML14 нед.зависит от M1.14
Зачем

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

Что делаем
  1. Анализ визуального сходства письма с известными брендами.
  2. Проверка соответствия визуального оформления и фактического отправителя.
  3. Предупреждение при расхождении.
  4. Обучение на подтверждённых случаях.
Готово, когда

Детектор работает, визуальный фишинг обнаруживается.

Как проверяем

На корпусе визуального фишинга полнота не ниже восьмидесяти процентов при доле ложных срабатываний ниже одной десятой процента.

M4.5

Суммаризация переписок

Почта2 ML12 нед.зависит от 5.15
Зачем

Пересказ переписки из тридцати писем — заметная экономия времени, особенно при подключении к обсуждению в середине.

Что делаем
  1. Пересказ длинного письма и целого треда.
  2. Только локальные модели: содержимое писем не покидает почтовый контур ни при каких условиях.
  3. Полная отключаемость.
Готово, когда

Суммаризация работает локально, отключается.

Как проверяем

Аудит сетевых обращений: обращений к внешним интерфейсам моделей нет.

M4.6

Совместная работа с письмами

Почта2 фронтенд10 нед.зависит от M3.2
Зачем

В организациях письмо часто обсуждают до ответа, и это обсуждение сейчас уходит в мессенджеры, теряя связь с письмом.

Что делаем
  1. Внутренние комментарии к письму, видимые только сотрудникам организации.
  2. Назначение ответственного за письмо.
  3. Статусы обработки в общем ящике.
Готово, когда

Комментарии и назначение работают в общих ящиках.

Как проверяем

Внутренний комментарий не виден внешнему адресату ни при каких действиях: проверяется пересылкой, ответом всем и выгрузкой письма. Утечка внутреннего обсуждения наружу — единственная ошибка этой функции, которая имеет значение, и проверять её надо попыткой, а не чтением кода.

Ворота трека

Все критерии обязательны. Не пройдены — фаза продлевается, а не закрывается.

  • M0: решение «идём или не идём» принято и записано с обоснованием
  • M1: доставляемость во входящие крупных провайдеров не ниже 98%
  • M1: отсев спама не ниже 93% при доле ложных срабатываний не выше 0.08%
  • M1: поиск по ящику в 50 000 писем не дольше 200 мс на p95
  • M1: переезд с внешнего сервиса работает на ящике в 100 000 писем
  • M1: контур хранения развёрнут и проверен юристом
  • M1: внешние проверочные сервисы не находят замечаний
  • M1: 1000 ящиков в закрытой альфе, ни одного потерянного письма
  • M2: 50 000 ящиков, доля возвращающихся ежедневно не ниже 40%
  • M2: сборщик перенёс не менее 10 000 ящиков с других сервисов
  • M2: отсев спама не ниже 95% при ложных срабатываниях не выше 0.05%
  • M3: 500 000 ящиков, 2000 доменов на платных тарифах
  • M3: выручка покрывает операционные расходы трека
  • M3: доступность почты 99.95% за квартал

Параллельный трек

Картинки

Месяцы
трек
Календарь
с фазы 2
Команда
22 чел.
Индекс
1 млрд
Бюджет
700 млн ₽
Задач
64
Недель работ
304

Построить вертикаль «Картинки» как отдельный поисковый контур: свой обход изображений, свой индекс, где единицей является изображение со списком страниц-носителей, своё ранжирование по внешним текстовым и внутренним визуальным признакам, свой интерфейс с сеткой и просмотрщиком и свой правовой режим показа чужих произведений. Отличие от Яндекса и Google — источник первичен: миниатюра ведёт на страницу, а не заменяет её, лицензия видна в выдаче, а вебмастер видит, что мы взяли с его сайта и почему.

Картинки 8

I0.1

Измерение визуального спроса

Картинкикритический путьпродукт + аналитик4 нед.
Зачем

Отделить «картинки есть у всех» от измеренной потребности. Доли рынка, приведённые в §24.1, — чужие; на своём потоке запросов доля визуальных намерений может отличаться вдвое в любую сторону, а от неё зависит и команда, и очерёдность.

Что делаем
  1. Разметка выборки из 20 000 запросов собственного потока фазы 2 по визуальному намерению.
  2. Оценка доли запросов, где картинка в веб-выдаче полезнее ссылки, — вход для колдунщика I3.3.
  3. Разбор классов намерения из §24.8 по частоте: объект, сцена, человек, схема, скриншот, обои, товар, текст.
  4. Оценка доли запросов, на которые сегодняшняя веб-выдача отвечает плохо именно из-за отсутствия картинок.
  5. Письменное заключение с числами и методикой их воспроизведения.
Готово, когда

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

Как проверяем

Повторный замер на другом недельном срезе даёт долю, отличающуюся не более чем на 2 процентных пункта.

Риск

Поток фазы 2 непредставителен: у молодого поиска перекошенная аудитория. Смягчение: считаем долю отдельно по сегментам аудитории и указываем разброс, а не одно число.

I0.8

Решение «идём или не идём»

Картинкикритический путьруководство трека2 нед.зависит от I0.2, I0.3, I0.4, I0.6, I0.7
Зачем

Ворота фазы существуют, чтобы у трека была возможность не начаться. Решение, принятое молча и по умолчанию, невозможно оспорить и невозможно отменить.

Что делаем
  1. Сведение результатов I0.1–I0.7 в одну записку: спрос, право, качество, деньги.
  2. Формулировка условий, при которых трек не стартует, и условий, при которых он стартует урезанным.
  3. Выбор сценария бюджета и состава команды I1.
  4. Список того, что в трек не входит, — со ссылкой на §24.22.
  5. Публикация решения внутри проекта с датой и подписями.
Готово, когда

Решение принято письменно, сценарий выбран, исключённые сценарии перечислены с причиной.

Как проверяем

Записка содержит ответ по каждому из четырёх вопросов фазы и явный список условий, при которых решение пересматривается.

Риск

Решение принимается «по инерции»: трек стартует потому, что его планировали. Смягчение: условия отказа сформулированы до сведения результатов, а не после.

I1.10

Классификатор типа содержимого

Картинки2 ML6 нед.зависит от I1.4, 2.28
Зачем

Тип содержимого — половина понимания запроса в вертикали: «схема БП АТХ» и «закат над морем» требуют разных классов, и без класса выдача смешивает чертежи с фотографиями.

Что делаем
  1. Классы из §24.8: фото, рисунок, схема, скриншот, иконка, текст, коллаж.
  2. Обучающая выборка с разметкой, включающая пограничные случаи.
  3. Инференс на потоке обхода с бюджетом, укладывающимся в расчёт I0.7.
  4. Флаг наличия лица без каких-либо биометрических признаков (§24.16).
  5. Признак на выходе — распределение по классам, а не один класс: жёсткое решение теряет информацию.
Готово, когда

Точность классификации на контрольной выборке не ниже 0.90 макро-F1, распределение сохраняется в индекс, лицевые признаки не сохраняются.

Как проверяем

Контрольная выборка в 5000 изображений, размеченная асессорами и не участвовавшая в обучении.

Риск

Класс «скриншот» путается с классом «текст». Смягчение: классы объединяются в один при F1 ниже порога, чем сохраняется честность метрики.

I1.11

Классификатор безопасного поиска

Картинкикритический путь2 ML6 нед.зависит от I1.4, I0.6
Зачем

Единственное место продукта, где неуместный результат виден мгновенно всем, кто смотрит на экран, — включая тех, кто просто проходил мимо.

Что делаем
  1. Три уровня по политике I0.6 с отдельными порогами.
  2. Оценка «взрослого» содержимого и оценка насилия — раздельно, они требуют разных решений.
  3. Размытие вместо скрытия в зоне неуверенности классификатора.
  4. Подсчёт скрытого и объявление числа в интерфейсе.
  5. Список запрещённого законом, не имеющий переключателя.
Готово, когда

Пропуск явного содержимого при умеренном уровне не выше 1.0%, ложное срабатывание не выше 3%, скрытое считается и объявляется.

Как проверяем

Замер на корзине I0.6 из 2000 изображений; отдельно замеряется, что запрещённое законом не показывается ни на одном уровне.

Риск

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

I1.12

Палитра и цветовой фильтр

Картинки1 backend3 нед.зависит от I1.4
Зачем

Цвет — второй по частоте фильтр после размера, и единственный, который нельзя заменить текстовым запросом: «синий» в запросе означает синий предмет, а не синюю картинку.

Что делаем
  1. Пять доминирующих цветов кластеризацией в перцептивно равномерном пространстве.
  2. Доля серого и признак прозрачности.
  3. Сопоставление с двенадцатью образцами фильтра §24.14.
  4. Отдельный признак «чёрно-белое», не выводимый из палитры автоматически.
Готово, когда

Палитра считается для всех изображений, фильтр по цвету возвращает изображения, которые асессор относит к выбранному цвету, не менее чем в 85% случаев.

Как проверяем

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

Риск

Доминирующий цвет фона побеждает цвет предмета. Смягчение: центральная область кадра получает больший вес при кластеризации.

I2.1

Эмбеддинги изображений: выбор модели

Картинкикритический путь2 ML + юрист6 нед.зависит от I1.10, 2.28, 2.53
Зачем

Векторное представление — единственный сигнал о содержании картинки, который не контролирует автор страницы. От него зависят и поиск по картинке, и похожие, и защита от спама.

Что делаем
  1. Отбор открытых моделей общего вида «изображение — текст» с проверкой лицензии весов и лицензии обучающих данных.
  2. Замер качества кандидатов на корзине I0.4 и на корзине I0.5: поиск по картинке и различение дублей.
  3. Решение о размерности и о схеме сжатия под расчёт I0.7.
  4. Регистрация выбранной модели в реестре моделей (2.54) с версией.
  5. Инференс на потоке обхода через шлюз моделей 2.53 с учётом стоимости.
Готово, когда

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

Как проверяем

Сравнительная таблица кандидатов с числами по обеим корзинам и по стоимости инференса на миллион изображений.

Риск

Лицензия обучающих данных запрещает коммерческое использование при разрешительной лицензии весов. Смягчение: проверяются обе лицензии — правило, уже действующее в треке переводчика (T0.2).

I2.9

Признак первоисточника

Картинки1 backend + 1 аналитик4 нед.зависит от I1.8, I1.9
Зачем

Отличие, которого нет ни у Яндекса, ни у Google (§24.4): показать, где изображение появилось первым, и понизить тех, кто живёт перепубликацией чужого.

Что делаем
  1. Дата первой встречи изображения по каждому носителю как основа признака.
  2. Поправка на дату публикации страницы и на дату из разметки, где она есть.
  3. Признак «сайт живёт перепубликацией»: доля изображений, где он не первоисточник.
  4. Показ первоисточника в просмотрщике с оговоркой «по нашим данным обхода».
  5. Влияние признака на ранжирование с отдельным замером.
Готово, когда

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

Как проверяем

Корзина из 200 изображений с известной историей публикации: первоисточник определён верно не менее чем в 75% случаев.

Риск

Дата первой встречи зависит от порядка обхода, а не от порядка публикации, и молодой сайт объявляется первоисточником. Смягчение: оговорка в интерфейсе обязательна, а признак имеет ограниченный вес в ранжировании.

I4.6

Кадры видео в вертикали

Картинки1 backend + 1 ML6 нед.зависит от I3.1, 2.18
Зачем

Значительная часть визуального содержимого веба — видео, и поиск по кадру нужен ровно тогда, когда пользователь помнит картинку, но не помнит, где её видел.

Что делаем
  1. Извлечение ключевых кадров из индексируемых видео на механизмах вертикали «Видео».
  2. Индексация кадров как изображений с пометкой происхождения и тайм-кода.
  3. Переход из кадра в видео на нужной секунде.
  4. Отдельное правило разнообразия: не более двух кадров одного видео.
Готово, когда

Кадры индексируются с тайм-кодом, переход открывает видео на нужной секунде, правило разнообразия соблюдается.

Как проверяем

Корзина из 100 запросов по сценам из видео: доля запросов с верным кадром в топ-20 измерена и опубликована.

Риск

Кадры вытесняют фотографии из выдачи. Смягчение: доля кадров в сетке ограничена и настраивается по классу намерения.

Качество 6

I0.4

Корзина визуальных запросов

Качествоасессоры + аналитик6 нед.зависит от I0.1
Зачем

Качество вертикали, которое не измеряется, не улучшается. Веб-корзина здесь не годится: там оценивают текст, здесь — изображение, и шкала оценки другая.

Что делаем
  1. Отбор 500 запросов по восьми классам намерения пропорционально измеренному спросу.
  2. Руководство асессора для картинок: что такое релевантное изображение, как оценивать дубли, как оценивать качество файла отдельно от соответствия запросу.
  3. Разметка топ-60 на каждый запрос по пятибалльной шкале.
  4. Замер согласия асессоров между собой; переработка руководства, пока согласие не выйдет на порог.
  5. Отдельная разметка «первый экран»: пригодна ли сетка целиком, а не отдельная картинка.
Готово, когда

500 запросов размечены, согласие асессоров по каппе Коэна не ниже 0.6, руководство опубликовано.

Как проверяем

Контрольная переразметка 50 запросов другой группой асессоров даёт pFound, отличающийся не более чем на 0.03.

Риск

Асессоры оценивают красоту, а не релевантность. Смягчение: в руководстве качество файла и соответствие запросу разведены в две независимые оценки.

I0.5

Корзина дублей и версий

Качествоаналитик + асессоры4 нед.зависит от I0.4
Зачем

Дедупликация — главный источник «плохой» сетки: десять копий одной картинки подряд читаются как поломка. Мерить её нужно отдельно от релевантности, иначе одна метрика скроет другую.

Что делаем
  1. Сбор 5000 пар изображений с разметкой «точный дубль / перцептивный дубль / версия другого размера / похожее / разное».
  2. Включение в набор трудных случаев: водяной знак, обрезка полей, зеркальное отражение, смена палитры, коллаж из той же фотографии.
  3. Разметка групп: для 200 изображений — полный список носителей с датами.
  4. Формат хранения корзины, пригодный для автозамера в общем прогоне.
Готово, когда

5000 пар размечены, трудные случаи составляют не менее 20% набора, формат корзины принят автозамером.

Как проверяем

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

Риск

Корзина собрана из лёгких случаев и хвалит любой алгоритм. Смягчение: доля трудных случаев зафиксирована как требование, а не как пожелание.

I1.21

Автозамер качества вертикали

Качество1 аналитик + 1 backend4 нед.зависит от I1.14, I0.4, I0.5
Зачем

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

Что делаем
  1. Ежедневный прогон по корзинам I0.4 и I0.5 с публикацией метрик §24.20.
  2. Порог тревоги на падение pFound и на рост доли дублей.
  3. Замер задержки p95 и LCP как части того же прогона.
  4. История метрик с привязкой к версиям индекса и модели.
Готово, когда

Замер идёт ежедневно, история хранится, падение метрики выше порога поднимает тревогу.

Как проверяем

Искусственное ухудшение ранжирования на тестовом стенде поднимает тревогу в тот же день.

Риск

Замер на неизменной корзине перестаёт ловить новые дефекты. Смягчение: 10% корзины ежеквартально заменяется свежими запросами.

I2.14

Ворота качества I2

Качествоаналитик3 нед.зависит от I2.8, I2.5, I1.21
Зачем

Ворота — единственный способ не выкатить вертикаль, которая «в целом работает». Числа заданы в §24.20 заранее, чтобы их нельзя было подогнать под результат.

Что делаем
  1. Прогон по всем метрикам §24.20 в колонке I2.
  2. Отдельный замер поиска по картинке на корзине из 300 изображений.
  3. Замер безопасного поиска на корзине I0.6.
  4. Публикация результата внутри проекта независимо от того, пройдены ворота или нет.
  5. При непройденных воротах — разбор причин и план добора, а не смягчение порога.
Готово, когда

Все метрики колонки I2 замерены и опубликованы, решение о прохождении ворот принято письменно.

Как проверяем

Замер воспроизводится в общем прогоне тестов на тех же корзинах и даёт те же числа.

Риск

Порог смягчается ради срока. Смягчение: смягчение порога требует письменного решения с обоснованием и фиксируется в истории вместе с метрикой.

I3.11

Ворота качества I3

Качествоаналитик3 нед.зависит от I3.6, I3.1, I1.21
Зачем

Последние ворота перед переводом вертикали в режим сопровождения. После них качество поддерживается автозамером, а не проектной работой.

Что делаем
  1. Прогон по всем метрикам §24.20 в колонке I3.
  2. Замер задержки и LCP под боевой нагрузкой, а не на стенде.
  3. Сравнение с Яндекс.Картинками и Google Images на общей корзине силами асессоров.
  4. Публикация результата, включая проигранные сравнения.
  5. План сопровождения: что замеряется ежедневно, кто отвечает, при каком падении поднимается тревога.
Готово, когда

Метрики колонки I3 достигнуты, сравнение с конкурентами проведено и опубликовано, план сопровождения принят.

Как проверяем

Слепое сравнение асессорами на 300 запросах: доля побед и ничьих против каждого конкурента опубликована как есть.

Риск

Сравнение проводится на удобных запросах. Смягчение: корзина сравнения формируется из живого потока случайной выборкой и фиксируется до замера.

I4.9

Передача вертикали в сопровождение

Качестворуководство трека3 нед.зависит от I3.11, I4.3
Зачем

Трек заканчивается не выкаткой, а тем, что кто-то принимает вертикаль в постоянную работу с понятными обязанностями и метриками.

Что делаем
  1. Регламент сопровождения: ежедневные метрики, пороги тревоги, дежурство.
  2. Передача корзин, руководств асессора и стендов замера.
  3. Список известного технического долга с оценкой.
  4. Список отвергнутых сценариев с причинами — обновление §24.22.
  5. Ретроспектива трека с числами: что оценено верно, что нет.
Готово, когда

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

Как проверяем

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

Риск

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

Инфраструктура 3

I0.7

Расчёт ёмкости и стоимости вертикали

Инфраструктураинфраструктура + аналитик4 нед.зависит от I0.1
Зачем

Картинки дороже, чем кажется: обход тянет оригиналы, хранение тянет миниатюры и векторы, отдача тянет трафик. Ошибка в расчёте обнаруживается на третьем месяце обхода, когда менять что-либо поздно.

Что делаем
  1. Расчёт по §24.19 на 100 млн, 1 млрд и 3 млрд изображений: хранение, память, трафик, ускорители.
  2. Оценка эффекта отбраковки до загрузки: стоимость при отсеве 50%, 70% и 85%.
  3. Расчёт отдачи миниатюр: трафик на запрос, доля кэша, стоимость канала.
  4. Стоимость инференса классификаторов и эмбеддингов на потоке обхода.
  5. Три сценария бюджета трека с указанием, что именно урезается в каждом.
Готово, когда

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

Как проверяем

Модель проверяется на выборке в 1 млн изображений: предсказанные объёмы расходятся с измеренными не более чем на 20%.

Риск

Средний вес оригинала занижен — трафик обхода вырастает вдвое. Смягчение: средний вес берётся не из литературы, а из собственной выборки обхода фазы 1.

I3.1

Миллиард изображений

Инфраструктуракритический путь3 инфраструктуры + 2 backend10 нед.зависит от I2.2, 3.1
Зачем

Вертикаль на ста миллионах и на миллиарде — разные системы: меняется раскладка по шардам, объём памяти под векторы и стоимость обхода.

Что делаем
  1. Раскладка по шардам с вторичным расщеплением гигантских CDN-хостов.
  2. Память под сжатые векторы и горячие метаданные в пределах расчёта I0.7.
  3. Холодный слой для редко запрашиваемых миниатюр на объектном хранилище.
  4. Ускорение обхода изображений до целевой скорости с сохранением вежливости.
  5. Нагрузочное испытание на полном объёме до перевода трафика.
Готово, когда

Индекс на миллиард изображений обслуживает целевой поток запросов в бюджете задержки, перекос шардов не выше 10%.

Как проверяем

Нагрузочное испытание на полном объёме с замером задержки, памяти и перекоса; сверка с расчётом I0.7.

Риск

Стоимость превышает расчёт вдвое. Смягчение: три сценария бюджета из I0.7 предусматривают урезание глубины индекса, а не качества выдачи.

I3.2

Отдача миниатюр

Инфраструктура2 инфраструктуры5 нед.зависит от I3.1
Зачем

Одна страница выдачи — это шестьдесят файлов. Отдача миниатюр становится крупнейшей статьёй трафика продукта, крупнее самой выдачи.

Что делаем
  1. Кеш на границе сети с раздельными правилами для трёх размеров.
  2. Согласование форматов с браузером: AVIF, WebP, откат на JPEG.
  3. Немедленная инвалидация при отзыве изображения (I1.5).
  4. Защита от чужого встраивания наших миниатюр.
  5. Замер доли попаданий в кеш и стоимости канала.
Готово, когда

Доля попаданий в кеш не ниже 90%, инвалидация при отзыве укладывается в минуты, стоимость канала соответствует расчёту I0.7.

Как проверяем

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

Риск

Кеш переживает отзыв изображения, и удалённое продолжает показываться. Смягчение: инвалидация — часть операции отзыва, отдельным тестом проверяется её выполнение.

Обработка 2

I1.1

Извлечение кандидатов из страниц

Обработка2 backend5 нед.зависит от I0.8, 1.8
Зачем

Изображение попадает в индекс не само: его нужно найти в разметке вместе со всем текстовым контекстом, который потом будет единственным текстовым сигналом.

Что делаем
  1. Разбор источников кандидатов по таблице §24.7: img, srcset, picture, figure, og:image, JSON-LD ImageObject, noscript.
  2. Сбор текстового контекста: alt, подпись, ближайший заголовок, окружающий текст ±300 символов, title, имя файла.
  3. Разрешение относительных адресов и выбор наибольшей версии из srcset.
  4. Пометка роли изображения: содержание, обвязка, картинка страницы.
  5. Стык с конвейером экстракции 1.8 — без второго прохода по документу.
Готово, когда

На корпусе из 10 000 страниц кандидаты извлекаются вместе с контекстом, роль проставлена, второго разбора HTML не происходит.

Как проверяем

Ручная сверка на 200 страницах: доля правильно извлечённых подписей и окружающего текста не ниже 95%.

Риск

Ленивая загрузка прячет настоящий адрес в атрибутах, которые мы не знаем. Смягчение: список атрибутов ленивой загрузки ведётся как данные, а не как код, и пополняется по находкам.

I1.4

Конвейер миниатюр

Обработка2 backend5 нед.зависит от I1.3
Зачем

Мы показываем миниатюры и только их: оригиналы не храним ни по праву, ни по деньгам (§24.6). Значит, конвейер миниатюр — не оптимизация, а основной способ показа.

Что делаем
  1. Три размера по длинной стороне: 200, 640, 1280 px, в AVIF и WebP.
  2. Учёт ориентации из EXIF и удаление всех остальных EXIF-полей, включая координаты.
  3. Прогрессивная загрузка: доминирующий цвет как заглушка до прихода файла.
  4. Хранение в объектном хранилище с адресацией по хешу содержимого.
  5. Пересчёт при изменении оригинала и удаление при отзыве.
Готово, когда

Миниатюры собираются для всех поддерживаемых форматов, EXIF-координаты отсутствуют в результате, средний вес трёх размеров не превышает 45 КБ.

Как проверяем

На выборке в 100 000 изображений: ни в одной миниатюре нет полей EXIF с координатами и моделью устройства; средний вес соответствует расчёту I0.7 с отклонением не более 15%.

Риск

Пересчёт всех миниатюр при смене формата — многомесячная операция. Смягчение: формат и размеры зафиксированы в схеме с версией, пересчёт выполняется фоновой миграцией по частям.

Обход 2

I1.2

Отбраковка кандидатов до загрузки

Обходкритический путь2 backend4 нед.зависит от I1.1
Зачем

Главный рычаг стоимости всей вертикали (§24.19): загрузка — дорогая операция, а 70–85% кандидатов её не заслуживают. Отбраковка после загрузки экономит только диск, но не канал.

Что делаем
  1. Шесть дешёвых проверок из §24.7 в порядке возрастания стоимости.
  2. Счётчики по каждой причине отбраковки — они же станут отчётом вебмастеру (I1.22).
  3. Порог повторяемости: один и тот же адрес на N страницах сайта — шаблон, а не содержание.
  4. Настраиваемость порогов без выкатки кода.
  5. Замер доли отсева и его влияния на полноту: сколько хороших изображений теряется.
Готово, когда

Отсев на контрольной выборке не ниже 70% при потере хороших изображений не выше 2%.

Как проверяем

Выборка из 2000 отбракованных кандидатов размечается вручную: доля ошибочно отброшенных содержательных изображений не выше 2%.

Риск

Агрессивный отсев выбрасывает единственную иллюстрацию небольшого сайта. Смягчение: правило повторяемости считается по доле от числа страниц сайта, а не по абсолютному числу.

I1.3

Загрузчик изображений

Обход2 backend6 нед.зависит от I1.2, 1.4
Зачем

Картиночный обход способен уронить сайт незаметнее, чем обход страниц: изображений на порядок больше, и они тяжелее.

Что делаем
  1. Отдельный класс вежливости: не более двух изображений в секунду на хост, общий бюджет с обходом страниц.
  2. Условные запросы по ETag и Last-Modified — картинки меняются реже страниц.
  3. Ограничения: 20 МБ на файл, 100 мегапикселей до декодирования, таймауты на каждую стадию.
  4. Поддержка форматов JPEG, PNG, WebP, AVIF, GIF, HEIC и SVG с обезвреживанием.
  5. Декодирование в песочнице с ограничением памяти и времени.
  6. Повторные попытки и карантин хостов, отдающих ошибки на изображениях, но не на страницах.
Готово, когда

Загрузчик держит заявленные лимиты под нагрузкой, декодер не выходит за границы памяти на подготовленных вредоносных файлах, доля 304 на повторном обходе не ниже 80%.

Как проверяем

Набор из 50 намеренно вредоносных файлов (зип-бомбы, гигантские размеры, битые заголовки, SVG со скриптами) не приводит ни к одному падению и ни к одному выходу за лимит памяти.

Риск

Библиотека декодирования — известная точка уязвимостей. Смягчение: декодирование в отдельном процессе с ограничением прав, обновление библиотек как отдельный регламент.

Индекс и поиск 5

I1.6

Схема записи изображения

Индекс и поиск2 backend4 нед.зависит от I0.8, 1.59
Зачем

Изображение — самостоятельная сущность со списком носителей, а не поле документа (§24.1). Схема, начатая как поле, потом не переделывается: на ней успевает вырасти всё остальное.

Что делаем
  1. Схема по §24.6 с разделением полей на четыре группы по происхождению и доверию.
  2. Регистрация схемы в реестре 1.59 с версией и правилом совместимости.
  3. Связь «изображение — страницы-носители» как отдельная таблица с датами первой встречи.
  4. Поля под визуальные признаки, заполняемые позже (эмбеддинг, классы), объявляются сразу — как это сделано для заготовок ИИ в ai.py.
  5. Ключ шардирования и правило раскладки, согласованные с 1.14.
Готово, когда

Схема зарегистрирована, несовместимое изменение не проходит сборку, связь с носителями хранится отдельной таблицей.

Как проверяем

Попытка выкатить несовместимое изменение схемы останавливается сборкой автоматически.

Риск

Ключ шардирования по хосту файла даёт перекос на крупных CDN. Смягчение: вторичное расщепление гигантов — тот же приём, что в shard.py, где перекос снижен с 51% до 7.7%.

I1.7

Текстовые поля изображения и BM25F

Индекс и поиск2 backend5 нед.зависит от I1.6, I1.1
Зачем

Все текстовые сигналы изображения — внешние, и веса у них должны быть разными: подпись под фотографией и alt, написанный ради поисковика, стоят по-разному.

Что делаем
  1. Девять полей из §24.9 как отдельные поля BM25F с априорными весами.
  2. Морфология и лемматизация на тех же правилах, что в вебе (text.py).
  3. Правило согласия: расхождение alt с окружающим текстом снижает доверие к alt на хосте.
  4. Слияние текста со всех носителей одной группы дублей — с ограничением вклада одного носителя.
  5. Инкрементальное обновление при появлении нового носителя.
Готово, когда

Поиск по текстовым полям работает на индексе из 10 млн изображений, правило согласия считается, вклад одного носителя ограничен.

Как проверяем

На корзине I0.4 замер pFound по чисто текстовому ранжированию даёт базовый уровень, зафиксированный как точка отсчёта для всех дальнейших улучшений.

Риск

Слияние текста от сорока носителей превращает запись в мешок ключевых слов. Смягчение: вклад носителя ограничен, ограничение проверяется замером на корзине.

I1.8

Перцептивный хеш и группировка дублей

Индекс и поисккритический путь2 backend + 1 ML6 нед.зависит от I1.4, I0.5
Зачем

Десять копий одной картинки в сетке читаются как поломка поиска, даже если каждая релевантна. Дедупликация здесь — не гигиена индекса, а видимое качество продукта.

Что делаем
  1. Точный дубль по SHA-256 и перцептивный по dHash 64 бита.
  2. Блочный поиск кандидатов по хешу — приём, уже применённый для текста в simhash.py.
  3. Транзитивная группировка с ограничением диаметра группы: иначе цепочка похожестей склеивает несвязанное.
  4. Устойчивость к обрезке полей, водяному знаку в углу и зеркальному отражению.
  5. Подбор порога на половине корзины I0.5 с проверкой на второй половине.
Готово, когда

Полнота группировки на корзине I0.5 не ниже 0.85 при точности не ниже 0.95, диаметр группы ограничен.

Как проверяем

Замер на второй половине корзины, не участвовавшей в подборе порога; результат воспроизводится в общем прогоне тестов.

Риск

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

I1.9

Выбор представителя группы и версии

Индекс и поиск1 backend3 нед.зависит от I1.8
Зачем

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

Что делаем
  1. Правило выбора по §24.10: разрешение → отсутствие водяного знака → авторитет носителя → ранняя дата.
  2. Список версий по убыванию разрешения — для раздела «Другие размеры».
  3. Детектор водяного знака как отдельный признак (эвристика по краевым областям на этой фазе).
  4. Пересчёт представителя при появлении версии лучше.
Готово, когда

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

Как проверяем

На 200 группах из корзины I0.5 выбор представителя совпадает с экспертным в 90% случаев.

Риск

Крупнейшая версия оказывается апскейлом — формально больше, фактически хуже. Смягчение: в правило включается оценка реальной резкости, а не только число пикселей.

I2.2

Индекс ближайших соседей

Индекс и поисккритический путь2 backend6 нед.зависит от I2.1, 1.14
Зачем

Миллиард векторов не перебирается. Структура поиска соседей определяет и задержку вертикали, и объём памяти на шард — то есть стоимость всей затеи.

Что делаем
  1. Сжатие векторов до 64 байт и HNSW поверх сжатых представлений (§24.10).
  2. Переранжирование топ-200 по несжатым векторам с диска.
  3. Раскладка по шардам, согласованная с шардированием индекса изображений.
  4. Инкрементальное добавление без полной перестройки.
  5. Замер задержки и полноты относительно полного перебора на подвыборке.
Готово, когда

Поиск соседей укладывается в 40 мс на p95 в шарде, полнота относительно полного перебора не ниже 0.95, добавление инкрементальное.

Как проверяем

Стенд на 50 млн векторов: замер задержки, полноты и памяти; сверка с полным перебором на 1000 запросах.

Риск

Инкрементальное добавление постепенно ухудшает граф. Смягчение: замер полноты идёт ежедневно, при падении ниже порога шард перестраивается фоном.

Ранжирование 8

I1.13

Отбор кандидатов и жёсткие фильтры

Ранжирование2 backend5 нед.зависит от I1.7, I1.8
Зачем

Уровень L0 определяет потолок качества: чего нет среди кандидатов, того не будет в выдаче ни на каком уровне переранжирования.

Что делаем
  1. Отбор по текстовым полям с отсечением непроходных — тот же приём, что в wand.py.
  2. Жёсткие фильтры как условия отбора, а не как постфильтрация: размер, тип, цвет, лицензия, безопасный поиск.
  3. Схлопывание группы дублей на уровне отбора, а не после ранжирования.
  4. Бюджет 30 мс на p95 при индексе 100 млн изображений.
Готово, когда

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

Как проверяем

Стенд с замером задержки и сверкой выдачи с полным перебором на подвыборке: расхождений в составе топ-60 нет.

Риск

Жёсткий фильтр по редкому цвету оставляет ноль кандидатов. Смягчение: при пустой выдаче фильтр ослабляется с явным сообщением пользователю, а не молча.

I1.14

Линейная модель ранжирования вертикали

Ранжирование1 backend + 1 ML4 нед.зависит от I1.13, I0.4
Зачем

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

Что делаем
  1. Двадцать признаков по группам §24.11 с априорными весами.
  2. Явное разложение вклада каждого признака — вход для панели «почему найдено» (I2.12).
  3. Замер вклада каждого признака отдельным отключением.
  4. Фиксация весов в реестре признаков (2.1) с датой и обоснованием.
Готово, когда

Модель работает, вклад признаков раскладывается, pFound на корзине I0.4 не ниже 0.55.

Как проверяем

Замер на корзине I0.4 в общем прогоне; отключение любого признака ухудшает или не меняет метрику, но не улучшает её.

Риск

Априорные веса выдаются за обученные. Смягчение: в интерфейсе и в реестре они помечены как априорные — так же, как это сделано в quality.py.

I1.15

Правила разнообразия сетки

Ранжирование1 backend3 нед.зависит от I1.14
Зачем

Сетка из шестидесяти релевантных картинок с одного сайта бесполезна. В вебе это правило уже есть (1.25), но здесь оно строже: однообразие видно взглядом, а не чтением.

Что делаем
  1. Четыре правила из §24.11: хост, дубли, цветовая доминанта, классы содержимого в первом ряду.
  2. Применение правил после ранжирования, но до раскладки рядов.
  3. Замер цены разнообразия: насколько падает pFound и насколько растёт оценка «сетка целиком» из I0.4.
  4. Настраиваемость порогов без выкатки.
Готово, когда

Правила применяются, оценка «первый экран» на корзине I0.4 растёт, падение pFound не превышает 0.02.

Как проверяем

Сравнение двух прогонов на корзине: с правилами и без, по обеим метрикам сразу.

Риск

Разнообразие ради разнообразия выталкивает лучший результат из первого ряда. Смягчение: первое место в выдаче правилам разнообразия не подчиняется.

I2.3

Слияние текстовой и визуальной ветвей

Ранжирование1 backend + 1 ML4 нед.зависит от I2.2, I1.13
Зачем

Проект уже наступил на это в вебе: узким местом гибридного поиска оказалась не векторная ветвь, а способ слияния (§22.7). Повторять ошибку во второй раз непозволительно.

Что делаем
  1. Слияние по обратным рангам (RRF) как основной способ — без взвешенной суммы несравнимых величин.
  2. Вес ветвей в зависимости от класса намерения запроса.
  3. Пометка происхождения результата: найдено текстом, вектором или обоими.
  4. Замер вклада каждой ветви отключением.
Готово, когда

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

Как проверяем

Три прогона на корзине I0.4: только текст, только вектор, слияние; результат слияния лучше обоих.

Риск

Векторная ветвь тянет вверх красивое, но нерелевантное. Смягчение: вес ветви привязан к классу намерения, а не задан константой.

I2.7

Обучение весов текстовых полей

Ранжирование2 ML5 нед.зависит от I1.7, I0.4
Зачем

Веса полей из §24.9 априорные. Обучить их на корзине — самое дешёвое улучшение вертикали из возможных: данные уже собраны, инфраструктура уже есть.

Что делаем
  1. Обучение весов BM25F на корзине I0.4 с разделением на обучение и проверку.
  2. Отдельные веса для классов намерения, если разделение даёт прирост.
  3. Проверка на утечку: запросы проверочной половины не участвуют в обучении.
  4. Запись обученных весов в реестр признаков с датой и метрикой.
Готово, когда

Обученные веса дают прирост pFound не менее 0.03 на проверочной половине, утечка исключена проверкой.

Как проверяем

Прогон на отложенной части корзины, не участвовавшей ни в подборе, ни в обучении.

Риск

Прирост на корзине не переносится на живой поток. Смягчение: подтверждение интерливингом (2.10) до выкатки на всех.

I2.8

Ранжирование второго уровня

Ранжирование2 ML6 нед.зависит от I2.3, I2.7, 2.3
Зачем

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

Что делаем
  1. Около 180 признаков по группам §24.11, включая визуальные и признаки группы дублей.
  2. Обучение на корзине I0.4 в той же инфраструктуре, что 2.3.
  3. Бюджет 60 мс на топ-200.
  4. Регистрация признаков в реестре 2.1 со сроком жизни.
  5. Сравнение с L1 на отложенной корзине и по интерливингу.
Готово, когда

L2 даёт прирост pFound не менее 0.06 относительно L1, укладывается в бюджет задержки, признаки зарегистрированы.

Как проверяем

Замер на отложенной корзине и подтверждение интерливингом на живом трафике.

Риск

Модель выучивает артефакты корзины — например, предпочтение крупным файлам. Смягчение: анализ важности признаков вручную перед выкаткой, с отклонением подозрительных.

I3.5

Поведенческие признаки вертикали

Ранжирование1 ML + 1 backend5 нед.зависит от I3.1, 3.7
Зачем

В картинках поведение информативнее, чем в вебе: открытие карточки и переход на источник — быстрые и частые сигналы. И так же быстро накручиваются.

Что делаем
  1. Признаки: доля открытий карточки, доля переходов на источник, возвраты, время до первого клика.
  2. Нормировка по позиции в сетке: верхний ряд получает клики просто потому, что он верхний.
  3. Защита от накрутки на механизмах 3.9.
  4. Отдельный замер вклада поведенческих признаков.
Готово, когда

Признаки считаются, нормировка по позиции применена, прирост качества измерен, накрутка обнаруживается.

Как проверяем

Замер на отложенной корзине и проверка защиты имитацией накрутки на тестовом контуре.

Риск

Признаки закрепляют текущую выдачу: что показано наверху, то и кликают. Смягчение: доля трафика исследования по правилам 3.8, нормировка по позиции обязательна.

I3.6

Нейросетевое переранжирование

Ранжирование2 ML6 нед.зависит от I2.8, I3.5, 2.9
Зачем

Последний уровень каскада: соответствие изображения запросу оценивается моделью, видящей и текст запроса, и само изображение, а не только признаки.

Что делаем
  1. Переранжирование топ-60 моделью общего пространства текста и изображения.
  2. Бюджет 90 мс на p95 в общем бюджете вертикали.
  3. Обучение на корзине и на поведенческих данных с проверкой на утечку.
  4. Флаг функции и возможность мгновенного отключения.
Готово, когда

L3 даёт прирост pFound не менее 0.04 к L2, укладывается в бюджет, отключается флагом за минуту.

Как проверяем

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

Риск

Задержка модели съедает бюджет вертикали. Смягчение: резерв в бюджете задержек по правилу 1.55; при исчерпании — деградация до L2 без отказа.

Продукт 17

I1.16

Вкладка «Картинки»: сетка

Продукткритический путь2 frontend6 нед.зависит от I1.14, 1.26
Зачем

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

Что делаем
  1. Обоснованные ряды с целевой высотой 200 px и допуском ±25% (§24.12).
  2. Резервирование места до загрузки файлов: CLS не выше 0.02.
  3. Ленивая загрузка с порогом в два экрана, srcset по плотности пикселей.
  4. Догрузка по кнопке и по прокрутке с остановкой каждые 300 результатов.
  5. Подпись на карточке при наведении и при фокусе с клавиатуры.
  6. Мобильная раскладка с высотой ряда 140 px.
Готово, когда

Сетка раскладывается без искажения пропорций, CLS не выше 0.02, LCP на 4G не выше 1.8 с, лента останавливается каждые 300 результатов.

Как проверяем

Замер CLS и LCP на трёх типах запросов и трёх ширинах окна; проверка соответствия макету mockups/images.html.

Риск

Раскладка пересчитывается на каждом кадре прокрутки и греет процессор. Смягчение: раскладка считается один раз на порцию и кешируется по ширине контейнера.

I1.17

Просмотрщик с приоритетом источника

Продукткритический путь2 frontend5 нед.зависит от I1.16, I0.2
Зачем

Место, где решается главный правовой и этический вопрос вертикали: ведём ли мы к источнику или заменяем его (§24.13). Требования сформулированы в I0.2 и здесь исполняются.

Что делаем
  1. Панель с изображением, метаданными и действиями; первичная кнопка — «Перейти на страницу».
  2. Открытие файла — вторичной ссылкой с пометкой, на чьём сайте лежит файл.
  3. Изменение адреса при открытии: «назад» закрывает просмотрщик, а не уходит с выдачи.
  4. Разделы «Все страницы», «Другие размеры», «Почему найдено» (последний — заготовка до I2.12).
  5. Переход к соседним изображениям стрелками с синхронной прокруткой сетки.
  6. Кнопка жалобы с предзаполненной формой site/legal/removal.html.
  7. Отсутствие рекламы в просмотрщике — как правило, а не как текущее состояние.
Готово, когда

Каждое требование списка I0.2 выполнено, адрес меняется, «назад» работает, реклама отсутствует.

Как проверяем

Построчная сверка со списком требований I0.2 и проверка сценария «открыл — вернулся» на трёх браузерах.

Риск

Первичная кнопка на источник снижает вовлечённость, и её начинают «оптимизировать». Смягчение: правило записано в документ продукта со ссылкой на правовое основание, а не на предпочтение дизайнера.

I1.18

Фильтры вертикали

Продукт1 frontend + 1 backend4 нед.зависит от I1.13, I1.12
Зачем

В картинках фильтр — не вспомогательный инструмент, а часть запроса: «нужна крупная горизонтальная фотография без текста» словами не формулируется.

Что делаем
  1. Девять фильтров из §24.14 с мгновенным применением без перезагрузки.
  2. Запись состояния фильтров в адрес и восстановление при возврате «назад».
  3. Кнопка сброса, видимая при любом непустом наборе.
  4. Сообщение при пустой выдаче с предложением снять конкретный фильтр.
  5. Соответствие операторам языка запросов: фильтр и оператор дают одинаковый результат.
Готово, когда

Фильтры применяются мгновенно, состояние живёт в адресе, оператор и фильтр дают идентичную выдачу.

Как проверяем

Автотест сверяет выдачу по size:large и по фильтру «Большие» — списки совпадают полностью.

Риск

Число фильтров превращает панель в форму настройки. Смягчение: на первом экране не более пяти, остальные — под кнопкой «Ещё фильтры».

I1.19

Доступность сетки и просмотрщика

Продукт1 frontend4 нед.зависит от I1.16, I1.17
Зачем

Сетка изображений — самый недоступный элемент любого поиска: бесконечная лента, отсутствие альтернативного текста и мышиные жесты вместо клавиатуры. Проект обязался соблюдать WCAG 2.2 AA (§6.8), и здесь это дороже всего.

Что делаем
  1. Роль grid и перемещение стрелками по строкам и столбцам.
  2. Альтернативный текст: из источника, при отсутствии — осмысленная замена, а не пустая строка.
  3. Ловушка фокуса в просмотрщике и возврат фокуса на исходную карточку по Esc.
  4. Объявление изменений через aria-live: сколько показано, какие фильтры применены.
  5. Подписи на подложке, а не поверх изображения, — контраст не ниже 4.5:1 при любой картинке.
  6. Уважение prefers-reduced-motion.
Готово, когда

Вся вертикаль проходима с клавиатуры, скринридер объявляет состояние, контраст подписей соблюдён на любом изображении.

Как проверяем

Проверка двумя скринридерами и полное прохождение сценария поиска без мыши; автоматическая проверка контраста на 200 случайных карточках.

Риск

Стрелки конфликтуют с прокруткой страницы. Смягчение: сетка перехватывает стрелки только при фокусе внутри неё, что проверяется отдельным тестом.

I1.20

Работа без JavaScript и постраничная навигация

Продукт1 frontend3 нед.зависит от I1.16
Зачем

Требование §6.1 действует и здесь: выдача работает без JavaScript. Для сетки картинок это не идеология, а способ остаться доступным для поисковых роботов, читалок и медленных сетей.

Что делаем
  1. Серверная отрисовка первой порции сетки с готовыми размерами рядов.
  2. Постраничная навигация как основной путь при отключённом JavaScript.
  3. Фильтры как обычная форма с отправкой на сервер.
  4. Просмотрщик как отдельная страница при отсутствии JavaScript.
Готово, когда

При отключённом JavaScript работают поиск, фильтры, постраничная навигация и просмотр изображения.

Как проверяем

Полный сценарий поиска и просмотра в браузере с отключённым JavaScript и в текстовом браузере.

Риск

Серверная раскладка рядов расходится с клиентской, и при включении JavaScript сетка «прыгает». Смягчение: алгоритм раскладки один и тот же, вынесен в общий модуль и покрыт тестом на совпадение.

I1.22

Отчёт по изображениям в кабинете вебмастера

Продукт1 frontend + 1 backend4 нед.зависит от I1.2, I1.5, 2.24
Зачем

Вебмастер, чьи картинки не попали в индекс, сегодня не может узнать почему ни у одного поисковика. Счётчики причин отбраковки у нас уже есть (I1.2) — остаётся их показать.

Что делаем
  1. Сколько изображений с сайта в индексе и динамика.
  2. Отбраковано и почему — по причинам §24.7, с примерами адресов.
  3. Ошибки alt: пустые, дублирующиеся, расходящиеся с содержимым.
  4. Состояние разметки ImageObject — на механизме 1.13.
  5. Точечный запрет показа по файлу или маске с исполнением через I1.5.
Готово, когда

Отчёт показывает пять разделов, запрет из кабинета исполняется за 24 часа, примеры адресов доступны для каждой причины.

Как проверяем

Контрольный сайт с намеренно внесёнными ошибками: каждая ошибка появляется в отчёте в течение суток после обхода.

Риск

Отчёт раскрывает пороги отбраковки и становится инструкцией по их обходу. Смягчение: причина называется, численный порог — нет.

I2.4

Приём изображения как запроса

Продукт1 frontend + 1 backend5 нед.зависит от I2.2, I0.2
Зачем

Способ ввода, ради которого половина пользователей приходит в вертикаль. Четыре пути ввода из §24.5 должны вести к одному результату и оставлять после себя ссылку, которую можно переслать.

Что делаем
  1. Загрузка файла, перетаскивание в окно, вставка из буфера, ссылка на изображение.
  2. Временный идентификатор запроса-изображения и постоянная ссылка на результат.
  3. Ограничения по весу и формату с понятными сообщениями об ошибке.
  4. Текстовая замена для каждого пути при отключённом JavaScript.
  5. Индикация состояния: что загружено, чем ищем, как отменить.
Готово, когда

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

Как проверяем

Один и тот же файл, введённый четырьмя способами, даёт идентичные первые двадцать результатов.

Риск

Постоянная ссылка на загруженное изображение живёт дольше, чем ожидает пользователь. Смягчение: срок жизни ограничен и назван прямо в интерфейсе (I2.13).

I2.5

Поиск по фрагменту

Продукт1 frontend + 1 backend4 нед.зависит от I2.4
Зачем

Запрос обычно относится не ко всему кадру, а к предмету в нём. Рамка на изображении — единственный способ сказать «вот это», не подбирая слов.

Что делаем
  1. Рамка поверх загруженного изображения с перетаскиванием и изменением размера.
  2. Пересчёт вектора по вырезанной области, а не по всему кадру.
  3. Автоматическое предложение рамки по крупнейшему объекту (эвристика до I4.1).
  4. Передача области в адрес результата — фрагмент воспроизводится по ссылке.
  5. Управление рамкой с клавиатуры.
Готово, когда

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

Как проверяем

Корзина из 100 изображений с предметом в углу кадра: поиск по фрагменту находит предмет чаще, чем поиск по всему кадру, — измеряется долей верных ответов в топ-5.

Риск

Рамка на мобильном неуправляема пальцем. Смягчение: увеличенные зоны захвата и режим «уточнить» с отдельным экраном.

I2.6

Похожие изображения

Продукт1 frontend + 1 backend3 нед.зависит от I2.2
Зачем

Продолжение поиска без формулировки нового запроса. В картинках это работает лучше, чем в вебе: похожесть видна мгновенно и не требует чтения.

Что делаем
  1. Лента похожих под просмотрщиком по косинусной близости с порогом.
  2. Исключение из ленты дублей той же группы — для них есть «Другие размеры».
  3. Переход от похожего к похожему без потери исходного запроса.
  4. Пометка, что лента построена по изображению, а не по тексту запроса.
Готово, когда

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

Как проверяем

Асессорская оценка 300 лент: доля релевантных в первых десяти не ниже 0.7.

Риск

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

I2.11

Фильтр лицензий

Продукт1 frontend + 1 backend3 нед.зависит от I0.3, I1.18
Зачем

Для половины сценариев («нужна картинка в презентацию») право использования — главный фильтр, а не дополнительный. У Google он есть и спрятан; наше отличие в том, что он на виду (§24.4).

Что делаем
  1. Три значения фильтра по политике I0.3 плюс «любая».
  2. Бейдж лицензии на карточке в сетке и в просмотрщике.
  3. Явное «лицензия неизвестна» вместо умолчания «свободная».
  4. Ссылка на страницу приобретения лицензии, если она объявлена разметкой.
  5. Дисклеймер о проверке на стороне пользователя в формулировке юриста.
Готово, когда

Фильтр работает, бейдж показывается, неизвестная лицензия называется неизвестной, ссылка на приобретение работает там, где объявлена.

Как проверяем

Замер на корзине I0.3: совпадение объявленной лицензии с проверенной вручную не ниже 99% при доле «неизвестна» не выше 60%.

Риск

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

I2.12

Панель «почему найдено»

Продукт1 frontend + 1 backend3 нед.зависит от I1.14, I2.8
Зачем

Отличие проекта, уже сделанное в веб-выдаче: вебмастер видит вклад признаков в позицию. В картинках вопрос «почему моя фотография на сороковом месте» задаётся чаще, а ответа не даёт никто.

Что делаем
  1. Разложение скора по группам признаков §24.11 в просмотрщике.
  2. Пометка происхождения результата из I2.3: текст, вектор или оба.
  3. Указание, какие правила применились: разнообразие, схлопывание дублей, безопасный поиск.
  4. Ограничение раскрытия: называем группы и направление вклада, не называем численные пороги.
Готово, когда

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

Как проверяем

Сверка вклада, показанного в панели, с формулой ранжирования на 100 результатах — расхождений нет.

Риск

Панель становится инструкцией по накрутке. Смягчение: раскрываются группы и знак вклада, а не веса и пороги — то же правило, что в веб-выдаче.

I3.3

Колдунщик «картинки в строку»

Продукт1 frontend + 1 backend4 нед.зависит от I2.8, 3.16
Зачем

Обратная связка с вебом: на визуальном запросе ряд картинок отвечает лучше десяти ссылок. Правило вытеснения (§6.4) при этом не отменяется.

Что делаем
  1. Триггер по классу намерения с порогом уверенности и минимальным числом хороших изображений.
  2. Один ряд, 6–8 картинок, без прокрутки внутри ряда.
  3. Позиция по правилам вытеснения; учёт в общем лимите блоков.
  4. Переход в вертикаль с сохранением запроса и в просмотрщик по клику.
  5. Замер: растёт ли доля решённых задач и не падает ли переход на органику.
Готово, когда

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

Как проверяем

Эксперимент с разделением трафика: доля отказов не растёт, доля переходов на сайты не падает более чем на 1 процентный пункт.

Риск

Блок отодвигает органику и забирает клики у сайтов. Смягчение: правило вытеснения из §6.4 применяется без исключений, что проверяется автотестом раскладки.

I3.4

Метод программного интерфейса

Продукт1 backend4 нед.зависит от I2.4, 3.17
Зачем

Платный метод из 08 и единственный способ для автора найти свои картинки в чужих руках — сценарий, ради которого адрес оригинала отдаётся всегда (§24.21).

Что делаем
  1. Параметры по §24.21, включая поиск по изображению и по фрагменту.
  2. Формат ответа с миниатюрой, оригиналом, источником, первоисточником и лицензией.
  3. Квоты и тарификация в общей схеме интерфейса.
  4. Ошибки с именем поля — тот же контракт, что у остальных методов.
  5. Документация с примерами и ограничениями на использование ответа.
Готово, когда

Метод отвечает по контракту, квоты применяются, документация опубликована, ошибки называют поле.

Как проверяем

Набор контрактных тестов, проверяющий каждый параметр и каждый класс ошибки.

Риск

Метод используется для массового скачивания чужих изображений. Смягчение: отдаём адреса, а не файлы; квоты и обнаружение аномального профиля использования.

I3.8

Камера и голосовой ввод

Продукт2 мобильных5 нед.зависит от I2.4, 4.4
Зачем

На мобильном камера — самый естественный способ ввода для картинок, и ровно там, где текстовый ввод самый неудобный.

Что делаем
  1. Съёмка кадра и поиск по нему — снимок, а не поток.
  2. Рамка фрагмента на снятом кадре.
  3. Голосовой ввод текстового запроса на общем механизме 2.37.
  4. Работа на медленной сети: сжатие кадра до отправки.
  5. Явное согласие на доступ к камере с объяснением, что произойдёт со снимком.
Готово, когда

Съёмка и поиск работают на обеих мобильных платформах, кадр сжимается перед отправкой, согласие запрашивается с объяснением.

Как проверяем

Сценарные испытания на десяти моделях устройств, включая медленную сеть; замер времени от снимка до выдачи.

Риск

Снимок уходит на сервер до согласия. Смягчение: порядок операций закреплён тестом, а не соглашением между разработчиками.

I3.9

Управление изображениями в кабинете

Продукт1 frontend + 1 backend4 нед.зависит от I1.22, I2.9
Зачем

Вторая половина отличия из §24.4: не только показать, что мы взяли, но и дать управлять — включая ответ на вопрос «кто ещё использует мои картинки».

Что делаем
  1. Отчёт «кто использует ваши изображения» на основе групп дублей.
  2. Показы и переходы по изображениям сайта.
  3. Управление точечными запретами списком с историей изменений.
  4. Заявление о первоисточнике с проверкой прав на сайт.
  5. Выгрузка отчёта в машинно-читаемом виде.
Готово, когда

Четыре отчёта работают, запреты управляются списком, выгрузка доступна.

Как проверяем

Контрольный сайт: изображение, скопированное на второй сайт, появляется в отчёте «кто использует» в течение недели после обхода.

Риск

Отчёт «кто использует» становится инструментом давления на добросовестных цитирующих. Смягчение: отчёт информационный, никаких автоматических действий из него не следует.

I4.3

Поиск товара по фотографии

Продукт2 backend + 1 ML8 нед.зависит от I4.1, 4.2
Зачем

Сценарий с наибольшей коммерческой ценностью и наибольшим спросом на мобильном: сфотографировать вещь и найти, где её купить.

Что делаем
  1. Связь изображения с товарными карточками вертикали «Товары».
  2. Поиск похожих товаров по фотографии, снятой в неидеальных условиях.
  3. Показ предложений с ценой и наличием под просмотрщиком.
  4. Явное разделение органических изображений и товарных предложений.
  5. Замер на корзине из 200 фотографий реальных вещей.
Готово, когда

По фотографии находятся товарные карточки, предложения отделены от органики, замер на корзине проведён.

Как проверяем

Корзина из 200 фотографий: верный товар в топ-5 не менее чем в 60% случаев.

Риск

Сценарий превращается в скрытую рекламу. Смягчение: товарные предложения помечены и отделены визуально, как требует §6.1.

I4.8

Инструменты автора

Продукт1 frontend + 1 backend5 нед.зависит от I3.9, I2.9
Зачем

У автора изображений сегодня нет ни одного инструмента, чтобы следить за своими работами в вебе. Это отличие, которое невозможно скопировать быстро: оно требует групп дублей и первоисточника, то есть всего, что построено в I1 и I2.

Что делаем
  1. Подписка на появление новых носителей своего изображения.
  2. Отчёт по подтверждённым сайтам автора с историей.
  3. Выгрузка списка носителей в машинно-читаемом виде.
  4. Прямой переход к форме обращения по праву при обнаружении нарушения.
  5. Ограничения против использования инструмента для слежки за чужими изображениями.
Готово, когда

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

Как проверяем

Попытка подписаться на изображение с неподтверждённого сайта отклоняется; появление нового носителя приводит к уведомлению в течение недели.

Риск

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

Антиспам 1

I2.10

Антиспам вертикали

Антиспам1 ML + 1 backend5 нед.зависит от I2.1, I1.7, 2.12
Зачем

Все текстовые сигналы картинки внешние и подделываются бесплатно. Без визуальной проверки согласия вертикаль превращается в галерею дорвеев за один квартал.

Что делаем
  1. Пять приёмов из таблицы §24.11 как отдельные детекторы.
  2. Проверка согласия текста и изображения по общему пространству представлений.
  3. Признак «ворованная галерея»: доля оригинальных изображений на хосте.
  4. Проверка подмены по User-Agent выборочной загрузкой из другого пула адресов.
  5. Защита от ложных срабатываний на добросовестных двойниках — как в spam.py.
Готово, когда

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

Как проверяем

Размеченный спам-корпус изображений: полнота отсева не ниже 0.85 при названной доле ложных срабатываний.

Риск

Детектор «ворованной галереи» бьёт по легальным агрегаторам стоков. Смягчение: наличие лицензионной разметки и договорных отношений — отдельный признак-исключение.

Многоязычие 2

I3.7

Английский сегмент вертикали

Многоязычие1 backend + 1 аналитик5 нед.зависит от I3.1, 2.42, 3.36
Зачем

Картинки — самая языконезависимая вертикаль: изображение одно, подписи на разных языках. Это делает её естественной первой ступенью выхода за пределы русского.

Что делаем
  1. Текстовые поля на английском в том же индексе, без отдельного контура.
  2. Слияние подписей на разных языках в одной группе дублей.
  3. Английская корзина визуальных запросов на 200 запросов.
  4. Замер качества отдельно по языкам.
  5. Кросс-языковой ответ: русский запрос находит изображение с английской подписью.
Готово, когда

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

Как проверяем

Замер pFound отдельно на русской и английской корзинах; проверка кросс-языкового сценария на 100 парах запросов.

Риск

Смешение языков в полях ухудшает русскую выдачу. Смягчение: язык поля хранится явно, вес поля зависит от языка запроса.

I4.5

Перевод текста на изображении

Многоязычие1 backend5 нед.зависит от I4.2, T3.6
Зачем

Стык двух треков, дающий сценарий, которого нет по отдельности ни у одного: нашли вывеску или схему на чужом языке — прочитали на своём.

Что делаем
  1. Перевод распознанного текста движком трека переводчика.
  2. Подстановка перевода на изображение в просмотрщике с переключателем «оригинал / перевод».
  3. Откат к списку строк, когда подстановка нечитаема.
  4. Пометка машинного происхождения перевода.
Готово, когда

Перевод подставляется читаемо, переключение работает, при невозможности показывается список строк.

Как проверяем

Оценка асессорами на 200 изображениях: читаемость и уместность подстановки не ниже, чем в приёмке T3.6.

Риск

Подстановка портит изображение. Смягчение: при сложном фоне используется подложка под текст, а не затирание.

ИИ-структура 3

I4.1

Распознавание объектов на изображении

ИИ-структура3 ML8 нед.зависит от I2.1, 2.53
Зачем

Основа сценария «что это»: без списка объектов поиск по картинке отвечает «похоже вот на это», но не отвечает «это вот что».

Что делаем
  1. Модель обнаружения объектов с проверкой лицензии по правилам I2.1.
  2. Автоматическое предложение рамки фрагмента по крупнейшему объекту (замена эвристике I2.5).
  3. Подписи объектов на русском с привязкой к сущностям графа знаний.
  4. Переход от объекта к текстовому запросу одним нажатием.
  5. Никакой идентификации людей — только класс «человек» (§24.16).
Готово, когда

Объекты обнаруживаются, рамка предлагается автоматически, подписи связаны с сущностями, лица не идентифицируются.

Как проверяем

Корзина из 500 изображений с размеченными объектами: полнота обнаружения не ниже 0.8 при точности не ниже 0.85.

Риск

Ошибочная подпись объекта воспринимается как утверждение поисковика. Смягчение: подпись подаётся как предположение с возможностью уточнить запрос текстом.

I4.2

Поиск текста на изображении

ИИ-структура2 ML + 1 backend8 нед.зависит от I4.1, T3.5
Зачем

Огромный пласт содержимого — таблицы, вывески, скриншоты, объявления — недоступен текстовому поиску, потому что текст в них не текст, а пиксели.

Что делаем
  1. Распознавание текста на изображениях на движке трека переводчика (T3.5) — без второй модели.
  2. Индексация распознанного как отдельного поля с собственным весом и пометкой происхождения.
  3. Порог уверенности: нераспознанное лучше неверно распознанного.
  4. Использование признака в антиспаме: текст-картинкой ради ключевых слов (§24.11).
  5. Замер прироста на запросах класса «текст».
Готово, когда

Распознанный текст индексируется отдельным полем, порог уверенности соблюдается, прирост на классе «текст» измерен.

Как проверяем

Корзина из 300 изображений с текстом: доля запросов, где нужное изображение попадает в топ-20, растёт не менее чем на 15 процентных пунктов.

Риск

Ошибки распознавания засоряют индекс мусорными словами. Смягчение: поле имеет пониженный вес и не участвует в точных фразовых совпадениях.

I4.4

Мультимодальный запрос

ИИ-структура2 ML8 нед.зависит от I4.1, 3.38
Зачем

«Такое же, но синее» и «где это находится» невозможно сформулировать ни картинкой, ни текстом по отдельности. Это и есть та задача, ради которой строится общее пространство представлений.

Что делаем
  1. Совмещение вектора изображения и текстового уточнения в одном запросе.
  2. Интерфейс: строка остаётся активной при загруженной картинке.
  3. Разбор типов уточнений: цвет, материал, количество, стиль, отрицание.
  4. Замер на корзине пар «изображение + уточнение» с известным ответом.
Готово, когда

Комбинированный запрос обрабатывается, типы уточнений разбираются, замер на корзине проведён.

Как проверяем

Корзина из 200 пар: доля верных ответов в топ-10 не ниже 0.5, что заметно выше поиска только по изображению.

Риск

Уточнение игнорируется, и результат неотличим от поиска по картинке. Смягчение: замер сравнивает с базовым сценарием обязательно, а не по желанию.

Ворота трека

Все критерии обязательны. Не пройдены — фаза продлевается, а не закрывается.

  • I0: решение «идём или не идём» принято и записано с обоснованием
  • I0: правовая позиция по показу чужих изображений подписана юристом
  • I0: корзина из 500 визуальных запросов размечена, согласие асессоров не ниже 0.6
  • I1: pFound@60 на визуальной корзине не ниже 0.55
  • I1: доля дублей в первых тридцати не выше 10%, полнота дедупликации не ниже 0.85
  • I1: пропуск явного содержимого при умеренном фильтре не выше 1.0%
  • I1: любой из четырёх видов запрета исполняется не позднее 24 часов
  • I1: вертикаль полностью проходима с клавиатуры и работает без JavaScript
  • I1: LCP сетки на 4G не выше 1.8 с, CLS не выше 0.02
  • I2: pFound@60 не ниже 0.68, доля дублей в первых тридцати не выше 4%
  • I2: при поиске по картинке исходное изображение в топ-5 не реже 80%
  • I2: загруженное пользователем изображение не оставляет следов после срока — подтверждено тестом
  • I2: объявленная лицензия совпадает с проверенной вручную не ниже 99%
  • I3: индекс на миллиард изображений, задержка p95 не выше 300 мс
  • I3: pFound@60 не ниже 0.75, LCP не выше 1.2 с
  • I3: слепое сравнение с Яндексом и Google на 300 запросах проведено и опубликовано
  • I3: обращения правообладателей рассматриваются не дольше трёх рабочих дней
  • I4: вертикаль передана в сопровождение с регламентом и назначенными ответственными

Параллельный трек

Переводчик

Месяцы
трек
Календарь
с фазы 3
Команда
24 чел.
Бюджет
520 млн ₽
Задач
64
Недель работ
312

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

Перевод 31

T0.1

Разбор спроса и решение о треке

Переводкритический путьпродукт + аналитик4 нед.
Зачем

Отделить «хотим переводчик, потому что он есть у Яндекса» от измеренной потребности, и определить, какие сценарии дают трафик, а какие — выручку.

Что делаем
  1. Оценка доли переводческих намерений в собственном потоке запросов на данных фазы 2.
  2. Разбор сценариев: перевод текста, страниц, документов, картинок, видео — частота и цена реализации каждого.
  3. Оценка кросс-языкового сценария: сколько запросов остаются без хорошего ответа на русском.
  4. Модель выручки: программный интерфейс и глоссарии как единственный прямой источник.
  5. Решение о старте трека с указанием, какие сценарии в него не входят.
Готово, когда

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

Как проверяем

Оценка доли переводческих намерений воспроизводится по описанной методике на свежем срезе запросов.

Риск

Спрос переоценён по аналогии с Яндексом, у которого переводчик тянет трафик браузера. Смягчение: считаем на своих данных, а не на чужих долях рынка.

T0.5

Добыча параллельных страниц из индекса

Переводкритический путь2 ML-инженера8 нед.зависит от 0.1
Зачем

Это то, что отличает нашу модель от открытой: свежий параллельный корпус рунета, которого нет ни в одном публичном наборе.

Что делаем
  1. Поиск кандидатов в индексе: страницы одного хоста с разными языковыми версиями по hreflang, по структуре адреса, по совпадению структуры документа.
  2. Оценка объёма: сколько параллельных пар даёт корпус фазы 3.
  3. Выравнивание документов: сопоставление страниц между языковыми версиями.
  4. Оценка чистоты выборки вручную на подвыборке в 500 пар.
  5. Учёт отказов из T0.3.
Готово, когда

Объём измерен, чистота выборки на подвыборке не ниже 90%, конвейер добычи работает на срезе индекса.

Как проверяем

Ручная проверка 500 пар: доля действительно параллельных страниц не ниже 90%.

Риск

Параллельных страниц в рунете меньше, чем ожидалось. Смягчение: объём измеряется в T0.5 до того, как на него рассчитан план обучения.

T0.9

Выбор стека и отчёт по фазе

Переводкритический путьлид трека3 нед.зависит от T0.8, T0.5, T0.7
Зачем

Ворота трека: до этой точки можно отказаться, потеряв три месяца анализа, а не два года разработки.

Что делаем
  1. Решение по модели ru↔en: обучаем свою или берём открытую с дообучением.
  2. Решение по остальным языкам и порядку их подключения.
  3. Решение по рантайму и обучающему фреймворку.
  4. Отчёт по фазе: разрыв, стоимость, лицензии, риски.
  5. Решение «идём дальше или нет» с указанием, при каком условии останавливаемся.
Готово, когда

Решения приняты письменно и обоснованы цифрами T0.8 и T0.7.

Как проверяем

Каждое решение в отчёте ссылается на конкретный замер, а не на общее соображение.

Риск

Разрыв оказывается таким, что закрыть его в бюджете трека нельзя. Смягчение: это и есть ворота — отказ здесь дешевле отказа через год.

T1.1

Конвейер очистки корпуса

Переводкритический путь2 ML-инженера6 нед.зависит от T0.9
Зачем

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

Что делаем
  1. Отбор и загрузка корпусов через OpusCleaner с записью источника и лицензии из реестра T0.2.
  2. Фильтры: длина, соотношение длин, доля цифр и латиницы, повторы, язык каждой стороны.
  3. Классификатор качества пары на Bicleaner AI с порогом, подобранным по корзине.
  4. Отсев машинного перевода: пары, подозрительно похожие на выход публичных систем.
  5. Журнал: сколько отсеяно на каждом фильтре и почему.
Готово, когда

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

Как проверяем

Ручная проверка 300 случайных пар после очистки: доля пригодных не ниже 95%.

Риск

Слишком жёсткая фильтрация выбрасывает редкие, но ценные явления. Смягчение: пороги подбираются по качеству модели на корзине, а не по «чистоте» корпуса.

T1.2

Выравнивание предложений из индекса

Переводкритический путь2 ML-инженера7 нед.зависит от T0.5, T1.1
Зачем

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

Что делаем
  1. Выравнивание предложений через многоязычные эмбеддинги LaBSE.
  2. Обработка несоответствий: абзац на одном языке против двух на другом.
  3. Отсев пар с низкой уверенностью сопоставления.
  4. Пропуск результата через конвейер очистки T1.1.
  5. Замер: сколько пригодных пар даёт индекс в месяц и как это растёт с обходом.
Готово, когда

Корпус из индекса собран, объём измерен, доля пригодных пар на ручной проверке не ниже 92%.

Как проверяем

Ручная проверка 300 пар; сравнение обучения с добавкой этого корпуса и без неё на корзине.

Риск

Собственный корпус не даёт прироста качества. Смягчение: проверяется обучением до того, как на нём строятся планы.

T1.3

Токенизация и словарь

ПереводML-инженер3 нед.зависит от T1.1
Зачем

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

Что делаем
  1. Обучение словаря SentencePiece на объединённом корпусе двух языков.
  2. Подбор размера словаря по качеству на корзине, а не по традиции.
  3. Проверка на русской морфологии: доля слов, режущихся по границам морфем.
  4. Отдельные метки для непереводимых подстановок из T1.9.
  5. Фиксация словаря как артефакта с версией: смена словаря означает переобучение.
Готово, когда

Словарь обучен, размер обоснован замером, метки подстановок зарезервированы.

Как проверяем

Сравнение двух-трёх размеров словаря на одинаковом обучении: выбранный не хуже остальных на корзине.

Риск

Словарь, оптимальный для новостей, плох для технических текстов. Смягчение: замер по типам текста отдельно.

T1.4

Обучение модели ru↔en

Переводкритический путь3 ML-инженера10 нед.зависит от T1.2, T1.3, T0.6
Зачем

Русский — наш главный язык, и качество на нём определяет продукт целиком. Открытые модели ru↔en обучены на нефильтрованных данных и на нашей корзине проигрывают заметно.

Что делаем
  1. Обучение модели на Marian: базовая архитектура, наши данные, наш словарь.
  2. Планирование состава данных через OpusTrainer: расписание смешивания корпусов по эпохам.
  3. Аугментация на устойчивость: опечатки, регистр, разметка внутри текста.
  4. Обратный перевод одноязычных текстов из индекса для расширения корпуса.
  5. Обучение в обе стороны: ru→en и en→ru — это две модели, а не одна.
Готово, когда

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

Как проверяем

Прогон корзины на стенде T0.6 по восьми типам текста: превосходство по каждому типу, а не только в среднем.

Риск

Обучение не даёт прироста над открытой моделью. Смягчение: если после двух циклов прироста нет, берём открытую модель с дообучением — это решение T0.9, а не поражение.

T1.5

Сервис перевода на открытых моделях

Переводкритический путь2 backend5 нед.зависит от T0.9
Зачем

Потребителям в основном плане переводчик нужен раньше, чем будет обучена собственная модель. Контракт, за которым сначала стоит открытая модель, снимает эту зависимость полностью.

Что делаем
  1. Входная точка yotti-tr-api с контрактом из документа, §23.5.6.
  2. Открытая модель, прошедшая по лицензии, как первая реализация.
  3. Квоты, авторизация, метрики, журнал вызовов.
  4. Клиентская библиотека для внутренних потребителей.
  5. Явное поле версии модели в ответе: потребитель всегда знает, чем переведено.
Готово, когда

Сервис в проде, задача 3.39 работает через него, а не через внешний интерфейс.

Как проверяем

Отключение внешнего интерфейса перевода не влияет на кросс-языковой поиск.

Риск

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

T1.6

Рантайм на CTranslate2 и квантование

ПереводML-инженер + backend5 нед.зависит от T1.4
Зачем

Модель, не влезающая в бюджет задержек, не улучшает продукт. Квантование даёт примерно четверть исходного размера при небольшой потере качества — без него быстрая ветка не работает на процессорах.

Что делаем
  1. Конвертация обученных моделей в формат CTranslate2.
  2. Квантование в INT8 и замер потери качества на корзине.
  3. Подбор параметров батчировки под два профиля нагрузки: одиночные запросы и пакеты.
  4. Замер задержки p50, p95, p99 на каждом профиле.
  5. Регресс-тест производительности в сборке (1.37).
Готово, когда

Быстрая ветка укладывается в 40 мс на предложение p95, потеря COMET от квантования не выше 0.5%.

Как проверяем

Нагрузочный прогон на профиле, соответствующем расчёту T0.7.

Риск

Квантование сильнее бьёт по редким языкам. Смягчение: замер потери по каждому языку отдельно, а не в среднем.

T1.7

Определение языка

ПереводML-инженер3 нед.зависит от T1.5
Зачем

Автоопределение языка — первое, что делает переводчик, и первое, где он ошибается. Ошибка здесь портит всё, что идёт следом.

Что делаем
  1. Внедрение GlotLID как основного определителя.
  2. Порог уверенности: ниже порога честно спрашиваем пользователя, а не угадываем.
  3. Учёт графики и подсказки интерфейса для коротких строк.
  4. Переиспользование определителя языка документа из 1.12, а не второй его экземпляр.
  5. Замер точности на коротких строках отдельно: это худший случай.
Готово, когда

Точность на строках длиннее 20 символов не ниже 98%, на коротких строках измерена и показана честно.

Как проверяем

Замер на размеченном наборе, включающем близкие языки: русский и украинский, сербский и хорватский.

Риск

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

T1.8

Сегментация на предложения

Переводbackend3 нед.зависит от T1.5
Зачем

Разрезанное пополам предложение переводится как два обрубка. Ошибка сегментации не исправляется никакой моделью — она уже произошла.

Что делаем
  1. Правила разбиения в формате SRX с исключениями на сокращения по языкам.
  2. Обработка списков, заголовков, таблиц: не всё, что без точки, — не предложение.
  3. Ограничение длины сегмента с разбиением по придаточным при переполнении.
  4. Склейка сегментов обратно с сохранением исходных пробелов и переносов.
  5. Набор тестов на сложных случаях: сокращения, инициалы, номера, адреса.
Готово, когда

На тестовом наборе сложных случаев ошибок сегментации нет; склейка возвращает исходное форматирование.

Как проверяем

Прогон: разбить и склеить без перевода — результат совпадает с исходником байт в байт.

Риск

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

T1.9

Защита разметки и подстановок

Переводкритический путьbackend + ML-инженер5 нед.зависит от T1.8, T1.3
Зачем

Без этого перевод страниц и документов ломает вёрстку, а перевод интерфейсных строк ломает подстановки. Это самая частая претензия к машинному переводу в продуктовых сценариях.

Что делаем
  1. Замена непереводимого на метки: теги, ссылки, адреса почты, числа с единицами, эмодзи, плейсхолдеры вида {name}.
  2. Возврат меток на место после перевода по выравниванию внимания.
  3. Проверка целостности: если метка потерялась или размножилась, сегмент отдаётся без перевода, а не с испорченной разметкой.
  4. Метрика сохранности разметки в стенде T0.6.
  5. Набор тестов на вложенной разметке.
Готово, когда

Сохранность разметки на тестовом наборе не ниже 99.9%, потерянная метка приводит к отказу от перевода сегмента, а не к порче.

Как проверяем

Прогон корзины с разметкой из T0.4: сравнение дерева разметки до и после.

Риск

Модель переставляет метки местами при смене порядка слов. Смягчение: выравнивание внимания, а не позиционное соответствие.

T1.10

Память переводов и кеш сегментов

Переводbackend5 нед.зависит от T1.5, T1.8
Зачем

При доле попаданий 40% парк быстрой ветки уменьшается почти вдвое. Для документов и страниц доля выше: типовые фразы повторяются постоянно.

Что делаем
  1. Кеш сегментов: ключ «текст, пара языков, версия модели, глоссарий».
  2. Инвалидация по версии модели: смена модели не должна отдавать старые переводы.
  3. Память переводов пользователя как отдельное хранилище с другими правилами жизни.
  4. Кеш переведённых страниц с временем жизни до переобхода страницы.
  5. Замер доли попаданий по сценариям.
Готово, когда

Кеш работает, доля попаданий измерена, смена версии модели корректно обесценивает записи.

Как проверяем

Прогон суточного среза трафика: доля попаданий соответствует расчёту T0.7 в пределах 10%.

Риск

Кеш отдаёт перевод, сделанный со старым глоссарием. Смягчение: глоссарий входит в ключ.

T1.11

Маршрутизация веток

Переводbackend4 нед.зависит от T1.6, T1.10
Зачем

Большая модель на каждое нажатие клавиши — это стоимость, которая не окупается ничем. Правило «печатает — быстрая, остановился — качественная» решает и стоимость, и ощущение скорости.

Что делаем
  1. Две ветки за одним контрактом с явным параметром качества.
  2. Правило автоматического выбора и его переопределение потребителем.
  3. Отмена незавершённых запросов при продолжении набора.
  4. Жёсткий таймаут для колдунщика в выдаче: не успел — колдунщик не показывается.
  5. Учёт стоимости вызова по веткам (3.48).
Готово, когда

Обе ветки работают за одним контрактом, отмена запросов не оставляет висящих вызовов, таймаут колдунщика соблюдается.

Как проверяем

Замер: перевод в выдаче ни при каких условиях не увеличивает время ответа SERP.

Риск

Переключение веток заметно как «дёрганье» текста. Смягчение: замена результата на месте с плавным переходом, проверяется на людях.

T1.12

Постобработка

Переводbackend + лингвист4 нед.зависит от T1.9
Зачем

Модель хорошо переводит слова и плохо — форматы. Числа, даты, единицы, кавычки и регистр правятся правилами дешевле и надёжнее, чем обучением.

Что делаем
  1. Форматы чисел и дат по правилам целевого языка.
  2. Кавычки и типографика: русские «ёлочки» против английских кавычек.
  3. Единицы измерения: перевод без конвертации по умолчанию, конвертация — по явной настройке.
  4. Восстановление регистра первого слова и правил заглавных букв в заголовках.
  5. Единообразие терминологии внутри одного документа.
Готово, когда

Правила применяются, набор тестов на форматы проходит полностью.

Как проверяем

Корзина по типу «техническая документация»: доля сегментов с испорченными числами и единицами — ноль.

Риск

Правила конфликтуют с глоссарием пользователя. Смягчение: глоссарий приоритетнее правил, порядок применения зафиксирован.

T1.13

Внутренний контракт и потребители

Переводbackend3 нед.зависит от T1.11
Зачем

Пять подсистем основного плана должны вызывать переводчик одинаково. Пять разных интеграций — это пять мест, где потом ломается совместимость.

Что делаем
  1. Клиентская библиотека с батчировкой и повторами.
  2. Подключение потребителей: кросс-языковой поиск, колдунщик, сниппеты, вертикаль «Видео».
  3. Версионирование контракта и правило совместимости.
  4. Ограничение потока по потребителям, чтобы пакетный перевод сниппетов не вытеснял пользователей.
  5. Регистрация переводчика в шлюзе моделей (2.53).
Готово, когда

Все потребители работают через библиотеку, ограничение потока проверено под нагрузкой.

Как проверяем

Нагрузочный прогон: пакетный перевод сниппетов не увеличивает задержку пользовательских запросов.

Риск

Пакетная нагрузка вытесняет интерактивную. Смягчение: раздельные очереди и приоритеты, а не общий пул.

T1.14

Граница данных: публичный текст и пользовательский

Переводкритический путьbackend + юрист4 нед.зависит от T1.10
Зачем

Через переводчик проходят договоры, письма и медицинские выписки. Правило «пользовательский текст не попадает в общий кеш и в обучение» должно быть свойством типа данных, а не строчкой в регламенте.

Что делаем
  1. Разделение источников в типе данных: текст из индекса и текст от пользователя — разные типы.
  2. Запрет на уровне компиляции: пользовательский текст не может быть записан в общий кеш.
  3. Правило для обучающего конвейера: пользовательские тексты в обучение не идут по умолчанию.
  4. Согласие на использование правок для улучшения — отдельное, явное, отзываемое.
  5. Удаление истории переводов по запросу вместе с производными.
Готово, когда

Попытка записать пользовательский текст в общий кеш не компилируется; удаление истории проверено сквозным тестом.

Как проверяем

Тест: намеренная попытка нарушить границу останавливается сборкой, а не проверкой на ревью.

Риск

Граница обходится через промежуточные структуры. Смягчение: аудит всех путей записи в кеш при приёмке задачи.

T1.16

Доменная адаптация

Перевод2 ML-инженера6 нед.зависит от T1.4, T1.15
Зачем

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

Что делаем
  1. Сбор доменных подкорпусов из индекса по тематике хостов.
  2. Дообучение на доменных данных без потери качества на общих текстах.
  3. Определение домена входного текста и выбор модели или адаптера.
  4. Замер на доменных частях корзины отдельно.
  5. Правило отката: адаптер, ухудшающий общий текст, не выкатывается.
Готово, когда

На технических и юридических типах корзины прирост COMET не ниже 2% без просадки на остальных.

Как проверяем

Прогон всех восьми типов до и после: ни один не просел.

Риск

Ошибка определения домена ухудшает перевод. Смягчение: при низкой уверенности работает общая модель.

T3.1

Глоссарии

Переводкритический путьbackend + frontend6 нед.зависит от T1.9, T1.12
Зачем

Для организации важнее не средняя красота перевода, а то, что её термины переведены одинаково во всех документах. Это то, за что платят.

Что делаем
  1. Создание и редактирование словарей терминов в кабинете, импорт из TMX и таблиц.
  2. Применение глоссария до перевода с защитой терминов как подстановок.
  3. Учёт морфологии: термин склоняется, но не подменяется.
  4. Проверка конфликтов внутри глоссария и с правилами постобработки.
  5. Метрика соблюдения: доля терминов, переведённых по словарю.
Готово, когда

Глоссарии работают, соблюдение не ниже 99%, конфликты обнаруживаются при сохранении словаря.

Как проверяем

Прогон документа с глоссарием на 200 терминов: все термины переведены по словарю, согласование не нарушено.

Риск

Жёсткая подстановка терминов ломает грамматику. Смягчение: учёт морфологии, замер согласования отдельно.

T3.2

Автоподбор терминологии из индекса

ПереводML-инженер5 нед.зависит от T3.1, T1.2
Зачем

Составить глоссарий с нуля — работа на недели, и из-за неё функцией не пользуются. Мы можем предложить готовый вариант: как этот термин переводят на сайтах отрасли.

Что делаем
  1. Извлечение терминов из загруженного документа.
  2. Поиск их переводов в параллельном корпусе по доменам, близким к тематике документа.
  3. Предложение вариантов с частотностью и ссылками на источники.
  4. Принятие или отклонение варианта одним нажатием.
  5. Сохранение принятых терминов в глоссарий организации.
Готово, когда

По документу строится черновик глоссария, доля принимаемых предложений не ниже 60% на пилоте.

Как проверяем

Пилот на пяти организациях с их реальными документами: замер доли принятых предложений.

Риск

Предложения из неподходящей отрасли. Смягчение: подбор доменов по тематике документа, показ источника рядом с вариантом.

T3.3

Перевод документов офисных форматов

Переводкритический путь2 backend7 нед.зависит от T3.1
Зачем

Перевод, после которого документ нужно верстать заново, экономит не время, а его половину. Сохранение форматирования — суть функции, а не приятное дополнение.

Что делаем
  1. Извлечение переводимого текста через фильтры Okapi Framework: docx, xlsx, pptx, odt, txt.
  2. Промежуточное представление в XLIFF, перевод сегментов, сборка документа обратно.
  3. Сохранение стилей, таблиц, колонтитулов, примечаний, оглавления.
  4. Обработка изменения длины текста: русский длиннее английского примерно на 15%, и таблицы это переживают плохо.
  5. Ограничения по размеру файла и понятное сообщение при их превышении.
Готово, когда

Документы переводятся с сохранением форматирования, на наборе из 100 реальных документов вёрстка не сломана ни в одном.

Как проверяем

Открытие переведённых документов в двух офисных пакетах: структура и стили совпадают с оригиналом.

Риск

Экзотические возможности форматов ломают сборку. Смягчение: набор из 100 реальных документов как приёмочный тест, а не синтетические примеры.

T3.4

Перевод PDF

Переводbackend + юрист6 нед.зависит от T3.3
Зачем

PDF — самый частый формат присылаемых документов и самый трудный: текст в нём размещён координатами, а не потоком.

Что делаем
  1. Решение по библиотеке разбора: коммерческая лицензия или pdfium под BSD — лицензионный вопрос решается первым.
  2. Извлечение текста с позициями и восстановление порядка чтения.
  3. Перевод и размещение обратно с подбором размера шрифта под изменившуюся длину.
  4. Отдельная ветка для сканов: распознавание через T3.5.
  5. Отказ с понятным сообщением там, где вёрстку сохранить нельзя, вместо испорченного результата.
Готово, когда

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

Как проверяем

Набор из 50 PDF разной сложности: доля приемлемого результата не ниже 85%, остальные дают честный отказ.

Риск

Лицензия библиотеки разбора требует раскрытия исходников. Смягчение: вопрос решается до написания кода, вариант на BSD подготовлен заранее.

T3.5

Распознавание текста на изображениях

ПереводML-инженер6 нед.зависит от T1.11
Зачем

Вывеска, меню, инструкция, скриншот — самый частый сценарий перевода в мобильном мире.

Что делаем
  1. Внедрение PaddleOCR: детекция областей текста с наклоном и распознавание.
  2. Поддержка кириллицы и латиницы, определение языка текста на изображении.
  3. Объединение областей в строки и абзацы для осмысленного перевода.
  4. Обработка сложных случаев: низкий контраст, перспектива, рукописный текст — с честным отказом.
  5. Замер качества распознавания на подготовленном наборе фотографий.
Готово, когда

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

Как проверяем

Замер на наборе из 500 фотографий, снятых в реальных условиях, а не отсканированных.

Риск

Качество на фотографиях под углом заметно ниже. Смягчение: отдельный замер по условиям съёмки, предупреждение пользователю.

T3.7

Публичный программный интерфейс

Перевод2 backend5 нед.зависит от T1.13, T3.1, 3.17
Зачем

Единственный прямой источник выручки трека. Плюс канал распространения: интеграция в чужой продукт закрепляет нас в нём надолго.

Что делаем
  1. Методы: перевод текста, определение языка, перевод документа, список языков, работа с глоссариями.
  2. Совместимость по форме с распространённым открытым интерфейсом, чтобы миграция стоила замены адреса.
  3. Ключи, квоты, ограничение потока, версионирование.
  4. Документация с примерами на пяти языках программирования и песочница.
  5. Правило хранения: тексты, пришедшие через интерфейс, не идут в обучение никогда.
Готово, когда

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

Как проверяем

Интеграция сторонним разработчиком по документации без обращения в поддержку.

Риск

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

T3.8

Тарифы, квоты и оплата

Переводbackend + продукт5 нед.зависит от T3.7, 4.17
Зачем

Без биллинга программный интерфейс — это расходы без выручки.

Что делаем
  1. Тарифы по объёму символов с бесплатным уровнем.
  2. Учёт потребления с точностью до символа и раздельно по веткам качества.
  3. Предупреждения о приближении к лимиту и понятное поведение при его исчерпании.
  4. Отдельные тарифы на документы и глоссарии.
  5. Отчёты по потреблению в кабинете.
Готово, когда

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

Как проверяем

Сверка учёта с журналом вызовов за месяц: расхождение не выше 0.1%.

Риск

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

T3.11

Субтитры

Переводbackend4 нед.зависит от T1.9, T1.12
Зачем

Дешёвая половина перевода видео, полезная сама по себе: перевод готовых субтитров не требует ни распознавания речи, ни синтеза.

Что делаем
  1. Разбор форматов SRT и WebVTT с сохранением тайм-кодов.
  2. Перевод с учётом контекста соседних реплик, а не построчно.
  3. Контроль длины строки и скорости чтения по стандартам субтитрирования.
  4. Разбиение длинных реплик с сохранением синхронности.
  5. Выгрузка в исходном формате.
Готово, когда

Субтитры переводятся с сохранением тайм-кодов, скорость чтения соблюдает стандарт.

Как проверяем

Проверка на 50 файлах: тайм-коды не сдвинуты, длина строк в пределах нормы, смысл соседних реплик связан.

Риск

Построчный перевод теряет связность диалога. Смягчение: перевод с окном контекста из соседних реплик.

T4.2

Распознавание речи для видео

Перевод2 ML-инженера6 нед.зависит от T4.1, 4.5
Зачем

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

Что делаем
  1. Внедрение faster-whisper на общем рантайме CTranslate2.
  2. Сравнение с Parakeet TDT на нашем материале, выбор по качеству и пропускной способности.
  3. Восстановление пунктуации и предложений: перевод пословного потока бессмыслен.
  4. Обработка шума, музыки и наложенной речи.
  5. Замер ошибки по словам на материале разных типов видео.
Готово, когда

Ошибка по словам на речи хорошего качества не выше 8%, пунктуация восстанавливается.

Как проверяем

Замер на наборе из 50 видео разных жанров с эталонной расшифровкой.

Риск

Качество падает на видео с музыкой и шумом. Смягчение: предварительное разделение дорожек, честный отказ при невозможности.

T4.3

Диаризация и определение говорящих

ПереводML-инженер5 нед.зависит от T4.2
Зачем

Без разделения на говорящих дубляж получается одноголосым, и диалог в нём неразличим. Это разница между «перевели» и «можно смотреть».

Что делаем
  1. Диаризация через pyannote.audio: кто и когда говорит.
  2. Определение пола говорящего для подбора голоса.
  3. Устойчивое сопоставление говорящих на протяжении всего видео.
  4. Обработка перебиваний и наложенной речи.
  5. Замер точности разделения.
Готово, когда

Говорящие разделяются, ошибка диаризации не выше 10% на наборе диалогов.

Как проверяем

Замер на 30 видео с несколькими говорящими и размеченными границами реплик.

Риск

Похожие голоса сливаются в одного говорящего. Смягчение: замер на наборе с однополыми диалогами отдельно.

T4.4

Перевод с контролем длины

Переводкритический путь2 ML-инженера6 нед.зависит от T4.2, T1.4
Зачем

Перевод, который вдвое длиннее оригинала, невозможно уложить в ту же реплику. Либо речь ускоряется до неразборчивости, либо дорожка расходится с видео. Контроль длины — то, что отличает дубляж от озвученного перевода.

Что делаем
  1. Управление длиной перевода: целевая длительность произнесения как параметр.
  2. Обучение или дообучение на данных с контролем длины.
  3. Компромисс «точность против длины» с явным приоритетом смысла.
  4. Учёт скорости речи целевого языка: одинаковый текст произносится за разное время.
  5. Замер: доля реплик, уложившихся в исходную длительность без ускорения.
Готово, когда

Не менее 85% реплик укладываются в исходную длительность с отклонением не более 10%, без потери смысла по оценке асессоров.

Как проверяем

Оценка асессорами на 200 репликах: смысл сохранён, длительность соблюдена.

Риск

Сокращение ради длины теряет смысл. Смягчение: приоритет смысла, при конфликте допускается небольшое ускорение речи.

T4.5

Синтез голоса для дубляжа

ПереводML-инженер6 нед.зависит от T4.4, T4.3, T4.1
Зачем

Последнее звено каскада, и именно его слышит пользователь. Механический голос обесценивает точный перевод полностью.

Что делаем
  1. Синтез Kokoro для фиксированных голосов, Chatterbox — там, где допустимо клонирование по T4.1.
  2. Подбор голоса под говорящего: пол, возрастной тон, темп.
  3. Сохранение интонационного рисунка исходной речи.
  4. Обязательная пометка синтезированной речи по требованиям T4.1.
  5. Замер разборчивости и естественности асессорами.
Готово, когда

Синтез работает, оценка естественности не ниже 3.8 из 5 на выборке, пометка присутствует всегда.

Как проверяем

Слепая оценка асессорами: синтезированная речь против исходной по шкале естественности.

Риск

Клонирование запрещено заключением T4.1. Смягчение: фиксированные голоса как основной вариант, клонирование — как расширение.

T4.6

Синхронизация дорожки

Переводbackend5 нед.зависит от T4.5
Зачем

Перевод, отстающий от губ на две секунды, воспринимается как поломка, даже если он точен.

Что делаем
  1. Размещение реплик по тайм-кодам исходной речи.
  2. Растяжение и сжатие пауз вместо ускорения речи там, где это возможно.
  3. Микширование с исходной дорожкой: приглушение оригинала, сохранение музыки и звуков.
  4. Обработка наложенных реплик.
  5. Замер расхождения между репликой и исходной речью.
Готово, когда

Расхождение не выше 300 мс на 95% реплик, музыка и звуки сохранены.

Как проверяем

Замер по тайм-кодам на 30 видео плюс оценка людьми на предмет заметности рассинхрона.

Риск

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

Качество 5

T0.4

Корзина оценки перевода

Качествокритический путьлингвист + аналитик6 нед.зависит от T0.1
Зачем

Без корзины любое улучшение модели — это мнение. Средняя оценка по всему тексту скрывает провалы на отдельных типах, поэтому корзина делится по типам с самого начала.

Что делаем
  1. 3000 сегментов ru↔en по восьми типам текста в долях из документа, §23.6.1.
  2. Эталонные переводы от профессиональных переводчиков, двойная проверка.
  3. Отдельный набор с разметкой: страницы, интерфейсные строки, тексты с подстановками.
  4. Набор коротких строк без контекста — там, где модели ломаются чаще всего.
  5. Разделение на открытую и закрытую часть: закрытая не публикуется и не попадает в обучение.
Готово, когда

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

Как проверяем

Проверка на утечку: поиск сегментов закрытой корзины в обучающем корпусе даёт ноль совпадений.

Риск

Эталоны низкого качества обесценивают все дальнейшие замеры. Смягчение: двойная проверка и отбраковка переводчиков по тестовому заданию.

T0.6

Стенд оценки качества

КачествоML-инженер5 нед.зависит от T0.4
Зачем

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

Что делаем
  1. Реализация замеров: COMET с эталоном, COMET без эталона, MetricX, chrF и BLEU через sacreBLEU.
  2. Замер по типам текста отдельно, а не только среднее.
  3. Метрики сохранности разметки и точности терминологии.
  4. Панель сравнения двух моделей с указанием, где именно они расходятся.
  5. Экспорт результатов в общее аналитическое хранилище (1.34).
Готово, когда

Одна команда считает все метрики, результат воспроизводим, панель сравнения работает.

Как проверяем

Двукратный прогон на одной модели даёт одинаковые цифры; известная слабая модель уверенно отличается от сильной.

Риск

Слепое доверие одной метрике. Смягчение: две нейрометрики и правило разбираться при их расхождении.

T0.8

Замер разрыва в качестве

Качествокритический путь2 ML-инженера6 нед.зависит от T0.4, T0.6, T0.2
Зачем

Знать в цифрах, насколько открытый baseline хуже конкурентов на нашей корзине. Это отправная точка всего трека и единственный способ обсуждать «сколько стоит закрыть разрыв» не на ощупь.

Что делаем
  1. Прогон корзины через открытые модели-кандидаты, прошедшие по лицензии.
  2. Прогон через публичные интерфейсы конкурентов в пределах, допустимых их условиями.
  3. Сравнение по каждому типу текста отдельно.
  4. Разбор ошибок вручную на подвыборке: какие категории ошибок дают основной вклад.
  5. Отчёт: разрыв в цифрах и гипотезы о том, чем он закрывается.
Готово, когда

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

Как проверяем

Ручной разбор 200 худших сегментов подтверждает, что категории ошибок определены верно.

Риск

Условия конкурентов запрещают такое сравнение. Смягчение: юрист проверяет допустимость до прогона; при запрете сравниваем с опубликованными результатами.

T1.15

Ежедневный автозамер качества

КачествоML-инженер3 нед.зависит от T0.6, T1.5
Зачем

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

Что делаем
  1. Ночной прогон корзины на текущей продакшен-модели.
  2. Замер без эталона на живом трафике: COMET-QE на выборке.
  3. Оповещение при просадке любого типа текста больше чем на 1%.
  4. Панель динамики метрик рядом с панелью качества поиска (1.40).
  5. Хранение истории замеров для сравнения версий.
Готово, когда

Замер идёт ежедневно без ручных действий, оповещение проверено намеренной выкаткой ухудшенной модели.

Как проверяем

Учебная выкатка заведомо худшей модели вызывает оповещение в течение суток.

Риск

Замер без эталона смещён на редких типах текста. Смягчение: замер по типам отдельно, редкие типы проверяются человеком.

T4.10

Оценка качества дубляжа

Качестволингвист + аналитик4 нед.зависит от T4.7
Зачем

В каскаде из четырёх звеньев средняя оценка не говорит ничего: непонятно, что чинить. Оценка должна быть раздельной по звеньям.

Что делаем
  1. Раздельные метрики: ошибка распознавания, качество перевода, естественность синтеза, точность синхронизации.
  2. Сквозная оценка людьми: можно ли это смотреть.
  3. Разбор худших примеров с определением звена-виновника.
  4. Регулярный замер на постоянном наборе видео.
  5. Ворота на выкатку: ни одно звено не просело.
Готово, когда

Оценка идёт по четырём звеньям отдельно и сквозная, ворота на выкатку действуют.

Как проверяем

Разбор 50 худших примеров: звено-виновник определяется однозначно в 90% случаев.

Риск

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

Инфраструктура 4

T0.7

Расчёт ёмкости и стоимости трека

Инфраструктураархитектор4 нед.зависит от T0.1
Зачем

Число, с которым идут за бюджетом. Перевод сниппетов миллионами в сутки меняет требования к парку на порядок, и посчитать это надо до, а не после.

Что делаем
  1. Расчёт нагрузки по пяти сценариям из документа, §23.7.
  2. Расчёт парка: быстрая ветка на процессорах, качественная на ускорителях, обучение циклами.
  3. Оценка доли попаданий в кеш и её влияния на парк.
  4. Стоимость хранения корпусов и памяти переводов.
  5. Сравнение с ценой внешнего интерфейса перевода при том же объёме.
Готово, когда

Расчёт готов, три сценария нагрузки просчитаны, сравнение с внешним вариантом приложено.

Как проверяем

Расчёт воспроизводим по описанной методике третьим лицом.

Риск

Недооценка объёма перевода сниппетов. Смягчение: считаем от объёма иноязычной части индекса, а не от числа пользователей.

T1.17

Наблюдаемость и бюджет задержек

Инфраструктураинфраструктура3 нед.зависит от T1.11
Зачем

Бюджет задержек из документа, §23.5.4, существует, только если он измеряется поэтапно. Иначе известно лишь «стало медленно».

Что делаем
  1. Разметка этапов конвейера в трассировке: язык, сегментация, кеш, перевод, постобработка.
  2. Панели по каждому этапу с целевыми значениями.
  3. Оповещения на выход за бюджет по каждому этапу отдельно.
  4. Учёт стоимости инференса по потребителям.
  5. Подключение к общей наблюдаемости (1.35).
Готово, когда

Задержка видна поэтапно, выход за бюджет любого этапа даёт оповещение.

Как проверяем

Искусственное замедление одного этапа обнаруживается панелью за минуты.

Риск

Трассировка сама добавляет задержку. Смягчение: выборочная трассировка, замер накладных расходов.

T3.10

Пакетный перевод и очередь

Инфраструктураbackend4 нед.зависит от T3.3, T1.13
Зачем

Документ на 500 страниц не переводится в синхронном запросе. Очередь с прогрессом — единственный работающий способ, и она же защищает интерактивную нагрузку.

Что делаем
  1. Очередь задач с приоритетами: интерактивные выше пакетных.
  2. Прогресс и оценка оставшегося времени.
  3. Возобновление после сбоя без повторного перевода готовых сегментов.
  4. Ограничение параллельных задач на аккаунт.
  5. Уведомление о завершении.
Готово, когда

Документ на 500 страниц переводится, прогресс отображается, перезапуск сервиса не теряет готовые сегменты.

Как проверяем

Намеренная остановка сервиса на середине задачи: после перезапуска работа продолжается с той же точки.

Риск

Пакетные задачи забивают парк. Смягчение: раздельные очереди и приоритеты, проверка под нагрузкой.

T4.9

Ёмкость под обработку видео

Инфраструктураинфраструктура4 нед.зависит от T4.6, T0.7
Зачем

Каскад из четырёх моделей на час видео — это минуты работы ускорителей. Без отдельного расчёта видео съедает парк, предназначенный для текста.

Что делаем
  1. Расчёт стоимости обработки часа видео по всем звеньям каскада.
  2. Отдельные очереди и лимиты для видео.
  3. Приоритеты: интерактивный перевод текста всегда выше пакетной обработки видео.
  4. Ограничения по длительности на бесплатном уровне.
  5. Замер фактической стоимости и сверка с расчётом.
Готово, когда

Стоимость часа обработки измерена, лимиты действуют, текстовый перевод не деградирует при полной загрузке видеоочереди.

Как проверяем

Нагрузочный прогон: очередь видео заполнена, задержка текстового перевода в пределах бюджета.

Риск

Стоимость обработки делает функцию убыточной. Смягчение: лимиты на бесплатном уровне и кеш переведённых видео.

Продукт 20

T1.18

Колдунщик перевода получает движок

Продуктfrontend + backend3 нед.зависит от T1.11, 1.28
Зачем

Колдунщик перевода в выдаче стоит в плане с фазы 1, но до сих пор опирался на заглушку. Это первый пользовательский выход трека.

Что делаем
  1. Подключение колдунщика к сервису перевода быстрой веткой.
  2. Разбор запросов вида «перевести … на английский» и «… по-английски».
  3. Ссылка на полную страницу переводчика.
  4. Жёсткий таймаут: не успел — выдача уходит без колдунщика.
  5. Замер доли запросов, где колдунщик показан и полезен.
Готово, когда

Колдунщик работает на реальном движке, время ответа SERP не изменилось.

Как проверяем

Сравнение p95 выдачи до и после включения: разница в пределах погрешности.

Риск

Колдунщик показывается на запросах, где перевод не нужен. Смягчение: порог уверенности определения намерения, замер полезности на асессорах.

T2.1

Страница переводчика

Продукткритический путь2 frontend + дизайнер5 нед.зависит от T1.11
Зачем

Основная точка входа. Раскладка «два поля рядом» устоялась, и изобретать здесь новое — вредить пользователю: мышечная память с другого сервиса стоит дороже оригинальности.

Что делаем
  1. Два поля, выбор языков, кнопка обмена, счётчик символов, копирование результата.
  2. Определённый язык показывается явно, с возможностью исправить.
  3. Тёмная тема и доступность по требованиям 09.
  4. Мобильная раскладка: поля друг под другом, клавиатура не перекрывает результат.
  5. Состояния: пусто, набирается, переведено быстрой веткой, уточнено качественной, ошибка.
Готово, когда

Страница работает на всех размерах экрана, проходит проверку доступности, все пять состояний реализованы.

Как проверяем

Проверка с клавиатуры и с экранным диктором; замер на мобильном соединении.

Риск

Переключение веток заметно как мигание результата. Смягчение: замена на месте, проверяется на людях.

T2.2

Мгновенный перевод по мере набора

Продуктfrontend + backend4 нед.зависит от T2.1, T1.11
Зачем

Именно это определяет ощущение скорости продукта. Пауза в полсекунды между «допечатал» и «увидел перевод» ощущается как медленный сервис, даже если сервер отвечает за 40 мс.

Что делаем
  1. Отправка на быструю ветку с задержкой в 150 мс после остановки набора.
  2. Отмена предыдущих незавершённых запросов.
  3. Уточнение качественной веткой через 600 мс без набора.
  4. Индикатор того, что показан быстрый перевод и он сейчас уточнится.
  5. Работа при плохом соединении: показ последнего успешного результата, а не пустоты.
Готово, когда

Перевод появляется не позже 250 мс после остановки набора на p95, уточнение не «дёргает» страницу.

Как проверяем

Замер на записи реального набора текста при задержке сети 100 мс.

Риск

Поток запросов при быстром наборе перегружает быструю ветку. Смягчение: задержка и отмена, замер числа запросов на символ.

T2.3

Словарная карточка

Продуктfrontend + лингвист5 нед.зависит от T2.1
Зачем

При переводе одного слова человеку нужен не перевод, а словарь: значения, части речи, устойчивые сочетания. Это половина обращений к переводчику.

Что делаем
  1. Определение случая «одно слово или короткое выражение» и переключение вида.
  2. Значения по частям речи, с пометами области употребления.
  3. Обратные переводы: как это слово переводится назад, с частотностью.
  4. Устойчивые сочетания и управление.
  5. Транскрипция и произношение.
Готово, когда

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

Как проверяем

Оценка асессорами на 300 частотных словах: полнота карточки не хуже словарной статьи.

Риск

Данных для карточки на редких словах нет. Смягчение: карточка деградирует до простого перевода, а не показывает пустые разделы.

T2.4

Примеры употребления из индекса

Продукткритический путьbackend + ML-инженер6 нед.зависит от T2.3, T1.2
Зачем

Это главное отличие продукта. Примеры не выдуманы и не куплены — они взяты с настоящих страниц, и на каждый есть ссылка. Пользователь может проверить.

Что делаем
  1. Поиск предложений с искомым словом в параллельном корпусе из индекса.
  2. Отбор примеров: разные значения, разная длина, разные домены.
  3. Фильтр качества источника: страницы с высоким показателем качества, без спама.
  4. Ссылка на страницу-источник для каждого примера.
  5. Фильтр приличий: примеры не должны содержать оскорбительного или взрослого содержимого.
Готово, когда

Примеры показываются со ссылками, покрытие частотных слов не ниже 90%, фильтр приличий проверен на подготовленном наборе.

Как проверяем

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

Риск

Примеры из спамных или машинно-переведённых страниц. Смягчение: фильтр по показателю качества хоста и отсев машинного перевода из T1.1.

T2.5

Альтернативы и объяснение варианта

Продуктfrontend + ML-инженер5 нед.зависит от T2.4
Зачем

Та же линия, что панель «как ранжировано» в выдаче: машина обязана уметь показать, почему она так решила. У конкурентов альтернативы есть, объяснения — нет.

Что делаем
  1. Показ альтернативных гипотез декодера с их оценками.
  2. Замена варианта в тексте одним нажатием, с сохранением согласования.
  3. Панель «почему так»: сработавшие термины глоссария, определённый домен, примеры из индекса, подтверждающие вариант.
  4. Пометка мест низкой уверенности модели прямо в тексте перевода.
  5. Всё объяснение — по явному действию, а не постоянно на экране.
Готово, когда

Альтернативы показываются, замена работает, панель объяснения собирает все четыре источника.

Как проверяем

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

Риск

Объяснение перегружает интерфейс. Смягчение: скрыто по умолчанию, открывается по нажатию.

T2.6

Правка перевода пользователем

Продуктfrontend + backend3 нед.зависит от T2.5, T1.14
Зачем

Правка — самый ценный сигнал качества, какой бывает. И самый опасный: правки, идущие напрямую в обучение, — готовый канал отравления модели.

Что делаем
  1. Редактирование результата и отправка правки с явным согласием.
  2. Правки идут в оценку качества и в очередь на разбор, но не в обучение напрямую.
  3. Разбор правок асессорами перед попаданием в обучающий корпус.
  4. Отчёт: какие категории ошибок правят чаще всего.
  5. Отзыв согласия удаляет отправленные правки.
Готово, когда

Правки собираются, ни одна не попадает в обучение без проверки человеком, отзыв согласия работает.

Как проверяем

Попытка провести правку в обучающий корпус в обход разбора останавливается конвейером.

Риск

Массовая отправка искажающих правок. Смягчение: разбор человеком плюс ограничение по частоте на аккаунт.

T2.7

История и избранное

Продуктfrontend + backend3 нед.зависит от T2.1, T1.14
Зачем

Человек возвращается к тем же переводам. Без истории он переводит одно и то же по третьему разу.

Что делаем
  1. История переводов в Yottis ID с поиском по ней.
  2. Избранное: пометка и подборки.
  3. Управление данными из раздела приватности (2.22): просмотр, экспорт, удаление.
  4. Работа без аккаунта: история в браузере, не на сервере.
  5. Явное указание, где хранится история в каждом режиме.
Готово, когда

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

Как проверяем

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

Риск

История без аккаунта теряется при очистке браузера, и это воспринимается как потеря данных. Смягчение: предупреждение при первом сохранении.

T2.8

Озвучивание и голосовой ввод

Продуктfrontend + backend4 нед.зависит от T2.1, 2.37, 4.16
Зачем

Произношение — половина смысла обращения к переводчику для изучающих язык, а голосовой ввод — основной способ ввода на мобильном.

Что делаем
  1. Озвучивание исходного текста и перевода синтезом Kokoro.
  2. Голосовой ввод через распознавание из 2.37.
  3. Режим разговора: два языка, поочерёдный ввод.
  4. Скорость воспроизведения и повтор по слогам для обучения.
  5. Работа без сети: сообщение о недоступности, а не молчание.
Готово, когда

Озвучивание и ввод работают на всех поддерживаемых языках, режим разговора проходит сценарный тест.

Как проверяем

Оценка разборчивости синтеза асессорами на 100 фразах по каждому языку.

Риск

Синтез на редких языках неразборчив. Смягчение: язык без приемлемого синтеза не получает кнопку озвучивания вовсе.

T2.9

Перевод страницы по адресу

Продукткритический путь2 backend6 нед.зависит от T1.9, T1.10
Зачем

Прямая синергия с поиском: страница уже в индексе, её текст уже извлечён и очищен от обвязки. Конкурентам эту страницу нужно сначала скачать.

Что делаем
  1. Перевод по адресу: берём из индекса, при отсутствии — скачиваем.
  2. Перевод с сохранением разметки через защиту подстановок T1.9.
  3. Кеш переведённых страниц с временем жизни до переобхода.
  4. Переключатель «оригинал / перевод» и указание, что страница переведена машинно.
  5. Ограничения: не переводим страницы, требующие авторизации, и формы.
Готово, когда

Страницы переводятся с сохранением вёрстки, переключатель работает, кеш обесценивается при переобходе.

Как проверяем

Сравнение дерева разметки оригинала и перевода на 200 страницах: расхождений нет.

Риск

Владельцы сайтов возражают против показа их страниц в нашей обёртке. Смягчение: правовая проработка в T0.3, механизм запрета для владельца.

T2.10

Перевод сниппетов в выдаче

Продуктbackend4 нед.зависит от T1.13, 3.38
Зачем

Кросс-языковой поиск бесполезен, если результат непонятен. Найденная, но непрочитанная страница — это не найденная страница.

Что делаем
  1. Перевод заголовков и сниппетов иноязычных результатов быстрой веткой, пакетами.
  2. Пометка «переведено» и кнопка показа оригинала.
  3. Предварительный перевод для частых запросов, чтобы не переводить в горячем пути.
  4. Учёт стоимости: перевод только тех результатов, что попали в выдачу.
  5. Замер влияния на удовлетворённость кросс-языковыми результатами.
Готово, когда

Сниппеты переводятся, время ответа выдачи не изменилось, влияние на метрики качества измерено.

Как проверяем

Интерливинг (2.10): выдача с переводом сниппетов против выдачи без него.

Риск

Плохой перевод сниппета вредит больше, чем помогает. Смягчение: пометка и оригинал в один щелчок; при низкой уверенности сниппет не переводится.

T2.11

Управление формальностью обращения

ПродуктML-инженер + лингвист4 нед.зависит от T1.4
Зачем

Русское «ты/вы» — не стилистика, а смысл. Модель выбирает наугад, и в деловом письме это ошибка. У Яндекса такого переключателя нет.

Что делаем
  1. Обучение на размеченных по регистру данных или управление через префикс.
  2. Переключатель в интерфейсе: нейтрально, на «ты», на «вы».
  3. Единообразие внутри документа: регистр не меняется от абзаца к абзацу.
  4. Поддержка в контракте API и в глоссариях.
  5. Замер: доля сегментов, где выбранный регистр соблюдён.
Готово, когда

Переключатель работает, соблюдение регистра не ниже 97%, единообразие внутри документа обеспечено.

Как проверяем

Прогон корзины делового типа с обоими значениями: регистр соблюдён, смысл не изменился.

Риск

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

T2.12

Перевод страниц в расширении браузера

Продуктfrontend4 нед.зависит от T2.9, 3.18
Зачем

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

Что делаем
  1. Кнопка перевода страницы и предложение перевода при несовпадении языка страницы с языком интерфейса.
  2. Перевод на месте, с сохранением разметки, без перезагрузки.
  3. Перевод выделенного фрагмента по горячей клавише.
  4. Настройка языков, которые не предлагать переводить.
  5. Приватный режим: перевод на клиенте, если он включён (T2.13).
Готово, когда

Расширение переводит страницы на месте, предложение перевода не мешает и отключается.

Как проверяем

Проверка на 50 сайтах разной сложности: вёрстка не ломается, динамические части переводятся.

Риск

Тяжёлые страницы тормозят при переводе на месте. Смягчение: перевод видимой части первой, остальное по мере прокрутки.

T2.13

Клиентский режим на WebAssembly

ПродуктML-инженер + frontend6 нед.зависит от T1.6, T2.1
Зачем

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

Что делаем
  1. Сборка компактной модели под WebAssembly на основе конвейера Mozilla Translations.
  2. Загрузка модели по запросу с кешированием в браузере.
  3. Явный переключатель приватного режима с честным указанием: качество ниже, скорость ниже, текст никуда не уходит.
  4. Изоляция кода под лицензией MPL-2.0 в отдельных файлах согласно правилу лицензий.
  5. Замер качества клиентской модели на корзине и честная его публикация.
Готово, когда

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

Как проверяем

Проверка сетевой активности при переводе в приватном режиме: запросов с текстом нет.

Риск

Размер модели делает первую загрузку неприемлемо долгой. Смягчение: загрузка по запросу и только для выбранной пары языков.

T2.14

Транслитерация и произношение

Продуктfrontend + лингвист3 нед.зависит от T2.3
Зачем

Для языков с нелатинской графикой перевод без транслитерации наполовину бесполезен: прочитать результат нельзя.

Что делаем
  1. Транслитерация результата для языков с нелатинской графикой.
  2. Транскрипция в словарной карточке.
  3. Ударения для русского в режиме обучения.
  4. Копирование транслитерации отдельной кнопкой.
  5. Правила транслитерации по языкам, а не одна схема на все.
Готово, когда

Транслитерация показывается для всех языков, где она нужна, схема соответствует принятому стандарту языка.

Как проверяем

Проверка лингвистом по 100 примерам на каждый язык.

Риск

Разные стандарты транслитерации для одного языка. Смягчение: выбор стандарта фиксируется и указывается в интерфейсе.

T3.6

Подстановка перевода на изображение

Продуктfrontend + backend4 нед.зависит от T3.5
Зачем

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

Что делаем
  1. Затирание исходного текста с восстановлением фона.
  2. Размещение перевода с подбором размера и переносами под область.
  3. Сохранение цвета и начертания там, где это определимо.
  4. Переключатель «оригинал / перевод» и сохранение результата.
  5. Режим показа списком для случаев, когда подстановка невозможна.
Готово, когда

Перевод подставляется на изображение читаемо, переключение работает, при невозможности показывается список.

Как проверяем

Оценка асессорами на 200 изображениях: читаемость и уместность подстановки.

Риск

Затирание портит изображение. Смягчение: при сложном фоне переходим к подложке под текст вместо затирания.

T3.9

Кабинет переводчика

Продуктfrontend4 нед.зависит от T3.8, T3.1
Зачем

Организации нужен один экран, где видно ключи, потребление, глоссарии и историю документов. Без него всё это существует в письмах в поддержку.

Что делаем
  1. Ключи и их права.
  2. Потребление по дням, по методам, по веткам качества.
  3. Управление глоссариями и совместный доступ внутри организации (4.7).
  4. История переведённых документов с повторной загрузкой.
  5. Настройки хранения: срок жизни документов и их удаление.
Готово, когда

Кабинет работает, все четыре раздела наполнены реальными данными.

Как проверяем

Сценарный тест: организация заводит ключ, глоссарий, переводит документ и видит потребление — без обращения в поддержку.

Риск

Кабинет дублирует кабинет вебмастера. Смягчение: общий каркас и общая авторизация, разные разделы.

T3.12

Перевод в мобильных приложениях

Продукт2 мобильных разработчика6 нед.зависит от T2.13, 4.4
Зачем

Мобильный сценарий отличается от настольного принципиально: камера, голос, отсутствие сети. Перенос веб-версии как есть даёт неудобное приложение.

Что делаем
  1. Перевод текста, голоса и изображений с камеры (снимок, не поток).
  2. Офлайн-пакеты языков на основе клиентских моделей T2.13.
  3. Управление загруженными пакетами и их размером.
  4. Режим разговора с поочерёдным вводом.
  5. Быстрый доступ из системного меню копирования.
Готово, когда

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

Как проверяем

Проверка в режиме полёта: перевод по загруженному пакету работает полностью.

Риск

Офлайн-качество заметно ниже, и это воспринимается как поломка. Смягчение: явная пометка офлайн-режима и разницы в качестве.

T4.7

Дубляж в вертикали «Видео»

Продуктfrontend + backend5 нед.зависит от T4.6, 2.18
Зачем

Точка, где функция встречается с пользователем. Кнопка перевода у иноязычного видео в нашей вертикали — то, ради чего вертикаль откроют.

Что делаем
  1. Кнопка перевода у иноязычного видео с оценкой времени обработки.
  2. Очередь обработки и уведомление о готовности.
  3. Кеш переведённых видео: одно видео переводится один раз для всех.
  4. Переключение дорожек: оригинал, дубляж, субтитры.
  5. Ограничения: длительность, форматы, недоступные источники.
Готово, когда

Дубляж доступен из вертикали, кеш работает, ограничения объяснены пользователю до начала обработки.

Как проверяем

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

Риск

Правовые ограничения на обработку чужого видео. Смягчение: позиция из T4.1, обработка по запросу пользователя, а не заранее.

T4.8

Автоматические субтитры

Продуктbackend3 нед.зависит от T4.2, T3.11
Зачем

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

Что делаем
  1. Субтитры из распознавания без синтеза.
  2. Двухъязычный режим: оригинал и перевод одновременно.
  3. Соблюдение стандартов длины строки и скорости чтения из T3.11.
  4. Выгрузка файла субтитров.
  5. Доступность: настройки размера и контраста.
Готово, когда

Субтитры генерируются, двухъязычный режим работает, стандарты соблюдены.

Как проверяем

Проверка на 30 видео: субтитры читаемы на скорости воспроизведения, синхронны.

Риск

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

Многоязычие 1

T2.15

Пять новых языков

Многоязычие2 ML-инженера8 нед.зависит от T1.16, 3.34
Зачем

Языки добавляются вместе с языковыми кластерами поиска, а не отдельным списком: перевод на язык, которым мы не занимались в индексе, некому проверять и незачем показывать.

Что делаем
  1. Подключение пяти языков первого кластера через MADLAD-400 с дообучением.
  2. Сбор корзины по каждому языку не менее 500 сегментов.
  3. Асессоры-носители для каждого языка.
  4. Замер качества и честная публикация уровня поддержки: полная или предварительная.
  5. Правило: язык без корзины и асессоров не включается.
Готово, когда

Пять языков работают, по каждому есть корзина и замер, уровень поддержки указан в интерфейсе.

Как проверяем

Оценка носителями: доля приемлемых переводов не ниже 85% по каждому языку.

Риск

Языки включаются быстрее, чем находятся асессоры. Смягчение: правило «нет асессоров — нет языка» действует без исключений.

Ворота трека

Все критерии обязательны. Не пройдены — фаза продлевается, а не закрывается.

  • T0: реестр лицензий заполнен, ни одна некоммерческая модель не попала в стек
  • T0: разрыв в качестве с конкурентами измерен по восьми типам текста
  • T0: собственный параллельный корпус из индекса измерен, чистота не ниже 90%
  • T0: решение «идём дальше» принято письменно и обосновано цифрами
  • T1: собственная модель ru↔en превосходит лучшую открытую по COMET на каждом типе текста
  • T1: быстрая ветка укладывается в 40 мс на предложение p95
  • T1: сохранность разметки не ниже 99.9%
  • T1: кросс-языковой поиск работает через свой сервис, внешний интерфейс отключён
  • T1: пользовательский текст технически не может попасть в общий кеш
  • T1: ежедневный автозамер качества идёт без ручных действий
  • T2: страница переводчика в открытом доступе, перевод появляется не позже 250 мс после остановки набора
  • T2: примеры употребления из индекса покрывают не менее 90% частотных слов
  • T2: приватный режим работает без единого сетевого запроса с текстом
  • T2: перевод сниппетов не увеличил время ответа выдачи
  • T3: документы переводятся с сохранением вёрстки на 100 реальных файлах
  • T3: соблюдение глоссария не ниже 99%
  • T3: программный интерфейс опубликован, есть внешние интеграции
  • T3: выручка интерфейса и глоссариев покрывает операционные расходы ядра перевода
  • T4: правовое заключение по синтезу голоса получено до реализации дубляжа
  • T4: не менее 85% реплик укладываются в исходную длительность
  • T4: рассинхрон дубляжа не выше 300 мс на 95% реплик
  • T4: синтезированная речь помечена всегда и везде