Как стать автором
Обновить
74
IBS
IBS – технологический партнер лидеров экономики

Как подружить нейросети и разработку: программируем с ChatGPT

Уровень сложностиПростой
Время на прочтение7 мин
Количество просмотров13K

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

Привет, Хабр! Меня зовут Егор Чичерин, я работаю ведущим Java-разработчиком в компании IBS и специализируюсь на разработке API в микросервисной архитектуре. В этой статье я расскажу о собственном опыте создания программы с помощью ChatGPT.

Эксперимент: вводные

Чтобы проверить, способен ли ChatGPT на текущем этапе развития (самая популярная и доступная версия 3.5) создать работающий проект, я решил попробовать сделать с нуля сервис по покупке билетов для выступления на конференции разработчиков UfaDevConf.

Сразу поясню, почему я не работал со специализированными нейросетями, созданными специально для написаниях программного кода, — Codex от того же Open AI, или Copilot от Microsoft. В отличие от них, ChatGPT хорошо понимает обычную речь без кода; он удобнее для простого пользователя (не технического специалиста). В рамках эксперимента мне было интересно проверить, сможет ли машинный интеллект создать код по запросу на естественном языке — для бизнес-пользователя, который имеет базовые представления о программировании или небольшой опыт в разработке, но хорошо понимает, что он хочет получить. Вторая причина использования неспециализированной нейросети — она более универсальна. С помощью ChatGPT мы можем (в теории) создать не только код, но и описать всю структуру проекта в виде документации.

Поскольку мы берем нейросеть, которая не может создавать файлы и нужную нам структуру директорий, а может лишь выдавать код в текстовом виде, бесполезном без соответствующего окружения, нам понадобится некий «преобразователь». Я использовал JAIG — довольно простую утилиту, разработанную внутри IBS. JAIG выступает в роли посредника между человеком и машинным интеллектом; он берет запрос на естественном языке, отправляет его в нейросеть, забирает сгенерированный ответ и превращает его непосредственно в код, в саму структуру программы — классы, интерфейсы и прочее.

Итак, что мы имеем на входе:

Задача: создать простой REST-сервис на Java (с использованием Spring Boot и JPA) без написания кода.

Технологии: ChatGPT 3.5 + JAIG.

Эксперимент: описываем функционал будущей системы

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

Для визуализации я использовал бесплатный сервис plantuml.com:

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

Эксперимент: создаем проект

Берем все по классике: создаем проект с помощью start.spring.io, выбираем Java и Maven. Накидываем пару зависимостей: Spring Web (чтобы получился веб-сервер), Lombok (чтобы код был короче), H2 Database, Spring Data JPA (чтобы работать с данными). В качестве среды разработки будем использовать IntelliJ IDEA CE.

В этом моменте немного отходим от стандартной схемы создания проекта — добавляем в проект JAIG в качестве внешнего инструмента (external tool).

Далее получаем стандартный план создания проекта, в котором по пунктам расписано, что и в какой последовательности нужно создавать. Текст запроса, который возвращает нужный нам план: «Напиши план создания REST-сервиса на Spring Boot и JPA с использованием H2 Database. Распиши по шагам процесс создания проекта с учетом того, что у меня уже настроено окружение, установлена IDE и база данных, создан проект и добавлены все необходимые зависимости». 

Нейросеть выдаст примерно такой план:

Шаг 1: Создание моделей

Шаг 2: Создание репозитория

Шаг 3: Создание сервиса

Шаг 4: Создание контроллера

Шаг 5: Настройка базы данных H2

Шаг 6: …

и т. д.

(пояснения, которые выдаст нейросеть по каждому пункту я здесь опущу).

План возьмем за основу, но не будем запрещать себе от него отступать.

Эксперимент: генерируем модели

Пишу первый промпт: «Сгенерируй классы доменной модели на Java. Укажи все необходимые поля и import». Сверху даю ссылку на нашу UML-модель (для удобства я сразу добавил ее файлом в проект)…

И получаю такой ответ:

Полученные классы нам нужно разбить по пакетам. Вручную этого делать не хочется, поэтому возвращаем ChatGPT его предыдущий ответ и просим разбить классы по пакетам с учетом того, что базовый пакет — model, а в каждом пакете должно быть не больше 5 классов. Получаем в ответ:

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

Выполняем запрос при помощи JAIG и получаем ответ нейросети:

Полученный ответ JAIG пытается превратить в файлы-классы .java и создать нужную для них структуру директорий:

JAIG генерирует нам свой ответ:

Не очень изящно, но для первого раза пойдет :)

Эксперимент: генерируем DataLoader

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

В ответ получаем от JAIG новый класс — TicketApp:

Выглядит не очень. Нейросеть зачем-то создала нам второй метод main. Придется откатить изменения — благо, JAIG это позволяет.

Переформулируем промпт. Говорим, что класс должен называться DataLoader, и он должен иметь метод, который будет автоматически вызван после загрузки приложения, то есть нотированный @PostConstruct. Остальные формулировки оставляем прежними. Получаем:

Уже лучше. Но в ответ закралось несколько ошибок. Например, в 64 строке система пытается получить от event какие-то билеты.

Окееей. Передаем класс event, передаем DataLoader и просим пофиксить ошибку в методе loadData: «Найди причину и исправь ошибку везде, где она встречается. В ответе должен быть только код».

JAIG добавил поле с коллекцией наших билетов:

Отлично. Запускаем программу — работает! Но и это еще не все…

Эксперимент: создаем application.properties

Просим нейросеть создать содержимое файла application.properties с примерами распространенных параметров и снабдить каждый параметр комментарием с объяснением, зачем он нужен.

Тут все без проблем:

Эксперимент: добавляем UI

Передаем все модели и просим сгенерировать код Java-программы с пользовательским интерфейсом командной строки на русском языке.

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

После всех исправлений наша программа выглядит следующим образом:

Я попробовал воспользоваться сервисом — все работает:

Эксперимент: начинаем подключать персистентность

Прокачиваем модели до entity

Снова передаем все модели в нейросеть и просим добавить поддержку JPA. Посмотрите, как изменился класс User — добавились аннотации для поддержки персистентности — аннотация @Entity, название таблицы и аннотация для @Id:

Создаем репозитории

Передаем модели, просим сгенерировать репозитории Spring Data и сложить их в соответствующий пакет. JAIG создает нам репозитории:

Обновляем DataLoader

Просим нейросеть обновить DataLoader таким образом, чтобы он работал не с памятью, а с базой данных.

JAIG успешно добавил поля репозиториев и хибернейтовские методы для работы с базой данных (save, findById и прочие):

Запускаем программу и… получаем ряд ошибок:

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

Обновляем UI для работы с базой данных

Передаем нейросети модели, все репозитории и просим использовать их для обновления класса UI. В ответ JAIG добавляет репозитории и хибернейтовские методы для работы с базами данных.

После всех записей в базе данных успешно запускаемся. H2-консоль работает, и данные в таблицу записались:

Эксперимент: подключаем REST

Создаем структуру REST-запросов

Указываем в промпте конкретные требования и пример того, что мы хотим получить от машинного интеллекта. Ответ (структура эндпоинтов):

Создаем контроллеры

Передаем в запрос репозитории, сущность и документ со списком методов. Просим реализовать EventController, используя структуру ранее сгенерированных эндпоинтов. Получаем:

Все хорошо, если не считать отсутствия сервиса ??‍♂️ Создаем слой сервиса для нашего контроллера — добавляем, помимо прочего, наш новый контроллер и просим создать сервис, в котором были бы все методы для нашего контроллера (обычная слоистая архитектура).

В ответ создается вот такой классик-сервис:

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

Создаем юнит-тесты

Передаем сущность и контроллеры (в сервисе-то у нас логики пока нет) и просим накидать на каждый из них юнит-тесты. Получаем:

Прогоняем тесты — и вуаля:

Подключаем Swagger

Передаем нейросети описание REST API, наши сервисы, контроллер и просим добавить аннотации для Swagger (Open API), чтобы у нас была документация для фронт-энда. Получаем:

Стартуем:

Все хорошо, но при попытке вызвать метод events «Найти все события», получаем ошибку. Смотрим в консоль — мы словили StackOverflowError.

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

Эксперимент: выводы

На текущем уровне развития машинного интеллекта создать работающий проект ВОЗМОЖНО, но это ОЧЕНЬ трудозатратно и сложно. Нужно иметь технические компетенции, чтобы составлять работающие промпты.

Для понимания: если бы я самостоятельно, вручную писал весь этот код, я бы уложился примерно в один рабочий день с перекурами. На работу с ChatGPT и JAIG у меня ушло в общей сложности 10 дней ?

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

Теги:
Хабы:
Всего голосов 9: ↑8 и ↓1+8
Комментарии11

Публикации

Информация

Сайт
www.ibs.ru
Дата регистрации
Дата основания
1992
Численность
1 001–5 000 человек
Местоположение
Россия