Что чувствуют пользователи, когда ваш AI-код 'нормальный': UX-анализ трёх реализованных фич

#AI coding#UX#frontend

Технически корректный код — это не всегда то, что нужно пользователю. Особенно когда этот код сгенерирован ИИ. В этой статье разберём три реальных примера, где AI-код был “нормальным”, но вызвал проблемы с пользовательским опытом. И расскажем, как избежать таких ситуаций.

Модальное окно без фрикции: 14 случайных удалений аккаунта

Тикет: “Добавить кнопку удаления аккаунта в настройках с модальным окном подтверждения.”

Что было реализовано:

<Dialog>
  <DialogTitle>Delete account?</DialogTitle>
  <DialogDescription>
    This action cannot be undone.
  </DialogDescription>
  <DialogFooter>
    <Button variant="outline" onClick={close}>Cancel</Button>
    <Button variant="destructive" onClick={deleteAccount}>Delete</Button>
  </DialogFooter>
</Dialog>

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

ИИ написал то, что было в тикете: модальное окно с двумя кнопками. Но тикет не упоминал о необходимости фрикции — PM предположил, что это само собой разумеется. Для модели “модальное окно подтверждения” — это именно две кнопки.

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

Голый спиннер: снижение завершения платежей на 4.1%

Тикет: “Добавить спиннер загрузки во время обработки платежа.”

Что было реализовано:

{isProcessing ? <Spinner /> : <Button onClick={pay}>Pay $49</Button>}

Технически всё верно. Но пользователь видел следующее: нажимает “Pay $49”, кнопка исчезает, появляется спиннер, и через 1.2 секунды — экран успеха.

Мы протестировали альтернативу:

{isProcessing ? (
  <div className="flex items-center gap-2 text-sm text-muted-foreground">
    <Spinner />
    <span>{stage}</span>
  </div>
) : <Button onClick={pay}>Pay $49</Button>}

Где stage циклически менялся: “Contacting your bank…” → “Confirming payment…” → “Almost done…”. Результат: завершение платежей увеличилось на 4.1%. Пользователи, которые чувствовали себя информированными, не уходили.

Урок: Модель не понимает, что спиннер — это UX-пропасть. Она знает, что спиннер — это каноническое решение для состояния загрузки. Это разные вещи.

Ошибки, которые обвиняют пользователя

Типичный AI-код для обработки ошибок:

try {
  await createOrder(input);
} catch (e) {
  toast.error("Invalid input. Please check your details and try again.");
}

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

Например, один пользователь в записи сессии: “Я проверил. Дважды. Это не моя карта. Забудьте.” (закрывает вкладку)

Ошибка на самом деле: коллизия ключа идемпотентности из-за двойного нажатия кнопки. Ничего не было неверно. Заказ прошёл при первом клике.

Переписанная обработка ошибки:

try {
  await createOrder(input);
} catch (e) {
  if (e.code === "idempotency_conflict") {
    toast.info("Looks like this went through already — refreshing your order list.");
    await refetchOrders();
    return;
  }
  toast.error(
    "Something on our end didn't work. Your card wasn't charged. Try again or ping support — we'll fix it."
  );
}

Результат: запросы на возврат средств сократились вдвое.

Урок: Модель пишет достаточный код, но не человечный. Она оптимизирует выполнение спецификации, а спецификация — это сжатая версия того, что делает продукт хорошим.

Чеклист для AI-generated PR

Мы добавили четыре пункта в наш процесс проверки PR:

  1. Фрикция для деструктивных действий. Каждое критическое действие должно иметь шаг подтверждения, пропорциональный последствиям.
  2. Прогресс для асинхронных операций. Любой асинхронный вызов длительностью более 400 мс должен показывать индикатор прогресса с пояснением, а не просто спиннер.
  3. Человечные ошибки. Сообщения об ошибках не должны содержать слов “Invalid”, “Wrong” или “You”. Они должны указывать, что не произошло (например, списание средств), и предлагать следующий шаг.
  4. Пустые состояния с подсказками. Пустые состояния должны содержать советы для первого использования, а не просто “Нет элементов”.

Ни один из этих пунктов не может быть проверен линтером. Это вещи, которые заметит человек, просмотревший 50 часов записей пользовательских сессий.

Что делать дальше?

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

Какой из четырёх пунктов чеклиста провалил ваш последний AI-authored PR? У меня это был голый спиннер — дважды.


Источник: https://dev.to/lucas_martin_8cb158b9a81b/what-users-actually-feel-when-your-ai-generated-code-is-fine-a-ux-autopsy-of-3-shipped-features-2emc