LLM и 1С: изучаем сервисы для автоматизации написания кода 1С
Золотая мечта в IT — это сделать так, чтобы для написания программ не требовались особые навыки и знания. Для этого разрабатываются различные подходы и low-code платформы, и вот вполне закономерно был создан кардинально новый инструмент или подход, который призван если не заменить, то облегчить работу разработчика.
В 2021 году миру был представлен GitHub Copilot и даже в тот момент, что по меркам больших языковых моделей (LLM) очень давно, он показывал хорошие результаты работы. Сейчас же в России он недоступен: требуется VPN, оплата зарубежной картой, что делает недопустимым его использование при enterprise-разработке.
За эти три года рынок подобных решений не стоял на месте, а интенсивно развивался, и оказалось, что GitHub и Copilot абсолютно не монополисты. Появилось много альтернатив — в том числе российских, а ряд исследований заверяют о эффективности их применения
Мы решили пощупать этот рынок, посмотреть, какие есть инструменты и как их можно использовать в контексте 1С-разработки.
Ожидания
Мы решили начать с азов и понять, насколько подобные инструменты эффективны и какого ожидать профита от их использования. Нашли ряд исследований и собрали их в таблицу:
Исходя из исследований выше, можно сделать вывод, что ни одна из механик оценки производительности разработчика и влияния Copilot на неё не дает стабильных результатов, которые можно было бы экстраполировать на других.
Исследование от Github показывает, что разработчики, которые используют Copilot, тратят на 55% меньше времени на написание кода, при этом независимое исследование от harness говорит о сокращении времени полного цикла разработки всего на 2,4%.
В целом все исследования сходятся в одном: воспринимаемая (субъективная) производительность с использованием Copilot выше нежели без него. Довольно часто наибольший эффект от применения инструмента показывают группы с уровнем ниже среднего.
Цели и задачи
Опираясь на возможности продуктов и сформированные ожидания, мы составили список кейсов, которые можно решать с помощью этих инструментов:
написание кода по текстовому описанию (комментарию);
автоматическое завершение кода;
понимание кода: описание логики выполнения кода, что делает код;
понимание контекста проекта или модуля;
написание тестов;
проверка кода на ошибки и необходимость в оптимизации;
оптимизация кода;
рефакторинг;
генерация комментариев;
генерация документации;
трансформация кода между разными языками.
Выделили два типа инструментов:
Встраивать нейросети в среду разработки. Пишешь код, онлайн идет подсказка того, как можно было бы эту строчку кода продолжить.
Использовать онлайн-сервис, куда отправляем свой промпт, вопрос к нейросети, и она дает нам ответ.
Плагины для IDE
Решили начать исследование с плагинов для IDE — они эффективнее: подсказка «на лету», команды генерации кода, документации или комментария по выделенному тексту.
Мы собрали список из более чем 10 плагинов, и это ещё не всё, что нам удалось найти.
Первое и самое мощное ограничение — мы работаем с 1С. У нас две среды: одна суперспециализированная исключительно для разработки 1С-решений — 1С Конфигуратор, и вторая — 1С: EDT, которая построена на Eclipse.
В первую очередь рассмотрели все плагины, которые работают в Eclipse:
Cтолкнулись с тем, что в EDT практически ни один из плагинов не работает.
Есть ещё альтернативный вариант разработки: он не такой распространенный для разработчиков 1С, но некоторые его используют — я говорю про Visual Studio Code. Это решение не для энтерпрайза, но мы все же решили попробовать использовать плагины-аналоги copilot в этой IDE.
Столкнулись с проблемой, что никто из этих плагинов не поддерживает язык 1С. Да, какие-то подсказки они генерируют, но подсказки настолько не в контексте 1С, что их даже использовать не имеет смысла — это только затрудняет разработку. А связано это с тем, что при обучении этих нейросетей не были использованы датасеты, которые построены на основе 1С-репозиториев.
В том числе это и касается и GigaCode от Сбера. Они первые вышли на российский рынок, и у нас были большие надежды на это решение. Но пока у них нет планов делать инструмент под 1С.
У «Яндекса» тоже есть свое решение, но оно используются внутренними командами и дат официальных релизов нет.
Пока что мы пришли к выводу, что сейчас на рынке нет плагинов, которые позволяют работать с 1С. Почти все плагины из тестируемых не запустились в основном IDE, используемом для разработки в 1С. Плагин Tabnine, как и в VSC, не поддерживает работу с 1С. Из тестируемых плагинов для VSC ни один не показал приемлемых результатов при работе с кодом 1С. Весь подсказанный код требовал доработки на 50 или более процентов, что только увеличивало продолжительность разработки.
При разработке на языке Python подсказки были более валидными (в том числе и GigaCode), использование плагинов приносило ощутимую пользу, что говорит о возможном потенциале использования при фокусировке разработчиков модели на язык 1С.
Онлайн-сервисы
Мы выработали следующую методику тестирования онлайн-сервисов.
Написание кода по текстовому описанию
Напиши на языке 1С код отправки сообщений в telegram
Напиши на языке запросов 1С запрос получения свободных остатков товара на складах для УТ 10.3
Как на языке 1С в конфигурации УТ 11 проверить наличие свойства у объекта или ссылки
Как в 1С получить значение реквизита «Наименование» элемента справочника «Контрагенты» если у него код равен »000001»
Авто завершение кода (для плагинов IDE)
СоединениеHTTP =
ЗапросHTTP
ОбщегоНазначенияКлиентСервер
Понимание кода (описание логики выполнения кода, что делает код)
Что делает этот код 1С?
Функция Функция1(НачСтрока,ЗаданнаяДлина) Экспорт
ЧислоПробелов=ЗаданнаяДлина-СтрДлина(НачСтрока);
ТекущаяСтрока=НачСтрока;
Если ЧислоПробелов<0 Тогда
Возврат Лев(НачСтрока,ЗаданнаяДлина);
Иначе
Для Индекс=1 По ЧислоПробелов Цикл
ТекущаяСтрока=ТекущаяСтрока+" ";
КонецЦикла;
Возврат ТекущаяСтрока;
КонецЕсли;
КонецФункции
Написание тестов
Есть функция на языке 1С. Нужно выполнить модульное тестирование с помощью YAxUnit. Для этого нужно подготовить текст для модуля регистрации тестов:
Функция МаксимальноеЗначениеВМассиве(Массив)
МаксимальноеЗначение = 0;
Для Индекс = 0 По Массив.Количество() - 1 Цикл
Значение = Массив[Индекс];
Если МаксимальноеЗначение < Значение Тогда
МаксимальноеЗначение = Значение;
КонецЕсли;
КонецЦикла;
Возврат МаксимальноеЗначение;
КонецФункции
Оптимизация кода
Оптимизировать код на языке 1С:
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| Ссылка
|ИЗ
| Справочник.Контрагенты
|ГДЕ
| Менеджер = &Менеджер
| И Не ПометкаУдаления
|";
Запрос.УстановитьПараметр("Менеджер", Пользователи.ТекущийПользователь().ФизическоеЛицо.Пользователь);
Контрагенты = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
Для каждого Контрагент Из Контрагенты Цикл
Пока Выборка.Следующий() Цикл
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ЗаказКлиентаТовары.Ссылка КАК Ссылка
|ИЗ
| Документ.ЗаказКлиента.Товары КАК ЗаказКлиентаТовары
|ГДЕ
| Ссылка.Контрагент = &Контрагент";
| И ЗаказКлиентаТовары.Дата > &Дата
| И ЗаказКлиентаТовары.Номенклатура = &Номенклатура";
Запрос.УстановитьПараметр("Номенклатура", Справочники.Номенклатура.Найти("Товар"));
Запрос.УстановитьПараметр("Дата", НачалоГода(ТекущаяДата()));
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
ЗаказОбъект = Выборка.Ссылка.ПолучитьОбъект;
ЗаказОбъект.УстановитьПометкуУдаления(Истина);
КонецЦикла;
КонецЦикла;
Рефакторинг
При подаче на вход комментарии, описывающие ошибки, очищались.
Выполни рефакторинг кода на языке 1С:
// Функция с большим количеством параметров
Функция ПолучитьДанныеПоЗадаче(МассивВходныхДанных, Организация, Контрагент, ДокСсылка, Соглашение=Неопределено, Договор=Неопределено, Валюта=Неопределено, ТипОтношений=Неопределено .... )
// Вложенные вызовы
РезультатОбработки = ПолучитьДанныеПоЗадаче(
МассивВходныхДанных,
ПолучитьОрганизациюИзДокумента(ДокСсылка, ПолучитьОрганизациюПоУмолчанию()),
ПолучитьКонтрагентаИзДокумента(ДокСсылка),
ПолучитьСоглашение(ДокСсылка,ПолучитьСоглашениеПоУмолчанию(ПолучитьОрганизациюПоУмолчанию())));
Возврат РезультатОбработки;
КонецФункции
Функция ПолучитьРезультатЗапроса(Организация = Неопределено, Договор)
// Кодирование в одну строку
Если НЕ ЗначениеЗаполнено(Организация) Тогда Организация=ПолучитьОрганизациюПоУмолчанию(); КонецЕсли;
// Рванный запрос
Запрос = Новый Запрос;
// получаем данные из таблицы остатков товаров организаций
Запрос.Текст = "ВЫБРАТЬ
| Т.АналитикаУчетаНоменклатуры КАК АналитикаУчетаНоменклатуры,
| Т.Организация КАК Организация,
| Т.ВидЗапасов КАК ВидЗапасов,
| Т.НомерГТД КАК НомерГТД,
| Т.КоличествоОстаток КАК КоличествоОстаток
|ИЗ
| РегистрНакопления.ТоварыОрганизаций.Остатки( ";
// если требуется отбор периода
Если ИспользоватьПериод=Истина Тогда
Запрос.Текст = Запрос.Текст + " &Период ";
КонецЕсли;
Запрос.Текст = Запрос.Текст + " , ";
// если требуется отбор по организации
Если ЗначениеЗаполнено(Организация)=Истина Тогда
Запрос.Текст = Запрос.Текст + " Организация = &Организация ";
КонецЕсли;
Запрос.Текст = Запрос.Текст + ") КАК Т ";
// если требуются только положительные остатки
Если ИгнорироватьОтрицательныеОстатки=Истина Тогда
Запрос.Текст = Запрос.Текст + " ГДЕ Т.КоличествоОстаток>0";
КонецЕсли;
Запрос.Текст = Запрос.Текст + " И &ИспользоватьКонтроль";
//Ненужная усложненность, однострочные вложенные сокращения и оператор «?» вместо использования условий ИспользоватьКонтроль = ?(ЗначениеЗаполнено(Партнер),?(ЗначениеЗаполнено(Договор),?(Договор.Контроль=Истина,Истина,Ложь),Ложь),Истина)
Запрос.УстановитьПараметр("ИспользоватьКонтроль", ИспользоватьКонтроль);
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
// Отсуствие форматирования
МассивСтрок = Новый Массив;
Если ЗначениеЗаполнено(Организация) Тогда
Для Каждого тмп из ТаблицаТовары Цикл
Если НЕ тмп.Организация=Организация Тогда
МассивСтрок.Добавить(Новый Структура("стр",тмп));
КонецЕсли;
КонецЦикла;
КонецЕсли;
// Чрезмерное сокращение
М = Преобр_НСТ_в_СПТР();
Для каждого эл из М Цикл
Если ПР_На_ВЗ_и_КВД(эл) Тогда
Сооб_ПИОВД(эл, Отказ);
Иначе
Обр_ДляСТР(эл);
КонецЕсли;
КонецЦикла
Генерация комментариев
Заполни комментарии к коду процедуры на языке 1С:
Процедура ДополнитьМассив(МассивПриемник, МассивИсточник, ТолькоУникальныеЗначения = Ложь) Экспорт
Если ТолькоУникальныеЗначения Тогда
УникальныеЗначения = Новый Соответствие;
Для Каждого Значение Из МассивПриемник Цикл
УникальныеЗначения.Вставить(Значение, Истина);
КонецЦикла;
Для Каждого Значение Из МассивИсточник Цикл
Если УникальныеЗначения[Значение] = Неопределено Тогда
МассивПриемник.Добавить(Значение);
УникальныеЗначения.Вставить(Значение, Истина);
КонецЕсли;
КонецЦикла;
Иначе
Для Каждого Значение Из МассивИсточник Цикл
МассивПриемник.Добавить(Значение);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Генерация документации
Дай подробное описание выполняемых действий в процедуре на языке 1С:
Процедура НастроитьОтображениеСпискаВнешнихПользователей(Форма) Экспорт
Если ПравоДоступа("Чтение", Метаданные.Справочники.ВнешниеПользователи) Тогда
Возврат;
КонецЕсли;
// Удаление отображения недоступных сведений.
СхемаЗапроса = Новый СхемаЗапроса;
СхемаЗапроса.УстановитьТекстЗапроса(Форма.Список.ТекстЗапроса);
Источники = СхемаЗапроса.ПакетЗапросов[0].Операторы[0].Источники; // ИсточникиСхемыЗапроса
Индекс = Источники.Количество();
Пока Индекс > 0 Цикл
Индекс = Индекс - 1;
Если Источники[Индекс].Источник.ИмяТаблицы = "Справочник.ВнешниеПользователи" Тогда
Источники.Удалить(Индекс);
КонецЕсли;
КонецЦикла;
Форма.Список.ТекстЗапроса = СхемаЗапроса.ПолучитьТекстЗапроса();
КонецПроцедуры
Трансформация кода между разными языками
При подаче на вход комментарии очищались.
Нужно трансформировать код, написанный на Python на язык 1С:
from random import randint
N = 10 # количество элементов в списке
a = []
for i in range(N):
a.append(randint(1, 99))
print(a) # вывод исходного неотсортированного списка
# Сама сортировка методом "пузырька"
for i in range(N-1):
for j in range(N-1-i):
if a[j] > a[j+1]:
a[j], a[j+1] = a[j+1], a[j]
print(a) # вывод отсортированного списка
По этой методике мы протестировали ряд известных и не очень онлайн-инструментов.
ChatGPT был безусловным фаворитом, на который мы возлагали большие надежды: мы решили потестировать его через прослойки. Много и российских сервисов: neuro1С, Сбер GigaChat и YandexGPT-2.
Есть сервисы, которые обучались просто на текстах. А есть те, которые специализированно натаскивались на коде, — к примеру, DeepSeekCoder: он показал крутые результаты. У нас нет информации, попадал ли ему в датасеты 1С код, но он выбил самое большое количество баллов по тестированию онлайн-сервисов, 36 очков из 60. По сравнению со всеми остальными — Яндексом, Сбер GigaChat и даже ChatGPT — он неплох. Кое-где его даже можно использовать, например, в описании кода: скажи мне, что делает код, напиши комментарий к этому коду и так далее. Где-то даже он может подсказать оптимизацию или найти ошибки в коде.
Вывод по онлайн-сервисам
Лидером стал DeepSeek coder, который к тому же является и полностью бесплатным. К сожалению, отечественные нейросети YandexGPT2 и Sber Gigachat показали не такие хорошие результаты как хотелось. Последняя отечественная нейросеть neuro1c.ru показала неплохие результаты, но она платная.
Все протестированные нейросети не очень хорошо понимают язык 1С. Они абсолютно неприемлемы для целей рефакторинга, написания тестов. Очень ограниченно могут быть использованы при написании кода по заданиям даже с небольшой сложностью.
Три лидера неплохо показали себя только в тестах генерации комментариев и документации.