Порой очень лениво выполнять рутинную работу или писать бойлерплейт с настройкой конфигураций под новый проект. Я считаю себя самым ленивым разработчиком на планете, так что эра ИИ для меня как манна небесная. Наконец-то появилась возможность отдать рутину второму пилоту. Но так ли этот пилот хорош? Больше года я использую ChatGPT в роли своего помощника, и вот что я понял...

Где ChatGPT Реально Полезен?

Быстрый поиск информации

Иногда нужно вспомнить синтаксис, как работает определенная функция, как правильно применить хуки в React или как отцентрировать div — ChatGPT может быстро напомнить нужные детали. Это экономит время на поиске в документации или Stack Overflow, когда нужен короткий ответ, а не глубокий поиск. Использовать нейронку вместо поисковика иногда гораздо удобнее и быстрее.

Пример: Как работает хук useContext в React?

Пример ответа на поиск общей информации по React хуку
Пример ответа на поиск общей информации по React хуку

Шаблоны для рутинного кода

В тех случаях, когда постоянно приходится писать шаблонный код, такой как конфигурация роутинга или настройки Formik, ChatGPT быстро генерирует скелет, а мы уже адаптируем его под свой проект. Это полезно, когда задача не требует особой индивидуальности кода, но нужна структурная основа.

Пример: Создай конфигурацию для API сервиса.

Пример как СhatGPT может накинуть шаблон для сервиса
Пример как СhatGPT может накинуть шаблон для сервиса

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

Рефакторинг кода

Когда есть подозрение, что код можно сделать проще или быстрее, ChatGPT поможет с вариантами. Это полезно при рефакторинге: можно попросить его предложить альтернативные версии, а затем выбрать или доработать нужную.

Пример: Помощь в рефакторинге.

Тут я перенес метод и попросил его улучшить
Тут я перенес метод и попросил его улучшить
 Его ответ
Его ответ

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

Объяснение сложных понятий или вопросов по библиотекам

Я очень часто использую ИИ для обучения: он объяснит любую тему, концепцию или архитектуру понятным языком, а детальность ответа можно регулировать во время беседы.

Ограничение: ChatGPT не всегда актуален, особенно для технологий, которые быстро развиваются. Если появилась новая версия библиотеки, он может давать устаревшую информацию.

Где ChatGPT Работает Слабо?

Отсутствие контекста проекта

ChatGPT не знает проекта целиком. Если в коде много связей или специфических зависимостей, он не может их учесть, из-за чего советы могут оказаться неприменимыми или даже ошибочными. Я советую использовать его в основном точечно или как вспомогательный источник информации.

Ограниченная поддержка сложных архитектурных решений

Когда требуется архитектурное решение или настройка на уровне FSD, ChatGPT может предложить лишь общие рекомендации. Для построения сложной архитектуры под конкретные требования потребуется более глубокий анализ, чем тот, который ИИ пока что может предложить.

Ошибки и устаревший код

Поскольку ChatGPT обучен на данных до 2021 года, некоторые из его решений могут быть устаревшими или неверными. Это особенно важно для тех технологий, которые активно развиваются, например, TypeScript или React.

Пример: Он может предлагать старые API или игнорировать последние изменения в синтаксисе хуков.

Как работать с СhatGPT эффективно

ChatGPT может быть отличным помощником, если понимать, как правильно взаимодействовать с ним и ставить задачи. Вот несколько стратегий и советов, которые помогут извлечь максимум пользы от второго пилота.

Четкая формулировка запроса

Создание правильного промта — это уже 90% успешной работы с любой нейросетью. Чем конкретнее ваш запрос, тем лучше результат. Вместо общих вопросов, таких как «как мне настроить роутинг», попробуй уточнить: «Как мне настроить роутинг в React с динамическими маршрутами?».

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

Мокковые данные

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

Генерация тестовых пользователей
Генерация тестовых пользователей

Быстрая типизация

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

Тип для ранее сгенерированных пользователей
Тип для ранее сгенерированных пользователей

Персонализация

У ChatGPT есть возможность становиться персональным и запоминать некоторые тезисы и факты из переписки о вас. Можно самостоятельно настраивать персонализацию в настройках. Это нужно для того, чтобы чат понимал, кто вы такой, и хранил контекст о вас. Я предоставил ему вводные данные, которые он использует при общении в каждом чате.

Контекст моего GPT
Контекст моего GPT

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

Еще одной интересной особенностью является его память.

Часть списка того, что он запомнил про меня из наших переписок.
Часть списка того, что он запомнил про меня из наших переписок.

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

Обязательное ревью каждого ответа

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

Разные варианты решения

Просите ChatGPT предложить альтернативные варианты решения. Хорошее решение может прийти в цифровую голову спустя некоторое количество попыток. Не останавливайтесь на одном варианте.

Объяснение кода

Языковая модель неплохо справляется с аналитикой небольших кусков кода. Это очень полезно, когда нужно разобраться в легаси или странной логике компонента.

Источник идей

ChatGPT может предложить тебе идеи проектов, модулей, структур данных и т.д. Очень часто, когда креатив на нуле, "железяка" подкидывала мне неплохие идейки, как реализовать модуль или даже как назвать переменную!

Заключение

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

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


  1. pilot114
    08.11.2024 11:45

    Спасибо за взвешенную оценку, всё очень похоже на мой собственный опыт.

    Пара дополнений:

    • надо постоянно думать как интегрировать в работу с llm "классические" инструменты. Например, линтеры и генераторы фейковых данных - это по сути своей решённые задачи, не надо мучить нейронки такой мелочью.

    • управлять контекстом - вещь муторная, но крайне важная. Если писать код по SRP, в момент решения задачи llm должна знать только о том коде, который к этой задаче относится, не больше и не меньше. В этом плане хорошо помогают утилиты типа aider. Он позволяет собрать саммари по проекту (имена папок, классов, методов) если задача архитектурная или загрузить в контекст конкретные файлы для точечных задач, буквально в пару команд.


    1. DmitryR3989 Автор
      08.11.2024 11:45

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


  1. SpiderEkb
    08.11.2024 11:45

    Приведу пример. Сразу скажу - он для достаточно специфического стека и языка. Суть в том, что в языке есть возможность прямой работы с БД. И во многих случаях этот способ намного быстрее и эффективнее чем делать то же самое через SQL.

    Так вот, есть две операции - READ - чтение следующей записи и READE - тоже самое, но с проверкой значения ключа (если ключ не совпал, вернется EOF).

    И вот интереса ради, берем два одинаковых куска кода

            dcl-f ECA10LF   disk(*ext)
                            usage(*input)
                            block(*yes)
                            usropn
                            keyed
                            qualified
                            static;
            
            dcl-ds dsECA    likerec(ECA10LF.ECAPFR: *all);
            dcl-s  LST      char(5);
    
            if not %open(ECA10LF);
              open ECA10LF;
            endif;
    
            for-each LST in %list('PPT': 'OMU': 'PE');
              setll (LST) ECA10LF;
              read ECA10LF.ECAPFR dsECA;
              
              dow not %eof(ECA10LF) and dsECA.ECALST = LST;
                read ECA10LF.ECAPFR dsECA;
              enddo;
            endfor;

    Читаем из файла с помощью READ до тех пор, пока не наткнемся на конец файла или не изменится ключ.

    Объяснение от ChatGPT

    1. Объявление файла: dcl-f ECA10LF объявляет файл ECA10LF как внешний файл на диске (*ext) с режимом доступа для чтения (*input) и блочной организацией (*yes). Файл открывается при запуске программы (*usropn), имеет ключевой доступ (*keyed), квалифицирован (*qualified) и статический (*static).

    2. Объявление структуры данных: dcl-ds dsECA объявляет структуру данных dsECA, которая имеет ту же структуру, что и запись ECAPFR из файла ECA10LF (используя likerec).

    3. Объявление переменной: dcl-s LST char(5) объявляет переменную LST как строковую с длиной 5 символов.

    4. Проверка открытия файла: if not %open(ECA10LF) проверяет, открыт ли файл. Если нет, то файл открывается с помощью open ECA10LF.

    5. Цикл по списку: for-each LST in %list('PPT': 'OMU': 'PE') создает цикл, который перебирает список значений ('PPT', 'OMU', 'PE').

    6. Установка ключа: setll (LST) ECA10LF устанавливает ключ файла ECA10LF на текущее значение LST.

    7. Чтение первой записи: read ECA10LF.ECAPFR dsECA считывает первую запись из файла ECA10LF и помещает ее в структуру dsECA.

    8. Внутренний цикл: dow not %eof(ECA10LF) and dsECA.ECALST = LST создает цикл, который работает, пока не достигнут конец файла (*eof) или пока значение поля ECALST в структуре dsECA не будет равно текущему значению LST.

    9. Чтение записей: read ECA10LF.ECAPFR dsECA считывает следующую запись из файла ECA10LF.

    Тут все верно, претензий нет.

    Аналогичный код, но с использованием READE

            dcl-f ECA10LF   disk(*ext)
                            usage(*input)
                            usropn
                            keyed
                            qualified
                            static;
            
            dcl-ds dsECA    likerec(ECA10LF.ECAPFR: *all);
            dcl-s  LST      char(5);
    
            if not %open(ECA10LF);
              open ECA10LF;
            endif;
    
            for-each LST in %list('PPT': 'OMU': 'PE');
              setll (LST) ECA10LF;
              reade (LST) ECA10LF.ECAPFR dsECA;
              
              dow not %eof(ECA10LF);
                reade (LST) ECA10LF.ECAPFR dsECA;
              enddo;
            endfor;

    Разница только в

    read ECA10LF.ECAPFR dsECA;
              
    dow not %eof(ECA10LF) and dsECA.ECALST = LST;

    В первом случае и

    reade (LST) ECA10LF.ECAPFR dsECA;
              
    dow not %eof(ECA10LF);

    Во втором.

    Объяснение второго от ChatGPT

    Этот фрагмент кода практически идентичен первому, с одним ключевым отличием: вместо read используется reade.

    reade - это более быстрый вариант read. Он оптимизирован для чтения записей с заданным ключом, что в нашем случае является эффективным, так как мы уже установили ключ файла с помощью setll.

    Тут тоже все верно. Но вот выводы абсолютно неверные

    Какой код работает быстрее?

    Фрагмент 2 будет работать быстрее, так как он использует reade, что значительно оптимизирует чтение записей с заданным ключом, что значительно ускоряет обработку файла.

    Дополнительные советы:

    • Используйте reade вместо read, когда вы читаете записи с известным ключом.

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

    Вот это уже в корне неверно. Если использовать "профилировщик" (PEX - Performance Explorer), то картинка такая:

    Для первого варианта с READ
    Для первого варианта с READ
    Для второго, с READE
    Для второго, с READE
    Сравнительные данные
    Сравнительные данные

    Тут надо сразу сказать - _QRNX_DB_READ и _QRNX_DB_READE - внутренние системные функции для физического чтения записи из БД. И вот тут видно что при одинаковом количестве вызовов READ и READE количество вызовов _QRNX_DB_READ в четыре раза меньше чем _QRNX_DB_READE и в результате вариант с READ и быстрее и эффективнее по ресурсам...

    Дело в том, что READ использует блочное чтение - за одно обращение _QRNX_DB_READ читает сразу несколько записей во внутренний буфер (сколько - зависит от размера буфера и размера записи). Т.е. в данном случае только каждый четвертый вызов READ приводит к физическому чтению с диска.

    А с READE это не работает... Там каждый вызов READE приводит к физическому чтению записи с диска...

    Все это описано в документации. Но, видимо, ChatGPT до этого места не дочитал... И в результате выдал совершенно неправильный совет.

    Нет, он соберется и будет корректно работать. Но... Неэффективно.

    Так что стоит ли верить ChatGPT? Вы уверены, что он действительно даст вам хороший совет?

    И это еще очень примитивный код и очень простой вопрос...


    1. DmitryR3989 Автор
      08.11.2024 11:45

      Опять же, доверяй но проверяй! В статье я описал базовые примеры использования, как правило только для ускорения процесса. Доверять аналитику файлов (тем более важных) или даже создание и проектирование ключевых модулей, я бы не стал. Вы верно подметили, что ChatGPT может давать некачественный ответ. Но для этого мы и сидим у него над душой и ревьювим каждый ответ. Стоит опираться в первую очередь на свой опыт.


      1. SpiderEkb
        08.11.2024 11:45

        Плохо что ChatGPT дает соблазн использовать его для экономии сил и времени не вдаваясь в подробности (или просто не зная тонкостей). Контролируя его просто по факту что "собралось и работает".

        В приведенном выше примере оба куска кода корректны и работают правильно. Разница лишь в эффективности.

        А постоянно его контролировать и ревьюить - тут проще и быстрее написать самому, ей богу...


  1. ValentinAndreev
    08.11.2024 11:45

    По примеру хорошо пишет/рефакторит. Не идеально - есть ошибки, причем странные, например, тупо какие-то методы класса выкидывает нужные. Они сразу в глаза бросаются, непонятно, почему вообще такие очевидные допускает. А в остальном - много кода и на удивление все норм. Один знакомый вообще говорит, что будет сокращать использование, чтобы свои мозги не заржавели.


    1. SpiderEkb
      08.11.2024 11:45

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


    1. DmitryR3989 Автор
      08.11.2024 11:45

      Я согласен с вашим знакомым. Спустя полгода использования для мелких задач, я понял, что сам стал забывать некоторые базовые конструкции. А то что он в примере допускает ошибки, то опять же раз на раз не приходится. Где-то нужен более качественный промт, где-то он и вовсе тупой. Полностью полагаться нельзя, это же не волшебная таблетка)


  1. AdrianoVisoccini
    08.11.2024 11:45

    очень удобно использовать для парсинга километровых Json, просто скорми ему и попроси написать все классы необходимые для парсинга.
    так же- преобразовывать url во всякие UriBuilder - он сам разобьет на фрагменты и заменит нужными переменными
    отличный вариант - писать миграции в liqubase на основании своих сущностей, он отлично справляется с такой задачей.

    и в обратную сторону тоже можно работать - проверить какой результат выдаст твой uriBuilder(когда много полей можно случайно что-то лишнее сделать)
    или точно ли хитровыдуманный тобой streamApi код выдает то что нужно. Использую постоянно, очень помогает


    1. DmitryR3989 Автор
      08.11.2024 11:45

      Полностью согласен! Именно для таких простых задач, он прекрасно подходит.


  1. zabelinleo
    08.11.2024 11:45

    Пробовал Chat-GPT для ответа на экономические вопросы он путает элементарные вещи. Типа пишет что ИП платят налог на прибыль или нужна регистрация как плательщик НДС. Даже как поисковик мне его тяжело рассматривать. В результатах обычного поиска ошибок почти нет.