Привет, Хабр! Я Сергей Кулабухов, старший разработчик на ИТ-проектах Fix Price. Сегодня поговорим о том, как мы используем ИИ в разработке. Начну с краткого ответа на интересующий многих вопрос, который вынесен в заголовок. ИИ отлично справляется с написанием кода, но лишь определенного кода, а именно: отдельных его фрагментов. Например, GPT может безошибочно написать код какой-либо функции, класса — словом, конкретного фрагмента. Причем в данном случае ИИ напишет оптимальный рабочий код, кратко и по делу. И не только напишет, но и подробно откомментирует по запросу.

Таким образом, главное, что должен сделать разработчик — суметь грамотно декомпозировать задачу, то есть разбить ее на логические части, каждая из которых будет отвечать за конкретную функцию. После этого остается лишь составить правильные запросы для ИИ, а затем собрать готовый код из выданных ИИ фрагментов, проверяя их на работоспособность. Это значительно ускоряет процесс разработки, тем более, что можно грузить ИИ задачами параллельно: пока ты проверяешь один сгенеренный кусок, GPT пишет другой.

Если же разработчик хочет полностью переложить написание кода на «плечи» ИИ, то здесь его ожидают сюрпризы. Дело в том, что по длинным промтам ИИ пишет код не оптимально: проблема в данном случае обычно возникает со связыванием блоков кода, в результате чего программа скорее всего будет функционировать не совсем так, как задумывалось. Либо же придется готовить детальное описание, что займет много времени. Поэтому-то лучше предварительно разделить задуманный функционал на логические блоки и «скармливать» боту ТЗ по частям.

Плюсы для разработчика

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

  • В случаях, когда разработчик не слишком хорошо разбирается в определенном ЯП. Ведь нередко бывает так, что в проекте есть встроенный код на разных языках, и в этом случае можно попросить ИИ дописать/переписать эти куски, с чем он легко справляется уже практически на любом ЯП.

  • При поиске определенной функциональности в больших фрагментах кода и группах файлов. Так, при подключении LLM локально, мы можем указать конкретный вывод, который нужно будет найти ИИ в файлах. Он просканирует все файлы и укажет, в каких из них содержится нужный нам вывод. Получается тоже кратная экономия времени, и чем больше проект, тем больше сокращается время на поиск. Существуют и IDE, поддерживающие индексацию кодовой базы с рефакторингом отдельных функций. Из тех, что используем мы, могу отметить IDE Cursor — бесценный инструмент, который может обрабатывать отдельные куски кода приложения (функции, классы).

  • ИИ отлично справляется и с задачами автодополнения кода. Например, мы начинаем писать какой-то метод (допустим get users). ИИ понимает, что есть сущность user, и что мы хотим получить список пользователей, и генерирует многострочную подсказку, которую можно вставить в код как есть, либо с минимальными правками. Причем GPT понимает даже стиль написания и предлагает соответствующим образом оформленный код. Разумеется, такой способ написания кода значительно быстрее, чем если бы всё делалось вручную. Поможет ИИ и в создании документации к коду: дополняя код, GPT подробно опишет используемые методы.

  • Интерфейсы для MVP — вот еще одна задача, с которой ИИ справляется великолепно. Согласитесь, тратить много времени на разработку графических интерфейсов для минимально жизнеспособных продуктов неразумно. ИИ же сводит это время к минимуму, и мы уже активно используем его для этих задач. Бэкендщики в восторге.

  • Также ИИ оказывает неоценимую помощь в суммаризации. Это сильно экономит нам время при классификации обращений в службу технической поддержки. Только представьте — многочисленные диалоги с массой «шума» (приветствия-прощания, реплики, не относящиеся к проблеме и т.д.), на отсеивание которого вручную уходили долгие часы. Теперь обработка десятков чатов занимает считанные минуты.

  • Наконец, ИИ закрыл нам проблему переписывания кода на другом ЯП. У нас есть проекты на PHP, для которых нужно было переписывать API клиент на JavaScript, Python и т.д. для взаимодействия с другими сервисами. Делать это вручную долго, куда удобнее «скормить» ИИ .json или .yaml со спецификацией и попросить его написать API клиент на другом ЯП — справляется отлично.

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

Примеры решения наших задач

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

    Промпт без предварительных подготовок и формата

    Создай скрипт для обработки файлов датасета. В папке annotations находятся txt файлы с форматом строк MOT: <frame_id>,<obj_id>,<bbox_left>,<bbox_top>,<bbox_width>,<bbox_height>,<score>,<object_category>,<truncation>,<occlusion> а в папке sequences находятся вложенные папки с наименованием как у файла аннотации, в которых файлы изображений с порядковым номером кадра. Преобразуй в формат для YOLO модели. Определи размеры изображения и нормализуй координаты.

    Ответ ChatGPT

    import os

    import cv2

    def convert_annotations(annotation_dir, sequences_dir, output_dir):

        # Проверяем и создаем выходную директорию

        os.makedirs(output_dir, exist_ok=True)

        # Проходим по всем файлам аннотаций в папке

        for annotation_file in os.listdir(annotation_dir):

            annotation_path = os.path.join(annotation_dir, annotation_file)

            sequence_name = os.path.splitext(annotation_file)[0]

            sequence_path = os.path.join(sequences_dir, sequence_name)

            # Проверяем существование папки с изображениями

            if not os.path.isdir(sequence_path):

                print(f"Sequence folder for {annotation_file} not found, skipping.")

                continue

            # Загружаем аннотацию и преобразуем

            with open(annotation_path, 'r') as f:

                lines = f.readlines()

            # Проходим по строкам аннотаций

            for line in lines:

                frame_id, obj_id, bbox_left, bbox_top, bbox_width, bbox_height, score, object_category, truncation, occlusion = map(float, line.split(','))

                frame_id = int(frame_id)

                # Формируем путь к изображению

                image_path = os.path.join(sequence_path, f"{frame_id:06d}.jpg")

                if not os.path.exists(image_path):

                    print(f"Image {image_path} not found, skipping annotation.")

                    continue

                # Загружаем изображение, чтобы получить размеры для нормализации

                img = cv2.imread(image_path)

                img_height, img_width = img.shape[:2]

                # Преобразуем координаты в формат YOLO

                x_center = (bbox_left + bbox_width / 2) / img_width

                y_center = (bbox_top + bbox_height / 2) / img_height

                width = bbox_width / img_width

                height = bbox_height / img_height

                category_id = int(object_category) - 1  # YOLO категории начинаются с 0

                # Запись аннотаций в формате YOLO

                output_annotation_dir = os.path.join(output_dir, sequence_name)

                os.makedirs(output_annotation_dir, exist_ok=True)

                output_annotation_path = os.path.join(output_annotation_dir, f"{frame_id:06d}.txt")

                with open(output_annotation_path, 'a') as output_file:

                    output_file.write(f"{category_id} {x_center} {y_center} {width} {height}\n")

            print(f"Processed annotations for {annotation_file}")

    # Укажите пути к папкам с аннотациями, изображениями и выходной папке

    annotation_dir = 'annotations'

    sequences_dir = 'sequences'

    output_dir = 'yolo_annotations'

    # Запуск конвертации

    convert_annotations(annotation_dir, sequences_dir, output_dir)

Итог: в момент постановки задачи самому себе просто изложили мысль в виде промта, а в ответ за пару секунд получили рабочий код. ИИ не только выполнил то, о чём было написано, но и самостоятельно понял, что в формат разметки MOT - это Multi Object Tracking и добавил форматирование имен изображений кадров ({frame_id:06d}.jpg , а мы не говорили что номер нужно дополнять нулями слева), или, например, самостоятельно указал, что для YOLO нужно номер категории объекта уменьшать на 1 и добавил соответствующий комментарий. Я специально не менял скрипт, чтоб у читателей была возможность увидеть сырой результат, увидеть, где можно чуть подправить и какой объем работы был выполнен за пару секунд, что даже у опытного разработчика заняло бы сильно больше времени даже просто напечатать это всё.

  • Нелюбимое всеми разработчиками cron расписание

Промпт без предварительных подготовок и формата

Создай crontab файл для скрипта send_logs.sh каждые 5 минут, для vacuum_logs.sh каждые 2 дня в 3 часа ночи, check_tasks.sh раз в 3 дня каждый второй месяц в 12:30 и 16:00

Ответ ChatGPT

# Выполняет send_logs.sh каждые 5 минут

*/5 * * * * /path/to/send_logs.sh

# Выполняет vacuum_logs.sh каждые 2 дня в 3 часа ночи

0 3 */2 * * /path/to/vacuum_logs.sh

# Выполняет check_tasks.sh раз в 3 дня каждый второй месяц в 12:30

30 12 */3 */2 * /path/to/check_tasks.sh

# Выполняет check_tasks.sh раз в 3 дня каждый второй месяц в 16:00

0 16 */3 */2 * /path/to/check_tasks.sh

Итог: не тратим время на все эти расчеты по формату crontab, пусть за нас ломает голову ИИ. Лично я редко делал эти расписания и постоянно приходилось вспоминать это всё и тратить время. Таким же образом создаются SQL запросы, сложность которых более не имеет значения, достаточно суметь изложить желаемое текстом на «человеческом» языке.


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

И далее просто нажимаем клавишу Tab пока предлагаются варианты — если мы с ними согласны, конечно.

Также в некоторых IDE после дополнения ИИ анализирует контекст и предлагает дополнить недостающие импорты, которые использованы в подсказке:

А теперь зададим нестандартный метод одним названием:

Всё верно, но у нас нет метода в crud. И это не беда, переходим в файл и сразу видим предложение:

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

Если совсем автоматизировать, то открываем файл и делаем примерно так:

И получаем полный код всего файла:

Получите 100+ строк кода за 5 секунд:

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

Покажет, что удалил и что добавил, а если недостаточно опыта можно и спросить:

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

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

Что с конфиденциальностью?

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

При работе с контекстом проекта важно выносить любые секретные данные в переменные окружения и настраивать игнорируемые системой файлы. Если позволяют корпоративные мощности, можно рассмотреть использование локальных моделей, таких как Code Llama или StarCoder, особенно если провести тюнинг на ваших проектах и стиле кодирования.

А при соблюдении элементарных правил безопасности Open AI (если допустить, что компания решит нарушить пользовательское соглашение) придется выделить целую команду для анализа получаемых от корпоративного пользователя данных. Риск, даже с учетом масштабов бизнеса, в нашем случае практически нулевой, так как экономическая выгода от этого для Open AI весьма сомнительная.

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


  1. panzerfaust
    22.11.2024 07:52

    Таким же образом создаются SQL запросы, сложность которых более не имеет значения, достаточно суметь изложить желаемое текстом на «человеческом» языке.

    А можно пример реально сложного запроса, который на "человеческом" короче, чем на самом SQL?


  1. ASTRIO
    22.11.2024 07:52

    А не случится так, что эти разработчики будут деградировать со временем т.к. захочется решать все задачи таким образом? Вместо архитектурно выверенного решения, будет набор "заплаток" из снипетов подобного кода? И, постепенно, своя нейронка разработчика выгрузится на внешку)