Как разработчик «LADA Цифра» создавал язык для преобразования данных вместе с ChatGPT

Евгений Хлызов, Ведущий разработчик Lada Цифра, рассказывает об эксперименте по созданию специализированного языка программирования с помощью ИИ

Иллюстрация к статье о языке Branchline

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

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

Тем не менее, с 2016 года прошло 10 лет, и я решил провести эксперимент по проектированию и созданию специализированного языка программирования с условием не писать самому ничего, кроме промптов. Мне удалось, используя ChatGPT и впоследствии Codex, за пару месяцев плотной работы по вечерам и субботам спроектировать язык (кодовое имя Branchline), написать на него интерпретатор, компилятор, виртуальную машину, а затем перевести это всё на Kotlin Multiplatform (KMP), чтобы получить версию под JS для онлайн-песочницы.

История эксперимента

Мой Kotlin бэкграунд — R&D в semantic web и построение прототипов разной степени детализации около 10 лет. За это время довелось поработать над разными задачами, так или иначе относящимися к интеграции данных и работе с большими графами. Но эта часть моей жизни осталась в прошлом, и сейчас я работаю над созданием MDM-систем в ООО «Lada Цифра» в качестве техлида.

Изначально идея языка и его первый прототип появились в результате исследования в пользу дружественной компании в августе 2025. К сожалению, R&D был приостановлен досрочно, но я настолько загорелся идеей, что почти все свободные вечера в течение сентября работал над его публичной версией.

Хотелось создать то, что способно работать в low-code системах. Решение должно быть:

  • Human-friendly — читаемым для тех, кто знаком с SQL и программированием на базовом уровне. Программы должны поддаваться отладке — в идеале это пошаговое выполнение и возможность анализа промежуточных результатов;
  • AI-friendly — код на языке Branchline должен быть оптимизирован для генерации агентами. Для этого важно, чтобы синтаксис был однозначен и язык хорошо ложился на промпт-формулировки;
  • Быстровыполнимым — некоторые JSONata-скрипты на несколько тысяч строк выполнялись критично медленно. Переписав их на Branchline, удалось получить скорость выполнения примерно в 30 раз выше;
  • Безопасным — программы на Branchline не должны иметь возможность повредить хост-систему.

Меня очень тянуло в сторону forth-like и lisp-like языков из-за простоты их реализации, но я быстро прекратил эти эксперименты под влиянием первого пункта. Тогда я запустил несколько deep research в ChatGPT и попросил спроектировать мне DSL.

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

Такая совместная с ИИ работа стала для меня полигоном для испытаний, возможностью подумать над автоматическим выводом типов, способом оптимального размещения JSON-like объектов в памяти стековой VM и много чем ещё.

Об языке Branchline

Так я пришёл к тому, что нужно стремиться к как можно меньшему числу специальных символов.

Переменные, объекты и list comprehensions
LET key = "okak"
// ещё одна маленькая радость – наличие list comprehensions
LET names = [ user.name FOR EACH user IN row.users WHERE user.active ]
LET obj = {
  1: "целые неотрицательные числа могут быть ключами",
  message: "ключи не обязательно помещать в кавычки",
  "но можно и закавычить": names,
  [key]: "если ключом объекта является переменная, она оборачивается в []",
}

Функции являются объектами первого класса:

Функции первого класса
LET sum = (x, y) -> x + y
LET inc = (x) -> APPLY(sum, x, 1)
OUTPUT { answer: inc(41) }

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

Общая память и dataflow
SHARED cache SINGLE; // ключ может быть записан только один раз
SHARED buf MANY;     // ключ может быть перезаписан сколько угодно раз

Далее в программе можно читать и писать в общую память, как будто это локальная переменная, а виртуальная машина уже будет предоставлять реализацию — Caffeine, Redis или что-то иное. Также есть элементы dataflow-программирования. Например, конструкция SUSPEND cache.key скажет виртуальной машине, что программу можно остановить и возобновить, как только в кеше появится нужный ключ.

Пара слов про отладку. Интерпретатор и ВМ поддерживают отладочный режим. В нём программно можно получить всю историю изменения данных или явно запросить её в программе через функцию EXPLAIN:

Отладка через EXPLAIN
LET subtotal = msg.unit_price * msg.quantity;
LET discount = msg.discount ?? 0;
LET total = subtotal - discount;

OUTPUT {
  order_id: msg.order_id,
  subtotal: subtotal,
  discount: discount,
  total: total,
  explain_total: EXPLAIN("total")
}

EXPLAIN генерирует машиночитаемый трейс, а для человека есть вывод в строку:

Вывод EXPLAIN в человекочитаемом формате
total
  → LET
    calc:
      subtotal = 105
      discount = 5
      (105 - 5) -> 100
  → OUTPUT
    calc:
      total -> 100

• order_id
  → OUTPUT
    calc:
      msg.order_id -> "A-1024"

• subtotal
  → LET
    calc:
      msg.unit_price = 35
      msg.quantity = 3
      (35 * 3) -> 105
  → OUTPUT
    calc:
      subtotal -> 105

• discount
  → LET
    calc:
      msg.discount = 5
      (5 ?? 0) -> 5
  → OUTPUT
    calc:
      discount -> 5

Посмотреть вживую можно в playground, пример называется «Explain derived totals».

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

В остальном, это довольно типичный язык. Планирую упростить его синтаксис, написать несколько нагрузочных тестов и создать рантайм, который сможет выполнять DAG из branchline-скриптов на кластере.

ChatGPT уже сейчас достаточно хорошо генерирует скрипты обработки данных на Branchline. В частности, был сгенерирован скрипт для обработки XML с результатами выполнения тестов в GitHub Workflow. Мне оставалось только дополнить его парой деталей.

Выводы

Их будет три.

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

Второй — о том, легко ли написать свой специализированный язык. Ответ — да, если знать, где остановиться. По моим представлениям, 80% времени уйдёт на дизайн, 10% на документацию и тесты и 10% непосредственно на кодирование. Создавать DSL можно и нужно, так как правильно подобранные абстракции существенно упростят и ускорят разработку.

Третий — об использовании KMP, а не генерировании нативного кода для каждой платформы. Возможность бесплатно получать версии под JS/WASM/JVM/Native выглядит привлекательно. Пока преимущества единой кодовой базы значительно перевешивают недостатки.

А ещё, лично я жду момента, когда решения вида spring-* канут в Лету за ненадобностью, а их код будет генерироваться на лету под конкретный проект. Тогда можно будет полностью сконцентрироваться на бизнес-логике.

Спасибо за внимание и stay tuned!

LADA Цифра — IT-компания, разработчик цифровых решений в автобизнесе

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

LECAR — ваш надёжный партнёр в поиске качественных запчастей для автомобилей различных марок и моделей