
Кажется почти все используют GPT или другие LLM-based-решения для генерации кода. Есть куча проектов, где так же генерируют фронт (код интерфейсов). Собственно, когда у нас появилась дизайн-система со множеством компонентов, стало понятно, что это идеальная документация для обучения модели, ведь она включает в себя описание типов, аргументы, тесты и состояния использования компонентов.
В какой-то момент я начал задумываться, почему мы не используем код, который есть в дизайн-системе, чтобы он автоматически генерировался помощником. Достаточно векторизовать эту базу, дальше модель сможет на основе нашей дизайн-системы выдавать готовые решения по текстовому запросу.
Многие наши компоненты достаточно сложные. Самый сложный — таблица, потому что у нас много разных типов таблиц для производственных данных. Внезапно выяснилось, что разработчику нужно три дня, чтобы вникнуть в матчасть и написать свою первую таблицу — или же примерно 30 секунд на запрос «сделай мне таблицу для такой-то задачи», чтобы GPT-4 выбрал подходящие параметры и сразу показал, что надо. Либо дал скорректировать запрос, если таблица не подходит.
Что происходит
Я досконально описываю каждый компонент, чтобы он был предоставлен для разработчиков. Там все возможные входящие данные, тесты на все кейсы, которые есть, все значения аргументов, текстовое описание, что это и зачем, как применять. В общем, из набора так описанных компонентов получается сторибук для дизайн-системы. Этот самый сторибук — идеальная система описания компонентов, чтобы получить правильную документацию для LLM. Точнее, под капотом у нас GPT-4, самая обычная четвёрка. В настройках температура и другие параметры выставлены на максимально формальные ответы, чтобы минимизировать галлюцинации.

Как векторизовал базу
Сначала нужно подготовить исходный код и определить, какие части перевести в текст для LLM. Важно не количество файлов, которые описывают ваши компоненты, а то, как структурирована информация об этих компонентах и какие у них бывают состояния. Я создал баш-скрипт, который объединяет файлы TypeScript и CSS в один текстовый файл (txt). Я с точки зрения текстового восприятия JS — просто технический писатель, который выбрал такой способ описания компонента.
Потом я использую скрипт на Python для векторизации базы, он делает локальный SQLite с инъекцией всех данных. Когда запускается первый запрос к ChatGPT — один раз создаётся локальная база с индексами и данными. Это занимает меньше 20 секунд.
Сама векторизация — LangChain. Он же даёт всякие интересные пакеты, например интеграцию с Whisper тем же. У него есть огромное количество пакетов для интеграций с Джирой, импорта PDF, аудио и т. п.
Результат
Ввёл простой запрос — получил хорошо сгенерированный код, который мог прямо с терминала скопировать в реферер в React. Нормальные шаблоны получаются с первого раза, даже с нормальными инпутами. Позже понял, как формировать превью компонента, без копирования кода в реферер.

Замечательно, что модель понимает наши цвета и стили и может их применить к графикам.

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

Несмотря на настройки по минимизации галлюцинаций, иногда модель всё же путается в показаниях. Были случаи, когда названия переменных не совпадали, были случаи, когда структура компонента жёстко менялась в выводе, были случаи использования методов, которых вообще нет в JS.
С другой стороны, есть случаи, когда мы получали почти готовый код сразу. Например, у нас есть отдельная команда, которая делает софт для веба, они пишут на Vue. Им рисуют наши дизайнеры в Фигме. Интеграция там с React. Код для интеграции с React на Vue сделали буквально за день, при помощи концепции веб-компонентов. Теперь дизайн-систему можно использовать с любым JS-фреймворком, без привязки строго к React.

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

Языковые модели хорошо позволяют экспериментировать. Мы быстро исправили тексты в дизайн-системе. Теперь легко можно будет её перевести на английский язык. Потом попробовали сделать китайскую локаль, но что-то (примерно всё) пошло не так. Другое направление чтения, сложности формулировок, другие представления про перенос текста, другие ожидания по дефолтным названиям кнопок и их расположению и так далее. В хинди часто одно наше слово становится двумя их. В общем, стало понятно, что под каждую локаль нужно искать отдельных экспертов — благо смогли быстро проверить.
Удобно оказалось делать шаблоны. Часто разработчикам не очень комфортно стараться описывать каждый аргумент и каждый компонент полностью. Допустим «инпут, который принимает число» — для чего, какое число, может ли быть отрицательное, может ли быть дробное, достаточно integer или надо длинное? Поэтому супер удобно, когда потом можно пройтись по типизации и навести порядок одним запросом.

В общем, оказалось полезно и практично, создать и использовать собственную модель для LLM.