Проектируем «умные» сайты в 2026: как не утонуть в справочниках, кодах и редакторских правках

Пятница, 23:38. Пицца остыла до состояния «картон», в Slack горит «кто на проде?». Мы добиваем редизайн медицинского справочника для сети клиник: всё красиво в фигме, всё работает локально, а продовый поиск по болезням даёт ноль по запросу «диарея». Клиент пишет: «Ребята, ну камон». Я открываю логи — 17 запросов подряд в течение 4 минут и ни одного хита. На столе мерцает кружка с чаем, который я разогревал трижды и всё равно забыл выпить. У коллеги на фоне скрипит детская рация: «Папаааа». Классическая ночь перед релизом.

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

Почему сайты со справочниками валятся не от трафика, а от контента

У больших инфо-проектов не столько проблемы с хостингом, сколько с людьми и смыслами. Когда у тебя 12 000+ карточек сущностей, любое кривое поле растягивается на тысячи страниц. Я видел, как один крупный ритейлер в 2025 удушил SEO из-за поля «Цвет» — редакторы вбивали туда «нежно-коралловый (как у неба после дождя)». Красиво, но машиной не читается. В медицинских справочниках то же самое: чуть не задал жёсткие словари — через месяц редакторы превращают базу в поэзию серебряного века.

Добавьте ещё коды и классификаторы. Любая вещь, у которой есть «официальная номенклатура», приносит две беды: версия и область применения. Даже буквы в коде иногда значат разное для смежных разделов. Если не привязать конкретный раздел, вы упрётесь в серые зоны и споры «а это сюда или туда» на 40 минут созвона.

И, конечно, поиск. Пользователь никогда не пишет так, как мы назвали сущность. Он пишет с ошибками, по-человечески и иногда совсем не тем словом. В нашем проекте 27% запросов приходили с опечатками по двум символам. Плюс жаргон, плюс «гастрит ночью болит чем помочь срочно». Если ваша модель не терпит хаоса — вы проиграли ещё до релиза.

Что сработало на реальном проекте

Мы оставили пять базовых сущностей и навели жесточайшую дисциплину связей. «Болезнь» — это каноническая карточка, у которой есть обязательный код (один или несколько), список форм, список синонимов, запрещённые синонимы (да-да, такое поле реально нужно), связанные симптомы, услуги и статьи. «Симптом» — отдельная сущность, не текстовый список. «Код» — самостоятельная таблица со ссылкой на раздел, версию и валидацией «код принадлежит к семейству X». Всё остальное — представления и деривативы.

Стек был предсказуемый: фронт на Next.js с серверными компонентами, бэкенд — headless на Node с Postgres, поиск — Meilisearch. Не экзотика, а нормальная кухня. Важнее процессы. Мы привезли редакторам «контент-линтер»: набор правил, который ругается на «возможное дублирование синонима» или «слово из стоп-листа». За первый месяц линтер поймал 632 нарушения, из них 119 — критические (непривязанный код, расхождение в формулировке титула и h1, отсутствующий канонический синоним).

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

Синонимы по ЖКТ оказались особенно бодрыми. «ГЭРБ» против «рефлюкс-эзофагит», «изжога» против «жжение за грудиной» — редакторам казалось, что это одно и то же, а врач в чате резонно писал: «Не путайте, у нас тут разные ветки». Мы разделили поля «то, как ищут» и «то, как правильно называть», развели их по разным индексам и добавили подсказки в админку.

В ночь перед сдачей я поймал себя на том, что уже в третий раз за неделю открываю страницу «болезни ЖКТ МКБ 10» — проверяю, в какой блок уезжают наши карточки и как формулировки соотносятся с тем, что мы предлагаем в поисковых подсказках. Скучнейшее действие оказался самым полезным: мы выкинули 14 «красивых, но лишних» синонимов и сократили шум в выдаче на 31%.

Там же мы заметили странную штуку: редакторы пытались засунуть в одно поле и код, и расшифровку. Прекрасно понятно, почему — «чтобы было рядом». Мы разделили это насильственно: техническое поле «код» закрыли от глаз, а в видимой карточке начали собирать «подпись» из трёх кусков: «канон», «версия», «человеческая расшифровка». По клику редактор всё равно добирается до кода, но руками его не трогает. Ошибок стало меньше в четыре раза уже на второй неделе (с 47 до 12 в спринт).

Как подружить редакторов и разработчиков, не устроив терапию группе

У редакторов другая ментальная модель. Им нужен контекст, «как это увидит читатель», а не наши нормализованные таблицы. Мы показали превью карточки сразу в админке — ровно так, как это увидит пользователь. Плюс три простых статуса: «черновик», «на валидации», «готово». Никаких «публикационных флоу v2». И ещё одна мелочь, которая сэкономила часы: поле «почему запрещён синоним». Это кажется бюрократией, но когда новый редактор открывает карточку и видит «запрещено, потому что это симптом, а не диагноз» — количество споров уходит в ноль.

Мы ещё добавили «памятки» по тонким местам. Например: «не пишем “кишечник” без уточнения отделов», «расхлопываем аббревиатуры при первом упоминании», «в поисковых подсказках — только разговорные формы, в h1 — канон». Никакой магии: это не про ИИ, а про взрослую редактуру и терпение.

Производительность и поиск: цифры без пафоса

Серверный рендер и кэш на краю сделали своё дело. Средний TTFB на карточках — 92 мс, LCP на среднем Android — 1,8 с, CLS — 0,02. Индексация Meilisearch проглатывала 11 238 синонимов за 2 минуты 40 секунд при 512 МБ RAM на воркере. Мы отрубили горячую нормализацию текста в рантайме и вынесли лемматизацию в препроцессор; задержка на запрос упала с 180 до 63 мс.

Подсказки в поиске строили из «разговорной» коллекции, а переход — на «каноническую» карточку. Если пользователь выбирает «понос», он попадёт на «диарея», но в заголовке видит обе формы: «Диарея (понос)». Людям так понятнее, а врачам спокойнее. CTR подсказок вырос с 7,9% до 12,6%, отказов стало меньше на 19%.

Самая болезненная мелочь — опечатки. Мы не побеждали их «одним алгоритмом», а собрали костыль из трёх: фонетическая близость (русифицированный Metaphone), редакционное расстояние и словарь «топ-300 ошибок». Да, кустарно. Но конверт из поиска в карточку перевалил за 41% против 28% в пилоте. Иногда на проде побеждают не лучшие идеи, а те, которые можно честно поддерживать год.

Баги, за которые стыдно, и чему они научили

18 июля 2025, 02:47, кто-то (я) неверно выставил каноникал на тестовом наборе карточек: половина болезней ссылалась на одну и ту же «родительскую». За ночь мы словили 123 дубликата в индексе. Было больно, но стало полезно — появилась проверка на уровне пайплайна, которая не пускает в релиз несогласованность «канон/синоним/родитель». Десять минут стыда — минус бесконечность похожих факапов в будущем.

Ещё был эпизод из серии «удобство важнее всего». Мы автодополняли запросы «как лечить…» и в топ подсказок улетела «борщ» — потому что в тестовом датасете кто-то из редакторов шутканул в поле «рецепты». Пользователи, к счастью, юмор не увидели — фича была закрыта за флагом. Но я до сих пор держу рядом список «что никогда не трогать без ревью».

Практические шаги, если завтра делать похожий проект

1) Начните с модели данных и дисциплины полей: что канон, что синоним, что запрещено и почему; 2) Отдельная сущность под коды с версионированием и жёсткой привязкой к разделам; 3) Два индекса в поиске — «разговорный» и «канонический», переход — всегда на канон; 4) Контент-линтер в админке: словари, стоп-листы, подсказки; 5) Превью карточки прямо там, где редактируешь; 6) Честная телеметрия: TTFB, LCP, конверсия из подсказок, доля опечаток, количество правок на карточку. Если чего-то не меряете — считайте, что оно не существует.

Что меняется в 2026 и как к этому подстроиться

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

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

Обсуждение закрыто.