Скрытые издержки AI-генерации кода: о чем молчат про поддержку

#ai#code-quality#maintenance#frontend

TL;DR

AI-генерация кода ускоряет разработку, но создает “jelly code” — хрупкие решения без архитектурной целостности. Основные проблемы: накопление технического долга, потеря контекста и инвертированный 80/20 rule. Эффективное использование требует строгого code review и компенсирующих практик.

Введение: магия и реальность AI-кодинга

Мы все видели демки, где ChatGPT за 30 секунд генерирует работающий CRUD с графиками и dark mode. Но через полгода такие codebase превращаются в maintenance nightmare. Проблема не в качестве кода как такового, а в его архитектурной согласованности и долгосрочной поддерживаемости.

Jelly Code: хрупкость под капотом

AI генерирует код, который выглядит рабочим, но содержит структурные проблемы:

// Типичные артефакты AI-генерации
function processData(data) {
  // 1. Избыточные проверки
  if (data && data.items && Array.isArray(data.items) && data.items.length > 0) {
    return data.items.map(item => {
      // 2. Дублирование логики (уже есть в utils/)
      const formatted = `${item.name}-${item.id}`.toLowerCase();
      
      // 3. Неиспользуемый импорт (см. выше)
      return formatted;
    });
  }
  
  // 4. Неявное поглощение ошибок
  return [];
}

Характерные маркеры jelly code:

Инвертированный 80/20 принцип

С AI классическое правило переворачивается:

  1. Первые 80% фичи: 20% времени (AI magic)
  2. Последние 20%: 300% времени (debugging и интеграция)

Пример из реального проекта:

// AI-сгенерированный хук для API
const useFetchData = (url: string) => {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    fetch(url)
      .then(res => res.json())
      .then(setData);
  }, [url]);

  return data;
};

// Проблемы:
// 1. Нет обработки ошибок
// 2. Нет abort controller
// 3. Нет кэширования
// 4. Нет debounce для частых вызовов

Стратегии работы с AI-кодом

1. Code Review как архитектурный контроль

Не проверяем “работает ли”, а оцениваем:

// Плохо (AI-стиль)
function getUser() {
  return fetch('/user').then(r => r.json());
}

// Хорошо (human-refactored)
const api = {
  async fetchJson(endpoint, opts) {
    const res = await fetch(`/api/v1${endpoint}`, opts);
    if (!res.ok) throw new ApiError(res.status);
    return res.json();
  }
};

2. Компенсирующие практики

# Пример проверки тестов
npx stryker run --mutator typescript

3. Контекстное документирование

AI генерирует JSDoc, но теряет бизнес-контекст:

/**
 * @param {number} price - The product price
 * @returns {number} - Discounted price
 */
function applyDiscount(price) {
  // Почему 15%? Какие продукты исключены?
  return price * 0.85;
}

Где AI действительно полезен

  1. Boilerplate generation:
# Next.js page scaffold
npx ai-gen "create Next.js page with dynamic routes, 
            getStaticProps and TS support"
  1. Тесты для стабильных API:
// Vitest + MSW
test('GET /api/user returns 200', async () => {
  server.use(rest.get('/api/user', (req, res, ctx) => {
    return res(ctx.json({ id: 1, name: 'Test' }));
  }));
  
  const res = await fetch('/api/user');
  expect(res.status).toBe(200);
});
  1. Learning spike:
// Вариант 1: Zustand
const useStore = create(set => ({
  count: 0,
  increment: () => set(state => ({ count: state.count + 1 })),
}));

// Вариант 2: Jotai
const countAtom = atom(0);
const useCount = () => useAtom(countAtom);

Заключение: баланс скорости и качества

AI — мощный инструмент, но не silver bullet. Ключевые принципы:

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

Как проверить здоровье codebase: представьте, что вам нужно переписать его с нуля за месяц. Если понимание кода займет больше времени — вы перегрузили систему AI-генерацией без должного контроля.


Источник: https://dev.to/elysiumquill/the-hidden-cost-of-ai-generated-code-what-nobody-tells-you-about-maintenance-3om