В прошлый раз я писал про то, что сообщение об ошибке читает уставший человек в два часа ночи. Там была одна простая мысль: ошибка должна сказать, что случилось, почему и что делать дальше. Переписали голое invalid_request в человеческий ответ, и стало лучше.

Вот только «стало лучше» — это ощущение. А ощущение нельзя положить в роадмап (или защитить перед руководством), чтобы сравнить через квартал. Улучшить то, что ты не измеряешь, нельзя: можно только верить, что улучшил.

Давайте сегодня разберёмся, как DX из набора интуиций превратился в измеримую дисциплину: с исследованиями, метриками и цифрами. И как этим пользоваться, не скатываясь в дашборд ради дашборда.

Интуиция в научном костюме

В 2023-м Артём Закируллин опубликовал статью «Cognitive Load is what matters» на Hacker News (её, кстати, переводили на Хабре). Тогда статью хвалили Роб Пайк, Андрей Карпатый, Джон Остерхаут, Адди Османи — не последние, мягко говоря, люди в индустрии. Основной тезис в статье был о том, что сложность кода стоит мерить не строчками, а тем, сколько всего разработчику приходится держать в голове, чтобы понять, что эти строчки делают.

Логично, не поспоришь. Но рядом, в обсуждении, появился любопытный комментарий исследователя из Стэнфорда. Если коротко: документ берёт идеи, с которыми разработчики и так согласны (композиция лучше наследования, микросервисов разводят слишком много и т.д.), и задним числом подпирает их «снижением когнитивной нагрузки». Выходит научная видимость там, где твёрдых экспериментальных данных почти нет. Читатель думает «ага, под моим чутьём есть наука» — а науки-то нам и не предъявили.

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

DX — это не один пост в блоге, а линия исследований

Сам термин не вчерашний. Академическое определение опыта разработчика дали ещё Фагерхольм и Мюнх в 2012-м: DX — это то, как разработчик переживает и воспринимает инфраструктуру, на которой работает. Дальше за измерение взялись всерьёз, и выстроилась внятная линия.

  • 2018, Accelerate / DORA (Форсгрен, Хамбл, Ким). Четыре ключевые метрики поставки: частота деплоев, время от коммита до прода, доля неудачных изменений, время восстановления. Книга получила премию Shingo, а метрики DORA стали индустриальным стандартом разговора про инженерную скорость.

  • 2021, SPACE (Форсгрен и соавторы, ACM Queue). Пять измерений продуктивности: Satisfaction, Performance, Activity, Communication, Efficiency. Вывод, который я цитирую чаще всего: продуктивность нельзя свести к одной цифре, и каждая попытка это сделать — враньё.

  • 2023, DevEx (Нода, Стори, Форсгрен, Грейлер, ACM Queue). Двадцать пять разрозненных социотехнических факторов свернули в три измеримых: петли обратной связи, когнитивная нагрузка и состояние потока.

  • 2024, DX Core 4 (DX, Лора Тачо и Аби Нода). Свели DORA, SPACE и DevEx в одну счёт-карту из четырёх измерений: Speed, Effectiveness, Quality, Impact.

Это не четыре конкурирующих мнения, а одна дозревающая модель. И сквозной человек в ней — Николь Форсгрен: соавтор и DORA, и SPACE, и DevEx. Её мысль кочует из работы в работу: соединяй данные восприятия с системными данными и никогда не сворачивай сложную систему в одну метрику (даже если это самая красивая метрика).

Дальше разберу три измерения DevEx по очереди — они самые применимые на практике.

Измерение 1. Петли обратной связи

Петля обратной связи — это скорость и качество ответа на действие разработчика. Запустил сборку: сколько ждёшь. Открыл PR: сколько висит ревью. Сделал запрос к API: через сколько понял, сработало или нет.

Самая показательная петля для внешнего API — та, про которую я писал в прошлый раз с другого боку: TTFHW, время до первого «Hello World». От «зашёл на сайт» до первого осмысленного ответа.

# Идеальная первая петля: один вызов, видимый ответ, никакого профиля компании
curl https://api.example.com/v1/ping \
  -H "Authorization: Bearer test_key_123"
{ "status": "ok", "message": "Авторизация прошла. Готовы к работе." }

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

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

На одном из проектов мы сократили этот самый TTFHW почти вчетверо. Причём не косметикой доков, а отдельным заходом — собрали no-code слой для интеграции с чужими API (по духу что-то вроде RapidAPI): ключи, песочница и готовые примеры в одном месте, чтобы между «захотел вызвать» и «получил ответ» не было получаса возни. Вышло дорого, зато петлю схлопнули так, как точечными правками её было не сдвинуть.

Измерение 2. Когнитивная нагрузка

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

В когнитивной психологии есть оценка ёмкости рабочей памяти. Популярная «семь плюс-минус два» Миллера (1956) давно уточнена: Коуэн и более поздние работы сходятся примерно на четырёх единицах разом. Это и есть потолок. Не «семь, если постараться», а около четырёх — и дальше понимание рассыпается.

Вот пример фрагмента кода, который пробивает потолок на ровном месте:

if val > LIMIT \
   and (cond_b or cond_c) \
   and (cond_d and not cond_e):
    do_the_thing()

Чтобы понять условие входа, нужно держать в голове: val против лимита, дизъюнкцию cond_b or cond_c, ещё конъюнкцию с отрицанием. Три-четыре независимых факта разом — уже у потолка, а это только if. Лечится именами:

is_within_limit = val > LIMIT
is_allowed = cond_b or cond_c
is_secure = cond_d and not cond_e

if is_within_limit and is_allowed and is_secure:
    do_the_thing()

Логика та же. Но рабочая память теперь чистая: вместо четырёх фактов — три читаемых имени, и держать их в голове не нужно, их видно. То же самое в большом масштабе делает наследование и «умная» архитектура: пока доберёшься до AdminController, в голове уже лежат BaseController, GuestController и UserController. Нагрузка копится по слоям и в какой-то момент пробивает потолок.

В API когнитивную нагрузку гонят вверх ровно три вещи, и все три измеримы. Непоследовательные имена: userId в одном эндпоинте и user_id в соседнем; каждое такое расхождение — лишняя единица в памяти. Сюрпризы: метод делает не то, что обещает имя, и приходится лезть в доки. И недокументированные ошибки: каждая 4xx, которой нет в документации, отправляет разработчика перебирать варианты наугад. Последнее даже не требует опроса, считается из логов: число кодов ответа, не описанных в доках. Цель тут ноль.

Измерение 3. Состояние потока

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

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

Метод, а не метрика

Тут легко споткнуться. Соблазн — сделать дашборд с одной большой цифрой «здоровье DX: 73%» и отчитываться ей. Это ровно та ошибка, против которой бьёт SPACE: одна метрика всегда найдёт способ соврать. Поджали тесты ради времени сборки, и петля «улучшилась», а качество просело.

Рабочий метод другой: соединять восприятие (что разработчик чувствует: опрос) и систему (что видно в данных: метрики) и держать три измерения рядом, не усредняя в одно. Перцептивную часть в DX Core 4 закрывают коротким опросником DXI; нам для начала хватит трёх честных вопросов по шкале от 1 до 5:

  1. Сборка и тесты отвечают мне достаточно быстро. (петли)

  2. Мне легко понять незнакомый кусок системы. (нагрузка)

  3. У меня есть длинные окна без прерываний на работу. (поток)

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

from statistics import mean

def normalize(value, good, bad):
    """Линейно к [0..1]: good -> 1, bad -> 0, с зажимом. good != bad."""
    if good == bad:
        raise ValueError("good и bad должны различаться")
    t = (value - bad) / (good - bad)
    return max(0.0, min(1.0, t))

def devex_snapshot(perceived, system):
    return {
        "feedback_loops": round(mean([
            perceived["ci_feels_fast"],                      # опрос
            normalize(system["ttfhw_min"], good=2, bad=15),  # система
            normalize(system["ci_p50_min"], good=3, bad=20),
        ]), 2),
        "cognitive_load": round(mean([
            perceived["easy_to_understand"],
            normalize(system["undocumented_4xx"], good=0, bad=10),
        ]), 2),
        "flow_state": round(mean([
            perceived["can_focus"],
            normalize(system["interruptions_per_day"], good=2, bad=12),
        ]), 2),
    }

perceived = {"ci_feels_fast": 0.4, "easy_to_understand": 0.5, "can_focus": 0.3}
system = {"ttfhw_min": 12, "ci_p50_min": 18,
          "undocumented_4xx": 6, "interruptions_per_day": 9}

print(devex_snapshot(perceived, system))
# {'feedback_loops': 0.25, 'cognitive_load': 0.45, 'flow_state': 0.3}

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

На выходе не одна цифра, а три. И сразу видно, куда вкладываться первым: петли просели сильнее всего. В этом и смысл метода — он показывает не «плохо или хорошо», а где именно и что чинить.

Зачем это бизнесу, а не только инженерам

DX легко записать во «внутреннюю гигиену разработчиков», на которую жалко денег. Цифры говорят обратное. В исследовании, на которое опирается работа DevEx, компании с лучшей рабочей средой для разработчиков показывали рост выручки в четыре-пять раз выше конкурентов. Это корреляция, а не доказанная причинность, но связь устойчивая. А последующая работа DevEx in Action разбирает уже конкретные эффекты: быстрее и надёжнее поставка, выше удержание людей.

Логика простая. Плохой DX — это не «разработчикам некомфортно». Это медленные релизы, тикеты в поддержку вместо фич, уходящие сеньоры и интеграции, которые клиент бросает на полпути. И каждое из этого превращается в строку P&L.

Хороший образец, как это монетизируется, — Stripe. Спросите на Hacker News про эталонные API-доки, и Stripe назовут по умолчанию: они сделали из документации, SDK и предсказуемых API сам продукт. Их идемпотентные запросы (тот самый Idempotency-Key, который клиент шлёт, чтобы безопасно повторить запрос и не списать деньги дважды) стали отраслевым паттерном. Результат измеримый: через Stripe в 2024-м прошло порядка 1,4 триллиона долларов. DX тут не статья расходов, а конкурентное преимущество, которое копится годами.

И при чём здесь агент

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

И посмотрите, как на агента ложатся ровно те же три измерения.

Петли обратной связи. Человек, упёршись в невнятный ответ, психанёт и напишет в поддержку. Агент — повторит запрос. И ещё раз. Без внятного кода ответа и стабильной формы он зациклится или тихо сделает не то. Хорошая петля для агента критичнее, чем для человека.

Когнитивная нагрузка. У агента «рабочая память» — это контекстное окно, и оно тоже не резиновое. Непоследовательные имена, сюрпризы, недокументированные ошибки забивают его контекст мусором ровно так же, как забивают голову человеку. Скучный, предсказуемый, единообразный API одинаково выручает и человека, и агента.

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

Поэтому AX, опыт для агента, — это не отдельная новая дисциплина, которую надо строить с нуля. Это тот же DX, доведённый до предела: всё, что вы измеряете и чините для разработчика, агенту нужно ещё сильнее, потому что ему некому пожаловаться. Стандарты тут уже укладывают: MCP как способ подключать агентов к инструментам, /llms.txt как карта сайта для них. Но карта не спасёт, если под ней API, который удивляет.

Что делать на практике

Откройте свою документацию и засеките время от первого экрана до первого работающего вызова. Больше пяти минут — вот и задача номер один, остальное подождёт. Дальше прогоните коды ответа своего API против документации: каждая 4xx, которой в доках нет, отправляет разработчика гадать наугад, то есть грузит голову лишним; цель тут ноль. И спросите себя, команду или внешних интеграторов по шкале от 1 до 5: быстро ли отвечают сборка и тесты, легко ли понять чужой кусок системы, остаются ли длинные окна без прерываний. Ответы положите рядом с системными числами.

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

Комментарии (1)


  1. Genius_Russian_Coders
    17.06.2026 09:08

    Заметил, что метрики вроде time-to-first-commit работают только когда CI не флакует. У нас лучшим DX-индикатором стало время от клона до зелёных тестов в докере — >5 минут = проблемы с онбордингом.