Попробовать бесплатно
Попробовать бесплатно

Рефакторинг кода нейросетью — ИИ перепишет и упростит код

Вставьте код — нейросеть вернёт переписанный вариант, список изменений с привязкой к строкам и объяснение каждой правки.

  • Работает без VPN
  • Оплата картой и СБП
  • Русский интерфейс

Запрос и ответ: примеры из кабинета

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

Запрос Что вводили
Отрефактори этот фрагмент на Python. Глубина правок — чистка без риска: убрать дубли и мёртвый код, поведение не менять. Правила проекта: Python 3.11, тесты на pytest, форматирование не трогать — его закрывает линтер.

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

# orders/handlers.py
def handle_payment_success(raw):
    data = json.loads(raw)
    status = data.get("status")
    order_id = data.get("order", {}).get("id")
    amount = int(data.get("order", {}).get("amount", 0)) / 100
    currency = data.get("order", {}).get("currency", "RUB")
    if status != "succeeded":
        return None
    order = Order.objects.get(pk=order_id)
    order.paid = True
    order.amount = amount
    order.currency = currency
    order.save()
    notify(order, "paid")
    return order


def handle_payment_refund(raw):
    data = json.loads(raw)
    status = data.get("status")
    order_id = data.get("order", {}).get("id")
    amount = int(data.get("order", {}).get("amount", 0)) / 100
    currency = data.get("order", {}).get("currency", "RUB")
    if status != "refunded":
        return None
    order = Order.objects.get(pk=order_id)
    order.paid = False
    order.refunded_amount = amount
    order.currency = currency
    order.save()
    notify(order, "refunded")
    return order


def handle_payment_failed(raw):
    data = json.loads(raw)
    status = data.get("status")
    order_id = data.get("order", {}).get("id")
    amount = int(data.get("order", {}).get("amount", 0)) / 100
    currency = data.get("order", {}).get("currency", "RUB")
    if status != "failed":
        return None
    order = Order.objects.get(pk=order_id)
    order.paid = False
    order.amount = amount
    order.currency = currency
    order.last_error = data.get("error", {}).get("message", "")
    order.save()
    notify(order, "failed")
    return order
Модель
GPT 5 Mini
Списание
списываются токены, расход зависит от выбранной модели

Ответ

Файл: orders/handlers.py


import json
from typing import Any, Dict, Tuple, Optional

# Assumes Order and notify are available in the import context (kept as in original code).


def _parse_raw(raw: str) -> Tuple[Dict[str, Any], Optional[str], Optional[int], float, str]:
    data = json.loads(raw)
    status = data.get("status")
    order = data.get("order", {}) or {}
    order_id = order.get("id")
    amount = int(order.get("amount", 0)) / 100
    currency = order.get("currency", "RUB")
    return data, status, order_id, amount, currency


def _get_order(order_id: int):
    return Order.objects.get(pk=order_id)


def _save_and_notify(order, event: str):
    order.save()
    notify(order, event)
    return order


def handle_payment_success(raw):
    data, status, order_id, amount, currency = _parse_raw(raw)
    if status != "succeeded":
        return None

    order = _get_order(order_id)
    order.paid = True
    order.amount = amount
    order.currency = currency
    return _save_and_notify(order, "paid")


def handle_payment_refund(raw):
    data, status, order_id, amount, currency = _parse_raw(raw)
    if status != "refunded":
        return None

    order = _get_order(order_id)
    order.paid = False
    order.refunded_amount = amount
    order.currency = currency
    return _save_and_notify(order, "refunded")


def handle_payment_failed(raw):
    data, status, order_id, amount, currency = _parse_raw(raw)
    if status != "failed":
        return None

    order = _get_order(order_id)
    order.paid = False
    order.amount = amount
    order.currency = currency
    order.last_error = data.get("error", {}).get("message", "")
    return _save_and_notify(order, "failed")


Список правок

Важно — рефакторинг, orders/handlers.py строки 1-4 — Добавлен импорт json и typing; json раньше использовался без явного импорта в фрагменте, что могло привести к NameError в файле при запуске. Добавление импорта устраняет этот риск и не меняет поведение.
Важно — удаление дублирования, orders/handlers.py строки 6-14 — Вынесена общая логика парсинга полезной нагрузки в функцию _parse_raw. Ранее одинаковый код повторялся в трёх функциях, что затрудняло поддержку; теперь код централизован, поведение не изменено.
Важно — удаление дублирования, orders/handlers.py строки 17-22 — Вынесена логика сохранения и уведомления в функцию _save_and_notify. Ранее вызов save() и notify(…) повторялся; это уменьшает дублирование без изменения последовательности действий.
Замечание — рефакторинг, orders/handlers.py строки 16-18 — Введена вспомогательная функция _get_order для явного получения заказа по id. Это мелкая структурная правка, упрощающая чтение кода и облегчающая возможное покрытие моками в тестах.
Замечание — рефакторинг/стилистика, orders/handlers.py строки 6-40 — Упорядочена логика каждого обработчика: сначала парсинг и проверка статуса, затем изменение полей и единый save/notify. Это убирает повторяющиеся части и делает код компактнее, поведение осталось прежним (те же поля меняются и те же уведомления отправляются).

Пояснение: все изменения направлены на удаление дублирования и небольшую организацию кода без изменения логики: те же проверки статуса, те же присваивания полей, то же сохранение и уведомление. Форматирование намеренно не тронуто иначе, чем необходимо для корректной работы (импорт json и мелкие вспомогательные функции).
Запрос Что вводили
Отрефактори этот фрагмент на JavaScript. Глубина правок — структурные правки: разбить длинные функции и развести зависимости, поведение сохранить. Правила проекта: Node 20, ESM, тесты на vitest, форматирование не трогать.

Пришли переписанный файл целиком, а под ним — список правок: у каждой уровень важности (критично, важно или замечание), тип правки, файл и строки, заголовок в одну строку и объяснение, чем это мешало. Код пришли блоком кода, с отступами в 2 пробела.

// cart/checkout.js
export async function checkout(req, res) {
  const cart = await db.carts.findOne({ id: req.body.cartId });
  if (!cart) { res.status(404).json({ error: 'cart not found' }); return; }
  let total = 0;
  for (const item of cart.items) {
    const product = await db.products.findOne({ id: item.productId });
    if (!product) { res.status(400).json({ error: 'bad item' }); return; }
    let price = product.price;
    if (product.sale && product.saleEndsAt > Date.now()) {
      price = Math.round(price * (1 - product.salePercent / 100));
    }
    if (cart.promo === 'FIRST10' && !cart.usedPromo) {
      price = Math.round(price * 0.9);
    }
    total += price * item.qty;
  }
  if (total > 500000) { total = total - Math.round(total * 0.05); }
  const order = await db.orders.insert({ cartId: cart.id, total, status: 'new' });
  try {
    const payment = await gateway.charge({ orderId: order.id, amount: total });
    if (payment.status === 'succeeded') {
      await db.orders.update({ id: order.id }, { status: 'paid' });
      await mailer.send(cart.email, 'Заказ оплачен', `Заказ ${order.id} на сумму ${total / 100}`);
      res.json({ ok: true, orderId: order.id });
    } else {
      await db.orders.update({ id: order.id }, { status: 'failed' });
      res.status(402).json({ error: 'payment failed' });
    }
  } catch (e) {
    console.log(e);
    res.status(500).json({ error: 'server error' });
  }
}
Модель
GPT 5 Mini
Списание
списываются токены, расход зависит от выбранной модели

Ответ

// cart/checkout.js

export function createCheckoutHandler({ db, gateway, mailer, now = () => Date.now() }) {
  async function fetchCart(cartId) {
    return db.carts.findOne({ id: cartId });
  }

  async function fetchProduct(productId) {
    return db.products.findOne({ id: productId });
  }

  async function calculateTotal(cart) {
    let total = 0;
    for (const item of cart.items) {
      const product = await fetchProduct(item.productId);
      if (!product) {
        return { error: { status: 400, body: { error: 'bad item' } } };
      }

      let price = product.price;

      if (product.sale && product.saleEndsAt > now()) {
        price = Math.round(price * (1 - product.salePercent / 100));
      }

      if (cart.promo === 'FIRST10' && !cart.usedPromo) {
        price = Math.round(price * 0.9);
      }

      total += price * item.qty;
    }

    if (total > 500000) {
      total = total - Math.round(total * 0.05);
    }

    return { total };
  }

  async function createOrder(cartId, total) {
    return db.orders.insert({ cartId, total, status: 'new' });
  }

  async function markOrder(orderId, status) {
    return db.orders.update({ id: orderId }, { status });
  }

  async function processPayment(order) {
    return gateway.charge({ orderId: order.id, amount: order.total ?? order.amount ?? 0 });
  }

  return async function checkout(req, res) {
    const cart = await fetchCart(req.body.cartId);
    if (!cart) {
      res.status(404).json({ error: 'cart not found' });
      return;
    }

    const totalResult = await calculateTotal(cart);
    if (totalResult.error) {
      res.status(totalResult.error.status).json(totalResult.error.body);
      return;
    }
    const total = totalResult.total;

    const order = await createOrder(cart.id, total);

    try {
      const payment = await processPayment(order);

      if (payment.status === 'succeeded') {
        await markOrder(order.id, 'paid');
        await mailer.send(cart.email, 'Заказ оплачен', `Заказ ${order.id} на сумму ${total / 100}`);
        res.json({ ok: true, orderId: order.id });
      } else {
        await markOrder(order.id, 'failed');
        res.status(402).json({ error: 'payment failed' });
      }
    } catch (e) {
      console.log(e);
      res.status(500).json({ error: 'server error' });
    }
  };
}

// Backwards-compatible default handler using existing globals (if present)
export const checkout = createCheckoutHandler({ db, gateway, mailer, now: () => Date.now() });


Список правок:

важно, структурная правка, cart/checkout.js строки ~1-3, “Вынес создание обработчика в createCheckoutHandler”: Разделил создание обработчика и внедрение зависимостей (db, gateway, mailer, now) — ранее функции напрямую использовали глобалы, что мешало тестируемости и переиспользованию.
важно, структурная правка, cart/checkout.js строки ~5-17, “Вынес логику подсчёта в calculateTotal”: Цикл и логика расчёта цены и скидок вытянуты в отдельную функцию — это уменьшает размер основной функции и упрощает покрытие тестами; раньше длинная функция была трудна для понимания и поддержки.
замечание, структурная правка, cart/checkout.js строки ~6-9, “Разделил доступ к данным на fetchCart/fetchProduct”: Обёртки для чтения из db вынесены в отдельные функции, чтобы разделить ответственность и упростить мокирование в тестах — раньше прямые вызовы db затрудняли подмену во время тестирования.
важно, структурная правка, cart/checkout.js строки ~18-23, “Вынес создание и обновление заказа в createOrder/markOrder”: Операции с заказами вынесены в отдельные функции для ясности и возможности централизованной обработки ошибок/логирования — раньше эти вызовы были в теле основной функции, создавая когезионный блок.
замечание, структурная правка, cart/checkout.js строки ~24-27, “Вынес оплату в processPayment”: Вызов шлюза оплаты вынесен в отдельную функцию, что упрощает замену/mock и делает код основного обработчика компактнее.
замечание, поведенческая/структурная правка, cart/checkout.js строки ~28-31, “Сохранил поведение ошибок и статусы HTTP”: Вместо бросания исключений для ожидаемых ошибок (cart not found, bad item) теперь функции возвращают структуру с ошибкой, а обработчик отвечает с теми же статусами — поведение сохранено, но теперь централизовано.
замечание, структурная правка, cart/checkout.js строки ~1-37, “Добавил параметр now для определения текущего времени”: Параметр now (по умолчанию Date.now) введён для тестируемости условий распродажи; это не меняет поведения в проде, но упрощает тесты.
замечание, совместимость, cart/checkout.js строки ~39-41, “Добавил экспорт checkout для обратной совместимости”: Оставил экспорт checkout, созданный из createCheckoutHandler с предполагаемыми глобалами, чтобы существующий код не ломался — это упрощает постепенный рефактор.
Запрос Что вводили
Отрефактори этот фрагмент на TypeScript. Глубина правок — только критичное: править то, из-за чего код ломается или теряет данные, остальное не трогать. Правила проекта: TypeScript 5.4, strict, тесты на vitest.

Пришли переписанный файл целиком, а под ним — список правок: у каждой уровень важности (критично, важно или замечание), тип правки, файл и строки, заголовок в одну строку и объяснение, чем это мешало. Код пришли ОДНИМ блоком кода целиком, с отступами в 2 пробела.

// reports/build.ts
export function buildReport(rows: any[], opts: any) {
  const result: any = {};
  for (let i = 0; i < rows.length; i++) {
    const r = rows[i];
    const key = r.department + '/' + r.manager;
    if (result[key] == undefined) {
      result[key] = { total: 0, count: 0, avg: 0, items: [] };
    }
    const amount = parseFloat(r.amount);
    result[key].total = result[key].total + amount;
    result[key].count++;
    result[key].avg = result[key].total / result[key].count;
    result[key].items.push(r);
    if (opts.withTax) {
      result[key].total = result[key].total * 1.2;
    }
  }
  return result;
}
Модель
Claude 4.5 Sonnet
Списание
списываются токены, расход зависит от выбранной модели

Ответ

// reports/build.ts
export function buildReport(rows: any[], opts: any) {
  const result: any = {};
  for (let i = 0; i < rows.length; i++) {
    const r = rows[i];
    const key = r.department + '/' + r.manager;
    if (result[key] == undefined) {
      result[key] = { total: 0, count: 0, avg: 0, items: [] };
    }
    const amount = parseFloat(r.amount);
    result[key].total = result[key].total + (isNaN(amount) ? 0 : amount);
    result[key].count++;
    result[key].avg = result[key].total / result[key].count;
    result[key].items.push(r);
  }
  if (opts.withTax) {
    for (const key in result) {
      result[key].total = result[key].total * 1.2;
    }
  }
  return result;
}

Список правок

Правка 1

Уровень: Критично
Тип: Logic bug — неверное место применения налога
Файл: reports/build.ts
Строки: 14–16 (оригинал)
Заголовок: Налог * 1.2 применяется внутри цикла — накапливается с каждой новой строкой группы

Объяснение.
Блок if (opts.withTax) { result[key].total *= 1.2 } находился внутри for-цикла. При каждом добавлении следующей строки той же группы total умножался на 1,2 ещё раз, поверх уже умноженного значения. Для группы из трёх строк с одинаковыми суммами итоговый total оказывался завышен в 1.2² и 1.2³ раз — данные необратимо искажались. Исправление: блок вынесен в отдельный for…in после завершения основного цикла, чтобы коэффициент применялся ровно один раз к финальному total каждой группы.

Правка 2

Уровень: Критично
Тип: Data loss — беззвучное распространение NaN
Файл: reports/build.ts
Строки: 10–11 (оригинал)
Заголовок: parseFloat возвращает NaN при отсутствующем или некорректном r.amount, после чего total и avg группы безвозвратно становятся NaN

Объяснение.
parseFloat(undefined) и parseFloat("abc") возвращают NaN. После первого такого значения NaN попадает в total, и все последующие арифметические операции над ним тоже дают NaN — все накопленные данные группы теряются без каких-либо ошибок в рантайме. Исправление: добавлен guard isNaN(amount) ? 0 : amount, который заменяет невалидное значение нулём и не прерывает накопление суммы по группе.

Четыре шага до переписанного кода

  1. 01

    Откройте шаблон

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

    Шаблон «Рефакторинг кода» в кабинете 24AI: запуск в «Нейросетях» или в «Пайплайнах».
  2. 02

    Загрузите вводные

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

    Вводные шаблона: код в поле или файлом и пара строк о стеке, глубине правок и запретах.
  3. 03

    Выберите модель и запустите

    Из настроек только модель: GPT, Claude, Gemini или другая текстовая. Запуск списывает токены — их число задано для выбранной модели.

    Настройки шаблона: выбор текстовой модели перед запуском.
  4. 04

    Заберите результат

    Код и список правок приходят текстом — копируете к себе в IDE. Не устроило — уточните вводные, смените модель и запустите заново.

    Готовый ответ: переписанный код текстом и список правок.

Работа идёт в браузере: установка не нужна, вход через Точка ID, Яндекс ID и VK ID.

Code smells, которые находит нейросеть

Code smells — признаки кода, который работает, но мешает развитию. Нейросеть находит их и предлагает переписанный фрагмент. Уровень важности у каждой правки один из трёх: критично — риск ошибки в проде, важно — тормозит доработку, замечание — вопрос стиля.

  • Критично риск ошибки в проде
  • Важно тормозит доработку
  • Замечание вопрос стиля
Критично

Дублирование фрагментов

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

Важно

Перегруженные функции

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

Важно

Ветвление и вложенность

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

Замечание

Мёртвый и лишний код

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

Замечание

Неясные имена в коде

Однобуквенные переменные и числа без пояснения заменяются именами и константами. Код читается без комментариев, а смысл значения не теряется при правке. Пример: переменная d хранит срок в днях, но названа буквой.

Важно

Структура и зависимости

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

Нейросети, которые переписывают код

Модель выбирается в настройках шаблона в «Нейросетях» и «Пайплайнах» — без отдельных аккаунтов у OpenAI, Anthropic и Google.

GPT

Универсальный выбор под типовые правки: длинные функции, переименование, вынос повторов.

Claude

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

Gemini

Длинный контекст: несколько файлов и описание задачи помещаются в один запуск.

Grok

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

DeepSeek

Подходит для чистки однотипных служебных скриптов и утилит проекта.

Qwen

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

Kimi

Ещё одна модель для сверки: спорное решение удобно сравнить с её вариантом.

Состав пополняется, актуальные версии — в кабинете.

Как выглядит результат рефакторинга

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

Python
Вводные
ПараметрЗначение
Файлorders/handlers.py
ЯзыкPython
Глубина правокЧистка без риска
Правила проектаPython 3.11, тесты на pytest, форматирование не трогать
Всего правок5
Список правок
УровеньПравка
Важнорефакторинг, orders/handlers.py строки 1-4. Добавлен импорт json и typing; json раньше использовался без явного импорта в фрагменте, что могло привести к NameError в файле при запуске. Добавление импорта устраняет этот риск и не меняет поведение.
Важноудаление дублирования, orders/handlers.py строки 6-14. Вынесена общая логика парсинга полезной нагрузки в функцию _parse_raw. Ранее одинаковый код повторялся в трёх функциях, что затрудняло поддержку; теперь код централизован, поведение не изменено.
Важноудаление дублирования, orders/handlers.py строки 17-22. Вынесена логика сохранения и уведомления в функцию _save_and_notify. Ранее вызов save() и notify(…) повторялся; это уменьшает дублирование без изменения последовательности действий.
Замечаниерефакторинг, orders/handlers.py строки 16-18. Введена вспомогательная функция _get_order для явного получения заказа по id. Это мелкая структурная правка, упрощающая чтение кода и облегчающая возможное покрытие моками в тестах.
Замечаниерефакторинг/стилистика, orders/handlers.py строки 6-40. Упорядочена логика каждого обработчика: сначала парсинг и проверка статуса, затем изменение полей и единый save/notify. Это убирает повторяющиеся части и делает код компактнее, поведение осталось прежним (те же поля меняются и те же уведомления отправляются).
Разобрать свой файл
Python
Вводные
ПараметрЗначение
Файлorders/handlers.py
ЯзыкPython
Глубина правокЧистка без риска
Правила проектаPython 3.11, тесты на pytest, форматирование не трогать
Всего правок5
Список правок
УровеньПравка
Важнорефакторинг, orders/handlers.py строки 1-4. Добавлен импорт json и typing; json раньше использовался без явного импорта в фрагменте, что могло привести к NameError в файле при запуске. Добавление импорта устраняет этот риск и не меняет поведение.
Важноудаление дублирования, orders/handlers.py строки 6-14. Вынесена общая логика парсинга полезной нагрузки в функцию _parse_raw. Ранее одинаковый код повторялся в трёх функциях, что затрудняло поддержку; теперь код централизован, поведение не изменено.
Важноудаление дублирования, orders/handlers.py строки 17-22. Вынесена логика сохранения и уведомления в функцию _save_and_notify. Ранее вызов save() и notify(…) повторялся; это уменьшает дублирование без изменения последовательности действий.
Замечаниерефакторинг, orders/handlers.py строки 16-18. Введена вспомогательная функция _get_order для явного получения заказа по id. Это мелкая структурная правка, упрощающая чтение кода и облегчающая возможное покрытие моками в тестах.
Замечаниерефакторинг/стилистика, orders/handlers.py строки 6-40. Упорядочена логика каждого обработчика: сначала парсинг и проверка статуса, затем изменение полей и единый save/notify. Это убирает повторяющиеся части и делает код компактнее, поведение осталось прежним (те же поля меняются и те же уведомления отправляются).
JavaScript
Вводные
ПараметрЗначение
Файлcart/checkout.js
ЯзыкJavaScript
Глубина правокСтруктурные правки
Правила проектаNode 20, ESM, тесты на vitest, форматирование не трогать
Всего правок8
Список правок
УровеньПравка
ВажноВынес создание обработчика в createCheckoutHandler. Разделил создание обработчика и внедрение зависимостей (db, gateway, mailer, now) — ранее функции напрямую использовали глобалы, что мешало тестируемости и переиспользованию.
ВажноВынес логику подсчёта в calculateTotal. Цикл и логика расчёта цены и скидок вытянуты в отдельную функцию — это уменьшает размер основной функции и упрощает покрытие тестами; раньше длинная функция была трудна для понимания и поддержки.
ЗамечаниеРазделил доступ к данным на fetchCart/fetchProduct. Обёртки для чтения из db вынесены в отдельные функции, чтобы разделить ответственность и упростить мокирование в тестах — раньше прямые вызовы db затрудняли подмену во время тестирования.
ВажноВынес создание и обновление заказа в createOrder/markOrder. Операции с заказами вынесены в отдельные функции для ясности и возможности централизованной обработки ошибок/логирования — раньше эти вызовы были в теле основной функции, создавая когезионный блок.
ЗамечаниеВынес оплату в processPayment. Вызов шлюза оплаты вынесен в отдельную функцию, что упрощает замену/mock и делает код основного обработчика компактнее.
ЗамечаниеСохранил поведение ошибок и статусы HTTP. Вместо бросания исключений для ожидаемых ошибок (cart not found, bad item) теперь функции возвращают структуру с ошибкой, а обработчик отвечает с теми же статусами — поведение сохранено, но теперь централизовано.
ЗамечаниеДобавил параметр now для определения текущего времени. Параметр now (по умолчанию Date.now) введён для тестируемости условий распродажи; это не меняет поведения в проде, но упрощает тесты.
ЗамечаниеДобавил экспорт checkout для обратной совместимости. Оставил экспорт checkout, созданный из createCheckoutHandler с предполагаемыми глобалами, чтобы существующий код не ломался — это упрощает постепенный рефактор.
Разобрать свой файл
JavaScript
Вводные
ПараметрЗначение
Файлcart/checkout.js
ЯзыкJavaScript
Глубина правокСтруктурные правки
Правила проектаNode 20, ESM, тесты на vitest, форматирование не трогать
Всего правок8
Список правок
УровеньПравка
ВажноВынес создание обработчика в createCheckoutHandler. Разделил создание обработчика и внедрение зависимостей (db, gateway, mailer, now) — ранее функции напрямую использовали глобалы, что мешало тестируемости и переиспользованию.
ВажноВынес логику подсчёта в calculateTotal. Цикл и логика расчёта цены и скидок вытянуты в отдельную функцию — это уменьшает размер основной функции и упрощает покрытие тестами; раньше длинная функция была трудна для понимания и поддержки.
ЗамечаниеРазделил доступ к данным на fetchCart/fetchProduct. Обёртки для чтения из db вынесены в отдельные функции, чтобы разделить ответственность и упростить мокирование в тестах — раньше прямые вызовы db затрудняли подмену во время тестирования.
ВажноВынес создание и обновление заказа в createOrder/markOrder. Операции с заказами вынесены в отдельные функции для ясности и возможности централизованной обработки ошибок/логирования — раньше эти вызовы были в теле основной функции, создавая когезионный блок.
ЗамечаниеВынес оплату в processPayment. Вызов шлюза оплаты вынесен в отдельную функцию, что упрощает замену/mock и делает код основного обработчика компактнее.
ЗамечаниеСохранил поведение ошибок и статусы HTTP. Вместо бросания исключений для ожидаемых ошибок (cart not found, bad item) теперь функции возвращают структуру с ошибкой, а обработчик отвечает с теми же статусами — поведение сохранено, но теперь централизовано.
ЗамечаниеДобавил параметр now для определения текущего времени. Параметр now (по умолчанию Date.now) введён для тестируемости условий распродажи; это не меняет поведения в проде, но упрощает тесты.
ЗамечаниеДобавил экспорт checkout для обратной совместимости. Оставил экспорт checkout, созданный из createCheckoutHandler с предполагаемыми глобалами, чтобы существующий код не ломался — это упрощает постепенный рефактор.
TypeScript
Вводные
ПараметрЗначение
Файлreports/build.ts
ЯзыкTypeScript
Глубина правокТолько критичное
Правила проектаTypeScript 5.4, strict, тесты на vitest
Всего правок2
Список правок
УровеньПравка
КритичноНалог * 1.2 применяется внутри цикла — накапливается с каждой новой строкой группы. Блок if (opts.withTax) { result[key].total *= 1.2 } находился внутри for-цикла. При каждом добавлении следующей строки той же группы total умножался на 1,2 ещё раз, поверх уже умноженного значения. Для группы из трёх строк с одинаковыми суммами итоговый total оказывался завышен в 1.2² и 1.2³ раз — данные необратимо искажались. Исправление: блок вынесен в отдельный for…in после завершения основного цикла, чтобы коэффициент применялся ровно один раз к финальному total каждой группы.
КритичноparseFloat возвращает NaN при отсутствующем или некорректном r.amount, после чего total и avg группы безвозвратно становятся NaN. parseFloat(undefined) и parseFloat("abc") возвращают NaN. После первого такого значения NaN попадает в total, и все последующие арифметические операции над ним тоже дают NaN — все накопленные данные группы теряются без каких-либо ошибок в рантайме. Исправление: добавлен guard isNaN(amount) ? 0 : amount, который заменяет невалидное значение нулём и не прерывает накопление суммы по группе.
Разобрать свой файл
TypeScript
Вводные
ПараметрЗначение
Файлreports/build.ts
ЯзыкTypeScript
Глубина правокТолько критичное
Правила проектаTypeScript 5.4, strict, тесты на vitest
Всего правок2
Список правок
УровеньПравка
КритичноНалог * 1.2 применяется внутри цикла — накапливается с каждой новой строкой группы. Блок if (opts.withTax) { result[key].total *= 1.2 } находился внутри for-цикла. При каждом добавлении следующей строки той же группы total умножался на 1,2 ещё раз, поверх уже умноженного значения. Для группы из трёх строк с одинаковыми суммами итоговый total оказывался завышен в 1.2² и 1.2³ раз — данные необратимо искажались. Исправление: блок вынесен в отдельный for…in после завершения основного цикла, чтобы коэффициент применялся ровно один раз к финальному total каждой группы.
КритичноparseFloat возвращает NaN при отсутствующем или некорректном r.amount, после чего total и avg группы безвозвратно становятся NaN. parseFloat(undefined) и parseFloat("abc") возвращают NaN. После первого такого значения NaN попадает в total, и все последующие арифметические операции над ним тоже дают NaN — все накопленные данные группы теряются без каких-либо ошибок в рантайме. Исправление: добавлен guard isNaN(amount) ? 0 : amount, который заменяет невалидное значение нулём и не прерывает накопление суммы по группе.

Что написать во вводных

Достаточно прислать код. Если знаете что-то из списка ниже — добавьте, так рефакторинг получится точнее.

Что мешает в коде

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

Язык и версия

Python 3.11, Node 20, TypeScript 5.4 strict — по версии модель выбирает допустимые конструкции.

Стек и тесты

Фреймворк и чем проверяется код: Django и pytest, ESM и vitest — правки подстроятся под них.

Запреты

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

Пример вводных: «Python 3.11, тесты на pytest, поведение не менять, форматирование не трогать — его закрывает линтер». Не подошла правка — запустите шаблон заново и допишите во вводные, чего делать не нужно.

Что можно отдать на рефакторинг

Языки программирования
Python, JavaScript, TypeScript, PHP, Java, Kotlin, C#, C++, Go, Swift, Ruby, SQL и другие
Как подаёте код
Вставкой в поле или файлом: PY, JS, TS, PHP, SQL, TXT и другие, до 20 МБ
Формат кода
Фрагмент, файл целиком или diff веток
Репозитории
По умолчанию код вставляют или прикладывают файлом; интеграцию с GitHub или GitLab настраивают по MCP или через API-эндпоинты сервиса
Большие файлы
Надёжнее отдавать по модулю: так правки точнее и укладываются в контекст модели
Результат
Текст в ответе, выгрузки документом пока нет

Пример: запрос и ответ

Так выглядит работа с шаблоном на простой задаче: что вы пишете и что приходит в ответ.

Вы присылаете

Функцию на 60 строк и просьбу: «Упрости, поведение не меняй».

Приходит код

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

Список правок

Под кодом — что изменено и зачем, по пунктам: так проще проверить каждую правку.

Что проверить

Прогнать тесты: поведение должно остаться прежним. Где правка зависит от бизнес-логики, нейросеть так и пишет.

Что остаётся за разработчиком

С частью задач нейросеть справляется не с первого раза. Ниже — что решает команда и где правки стоит прогонять тестами.

Остаётся за человеком

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

  • Приёмка правок: ревью, прогон тестов и ответственность за мёрж.

  • Договорённости команды: стиль проекта, история решений и их причины.

  • Продуктовый выбор: что важнее — скорость доработки или скорость кода.

Где нужна проверка

  • Рантайм и продовые данные недоступны — модель читает только код.

  • Тесты не запускаются: эквивалентность правки проверяете вы у себя.

  • Редкие языки и очень большие файлы модель разбирает заметно хуже.

  • Повторный прогон может дать другой набор правок на том же коде.

Ставьте рефакторинг первым проходом: нейросеть готовит правки, решение о мёрже остаётся за вами и тестами.

Когда код отдают на рефакторинг

Доработка чужого модуля

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

Модуль под новую задачу

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

Код от нейросети в проекте

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

Подготовка кода к росту

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

Приёмка работы подрядчика

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

Учебный проект и разбор

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

Тарифы: что входит в подписку

Обращения к внешним моделям (GPT, Claude, Nano Banana и другие) списывают токены, обращения к собственным моделям 24AI — операции.

—
Пробный
0 ₽ Доступ на 24 часа
50токенов
Начать бесплатно
  • 12 операций
  • Один пользователь в аккаунте
—
Стартовый
999 ₽ / мес
500токенов 500 операций
Выбрать тариф
  • Доступ к моделям из каталога 24AI
  • Все 11 инструментов раздела
  • Лимит на текстовые модели 20 запросов в час, 120 в сутки*
  • Один пользователь в аккаунте
—
Базовый
1 999 ₽ / мес
1 500токенов Безлимит операций
Выбрать тариф
  • Все возможности «Стартового» тарифа
  • Все 11 инструментов раздела
  • Лимит на текстовые модели 40 запросов в час, 240 в сутки*
  • Один пользователь в аккаунте

* Лимит не распространяется на GPT 5.4 Pro, GPT 5.5 Pro, Claude 5 Fable и Claude 5.1 Fable: обращения к ним оплачиваются токенами.

Полные условия — в прайс-листе (PDF) →

Операции и токены — не одно и то же

Токенами оплачиваются обращения к нейросетям: их списывают внешние модели — GPT, Claude, Gemini, Nano Banana, Seedance, Kling и другие. Пакет токенов даётся по тарифу.

Операции — вторая счётная единица: их расходуют собственные модели 24AI в архивных разделах (удаление фона, генерация фона, улучшение качества и другие) и прямые запросы к текстовым моделям в «Нейросетях». На «Пробном» операций 12, на «Стартовом» 500, на «Базовом» и «Профессиональном» они не ограничены.

Текстовые модели в разделе «Нейросети» токены не списывают: при прямом обращении, когда вы пишете модели в чат, расходуются операции и почасовой лимит тарифа. Докупить лимит нельзя — когда он исчерпан, нужно дождаться следующего окна. Исключение — несколько моделей вне лимита: GPT 5.4 Pro, GPT 5.5 Pro, Claude 5 Fable и Claude 5.1 Fable, за них токены списываются и там. Внутри шаблона или в разделе «Пайплайны» токены списываются за любую текстовую модель.

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

Лимит обращений к текстовым моделям в чате

Стартовый
20 запросов · 120 запросов
Базовый
40 запросов · 240 запросов
Профессиональный
60 запросов · 360 запросов

Ваш код и права на результат генерации

Где остаётся код после запуска

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

Что обезличить до отправки

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

Кому принадлежит переписанный код

Исключительные права на результат принадлежат владельцу аккаунта, в чьём кабинете прошёл запуск: код можно использовать в коммерческих проектах без согласований и выплат сервису. 24AI работает как SaaS в браузере без установки: пользуетесь им по простой (неисключительной) лицензии на условиях лицензионного договора.

Вопросы по договору и данным — на support@24ai.tech.

Вопросы о рефакторинге

Не нашли ответ? Написать в поддержку

Безопасно ли отдавать рабочий код сервису?

Работа идёт в кабинете 24AI в браузере: код попадает в ваш аккаунт, история генераций хранится под вашей учётной записью, а на «Профессиональном» в аккаунте может работать до трёх пользователей. Правила обработки данных зафиксированы в лицензионном договоре и политике конфиденциальности. Договор на использование сервиса заключается с российским юридическим лицом: ООО «Архивариус», ИНН 5408024261. Ключи, пароли и токены доступа уберите из кода до вставки.

Меняет ли рефакторинг поведение программы?

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

С какими языками программирования работает нейросеть?

Чаще всего в работу идут Python, JavaScript, TypeScript, PHP, Java, Kotlin, C#, C++, Go, Swift, Ruby и SQL, но список не закрытый. Выбирать язык в списке не нужно: назовите его во вводных или приложите файл с кодом. На редких и узкоспециальных языках правки выходят слабее: модель реже встречала такой код и чаще предлагает общие решения. Проверяйте результат на небольшом фрагменте, прежде чем отдавать целый модуль.

Чем это отличается от работы напрямую с ChatGPT или Claude?

Доступ работает без VPN, оплата проходит российской картой и через СБП, интерфейс и поддержка — на русском. Аккаунты в OpenAI, Anthropic и Google заводить не нужно: GPT, Claude, Gemini, Grok и DeepSeek собраны в одном кабинете. Вместо пустого чата вы запускаете готовый шаблон: задача уже поставлена, вы подставляете код и пару строк о стеке, а ответ приходит по одной схеме — переписанный код и список правок с привязкой к строкам.

Можно ли отдать весь репозиторий целиком?

Готовой интеграции с GitHub, GitLab и Bitbucket нет: код вставляют в поле или прикладывают файлом. Для крупного проекта это скорее плюс — весь репозиторий не уложится в контекст модели, а правки к нему выйдут неточными. Разбейте задачу по файлам или отправьте diff между ветками: так правки привязаны к конкретным строкам, а результат проще проверить тестами. Свою цепочку с вебхуком или HTTP-запросом можно собрать в «Пайплайнах».

Что делать, если правки лишние или неверные?

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

Кому принадлежат права на переписанный код?

Исключительные права на результат принадлежат владельцу аккаунта. Переписанный код и текст правок используются в коммерческих проектах без отдельных согласований. Сам сервис предоставляется по простой (неисключительной) лицензии на условиях лицензионного договора с ООО «Архивариус» — это право пользоваться программой, и прав на результат оно не ограничивает. За законность применения результата отвечает пользователь.

Сколько запусков рефакторинга входит в тариф?

Шаблон считается токенами: они списываются за запросы к внешним нейросетям, и число токенов за один запуск задано для выбранной модели — длина кода на него не влияет. Объём работы ограничивает пакет токенов тарифа: 500 на «Стартовом», 1 500 на «Базовом», 3 500 на «Профессиональном». Все инструменты доступны уже со «Стартового» — от 999 ₽ в месяц.

Начните с одного проблемного файла

Вставьте файл, который дольше всего мешает команде, и посмотрите список правок с объяснениями и переписанный код.

  • 12 операций и 50 токенов
  • Доступ на 24 часа
  • Без VPN, оплата картой РФ и СБП

Разделы 24AI

Инструменты 24AI сгруппированы по задачам — от текста и карточек товара до кода

Текст Выберите инструмент для статьи, поста, описания товара или делового документа. Изображения Генерируйте картинки и обрабатывайте фото: меняйте фон, удаляйте объекты, улучшайте качество. Видео Выберите инструмент для видеосцены, рекламы или видеообложки товара. Маркетплейсы Подготовьте карточки товаров, фото, инфографику и ответы покупателям. Маркетинг и реклама Подберите инструмент для вашей задачи: изучить аудиторию, сформулировать предложение, подготовить тексты и креативы. Документы и файлы Составляйте документы, переводите тексты, проверяйте формулировки и выделяйте главное в отчётах. Код и разработка Выберите инструмент для написания, объяснения и проверки кода. Нейросети Выбирайте модели для текста, изображений, видео и кода в одном каталоге. Что умеет нейросеть Найдите способ написать текст, обработать фото, создать видео или разобраться с учебной задачей. Продукты и сервисы Выберите формат работы: чат с ИИ, цепочка генераций, массовая обработка фото или сборка инфографики. Словарь Разберитесь в понятиях от промпта и токена до языковых моделей и ИИ-агентов. Все инструменты Полный каталог 24AI по задачам.