Разработка кода 1С с ИИ через Жёлтый мост: как шлюз для аналитики стал средой разработки
Жёлтый мост задумывался как легкий шлюз между ИИ и 1С: спросить остатки, долги, выручку и получить ответ словами. Так его и используют. Но заметная часть клиентов делает через него другое: пишет код 1С вместе с ИИ и доводит его до рабочего состояния прямо на живых данных, не выходя из чата или среды разработки. Разбираем, почему это стало возможным и как выглядит такая работа.
Почему так получилось
ИИ научился писать код 1С. Два года назад модель путала синтаксис запросов с SQL и выдумывала реквизиты. Сегодня ChatGPT, Claude и Алиса AI для бизнеса пишут запрос с виртуальными таблицами и временными таблицами с первого раза, если знают структуру базы. Проблема сместилась: не "напиши", а "напиши под мою конфигурацию и проверь".
Мост отдает метаданные и связи между ними. К ключу базы прикладывается справка по структуре: объекты, реквизиты, табличные части, регистры с измерениями и ресурсами, кто на кого ссылается. ИИ не угадывает имя поля выручки в регистре продаж, а смотрит его. Для типовых конфигураций справка готова, для доработанных собирается из вашей базы.
ИИ может проверить код на реальных данных. Запрос выполняется в вашей базе, результат возвращается модели, и она видит либо строки, либо текст ошибки платформы с номером строки. Дальше обычный цикл разработчика: поправил, запустил, посмотрел. Только быстрее, потому что оба шага делает модель.
Как выглядит работа
Задача от руководителя отдела продаж: выручка по менеджерам за месяц из Комплексной автоматизации 2. Агент в среде разработки получает ключ и справку по базе. Дальше происходит следующее.
- Модель пишет запрос по памяти, к регистру Продажи, как в старых конфигурациях, и отправляет его в базу через мост. Платформа отвечает: "Таблица не найдена РегистрНакопления.Продажи.Обороты", с позицией в тексте.
- Модель идет в справку по структуре базы, находит регистр ВыручкаИСебестоимостьПродаж с измерением Менеджер и ресурсами СуммаВыручки и Количество. Замечает, что в виртуальной таблице оборотов к имени ресурса добавляется слово Оборот.
- Правит имя регистра и полей, запускает снова, получает строки и показывает таблицу. На все уходит меньше минуты, и это ровно тот путь, который прошел бы человек, только без переключения окон.
ВЫБРАТЬ Продажи.Менеджер КАК Менеджер, СУММА(Продажи.СуммаВыручкиОборот) КАК Выручка, СУММА(Продажи.КоличествоОборот) КАК Количество ИЗ РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&Начало, &Конец, , ) КАК Продажи СГРУППИРОВАТЬ ПО Продажи.Менеджер УПОРЯДОЧИТЬ ПО Выручка УБЫВ
ВЫБРАТЬ Обороты.Субконто1 КАК НоменклатурнаяГруппа, СУММА(Обороты.СуммаОборотКт) КАК Выручка ИЗ РегистрБухгалтерии.Хозрасчетный.Обороты(&Начало, &Конец, , Счет.Код ПОДОБНО "90.01%", , ) КАК Обороты СГРУППИРОВАТЬ ПО Обороты.Субконто1 УПОРЯДОЧИТЬ ПО Выручка УБЫВ
Над каждым блоком кода переключатель конфигураций. Один вопрос в разных конфигурациях решается по-разному: в Комплексной автоматизации выручка лежит в регистре накопления с менеджером, в Бухгалтерии менеджера нет, а выручка берется из проводок по счету 90.01. Каждый вариант выполнен в базе своей конфигурации.
Ключевое здесь не сам запрос, он несложный. Ключевое, что модель узнала имя поля из структуры, а ошибку получила от платформы, а не от пользователя, который прислал бы скриншот через полчаса.
От запроса к обработке
Следующий уровень: не разовый ответ, а код, который останется в базе. Типичный запрос программиста: "напиши функцию поиска дублей контрагентов по ИНН, чтобы вставить в обработку". Модель пишет функцию, проверяет запрос из нее на данных через мост, убеждается, что временная таблица и соединение работают, и отдает готовый код с комментариями.
// Поиск дублей контрагентов по ИНН.
// Пустой ИНН не учитывается: он собрал бы в одну кучу всех, у кого он просто не заполнен.
// Пустая строка передается параметром, а не литералом в тексте запроса: так в модуле
// не нужны удвоенные кавычки, а запрос без правок переносится в консоль запросов.
// В УТ 11, КА 2 и ERP 2 справочник Контрагенты не иерархический, групп в нем нет.
// В Бухгалтерии 3.0 группы есть: там в условие добавляется "И НЕ Контрагенты.ЭтоГруппа".
//
// Возвращаемое значение:
// ТаблицаЗначений - колонки ИНН (Строка), Количество (Число),
// Список (Строка, наименования через запятую).
&НаСервереБезКонтекста
Функция ДублиКонтрагентовПоИНН()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.ИНН КАК ИНН,
| КОЛИЧЕСТВО(Контрагенты.Ссылка) КАК Количество
|ПОМЕСТИТЬ ДублиИНН
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| Контрагенты.ИНН <> &ПустойИНН
|СГРУППИРОВАТЬ ПО
| Контрагенты.ИНН
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(Контрагенты.Ссылка) > 1
|;
|ВЫБРАТЬ
| Контрагенты.ИНН КАК ИНН,
| Дубли.Количество КАК Количество,
| Контрагенты.Наименование КАК Наименование
|ИЗ
| ДублиИНН КАК Дубли
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
| ПО Дубли.ИНН = Контрагенты.ИНН
|УПОРЯДОЧИТЬ ПО
| Количество УБЫВ,
| ИНН";
Запрос.УстановитьПараметр("ПустойИНН", "");
// Одна строка на ИНН: наименования склеиваем, чтобы результат читался списком.
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("ИНН", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
Результат.Колонки.Добавить("Список", Новый ОписаниеТипов("Строка"));
ТекущаяСтрока = Неопределено;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если ТекущаяСтрока = Неопределено Или ТекущаяСтрока.ИНН <> Выборка.ИНН Тогда
ТекущаяСтрока = Результат.Добавить();
ТекущаяСтрока.ИНН = Выборка.ИНН;
ТекущаяСтрока.Количество = Выборка.Количество;
ТекущаяСтрока.Список = Выборка.Наименование;
Иначе
ТекущаяСтрока.Список = ТекущаяСтрока.Список + ", " + Выборка.Наименование;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
// Поиск дублей контрагентов по ИНН.
// Пустой ИНН не учитывается: он собрал бы в одну кучу всех, у кого он просто не заполнен.
// Пустая строка передается параметром, а не литералом в тексте запроса: так в модуле
// не нужны удвоенные кавычки, а запрос без правок переносится в консоль запросов.
// В Бухгалтерии 3.0 справочник Контрагенты иерархический: группы отсекаем условием
// на ЭтоГруппа. В УТ 11, КА 2 и ERP 2 групп у контрагентов нет, там это условие не нужно.
//
// Возвращаемое значение:
// ТаблицаЗначений - колонки ИНН (Строка), Количество (Число),
// Список (Строка, наименования через запятую).
&НаСервереБезКонтекста
Функция ДублиКонтрагентовПоИНН()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Контрагенты.ИНН КАК ИНН,
| КОЛИЧЕСТВО(Контрагенты.Ссылка) КАК Количество
|ПОМЕСТИТЬ ДублиИНН
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| НЕ Контрагенты.ЭтоГруппа
| И Контрагенты.ИНН <> &ПустойИНН
|СГРУППИРОВАТЬ ПО
| Контрагенты.ИНН
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(Контрагенты.Ссылка) > 1
|;
|ВЫБРАТЬ
| Контрагенты.ИНН КАК ИНН,
| Дубли.Количество КАК Количество,
| Контрагенты.Наименование КАК Наименование
|ИЗ
| ДублиИНН КАК Дубли
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
| ПО Дубли.ИНН = Контрагенты.ИНН
|ГДЕ
| НЕ Контрагенты.ЭтоГруппа
|УПОРЯДОЧИТЬ ПО
| Количество УБЫВ,
| ИНН";
Запрос.УстановитьПараметр("ПустойИНН", "");
// Одна строка на ИНН: наименования склеиваем, чтобы результат читался списком.
Результат = Новый ТаблицаЗначений;
Результат.Колонки.Добавить("ИНН", Новый ОписаниеТипов("Строка"));
Результат.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));
Результат.Колонки.Добавить("Список", Новый ОписаниеТипов("Строка"));
ТекущаяСтрока = Неопределено;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если ТекущаяСтрока = Неопределено Или ТекущаяСтрока.ИНН <> Выборка.ИНН Тогда
ТекущаяСтрока = Результат.Добавить();
ТекущаяСтрока.ИНН = Выборка.ИНН;
ТекущаяСтрока.Количество = Выборка.Количество;
ТекущаяСтрока.Список = Выборка.Наименование;
Иначе
ТекущаяСтрока.Список = ТекущаяСтрока.Список + ", " + Выборка.Наименование;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Пустая строка в условии передается параметром запроса. Это сознательный выбор: литерал пустой строки в тексте модуля пишется четырьмя кавычками, и при переносе запроса в консоль их приходится править руками, иначе условие перестает работать. С параметром запрос переносится как есть.
Обратите внимание на комментарии: модель объясняет, почему исключен пустой ИНН и чем отличаются конфигурации. Это не украшение. Через полгода код будет читать человек, и такие пояснения сэкономят ему время.
Что мост дает разработчику сверх выполнения запросов
- Проверка синтаксиса до запуска. Текст модуля можно прогнать через BSL Language Server, тот же анализатор, что используют в EDT и VS Code, и получить список ошибок с номерами строк, не открывая конфигуратор. Модель делает это сама перед тем, как предложить код.
- Метаданные с описанием. Не только имена, но и типы, синонимы, состав табличных частей и связи между объектами. Для доработанных конфигураций справка собирается из вашей базы.
- Запись с пробным прогоном. Если код создает или меняет данные, первый прогон идет в транзакции с откатом: модель видит, что изменилось бы, а база остается прежней. Настоящая запись только после подтверждения.
- Понятные ошибки. Текст ошибки платформы возвращается модели как есть, с позицией в запросе. Это то, чего не хватает большинству способов подключения ИИ к 1С, где на выходе либо результат, либо пустота.
- Маскировка персональных данных. Разработчик видит структуру и цифры, а ФИО, телефоны и ИНН физлиц уходят в модель закрытыми. Для отладки этого достаточно, а вопросов от службы безопасности становится меньше.
Где границы
Мост не заменяет конфигуратор. Он не создает объекты метаданных, не меняет формы и не обновляет конфигурацию. Его территория: запросы, серверный и клиентский код обработок, проверка логики на данных, разовые операции с данными под контролем. Код, который родился в чате, все равно попадает в базу руками разработчика, и это правильно: последнее слово остается за человеком.
Второе ограничение: качество зависит от модели. В тест-драйве мы видели, что на простых вопросах все модели точны, а на многошаговых ChatGPT и Claude дотошнее, но медленнее. Для разработки это скорее плюс: дотошность важнее скорости.
С чего начать
Подключите базу к мосту, на вкладке "Инструкции" выберите агента в среде разработки или чат с коннектором, получите ключ и промт. Первая задача пусть будет простой: запрос, который вы и так знаете как написать. Сравните с тем, что напишет модель, и посмотрите, как она реагирует на ошибку платформы. После этого станет понятно, какие задачи ей отдавать.
Скоро на сайте появится раздел с готовыми решениями типовых задач программиста: вопрос, проверенный на живой базе код с комментариями и универсальная обработка, куда этот код вставляется. Следите за новостями.