Попросите модель зарегистрировать изменения объекта к выгрузке в узел плана обмена. Сделайте это пять раз подряд, в чистом чате, одной и той же моделью. В нашем замере тип выборки изменений получил три разных имени: дважды ВыборкаИзмененийДанных, дважды ВыборкаИзмененийПланаОбмена и один раз ВыборкаИзмененийПлановОбмена. Правильное имя, разумеется, одно.
Это не придирка к формулировке. Это индикатор: там, где модель знает платформу, она называет объект одинаково хоть десять раз подряд. Там, где не знает, она собирает правдоподобное имя из знакомых кусков и делает это заново на каждом прогоне.
Ниже замер, который показывает, где проходит эта граница. Восемь типовых задач, по пять прогонов каждая, три модели разных поколений. Считали не «уровень интеллекта», а одну проверяемую вещь: сколько имен платформы модель выдумывает и на каких задачах.
Почему обычные бенчмарки тут не работают
Сравнить модели на 1С хочется так: взять сто задач, прогнать, посчитать долю рабочего кода. Мешает мелочь — проверить результат нечем. Синтаксическая корректность проверяется только конфигуратором, а конфигуратор требует базу, платформу и лицензию именно той конфигурации, под которую написан код. Автотест на «Управлении торговлей» не скажет ничего про самописную базу, которую пилят с 2011 года.
Второй тупик — эталонный список API. Машиночитаемого справочника платформы, который можно взять и сверить построчно, в открытом доступе нет. Синтакс-помощник живет внутри конфигуратора, документация ИТС закрыта подпиской.
Поэтому мы мерили то, что проверяется без эталона и воспроизводится любым читателем на своей машине.
Как устроен замер
Восемь задач, которые пишут в обычный рабочий вторник: остатки по регистру накопления, программное проведение документа с обработкой отказа, строка табличной части с пересчетом НДС, обработчик HTTP-сервиса с разбором JSON, программное выполнение схемы компоновки данных, подписка на событие перед записью, регистрация изменений в плане обмена и запуск фонового задания с ожиданием результата.
Формулировки нарочно даны языком аналитика, без подсказок по именам объектов. Как только вы пишете в запросе «используй ВыборкаИзмененийДанных», вы сообщаете модели ответ и меряете уже собственную память.
Температура — 1.0, то есть настройка по умолчанию, с которой с моделью работает живой человек. Ноль дал бы красивую воспроизводимость и не имел бы отношения к тому, что видит разработчик в чате.
Каждый прогон возвращал две вещи: код и список членов платформы, которые этот код использует. Список заполняла сама модель по собственному коду, так что разметка не зависит от нашего парсера русского синтаксиса.
Дальше два этапа. Разброс: одна задача, пять прогонов, смотрим, какие имена повторяются во всех пяти, а какие всплыли однажды. Очная ставка: каждое собранное имя предъявляется той же модели в чистом запросе, без контекста генерации — существует ли такой член платформы. Модель, отвергающая собственный вызов, дает доказательство, которое не требует ни эталона, ни нашего честного слова.
Разброс: где модель держит имена, а где импровизирует
Колонка «ядро» — доля имен, которые встретились во всех пяти прогонах. Чем она выше, тем устойчивее представление модели о задаче.
| Задача | Уникальных имен | Во всех 5 прогонах | Ядро |
|---|---|---|---|
| Остатки по регистру накопления | 4 | 4 | 100% |
| HTTP-сервис и разбор JSON | 44 | 17 | 39% |
| Подписка на событие | 13 | 5 | 38% |
| Фоновое задание | 36 | 13 | 36% |
| Проведение документа | 25 | 6 | 24% |
| План обмена | 27 | 5 | 19% |
| Программный вывод СКД | 31 | 4 | 13% |
| Табличная часть и НДС | 23 | 2 | 9% |
Сразу оговорка, без которой таблица врет. Низкое ядро само по себе еще не доказывает выдумку: задачу «добавить строку в табличную часть» можно решить пятью способами, и каждый потянет свой набор вызовов. Разброс — термометр, а диагноз ставит второй этап.
Зато верхняя строка говорит однозначно. Запрос к регистру накопления — единственная задача со стопроцентным ядром: четыре имени, все пять раз одни и те же. Это самый растиражированный кусок кода на 1С в интернете, и модель воспроизводит его без импровизации.
Очная ставка: модель против собственного кода
Все 187 уникальных имен, собранных с сорока прогонов, вернулись модели по одному, в чистом запросе, с единственным вопросом: что это такое. Классов ответа четыре, и разводить их обязательно, иначе цифра получится красивой и неправдой.
| Вердикт модели о собственном вызове | Имен | Доля |
|---|---|---|
| Член платформы | 138 | 73,8% |
| Реквизит или метод прикладной конфигурации | 25 | 13,4% |
| Системный тип платформы | 11 | 5,9% |
| Не существует | 13 | 7,0% |
Вторая строка — причина, по которой этот замер нельзя было делать в лоб. Вызовы вроде СтрокаТабличнойЧасти.Цена или ДокументОбъект.Товары модель честно относит к прикладным реквизитам конфигурации. Код с ними рабочий, платформа тут ни при чем, и записывать такое в галлюцинации значит подгонять результат под заголовок.
Остается 7% имен, которых нет нигде. Цифра выглядит скромно ровно до тех пор, пока вы не пересчитаете ее в то, что чувствует разработчик. Одно выдуманное имя ломает модуль целиком, поэтому единица счета здесь — ответ:
15 прогонов из 40 содержали хотя бы одно несуществующее имя. Это 38% ответов.
Карта: где ломается всегда, а где не ломается ни разу
Самое полезное в замере — распределение поломок по задачам. Оно оказалось не равномерным, а бинарным.
| Задача | Прогонов с выдуманным именем |
|---|---|
| План обмена: регистрация изменений | 5 из 5 |
| Фоновое задание с ожиданием результата | 5 из 5 |
| Программный вывод СКД | 4 из 5 |
| Программное проведение документа | 1 из 5 |
| Остатки по регистру накопления | 0 из 5 |
| Табличная часть и пересчет НДС | 0 из 5 |
| HTTP-сервис и разбор JSON | 0 из 5 |
| Подписка на событие | 0 из 5 |
Четыре задачи из восьми модель прошла чисто все пять раз. Три завалила почти всегда. Середины почти нет, и это главный практический вывод всего замера.
Посмотрите, что попало в верхнюю половину таблицы. Планы обмена, менеджер фоновых заданий, программное выполнение компоновки данных. Механизмы, которые средний разработчик трогает несколько раз в год, по которым мало открытых примеров и почти нет вопросов на форумах. Внизу то, что написано в интернете тысячи раз: запрос к регистру, работа с табличной частью, HTTP-сервис с JSON.
Модель воспроизводит частотность обучающего корпуса. Знание платформы тут ни при чем. Звучит банально ровно до момента, когда вы понимаете следствие: чем реже вы сами делали задачу, тем выше шанс, что модель уверенно соврет вам именно на ней. Ваша способность заметить подделку падает одновременно с ее надежностью.
Что именно выдумывается
Выдумки почти никогда не выглядят выдумками. Ни одного «ПолучитьВсеДанные()»: все имена собраны из настоящих кусков платформы и звучат ровно так, как звучал бы настоящий метод.
| Что написала модель | Раз | Что она же сказала на очной ставке |
|---|---|---|
| ПроцессорВыводаОбъектаКомпоновкиДанных… | 4 | Тип называется ПроцессорВыводаРезультатаКомпоновкиДанных… |
| ЗаписьСообщенияОбмена.ЗакончитьЗапись | 4 | Метод завершения сообщения называется иначе |
| СостояниеФоновогоЗадания.АварийноЗавершено | 4 | Значение перечисления называется ЗавершеноАварийно |
| ВыборкаИзмененийПлановОбмена.Получить | 1 | Такого метода у объекта нет, обход идет через Следующий |
| глобальный контекст.ПодробноеОписаниеОшибки | 1 | Функция называется ПодробноеПредставлениеОшибки |
| ФоновыеЗадания.ФоновыеЗадания | 1 | У менеджера нет одноименного члена |
Обратите внимание на характер ошибок. Переставленные слова внутри длинного имени типа. «Объекта» вместо «Результата». Инверсия «АварийноЗавершено» против «ЗавершеноАварийно». Синоним вместо точного термина: «Описание» вместо «Представления», «Завершить» вместо «Закончить».
Такое не ловится чтением. Глаз скользит по знакомой конструкции и подтверждает то, что ожидает увидеть. Ловится это конфигуратором, и только им.
Судья тоже плавает, и это часть результата
Честность требует показать слабое место метода. Модель, которая судит собственные вызовы, не является эталоном платформы: она такая же модель. В нашем прогоне она поймала себя на этом дважды в одной паре имен.
Разбирая вызов ЗаписьСообщенияОбмена.ЗакончитьЗапись, она объявила его несуществующим и предложила другое имя. Разбирая соседний вызов ЗаписьСообщенияОбмена.ЗавершитьЗапись, она снова сказала «не существует» и предложила в качестве правильного ровно то имя, которое отвергла минутой раньше.
Поэтому мы не утверждаем, какое из этих имен настоящее. Мы утверждаем ровно то, что померили: модель не имеет устойчивого представления об этом участке платформы. Ни когда пишет код, ни когда проверяет собственный код. Единственный источник правды остается там же, где был до появления языковых моделей — в синтакс-помощнике и конфигураторе.
Заодно это ответ тем, кто предлагает лечить галлюцинации второй моделью-проверяющей. На частотных задачах такая связка работает. На редких обе модели плавают в одной и той же луже, потому что учились на одних и тех же текстах.
Между поколениями моделей пропасть, и цена тут ни при чем
Тот же набор задач мы прогнали на флагманской модели предыдущего поколения — той, что стоит дороже за токен и думает над каждым ответом по несколько тысяч токенов. Ожидание было простое: флагман окажется аккуратнее. Результат оказался обратным, причем с большим отрывом.
| Замер, 8 задач по 5 прогонов | Свежая дешевая модель | Флагман прошлого поколения |
|---|---|---|
| Ядро имен, в среднем по задачам | 35% | 11% |
| Уникальных имен платформы в коде | 187 | 302 |
| Из них не существует | 13 (7,0%) | 78 (25,8%) |
| Ответов хотя бы с одним выдуманным именем | 15 из 40 (38%) | 35 из 40 (88%) |
Оговорка, без которой сравнение нечестное: старшая модель пишет заметно более развесистый код. На фоновом задании она использует 74 вызова платформы против 36 у младшей, на плане обмена 61 против 27. Часть разрыва объясняется этим: больше вызовов — больше поводов ошибиться. Но доля выдумок среди них все равно выше втрое, и складываются оба фактора в цифру, которую трудно не заметить: почти девять ответов из десяти содержат имя, которого нет.
Отдельно показательна задача про табличную часть. У старшей модели ядро равно нулю: за пять прогонов не нашлось ни одного вызова, который повторился бы во всех пяти. Каждый ответ — заново придуманный набор.
Вывод, который стоит унести: при выборе модели для 1С смотрите на дату выпуска модели, и лишь потом на ценник. Разрыв между поколениями здесь больше, чем между дешевым и дорогим тарифом внутри одного поколения. Обратная сторона того же вывода — любой рейтинг моделей протухает за месяцы, поэтому мерить надо самому и заново.
Третью модель, свежий preview флагманской линейки, мы прогнали только по первому этапу: на очной ставке уперлись в дневную квоту, вердикты собрались по двенадцати именам из ста тридцати восьми. Считать по такой выборке нельзя, и цифр по ней мы не приводим. По разбросу имен она встала между двумя другими — среднее ядро 38%.
Почему рвется именно на 1С
Три причины, и ни одна не связана с качеством самих моделей.
Корпус. Кода на 1С в открытом доступе на порядки меньше, чем на Python или JavaScript. Он живет не на GitHub, а внутри баз клиентов, в закрытых репозиториях франчайзи и на форумах за регистрацией. Модель видела типовые примеры из статей и не видела продакшена.
Документация. Синтакс-помощник поставляется с платформой, ИТС продается по подписке. Полного открытого справочника, который можно было бы вычитать целиком, просто нет. У Python есть docs.python.org, у 1С такого адреса нет.
Русский синтаксис и версии. Имена длинные, составные и похожие друг на друга, а платформа тащит совместимость с версиями от 8.0 до 8.3.2x, где часть методов появлялась, переименовывалась и устаревала. Модель собирает правдоподобное имя из привычных морфем и попадает в соседнюю версию или в соседний объект.
Добавьте сюда прикладной слой. Даже безупречный платформенный код ничего не знает про вашу конфигурацию: имена реквизитов, переписанное проведение, урезанные права. Что с этим происходит на живой базе, мы разбирали в статье про то, что ломается на базе с 2011 года.
Рабочий режим: как этим пользоваться и не влететь
Вывод из замера не «не пользуйтесь». Вывод — пользуйтесь по карте, которую он дает.
- Делите задачи на частотные и редкие. Запрос, обход результата, работа с табличной частью, HTTP-сервис, разбор JSON — берите черновик у модели, экономия реальная. Планы обмена, фоновые задания, программная компоновка, регистрация изменений — пишите руками или берите из своей же рабочей базы кода.
- Первым делом ищите глазами длинные составные имена типов. Именно там прячутся переставленные слова. Каждое такое имя копируйте в синтакс-помощник до того, как начнете читать логику.
- Никогда не принимайте значения системных перечислений на веру. «АварийноЗавершено» против «ЗавершеноАварийно» — самая дешевая для модели и самая дорогая для вас ошибка: код компилируется, а ветка условия молча не срабатывает.
- Спрашивайте одно и то же дважды. Дешевый детектор: задайте задачу в двух чистых чатах. Совпали имена — скорее всего, модель их знает. Разошлись — вы попали в зону импровизации, дальше только конфигуратор.
- Давайте контекст вместо надежды на память. Кусок рабочего модуля из вашей базы в запросе поднимает качество сильнее, чем переход на более дорогую модель: модель начинает копировать ваши имена вместо того, чтобы изобретать свои.
- Считайте черновик черновиком. Ни одна строка не уезжает в базу без прохода через конфигуратор и тестовый прогон. Правило скучное, но именно оно отделяет ускорение работы от честной оценки качества модели от веры в ее самоуверенность.
Когда нейросеть для кода 1С не нужна вовсе
Три случая, где выигрыш отрицательный.
Проверять черновик некому. Если в команде нет человека, читающего код на 1С, модель превращается в генератор технического долга, который обнаружится при закрытии месяца. Тут дешевле заплатить за доработку и получить ответственного за результат.
Задача целиком в редкой зоне. Обмены, регистрация изменений, хитрая компоновка. Проверка выдумок съест больше времени, чем написание с нуля по синтакс-помощнику.
База уходит на поддержку по договору. Код, который потом сопровождает другая команда, стоит писать так, как принято у нее. Сгенерированный модуль в чужом стиле обходится дороже сэкономленного часа.
Повторите замер на своей модели
Замер сознательно устроен так, чтобы его можно было воспроизвести за вечер и не верить нам на слово. Возьмите свои восемь задач, обязательно смешав частотные и редкие, прогоните каждую по пять раз в чистом контексте при температуре по умолчанию и сравните два числа: сколько имен повторилось во всех пяти прогонах и на скольких задачах имена разъехались.
Дальше предъявите собранные имена самой модели отдельным запросом. Все, что она отвергнет, — ваш личный список ловушек в этой модели на сегодня. Через три месяца и одно обновление список будет другим, поэтому мы и приводим метод, а не рейтинг моделей: рейтинг протухнет раньше, чем вы дочитаете.
Что это значит для проектов, где ИИ работает внутри 1С
Замер важен и тем, кто модели внедряет в учет. Между «модель пишет код для 1С» и «модель работает с данными в 1С» лежит пропасть, и путать их дорого.
В рабочих проектах модель занимается пониманием: что это за документ, какой позиции соответствует строка накладной, что имел в виду человек в заявке. Код, который ходит в базу, пишут люди, он проходит ревью и живет в расширении. Именно поэтому внедрение ИИ в 1С не сводится к тому, чтобы дать модели доступ к конфигуратору, а ассистент отличается от агента с правом записи набором ограничителей, и удачная формулировка запроса тут ничего не решает.
Тот же принцип работает при выборе, где крутить модель: локальная LLM для 1С нужна не всем, но там, где нужна, вопрос решается до начала работ. А правки конфигурации, если они все же требуются, живут в расширениях вместо правки типовой, чтобы обновления продолжали вставать.