Крутое пике. Сериал про RPA. Сезон 1, эпизод 1

29.09.26

Интеграция - Нейросети

Первый вылет - и сразу штопор. Воскресенье, 08:45 UTC: робот-аудитор RB-PROD-04 открывает карточку настройки авторизации Wildberries и видит «Client-Id» и «Api-Key» там, где по руководству должны быть два токена. Сервис NOPik уверенно перечисляет поля из статьи базы знаний, которая спорит с руководством. Пропажу находит дифференциальный допрос: два скриншота, эталон и актуал, и разность ответов - «API токен». Причина в ночном хотфиксе: Новый Массив(СписокВыбора) падает внутри чужого Попытка... Исключение, и форма молча переходит на параметры по умолчанию. В серии: обход форм по матрице «форма × профиль», тесты YAxUnit с прямым вызовом коннектора, сценарии Vanessa Automation с проверкой заголовков, BSL Language Server и CI-гейт контракта формы. Ответы сервиса получены живыми запросами, код расширения цитируется по версии 1.7.6.276, шаблоны - в техприложении.

Техно-детектив NOPik. Дело №1: «Исчезнувший токен» - надёжность и TDD для 1С

Статья 2 цикла NOPik. В статье 1, «От монолита к автономным агентам: архитектура и граф состояний ИИ-агента в 1С», мы собрали скелет автономного агента: адаптер «Команда формы», фоновые задания, внешний оркестратор на LangGraph. Там же мы пообещали шесть продолжений. Они выходят делами робота RB-PROD-04 под общим названием «Техно-детектив NOPik», каждое дело раскрывает одну тему дорожной карты. Героев мы представили в прологе, «Техно-детектив NOPik. Пролог: «Всё нормально, падаем!»».

Мы поменяли порядок тем. Первой идёт надёжность и TDD (в карте это была статья 4), потому что именно с неё начинается сюжет. Мультиагентная оркестрация переезжает в дело №2.

Правило цикла. Герои списаны с настоящих людей: имена изменены, истории сжаты и пересказаны для сюжета, номера тикетов и время событий условные. Всё техническое настоящее:

  • ответы сервиса nopikreport.com получены живыми запросами;
  • скриншоты сняты с сайта и из демонстрационной базы 1С;
  • код взят из расширений.

Сервис NOPik в этом цикле. Сервис отвечает по документам: руководству пользователя, базе знаний и коду расширения. К данным вашей базы он пока не подключён, поэтому о них не знает. Подключение устроено так: на вопрос о данных сервис присылает схему отчёта СКД, NOPik показывает, что она читает, и строит отчёт в вашей базе, а результат в сервис переносите вы сами. Схема только читает и сама ничего не передаёт; изменений в рабочей базе нет и не будет. Ошибки сервиса, которые мы находим, уходят команде открытым списком, исправления отмечаются в статьях датой. Цель цикла - к последней главе довести эту цепочку до работы. Главы выходят раз в неделю.

Статус цепочки на 28.09.2026:

  • ПРОВЕРЕНО сервис отвечает по документам: руководство, база знаний, код расширения; NOPik в 1С передаёт ему вопрос и скриншот;
  • ПРОВЕРЕНО первое исправление из задания команде сервиса: с 28.09 ответ помечает тип каждого источника (код, руководство, база знаний, общие знания), ответ из кеша и ответ без опоры на источники;
  • ПРОВЕРЕНО отчёт СКД по готовой схеме строится в учебном расширении из статьи 1;
  • ВЕРСИЯ схема СКД под вопрос о данных - в работе у команды сервиса: на 28.09 на вопрос «кто снял флаг» сервис отвечает текстом;
  • ВЕРСИЯ форма NOPik, которая проверяет схему по списку разрешённого и строит отчёт, - в работе;
  • в этой главе появляется вопрос «кто снял флаг „Создавать поставку в сервисе“», и робот оставляет его открытым;
  • в следующей главе Сборщик СКД появится в графе робота заглушкой без канала к данным, в пятой - первая схема для вопроса «кто снял флаг» на демобазе.

В конце главы есть врезка «Реальность и концепт».

Целевая аудитория: разработчики и тестировщики 1С, DevOps, архитекторы интеграций с маркетплейсами.
Ключевые технологии: 1С:Предприятие 8, BSL, YAxUnit, Vanessa Automation, BSL Language Server, nopikreport.com /api/ask (текст и скриншоты), CI-гейт контракта формы.

ЛИСТ 0108:45 UTC. Токены, которых нет

RB-PROD-04 проснулся по расписанию: регламентное задание, воскресенье, 20 сентября 2026 года. Его утренний обход - это цикл по матрице «форма × профиль доступа». Под каждым профилем робот открывает форму, снимает список видимых элементов с их заголовками, делает скриншот и сверяет всё это с контрактом формы.

Форма номер 7 - «Настройка авторизации в сервисе», сервис Wildberries, вкладка «Настройки подключения». По руководству пользователя расширения «Интеграция с маркетплейсами» (v 1.7.6, раздел 2.2) на этой вкладке должны быть два поля: «Токен (универсальный)» и «Токен (сервис статистики)».

Эталон: вкладка «Настройки подключения» с полями токенов (иллюстрация из руководства пользователя v 1.7.6)

Эталон. Иллюстрация из руководства пользователя v 1.7.6, раздел 2.2 (nopikreport.com/images/page_36_img_5.png). Значения токенов уже скрыты точками.

Робот увидел другое. Сервис по-прежнему Wildberries, но на вкладке остались «Адрес сервера для обмена», «Client-Id» и «Api-Key». Ни одного токена.

Актуал: вместо токенов WB - Client-Id и Api-Key (снимок из демонстрационной базы)

Актуал. Настоящий снимок из демонстрационной базы: «Управление торговлей 11» с расширением «УправлениеОнлайнТорговлей» 1.7.6.276. Сервис выбран Wildberries, а полей токенов нет. Как форма пришла в такое состояние - в улике №3.

ЛИСТ 02Улика №1. Показания сервиса NOPik - и почему им нельзя верить на слово

Первым делом робот спросил «свидетеля», который знает руководство, - сервис nopikreport.com. У сервиса два входа:

  • для людей - AI-помощник на сайте и глобальный поиск прямо в 1С;
  • для роботов - POST /api/ask.
Общий вид NOPik в 1С: раздел «НОПи» и чат «Интеллектуальный поиск»

Так выглядит NOPik для человека в 1С. В панели разделов есть раздел «НОПи». Чат «Интеллектуальный поиск» открывается из глобального поиска по префиксу «нопик,». Вверху - история вопросов и ответов со ссылками на источники [2], [5]. Внизу - поле сообщения и кнопки «Мои вопросы», «Вставить изображение» (скриншот уходит сервису вместе с вопросом) и «Отправить». Кнопки «Настройки чата…» и «Сохранить чат…» управляют диалогом, в котором NOPik помнит контекст последних вопросов.

RB-PROD-04 задал текстовый вопрос: «Какие поля нужно заполнить на вкладке „Настройки подключения“ в карточке настройки авторизации в сервисе для Wildberries?» Ответ пришёл через 34,5 секунды:

JSON UTF-8 Открыть файл
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
  "answer": "…необходимо заполнить следующие поля:\n1. **Наименование** … [9]\n2. **API токен** … [9]\n3. **Склад WB** - загружается автоматически. [9]\n4. **Организация** … [9]\n5. **Склад 1С** - внутренний склад. [9]",
  "sources": [
    "BSL: DataProcessors/CG_Online_WB_ИнтеграцияСВайлдберриз/Forms/ФормаНастройки/Ext/Form/Module.bsl",
    "…",
    "Настройка интеграции с Wildberries в ИСМП 1С - авторизация и API ключи",
    "Руководство пользователя v 1.7.6.docx (Стр. 36)"
  ],
  "images": [],
  "product": "utmp",
  "tier": 1,
  "source": "vertex",
  "request_id": null,
  "user_id": null
}

Реальный ответ nopikreport.com/api/ask, сокращён. Полный текст лежит в evidence/api/ch1-01-wb-auth-fields.json. 28.09.2026 на тот же вопрос сервис ответил верно: «Токен (универсальный)» и «Токен (сервис статистики)», источники - код расширения и руководство. В ответах по скриншоту статья базы знаний пока перевешивает руководство (улика №2).

Здесь бы детективу и остановиться: сервис подтвердил, что токен нужен, значит, это дефект. Но Ирина, бизнес-аналитик и хранитель регламентов, задала тот же вопрос на сайте, как это сделал бы любой пользователь, и заметила подвох.

Ирина задаёт тот же вопрос на сайте nopikreport.com

AI-помощник на сайте nopikreport.com. Ответ совпадает с API: у людей и роботов один бэкенд.

Ирина: «Смотрите на сноски. Все пять полей взяты из источника [9], а это статья базы знаний. Руководство - источник [10], страница 36: на этой вкладке „Токен (универсальный)“ и „Токен (сервис статистики)“, никакого „Склада WB“ там нет. Свидетель пересказывает не тот документ».

Первое правило расследования: показания сервиса читают вместе со сносками. Если бы контракт формы строили прямо из этого ответа, робот требовал бы от формы «Склад WB», которого на ней быть не должно, и каждое утро поднимал бы ложную тревогу.

ЛИСТ 03Улика №2. Дифференциальный допрос

Текстовый вопрос не отвечает на главное: что именно не так на этой конкретной форме. Для этого у /api/ask есть поле image: скриншот в Base64 уходит вместе с вопросом, и отвечает уже зрительный конвейер сервиса. Робот поставил эксперимент.

Он задал один и тот же вопрос дважды: «Сравни скриншот с руководством: каких полей не хватает?» Первый раз с эталонным снимком (всё на месте), второй раз со снимком без токенов.

  Со скриншотом-эталоном Со скриншотом без токенов
Время ответа 29,9 с 23,5 с
tier / source 2 / vision-l0 2 / vision-l0
«Не хватает» по мнению сервиса «Склад WB», «Организация», «Склад 1С», кнопка «Проверить подключение» «API токен», «Склад WB», «Организация», «Склад 1С»

Реальные ответы: evidence/api/ch1-08-image-reference.json и ch1-07-image-actual.json.

Даже про правильную форму сервис уверенно пишет, что полей не хватает. Причина та же, что в улике №1: статья базы знаний с «Складом WB» и «Организацией» перевешивает руководство. Это систематическая ошибка свидетеля.

Но систематическая ошибка повторяется в обоих ответах. Если вычесть показания по эталону из показаний по актуалу, остаётся ровно одна строка - «API токен». Именно она и пропала.

Урок: не спрашивайте сервис «всё ли в порядке». Спрашивайте дважды - по эталону и по актуалу - и сравнивайте ответы между собой. Смещение свидетеля сократится, останется сигнал.

На третий вопрос («перечисли все поля, видимые на скриншоте») зрительный конвейер ответил безошибочно: все 11 полей по порядку, со значениями. Распознаёт он надёжно, а путается в знании о том, «как должно быть». Эту границу мы будем использовать весь цикл.

Итог утреннего протокола:

================================================================================
AGENT-ID: RB-PROD-04 | DATE: 2026-09-20 | Онлайн торговля 1.7.6.276 + коннектор WB hf42
[08:45:12 UTC] Форма: Настройка авторизации в сервисе (Wildberries)
               Профиль: Администратор интеграций | TraceID: 5f0c2a7e-…-xxxx
               Контракт: КлючAPI.Заголовок = «Токен (универсальный)»   факт: «Api-Key»
                         ГруппаТокен.Видимость = Истина                факт: Ложь
[08:45:12 UTC] Oracle/text   → /api/ask (utmp)      ← 34.5 s, tier 1, vertex
               ВНИМАНИЕ: перечень полей из источника [9] (статья БЗ) ≠ руководство [10]
[08:45:47 UTC] Oracle/vision → /api/ask + image × 2 ← 29.9 s / 23.5 s, tier 2, vision-l0
               Дифференциал (актуал − эталон): {«API токен»}
[08:46:17 UTC] Verdict: UIContractViolation | Impact: Blocker | INC-WB-0471
[08:46:17 UTC] Action: раскатка коннектора WB hf42 на остальные базы ОСТАНОВЛЕНА
================================================================================

Обмен с Wildberries робот при этом не остановил. Почему - станет ясно, когда найдём причину.

ЛИСТ 0409:10 UTC. Ложная тревога

В 09:10 Лена, оператор склада FBS, написала в поддержку:

Лена (оператор): «Поставка на WB создаётся только у нас в 1С, в личном кабинете её нет. Срочно, SLA горит».

Лена не стала ждать ответа. Она набрала вопрос прямо в строке глобального поиска 1С с префиксом «нопик,». Установленное в базе расширение NOPik перехватывает такие запросы и открывает чат «Интеллектуальный поиск».

Лена спрашивает NOPik прямо из глобального поиска 1С

Расширение NOPik 1.0.6.1 в демонстрационной базе. Вопрос из глобального поиска с префиксом «нопик,», ответ со ссылками на источники.

Робот тем временем проверил АРМ «Сбор, маркировка и доставка заказов клиентов сервисов» под её профилем: состав формы совпал с контрактом. Он задал сервису NOPik тот же вопрос. Через 48,3 секунды пришёл точный ответ со ссылкой на руководство (источник «Руководство пользователя v 1.7.6.docx (Стр. 118)»):

«Документ „Поставка товаров“ может быть создан только в 1С, а не в сервисе маркетплейса, если в настройке генерации документов на вкладке „Поставки товаров в сервис“ не установлен флаг „Создавать поставку в сервисе“. В этом случае работа с документом „Поставка товаров“ возможна в режиме „Офлайн“».

RB-PROD-04 (автоответ): «Это не дефект. Руководство, раздел 8.15: без флага „Создавать поставку в сервисе“ поставка ведётся офлайн. Проверьте настройку генерации документов. AUD-WB-0502».

Лена: «Флаг снят. Кто-то его снял вчера. Поставила - ушла в ЛК. Закрываю, но кто снял?»

RB-PROD-04: «Вопрос зафиксирован. Данных для ответа недостаточно».

Кстати, более общий вопрос («почему не получается работать с поставками на WB?») сервис понял иначе. Он прочитал длинную и в целом верную лекцию о разнице FBS и FBO, но нужного флага так и не назвал. Точность ответа зависит от точности вопроса. Робот формулирует вопросы по шаблонам, и один из этих шаблонов попал в цель.

Две жалобы с одинаковым внешним симптомом: «что-то пропало». У первой причина в дефекте, у второй - в настройке. Вопрос Лены «кто снял флаг?» робот честно оставил открытым. Позже он станет отдельным делом.

ЛИСТ 05Улика №3. Молчаливый откат

Утром в понедельник Артём, разработчик, автор ночного хотфикса, первым делом тоже спросил NOPik. Спросил из 1С, как Лена.

Артём спрашивает NOPik, почему вместо токенов видны Client-Id и Api-Key

Реальный ответ: «Предоставленный контекст руководства не содержит информации, объясняющей, почему…».

Сервис честно ответил, что не знает, и это правильно: хуже было бы уверенно выдумать причину. (На тот же вопрос через API в другой раз пришло как раз такое объяснение, правдоподобное и неверное. Свидетели путаются в показаниях, этим займёмся в деле №2.)

Причину нашли там, где её и нужно искать, - в коде. Заголовки полей на этой форме не нарисованы в конфигураторе. Их отдаёт коннектор сервиса. Коннектор Wildberries в расширении прямо говорит, как должны называться поля:

BSL UTF-8 Открыть файл
1
2
3
4
5
6
// Расширение «УправлениеОнлайнТорговлей» 1.7.6.276,
// обработка CG_Online_WB_ИнтеграцияСВайлдберриз, функция ПараметрыСервиса (фрагмент)
Результат.ЗаголовокКлиентID = "UUID";
Результат.ЗаголовокКлючAPI = "Токен (универсальный)";
Результат.ЗаголовокТокен = "Токен (сервис статистики)";
Результат.ЗаголовокТокенЗаказов = "Токен (заказов)";

Форма при смене сервиса вызывает общую серверную функцию ПараметрыСервиса. Функция получает коннектор и спрашивает у него параметры. Вот ключевой фрагмент:

BSL UTF-8 Открыть файл
1
2
3
4
5
6
7
8
9
10
// Общий модуль CG_Online_ИнтеграцииССервисамиСервер, функция ПараметрыСервиса (фрагмент)
Если Коннектор <> Неопределено Тогда
    Попытка
        Результат = Коннектор.ПараметрыСервиса(Режим);
    Исключение
        ЗаполнитьПараметрыСервисаПоУмолчанию(Результат);
    КонецПопытки;
Иначе
    ЗаполнитьПараметрыСервисаПоУмолчанию(Результат);
КонецЕсли;

А «параметры по умолчанию» - это ровно то, что увидел робот:

BSL UTF-8 Открыть файл
1
2
3
Результат.Вставить("ЗаголовокКлиентID", "Client-Id");
Результат.Вставить("ЗаголовокКлючAPI", "Api-Key");
// … и никакого "Токен": группа «Токен (сервис статистики)» будет скрыта

Если коннектор не получен или упал с исключением, форма молча переходит на универсальный набор полей «как у Ozon». Ни сообщения, ни записи в журнале. Токен при этом никуда не делся, он по-прежнему лежит в реквизите Токен. Исчезло только поле, через которое его можно увидеть и заменить.

(Скриншот «актуала» выше снят в демонстрационной базе, где коннектор WB недоступен. Функция откатилась на те же параметры по умолчанию, симптом тот же.)

Артём: «Я ночью обновил наш коннектор WB, добавил домен рекламы. Выгрузка остатков после этого прошла, я проверил!»

Павел Сергеевич (архитектор): «Выгрузка вызывает другие методы коннектора. А ПараметрыСервиса вызывает только форма. Форму ты открывал?»

Артём: «…Нет».

Вот строка из хотфикса Артёма (реконструкция; всё, что выше, - настоящий код расширения):

BSL UTF-8 Открыть файл
1
2
// Коннектор WB, локальная сборка hf42: «скопировать список доменов рекламы»
Результат.ДоменОбменаРекламы = Новый Массив(СписокВыбора);

Знакомая грабля. Единственный параметр конструктора Массив - это размерность, а не коллекция для копирования. Компилятор такую строку пропускает, а во время исполнения она падает с «Ошибкой при вызове конструктора». Падала она внутри чужого Попытка … Исключение, и ошибка превратилась в «другую форму».

ЛИСТ 06Улика №4. Почему робот не остановил обмен

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

Реальный риск был отложенным. На вторник по регламенту ИБ стояла плановая ротация токенов. Администратор открыл бы карточку и увидел бы «Api-Key» вместо «Токена (универсального)». Возможно, он догадался бы вставить новый токен туда: это тот же реквизит КлючAPI, только с другим заголовком. А вот поля для токена статистики не было вовсе. После отзыва старого токена статистика и продажи перестали бы загружаться.

Поэтому робот сделал две вещи:

  1. Остановил раскатку hf42 на остальные базы.
  2. Поставил инциденту уровень Blocker со сроком «до ротации во вторник».

Урок: автомат, который блокирует всё подряд, быстро отключают. Реакция соразмерна пути ущерба.

ЛИСТ 07Улика №5. Компилятор молчит - шесть раз подряд

Артём: «Синтаксический контроль прошёл. Конфигуратор ничего не сказал!»

Ирина молча открыла журнал живых запусков самого NOPik. Расширение-агент из статьи 1 прошло через то же самое. Все шесть ошибок ниже реальные: они найдены живыми запусками 17 сентября и описаны прямо в комментариях к его коду. Ни одну из них компилятор не поймал.

№ Ошибка Что происходит в runtime Каким тестом ловится
1 Новый ОписаниеОповещения("Имя", Неопределено) «Ошибка при вызове конструктора»: нужен реальный модуль-владелец UI-сценарий: открыть ввод строки
2 Вызов серверного метода через двухконтекстный общий модуль «Метод объекта не обнаружен» UI-сценарий: полный путь команды
3 ТекущийПользователь().УникальныйИдентификатор() «Метод объекта не обнаружен»: это свойство модульный тест серверной функции
4 Новый Массив(КонтекстЗапроса) «Ошибка при вызове конструктора»: параметр - это размерность модульный тест — та самая грабля hf42
5 Пропущенная запятая в Новый HTTPСоединение(...) таймаут уезжает в позицию ЗащищенноеСоединение интеграционный тест против заглушки
6 ПрочитатьJSON(Чтение) без второго параметра возвращается Структура, у неё нет .Получить() модульный тест разбора эталонного ответа

Молчаливый откат делает всю таблицу опаснее. Там, где ошибка обёрнута в Попытка … Исключение без записи в журнал, runtime-дефект проходит мимо компилятора и вдобавок маскируется под нормальное поведение. Поэтому тесты должны вызывать такие функции напрямую, в обход чужих перехватчиков.

ЛИСТ 08Расследование. Пирамида тестов для 1С

Контракт формы в CI
имена + заголовки + видимость
↑
UI-сценарии - Vanessa Automation
под реальными профилями доступа
↑
Интеграционные тесты
HTTP против заглушки, фоновые задания
↑
Модульные тесты - YAxUnit
коннекторы, разбор JSON, чистые функции
↑
Статический анализ
BSL Language Server

Модульные тесты: YAxUnit против молчаливого отката

Тест, который поймал бы hf42 ещё до публикации, вызывает коннектор напрямую, минуя Попытка в общем модуле. Пример (синтаксис сверьте с вашей версией YAxUnit):

BSL UTF-8 Открыть файл
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Тестовый модуль: ОМ_КоннекторWB
Процедура ИсполняемыеСценарии() Экспорт
    ЮТТесты
        .ДобавитьТест("ПараметрыСервиса_ВыполняютсяБезИсключения")
        .ДобавитьТест("ПараметрыСервиса_ЗаголовкиТокеновСоответствуютРуководству");
КонецПроцедуры

Процедура ПараметрыСервиса_ВыполняютсяБезИсключения() Экспорт
    Коннектор = Обработки.CG_Online_WB_ИнтеграцияСВайлдберриз.Создать();
    Результат = Коннектор.ПараметрыСервиса(1);            // исключение = красный тест
    ЮТест.ОжидаетЧто(Результат.Статус).Равно("Выполнено");
КонецПроцедуры

Процедура ПараметрыСервиса_ЗаголовкиТокеновСоответствуютРуководству() Экспорт
    Результат = Обработки.CG_Online_WB_ИнтеграцияСВайлдберриз.Создать().ПараметрыСервиса(1);
    ЮТест.ОжидаетЧто(Результат.ЗаголовокКлючAPI).Равно("Токен (универсальный)");
    ЮТест.ОжидаетЧто(Результат.ЗаголовокТокен).Равно("Токен (сервис статистики)");
КонецПроцедуры

Для локального коннектора-обработки из справочника коннекторов объект создаётся через БСП (ДополнительныеОтчетыИОбработки.ОбъектВнешнейОбработки). Проверки остаются теми же. И одно требование из инструкции YAxUnit: у его расширения в конфигураторе снимают безопасный режим и защиту от опасных действий, иначе тесты не запустятся.

В расширении-агенте NOPik тестируемость предусмотрели заранее. Защита бота от ответа самому себе вынесена в чистую функцию НОПик_КлиентСервер.ЭтоСобственноеСообщениеБота(Автор, ТекущийПользователь), которую YAxUnit проверяет без сеанса пользователя.

Интеграционные тесты: заглушка вместо облака

В наших замерах реальный сервис отвечал от 4 до 66 секунд, и один и тот же вопрос в разное время получал разные ответы. Поэтому в тестовом контуре адрес сервиса подменяется заглушкой, которая мгновенно отдаёт сохранённый ответ в реальном формате: answer, sources, images, tier, source. Так ловится ошибка №5 (параметры HTTPСоединение) и проверяется разбор ответа (ошибка №6).

UI-сценарии: Vanessa Automation

Сценарий открывает форму под рабочим профилем и проверяет у элементов наличие и заголовки: в деле №1 элемент КлючAPI никуда не исчез, у него сменился заголовок.

Gherkin UTF-8 Открыть файл
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#language: ru
# Пример. Формулировки шагов сверяйте с библиотекой шагов вашей версии Vanessa Automation.

Функционал: Контракт формы «Настройка авторизации в сервисе» (Wildberries)

Сценарий: Администратор интеграций видит токены WB с правильными заголовками
    Дано Я подключаю TestClient "Админ интеграций" логин "test_integrations_admin" пароль ""
    И В командном интерфейсе я выбираю "Онлайн торговля" "Настройки и справочники"
    # ... путь к списку «Настройки авторизации в сервисах», открыть тестовую настройку WB ...
    Тогда элемент формы с именем "КлючAPI" присутствует на форме
    # Заголовок: в библиотеке VA есть условие «Если элемент с заголовком "…" присутствует на форме Тогда».
    # Оно ищет элемент по заголовку, а не сверяет заголовок КлючAPI. Для строгой проверки нужен свой шаг:
    # Элементы.КлючAPI.Заголовок = "Токен (универсальный)"
    И элемент формы с именем "Токен" присутствует на форме

Сценарии запускаются в базе с пользователями и рабочими профилями доступа. В «голой» базе без пользователей любая проверка прав заведомо истинна, и половина дефектов прав становится невидимой.

Статический анализ: BSL Language Server

BSL LS дешёвый и срабатывает первым: в IDE и на каждый коммит. Включите диагностики пустых блоков кода и обработки исключений. Блок Исключение, который подставляет «значения по умолчанию», для статики выглядит как нормальный код. Runtime-класс ошибок из таблицы статическим анализом в BSL не закрывается. Не делайте анализатор единственным гейтом.

ЛИСТ 09Суд автоматов: контракт формы в CI

Марат (DevOps) встроил проверку в конвейер сборки. LLM-сервис на горячий путь CI он не пустил: сервис медленный, недетерминированный и, как показали улики №1 и №2, бывает систематически смещён.

  1. Контракт формы создаётся с помощью сервиса, но утверждается человеком. Ирина прогоняет текстовый вопрос и дифференциальный допрос по скриншотам, затем сверяет сноски с руководством. Результат - JSON-контракт в Git: какие элементы, с какими заголовками, видимы под каким профилем.
  2. Сценарии Vanessa снимают структурный слепок. Для каждого профиля фиксируются видимые элементы и их заголовки, плюс скриншот.
  3. Гейт сравнивает слепок с контрактом. Любое нарушение даёт exit 1, и релиз блокируется.
  4. Визуальный слой опционален. SSIM сравнивается с собственным эталонным скриншотом из последней одобренной сборки. Иллюстрация руководства для этого не годится: у неё другое разрешение, другие данные и даже версия формы. Например, в руководстве у WB подписано поле «Client-Id», а текущий коннектор называет его «UUID». Значения SSIM около порога уходят на ручную проверку.
UI CONTRACT VIOLATION [INC-WB-0471]
Build:    коннектор WB hf42 (Онлайн торговля 1.7.6.276)
Form:     Настройка авторизации в сервисе (Wildberries)
Oracle:   vision-l0, дифференциал = {«API токен»}
$ python ui_contract_gate.py contracts/wb-auth-settings.json run/wb-auth-snapshot.json
FAIL [Администратор интеграций] КлючAPI: ожидался «Токен (универсальный)», получен «Api-Key»
FAIL [Администратор интеграций] не виден элемент Токен («Токен (сервис статистики)»)
Нарушений: 2. Релиз заблокирован.
Action:   Release blocked (exit 1)

Строки FAIL и итог вывел гейт из техприложения Г на контракте из техприложения В и слепке дела №1 (прогон 28.09.2026). Элемента Токен в слепке нет: скрыта его группа ГруппаТокен, а родителей учитывает функция из техприложения Д.

Короткий диалог: робот ↔ сервис NOPik ↔ CI ↔ человек

RB-PROD-04: «Wildberries, профиль „Администратор интеграций“. Заголовок КлючAPI = „Api-Key“, группа токенов скрыта. Запрашиваю сервис NOPik».

nopikreport.com (34,5 с): «…заполнить: Наименование, API токен, Склад WB, Организация, Склад 1С…»

RB-PROD-04: «Источник перечня - статья БЗ [9], руководство [10] его не подтверждает. Показания принимаю частично. Запрашиваю дифференциальный допрос по скриншотам».

nopikreport.com (29,9 с и 23,5 с): «…не хватает Склада WB, Организации, Склада 1С…» / «…не хватает API токена, Склада WB, Организации, Склада 1С…»

RB-PROD-04: «Разность: „API токен“. Фиксирую Proof Package, останавливаю раскатку hf42».

CI: «Контракт нарушен. Exit 1».

Ирина: «И заведите задачу на статью базы знаний про авторизацию WB. Она расходится с руководством».

Proof Package: что робот подшивает к делу

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

JSON UTF-8 Открыть файл
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
  "package_version": "0.2-concept",
  "incident": "INC-WB-0471",
  "trace_id": "5f0c2a7e-…-xxxx",
  "created_utc": "2026-09-20T08:46:17Z",
  "environment": {
    "configuration": "Управление торговлей 11",
    "extension": "УправлениеОнлайнТорговлей 1.7.6.276",
    "connector": "коннектор WB hf42",
    "user_profile": "Администратор интеграций"
  },
  "form": "Настройка авторизации в сервисе (Wildberries)",
  "evidence": {
    "screenshot_sha256": "d84a9e…xxxx",
    "title_mismatch": {"КлючAPI": {"expected": "Токен (универсальный)", "actual": "Api-Key"}},
    "hidden": ["ГруппаТокен"]
  },
  "oracle": [
    {"mode": "text",   "tier": 1, "source": "vertex",    "elapsed_sec": 34.5,
     "note": "перечень полей из статьи БЗ [9], расходится с руководством [10]"},
    {"mode": "vision", "tier": 2, "source": "vision-l0", "elapsed_sec": [29.9, 23.5],
     "differential": ["API токен"]}
  ],
  "reference": {
    "manual": "Руководство пользователя v 1.7.6",
    "section": "2.2",
    "image": "https://nopikreport.com/images/page_36_img_5.png"
  },
  "verdict": "UIContractViolation",
  "impact": "Blocker",
  "due": "до плановой ротации токенов (вторник)"
}

Поля verdict и impact вычисляет гейт робота по контракту. Сервис отвечает текстом и списком источников, решение принимает детерминированная проверка.

ЛИСТ 10Развязка

Строку Новый Массив(СписокВыбора) Артём заменил на цикл с .Добавить(). Коннектор hf43 прошёл гейт. Дольше обсуждали, как не допустить такого снова.

Решения ретроспективы

  1. Коннекторы тестируются напрямую. Каждый метод, который вызывается внутри чужого Попытка … Исключение, покрыт модульным тестом без перехватчика.
  2. Молчаливых откатов больше нет. В свою обёртку над вызовом коннектора добавили запись в журнал регистрации и статус «Предупреждение». Вендору отправили предложение сделать так же.
  3. Контракт формы проверяет и имена элементов, и заголовки. Он лежит в Git и утверждается человеком.
  4. Показания сервиса читаются вместе со сносками. Для проверок по скриншотам используется только дифференциальный допрос. На статью базы знаний, расходящуюся с руководством, заведена задача.
  5. Реакция автомата соразмерна пути ущерба. Остановить раскатку - да. Остановить работающий обмен из-за формы - нет.

RB-PROD-04 закрыл INC-WB-0471 и продолжил обход. Форма номер 8, «Настройка генерации товаров сервиса», вкладка «Фото и файлы»: «Режим выгрузки фото = Двоичные данные». Сервис NOPik подтвердил это за 7,2 секунды со ссылкой на руководство, контракт соблюдён (VER-WB-0476).

ЛИСТ 11Врезка «Реальность и концепт»

Что в статье Статус Где посмотреть
POST https://nopikreport.com/api/ask: запрос question, product, session_id, request_id, image (Base64), history; ответ answer, sources, images, product, tier, source, request_id, user_id ПРОВЕРЕНО работает живые запросы, evidence/api/*.json
Анализ скриншотов (tier: 2, source: vision-l0) ПРОВЕРЕНО работает ch1-07…ch1-09
Все цитаты сервиса в главе, включая ошибочные ПРОВЕРЕНО реальные ответы 25.09.2026 evidence/api, скриншоты сайта и 1С
AI-помощник на сайте nopikreport.com ПРОВЕРЕНО работает скриншот Ирины
NOPik 1.0.6.1 в 1С: глобальный поиск «нопик, …», чат, кеш ответов ПРОВЕРЕНО работает скриншоты Лены и Артёма
ПараметрыСервиса и молчаливый откат на «Client-Id / Api-Key» ПРОВЕРЕНО реальный код расширения 1.7.6.276 фрагменты в тексте
Шесть runtime-ошибок BSL ПРОВЕРЕНО реальные, 17.09.2026 комментарии в коде NOPik
Хотфикс коннектора hf42 со строкой Новый Массив(СписокВыбора) ИНСЦЕНИРОВКА реконструкция —
Дифференциальный допрос ПРОВЕРЕНО приём проверен живыми запросами; ВЕРСИЯ автоматизация в роботе - концепт —
Тесты YAxUnit, сценарии Vanessa, гейт контракта, Proof Package ВЕРСИЯ примеры и концепт техприложение
RB-PROD-04, Лена, Артём, Ирина, Павел Сергеевич, Марат, тикеты ИНСЦЕНИРОВКА художественные —

ЛИСТ 12Техприложение

А. Вопрос сервису со скриншотом (Python)

Python UTF-8 Открыть файл
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import base64
import uuid
from pathlib import Path

import requests

def ask(question: str, image_path: str | None = None) -> dict:
    trace_id = str(uuid.uuid4())
    payload = {
        "question": question,
        "product": "utmp",               # индекс руководства «Интеграция с маркетплейсами»
        "session_id": "rb-prod-04",
        "request_id": trace_id,
    }
    if image_path:                        # AskRequest.image - Base64 без префикса data:
        payload["image"] = base64.b64encode(Path(image_path).read_bytes()).decode("ascii")
    resp = requests.post("https://nopikreport.com/api/ask", json=payload,
                         headers={"X-Trace-ID": trace_id}, timeout=180)
    resp.raise_for_status()
    return resp.json()                    # answer, sources, images, tier, source, ...

Б. Дифференциальный допрос

Python UTF-8 Открыть файл
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Q = ("Это скриншот вкладки «Настройки подключения» карточки настройки авторизации "
     "Wildberries. Сравни его с руководством пользователя: каких полей не хватает?")

reference = ask(Q, "golden/wb-auth.png")    # эталон из последней одобренной сборки
actual    = ask(Q, "run/wb-auth.png")       # снимок текущего прогона

# Извлечение перечня полей из ответа - простая эвристика по жирному шрифту Markdown;
# в рабочей системе надёжнее просить сервис вернуть JSON-список.
import re
def claimed_missing(answer: str) -> set[str]:
    return {m.strip() for m in re.findall(r"\*\*([^*]+)\*\*", answer)}

signal = claimed_missing(actual["answer"]) - claimed_missing(reference["answer"])
print("Дифференциал:", signal)              # в деле №1: {'API токен'}

В. Контракт формы (contracts/wb-auth-settings.json)

JSON UTF-8 Открыть файл
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "form": "Справочник.CG_Online_IWS_НастройкиАвторизации.ФормаЭлемента",
  "service": "Wildberries",
  "manual_ref": "Руководство пользователя v 1.7.6, раздел 2.2; эталон page_36_img_5.png",
  "reviewed_by": "бизнес-аналитик",
  "profiles": {
    "Администратор интеграций": {
      "must_see": {
        "КлючAPI": "Токен (универсальный)",
        "Токен": "Токен (сервис статистики)"
      }
    }
  }
}

Г. Гейт контракта (ui_contract_gate.py)

Python UTF-8 Открыть файл
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/env python3
"""CI-гейт: сверка структурного слепка формы с контрактом.
snapshot.json: {"<профиль>": {"<имя элемента>": "<заголовок>", ...}, ...} - только видимые элементы.
"""
import json
import sys
from pathlib import Path


def check(contract: dict, snapshot: dict) -> list[str]:
    failures = []
    for profile, rules in contract["profiles"].items():
        visible = snapshot.get(profile)
        if visible is None:
            failures.append(f"[{profile}] нет слепка для профиля")
            continue
        for name, title in rules.get("must_see", {}).items():
            if name not in visible:
                failures.append(f"[{profile}] не виден элемент {name} («{title}»)")
            elif visible[name] != title:
                failures.append(f"[{profile}] {name}: ожидался «{title}», получен «{visible[name]}»")
        for name in rules.get("must_not_see", []):
            if name in visible:
                failures.append(f"[{profile}] виден запрещённый элемент {name}")
    return failures


if __name__ == "__main__":
    load = lambda p: json.loads(Path(p).read_text(encoding="utf-8"))
    problems = check(load(sys.argv[1]), load(sys.argv[2]))
    for p in problems:
        print("FAIL", p)
    print("PASS" if not problems else f"Нарушений: {len(problems)}. Релиз заблокирован.")
    sys.exit(1 if problems else 0)

Д. Структурный слепок формы (BSL, концепт)

Функция собирает заголовки элементов, которые видимы с учётом всех родительских групп:

BSL UTF-8 Открыть файл
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Функция ФактическиВидимыеЭлементы(Форма) Экспорт
    Результат = Новый Соответствие;
    Для Каждого Элемент Из Форма.Элементы Цикл
        Если ЭлементВидимСУчетомРодителей(Элемент) Тогда
            Результат.Вставить(Элемент.Имя, Элемент.Заголовок);
        КонецЕсли;
    КонецЦикла;
    Возврат Результат;
КонецФункции

Функция ЭлементВидимСУчетомРодителей(Элемент)
    Текущий = Элемент;
    Пока Текущий <> Неопределено
        И ТипЗнч(Текущий) <> Тип("ФормаКлиентскогоПриложения") Цикл
        Если Не Текущий.Видимость Тогда
            Возврат Ложь;
        КонецЕсли;
        Текущий = Текущий.Родитель;
    КонецЦикла;
    Возврат Истина;
КонецФункции

Е. Чек-лист выпуска правки расширения или коннектора

  1. Модульные тесты зелёные, включая прямые вызовы методов коннектора и тесты на шесть runtime-граблей.
  2. Интеграционный тест против заглушки бэкенда зелёный.
  3. Сценарии Vanessa прогнаны под каждым рабочим профилем, в базе с пользователями. Проверены наличие элементов и их заголовки.
  4. Гейт контракта форм: exit 0. Случаи в серой зоне визуального слоя просмотрены человеком.
  5. Каждый инцидент сопровождается Proof Package. На скриншотах замаскированы токены, ФИО и номера заказов.

ЛИСТ 13Следующее дело

Вечером RB-PROD-04 сложил рядом показания сервиса за день. Один и тот же вопрос про токены в одном случае дал честное «не знаю», в другом - уверенное неверное объяснение. Перечень полей пришёл из статьи, которая спорит с руководством. Про срок жизни токена WB в одном и том же ответе нашлось и «истёк», и «бессрочный до отзыва».

Один свидетель хорош, пока его показания однозначны. Когда он путается, нужен второй свидетель с другой точкой зрения и тот, кто выслушает обоих. А Лена так и не узнала, кто снял флаг «Создавать поставку в сервисе».

Техно-детектив NOPik. Дело №2: «Два свидетеля». Мультиагентная оркестрация: Супервайзер и Аналитик, ReAct и Tree-of-Thoughts в LangGraph.

Вступайте в нашу телеграмм-группу Инфостарт

TDD YAxUnit Vanessa Automation BSL Language Server автоматизированное тестирование модульные тесты CI/CD контракт формы Попытка Исключение управляемые формы Управление торговлей 11 Интеграция с маркетплейсами Wildberries маркетплейсы коннектор ИИ-агент LLM анализ скриншотов NOPik Техно-детектив NOPik

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

SALE! %

Банковские операции Обмен с интернет-банком Мастера заполнения Нейросети Разработчик Бухгалтер Пользователь 1С:Предприятие 8 1C:ERP 1С:Бухгалтерия 3.0 1С:ERP Управление предприятием 2 1С:Управление холдингом 1С:ERP. Управление холдингом 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Управление торговлей 11 1С:Розница 3.0 Платные (руб)

Корректируйте банковские документы быстро и легко! Создайте правило обработки — и оно автоматически применится при загрузке выписки (отбор по любому реквизиту или регулярному выражению). Решение заполняет расшифровку платежа, комиссию эквайринга, подбирает ведомости на выплату зарплаты, помечает дубли из банка на удаление и многое другое. Доплачивать за алгоритмы не нужно — они включены в решение. Обработка работает при загрузке из файлов клиент-банка и через DirectBank. Новое — искусственный интеллект: модель приводит нестандартные назначения платежа к виду, понятному алгоритмам, а ИИ-ассистент прямо в 1С консультирует по решению и разбирает код правил и алгоритмов. Поддерживаются локальные и облачные OpenAI-совместимые модели — данные могут не покидать ваш контур.

17500 руб.

20.12.2024    19831    104    32    

85

Нейросети Системный администратор Разработчик Аналитик Бухгалтер Пользователь Руководитель проекта 1С 8.3 1С:Документооборот 1С:Бухгалтерия 3.0 1С:Зарплата и Управление Персоналом 3.x Россия Платные (руб)

Задавайте вопросы базе 1С обычными словами: получайте данные, находите ошибки и связанные документы, проверяйте права, работайте с вложениями и контролируемо вносите изменения. Всё это работает в самой программе, а Codex и Claude подключаются по желанию.

16990 руб.

30.07.2026    13747    29    4    

28

Инструментарий разработчика Нейросети Платные (руб)

Первые попытки разработки на 1С с использованием больших языковых моделей (LLM) могут разочаровать. LLMки сильно галлюцинируют, потому что не знают устройства конфигураций 1С, не знают нюансов синтаксиса. Но если дать им подсказки с помощью MCP, то результат получается кардинально лучше. Далее в публикации: MCP для поиска по метаданным 1С, справке синтакс-помощника и проверки синтаксиса.

15250 руб.

25.08.2025    71811    142    41    

151

Распознавание документов и образов Нейросети 1С:Предприятие 8 1С 8.3 1С 8.5 1C:Бухгалтерия 1С:Зарплата и Управление Персоналом 3.x Беларусь Россия Казахстан Армения Платные (руб)

ИИ-сканер документов с REST API для интеграции с 1С и корпоративными системами. Извлекайте данные из счетов, паспортов, дипломов, патентов и трудовых книжек за секунды. Точность человека - скорость машины. Приложение поддерживает восемь типов документов, четырех провайдеров ИИ (имеется возможность использования локальных ИИ), локальный REST API и экспорт в JSON. Важно! модель должна поддерживать функцию Vision (распознавание файлов и картинок). Запускайте используя локальные ИИ, без подписок и ограничений

6100 руб.

24.08.2026    633    3    0    

1

Нейросети Разработчик 1С 8.3 Бесплатно (free)

Как устроен ИИ-агент, который работает в открытом сеансе пользователя 1С: показывает найденные документы в штатных списках, считает суммы типовыми отчётами, меняет данные только после подтверждения в форме предпросмотра и не передаёт модели персональные данные. Архитектура на MCP внутри тонкого клиента, приёмы и подводные камни, проверка на «Бухгалтерии предприятия 3.0».

вчера в 15:30    958    oyti    29    

11

Инструментарий разработчика Нейросети Разработчик 1С:Предприятие 8 Абонемент ($m)

MCP-сервер даёт модели всю цепочку правки кода: найти метод, показать изменения построчно, внести, загрузить в базу с проверкой синтаксиса и проверить результат на живых данных. Плюс перенос данных между базами со сверкой остатков, поиск по коду и по смыслу, проверка выдуманных вызовов и аргументов, обезличивание персональных данных на выходе. И главное: пока не выполнено обновление из хранилища, сервер отказывается править и загружать. Инструмент умеет говорить «нет» — в статье есть кадр с таким отказом.

6 стартмани

24.09.2026    5001    7    Rafael-87    16    

12

Нейросети 1С:Управление торговлей 11 Бесплатно (free)

Я не считаю покупку специализированных платных инструментов обязательной для разработки с ИИ: нужную обвязку тоже можно создать с агентом. Показываю этот подход на расширении УТ 11 с динамическим списком остатков. Одно задание Codex, 37 минут до проверки, работающая форма. Рассказываю, как устроено окружение, почему первую попытку пришлось переснять и что получилось в повторном прогоне.

17.09.2026    6352    107    Ibrogim    63    

21

Нейросети Разработчик Руководитель проекта 1C:ERP Бесплатно (free)

Служба на Rust, через которую Claude Code, Cursor или другой MCP-клиент вызывает узких ИИ-агентов. Агент — папка с prompt.md и config.toml, модель — строка в конфиге: DeepSeek, Claude Code по подписке, Codex или локальная модель. Агент получает MCP-инструменты, работает в фоне, каждый ход записывается. Внутри — цифры за три месяца: 10 351 вызов, 78 агентов.

17.09.2026    1910    0    Sorm    10    

11
Для отправки сообщения требуется регистрация/авторизация