IDE + MCPРасследование и устранение дублей
Найдены и устранены дубли товаров от автозагрузок с Ozon и Wildberries: на двух базах очищен 261 артикул, отчётность приведена в порядок без программиста
Коротко
Заказчик — розничная торговля через Ozon и Wildberries — обнаружил, что один и тот же товар попал в базу несколькими карточками: отчётность стала считаться неверно. Агент разобрался, откуда берутся дубли, нашёл сразу две причины, исправил их и навёл порядок в данных. На первой базе очищена 231 лишняя карточка и подготовлен список дублей с движением на ручное объединение; на второй базе того же предпринимателя очищен 261 артикул, а число групп дублей сведено к нулю. Все работы выполнены прямо в рабочей базе, без выезда программиста и без установки дополнительных обработок.
Что требовалось
Бухгалтер сообщил, что после автоматической загрузки отчётов с маркетплейсов один и тот же артикул товара оказывается сразу на двух-трёх разных карточках номенклатуры. Из-за этого продажи и поступления «размазываются» по дублирующим позициям, и отчётность считается неверно. Конкретных карточек или выгрузок предоставлено не было — только устная просьба: разобраться, почему так происходит, и наметить, как это исправить.
Как помог агент
Агент проанализировал справочник номенклатуры прямо в рабочей базе и составил полную картину: сколько всего дублей, по каким товарам и когда они появились. По времени создания карточек он восстановил хронологию и установил, что дубли возникали как при автозагрузках, так и при повторных загрузках спустя недели.
Сверив дубли с реальными продажами и поступлениями по счёту 45.01 в разрезе контрагентов Ozon и РВБ, агент отделил настоящие проблемные карточки от «технического шума».
Агент нашёл сразу две причины проблемы. Первая — недоработки в механизме автозагрузки: при наличии нескольких карточек с одним артикулом продажи могли «прилипнуть» к неверной карточке, а при создании новой карточки не проверялось, что такой артикул уже есть. Вторая — рабочая привычка бухгалтера: он копировал похожую карточку под новый канал продаж, менял наименование, но не очищал артикул, тем самым плодя двойники.
По обоим направлениям агент подготовил исправления: доработал механизм автозагрузки так, чтобы новые дубли больше не появлялись (в том числе теперь артикул автоматически очищается при копировании карточки), и проверил доработку набором из 21 контрольного сценария — все пройдены. Для уже накопленного «мусора» он подготовил инструмент очистки с безопасным предварительным просмотром (без записи в базу), чтобы заказчик сначала проверил выборку, а затем выполнил очистку. Для дублей, по которым уже прошли продажи, агент сформировал для бухгалтера таблицу с указанием, какую карточку оставить ведущей.
Через три дня заказчик попросил повторить очистку на другой рабочей базе того же предпринимателя. Здесь агент выполнил всё прямо в базе, без установки отдельной обработки: очистил лишние артикулы, по спорным товарам помог заказчику выбрать корректную карточку, а для двух самых неоднозначных случаев сверил данные с восемью отчётами Ozon (реестрами продаж и отчётами о реализации) и точно установил, какому реальному товару какой артикул принадлежит. Каждое действие фиксировалось в журнале с привязкой к учётной записи клиента.
Результат
Первая база: из 116 дублирующих карточек выявлено 24 с реальными продажами Ozon и Wildberries — переданы бухгалтеру на ручное объединение с готовой таблицей (товар, дата создания, обороты по каждой площадке). Ещё 231 лишняя карточка очищена от артикула за один проход. В механизме автозагрузки найдено и устранено три отдельные причины появления дублей, выпущена доработанная версия.
Вторая база: число карточек с артикулом сокращено с 536 до 275, очищен 261 артикул, а количество групп дублей с оборотами сведено с 10 до нуля. По двум спорным товарам сверка с отчётами Ozon показала реальные объёмы продаж за 2026 год — 280 шт. на 577 784 ₽ и 196 шт. на 80 570 ₽ — и позволила безошибочно определить ведущие карточки.
Дополнительно агент обнаружил, что часть продаж Wildberries (2 415 единиц товара) учитывалась обезличенно на служебной карточке «Товары WB», и передал это заказчику отдельной рекомендацией.
Главная польза: и расследование, и исправление, и наведение порядка в данных выполнены прямо в рабочих базах — без выезда программиста и без установки дополнительных обработок во вторую базу.
1. Контекст: что было сделано раньше
За два месяца до этого расследования, в рамках того же проекта, было разработано расширение зм_ЗагрузкаМаркетплейсов для типовой «Бухгалтерия предприятия 3.0».
Назначение расширения:
- автоматическая загрузка отчётов агентов по Ozon и Wildberries (РВБ);
- автосопоставление товаров маркетплейса с карточками номенклатуры в 1С по артикулу;
- автосоздание новой карточки, если совпадения нет;
- работа с регистром
НоменклатураКонтрагентовБЭД— стандартный механизм 1С для маппинга «артикул контрагента → наша номенклатура».
Расширение работало два месяца в продуктивной среде. Создавались документы поступления, продаж, возвратов на счёт 45.01 («Покупные товары отгруженные»).
2. Обращение заказчика
«Появились дубли карточек. Один и тот же артикул лежит на двух-трёх позициях номенклатуры. Бухгалтер при ручной правке схватился за это — отчётность считается криво».
Постановка задачи была общей: «разобраться, по какой причине это случилось, и наметить пути исправления». Конкретных карточек, журналов или выгрузок предоставлено не было — только устное обращение бухгалтера.
3. Исследование: как находили причины
3.1 Первый замер — масштаб проблемы
Запросом к справочнику номенклатуры через MCP query_1c сформирован список карточек, у которых артикул встречается более одного раза:
ВЫБРАТЬ Ном.Артикул, Ном.Ссылка, Ном.Код, Ном.Наименование
ИЗ Справочник.Номенклатура КАК Ном
ГДЕ Ном.Артикул В (
ВЫБРАТЬ Ном2.Артикул ИЗ Справочник.Номенклатура КАК Ном2
ГДЕ Ном2.Артикул <> "" И НЕ Ном2.ЭтоГруппа
СГРУППИРОВАТЬ ПО Ном2.Артикул
ИМЕЮЩИЕ КОЛИЧЕСТВО(*) > 1)
И НЕ Ном.ЭтоГруппа
УПОРЯДОЧИТЬ ПО Артикул, Ссылка
Результат: 116 карточек в 33 группах.
Технический момент. При группировке тех же данных в Python (с
dict[...].lower()) получилось 36 групп, а в SQL-запросе на стороне 1С — 33. Расхождение обусловлено тем, что 1С приСГРУППИРОВАТЬ ПОсравнивает строки регистронезависимо. Три дополнительные группы — это группы с расхождением регистра:ar/AR 150100/2fbs,ar/AR 4025/7,цитрат/Цитрат 120.
3.2 Восстановление времени создания карточек — без журнала регистрации
Для определения последовательности появления дублей необходимо знать время создания каждой карточки. В базе журнал регистрации не велся (включён только короткий retention), а бухгалтер не располагал сведениями о датах операций.
Использован следующий подход: 1С генерирует ссылки на новые объекты в формате UUID v1 — формате, в котором 60 бит отведены под таймстемп. Таким образом, время создания содержится непосредственно в ссылке, и журнал не требуется.
Распаковка:
import uuid
from datetime import datetime, timedelta, timezone
UUID_EPOCH = datetime(1582, 10, 15, tzinfo=timezone.utc) # Григорианская эпоха
LOCAL_TZ = timezone(timedelta(hours=3)) # МСК
def uuid_v1_to_datetime(u: str) -> datetime | None:
obj = uuid.UUID(u)
if obj.version != 1:
return None
return (UUID_EPOCH + timedelta(microseconds=obj.time / 10)).astimezone(LOCAL_TZ)
Метод применён ко всем 116 карточкам, данные сгруппированы по артикулу и отсортированы внутри группы по времени. Сформирован Excel со столбцами: Артикул | Наименование | Код | Создан (МСК) | UUID. Группы с расхождением регистра выделены жёлтым.
Это позволило установить два факта:
- внутри одной загрузки маркетплейса (пакет размером 100–500 строк) дубли возникали с интервалом 1–3 секунды (типичное время обработки одной строки в скрипте);
- старые группы создавались с разрывом в недели — то есть имело место повторное возникновение дубля при следующей загрузке.
3.3 Фильтр на «реальные» дубли — и обнаружение человеческого фактора
Бо́льшая часть из 33 групп не относилась к работающим маркетплейсам. По уточнению с заказчиком:
«Бухгалтер не грузит Магнит Маркет и Яндекс автоматически — он там делает карточки руками. Берёт похожую карточку из Ozon, копирует, правит наименование под новый канал — а артикул не очищает. Так и плодит. Это не ваш баг, это операционный шум».
Это позволило установить фактическую картину: значительная часть дублей — следствие массовой практики копирования карточек номенклатуры без очистки артикула. Бухгалтер не учитывал, что артикул является идентификатором, по которому система сопоставляет товары маркетплейса. Копия с неочищенным артикулом — это карточка, которая в любой момент может перехватить у корректной позиции движение от Ozon-загрузки.
Таким образом, проблема имела двойную природу:
| Источник | Что делал | Результат |
|---|---|---|
| Код расширения | Не защищался от уже существующих дублей при поиске и записи | Привязывался к некорректной карточке, создавал вторую |
| Операционная практика бухгалтера | Копировал карточки кнопкой «Скопировать», артикул не очищал, иногда менял регистр | Создавал в базе карточки-двойники, которые код затем дополнял движением |
Указанные факторы усиливали друг друга: бухгалтер создавал основу дубля, а расширение его размножало. При этом в коде расширения не было предусмотрено ни одного механизма противодействия этой практике: ни валидации при копировании, ни проверки коллизий при записи, ни предупреждения в журнале.
Чтобы количественно отделить дубли, обусловленные дефектом расширения, от ручного шума, список был перефильтрован: оставлены только карточки, у которых имеются обороты по счёту 45.01 («Покупные товары отгруженные») за 2026 год с контрагентом Ozon (ИНН 7704217370) или РВБ (ИНН 9714053621).
Запрос с виртуальной таблицей оборотов и фильтром по ИНН субконто:
ВЫБРАТЬ
ВЫРАЗИТЬ(Обороты.Субконто2 КАК Справочник.Номенклатура) КАК Номенклатура,
ВЫРАЗИТЬ(Обороты.Субконто1 КАК Справочник.Контрагенты).ИНН КАК ИНН,
СУММА(Обороты.СуммаОборотДт) КАК ОборотДт,
СУММА(Обороты.СуммаОборотКт) КАК ОборотКт,
СУММА(Обороты.КоличествоОборотДт) КАК КолДт,
СУММА(Обороты.КоличествоОборотКт) КАК КолКт
ИЗ РегистрБухгалтерии.Хозрасчетный.Обороты(
ДАТАВРЕМЯ(2026, 1, 1), ДАТАВРЕМЯ(2026, 12, 31, 23, 59, 59), ,
Счет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ПокупныеТоварыОтгруженные), ,
ВЫРАЗИТЬ(Субконто1 КАК Справочник.Контрагенты).ИНН В ("7704217370", "9714053621")
И ВЫРАЗИТЬ(Субконто2 КАК Справочник.Номенклатура) В (&НоменклатураСписок), , ) КАК Обороты
СГРУППИРОВАТЬ ПО ...
Технический момент. Без параметра
&НоменклатураСписокответ MCP превысил бы 87 КБ — был бы достигнут лимит ответа. Сужение по списку из 116 заранее найденных UUID решает эту проблему: на сервер передаётся только необходимый срез данных.
Результат фильтра: 10 групп / 24 карточки — это дубли, обусловленные дефектом расширения. Они выгружены во второй Excel со столбцами Артикул | Наименование | Код | Создан | Площадка | Кол-во Дт/Кт | Сумма Дт/Кт | UUID.
Пример выгрузки (фрагмент)
| Артикул | Карточек | Создание (МСК) | Обороты Ozon (₽) | Обороты WB (шт) | Комментарий |
|---|---|---|---|---|---|
| sunblind.AR | 4 | 2025-10..2026-05 | 49 419 | — | 4 карточки на одном Ozon-артикуле |
| AR/9050/5fbs | 2 | 2025-09 / 2026-05-03 | 22 113 | — | старая 473 и свежая 611 (одна загрузка) |
| AR/150100/2fbs | 2 | 2025-09 / 2026-05-03 | 49 419 | — | имя не совпадает: «Lada XRAY» vs «150х100» |
| wb16tk6nni | 3 | 2024-10..2025 | — | 2 415 шт | предопределённая «Товары WB» — аккумулятор |
| цитрат120 | 2 | 2025-12 / 2026-03 | — | 17 шт | расхождение регистра цитрат vs Цитрат 120 |
Элемент-накопитель в группе wb16tk6nni — отдельная находка: это предопределённый элемент Товары WB, на который относится всё, что не сопоставляется. Через него прошло 2 415 единиц товара — то есть часть WB-продаж учитывалась обезличенно. Это самостоятельный случай для отдельной проработки, он передан заказчику в рекомендации.
3.4 Анализ кода расширения — три независимых источника дублей
Исходники зм_ЗагрузкаМаркетплейсов.cfe распакованы через v8unpack -E. Изучены ключевые модули в CommonModule/ и менеджеры. Выявлены три независимых места, каждое из которых самостоятельно способно породить дубль:
| Блок | Где | Дефект | Когда срабатывает |
|---|---|---|---|
| 1 | СопоставлениеНоменклатурыКонтрагентов, поиск по артикулу |
При нескольких карточках с одним артикулом возвращалась произвольная — без детерминизма. Если возвращалась более ранняя карточка, новые движения относились не к актуальной. | На каждой загрузке, где артикул уже был дублирован иным образом (например, ручной копией бухгалтера). Усугубляло цепочку. |
| 2 | Запись новой карточки | Отсутствовала проверка коллизий перед Записать(). Если в момент создания новой карточки артикул уже был присвоен другой — в базу записывалась вторая карточка с тем же артикулом. |
На первом дубле в сессии загрузки — далее работает блок 1 и продолжает цепочку. |
| 3 | Обработчик ПриКопировании в карточке |
Артикул при копировании не очищался. У заказчика это массово проявлялось вследствие практики бухгалтера: «скопировать → переименовать → сохранить» — артикул-источник переносился в копию. Десятки таких карточек попадали в базу. | На каждой ручной операции копирования. Основной источник исходных дублей для дальнейшего размножения блоком 1 при следующей автозагрузке. |
4. Решения
4.1 Доработка расширения (3 блока фиксов)
В исходники src_cfe/CommonModule/СопоставлениеНоменклатурыКонтрагентов/CommonModule.obj.bsl и соответствующие модули внесены три исправления:
- Детерминированный поиск. При дублировании артикула выбирается карточка с минимальной ссылкой (
MIN(Ссылка)), факт срабатывания защиты фиксируется в журнале регистрации. - Проверка коллизий при записи. Перед
Объект.Записать()выполняется запрос на наличие карточки с этим артикулом, отличной от текущей. При наличии —ВызватьИсключениес информативным сообщением, чтобы загрузка остановилась, а не создала второй дубль без уведомления. - Очистка артикула в
ПриКопировании. В обработчике копирования карточки устанавливаетсяАртикул = "". Это устраняет уязвимость в операционной практике: при копировании карточек артикул в копию больше не переносится. До исправления именно это проявлялось массово и было основным источником исходных дублей для дальнейшего размножения через блок 1.
Тестирование выполнено отдельной EPF зм_ТестыРасширения.epf (17 964 байта, 21 кейс) — все тесты пройдены. Расширение пересобрано через v8unpack -B, версия повышена до 2026.05.26.12. Размер .cfe — 122 207 байт.
4.2 Внешняя обработка очистки исторического «мусора»
Три блока исправлений предотвращают появление новых дублей. Однако в базе уже числилась 231 карточка с артикулом, у которой нет оборотов Ozon/WB — это либо некорректные данные, либо позиции для каналов, не подключённых к автозагрузке. Хранение у них артикула нежелательно: следующая загрузка маркетплейса может сопоставиться с ними по совпадению.
Разработана внешняя обработка зм_ОчисткаАртикулов.epf (7 941 байт):
- одна кнопка «Выполнить»;
- один чекбокс «Записывать в базу (снять для драй-рана)» — по умолчанию снят, то есть dry-run по умолчанию;
- запрос: вся номенклатура с непустым артикулом, у которой нет оборотов по счёту
45.01с ИНН7704217370(Ozon) или9714053621(РВБ) за весь период; - в dry-run — лог из первых 100 строк + общее количество;
- в боевом режиме —
Артикул = ""+Записать()+ запись в журнал регистрации по каждой операции (зм.Артикул.Очистка/зм.Артикул.Очистка.Ошибка).
Заказчик выполнил dry-run, проверил выборку, установил флаг и очистил 231 артикул за один проход. После этого база приведена в корректное состояние — следующие загрузки маркетплейсов начинаются с известного состояния.
4.3 Документ для мердж-инга (рекомендации)
10 групп / 24 карточки — это дубли с движением, их нельзя очистить автоматически: требуется решение бухгалтера о том, какая карточка является ведущей и куда переносить остатки. Они выгружены в Excel-таблицу с временем создания, объёмом оборотов по каждой стороне (Ozon/WB) и выделением расхождений регистра. Это рабочий лист для бухгалтера: пройти 24 строки и принять решение по каждой.
Дополнительно в рекомендации внесена находка о предопределённом элементе Товары WB — на него относятся неопознанные позиции, и его необходимо очищать отдельным процессом.
4.4 Продолжение через три дня — повтор на боевой базе, без EPF (2026-05-29)
Через три дня после первого обращения заказчик обратился повторно: та же ситуация, но в другой продуктивной базе того же ИП Котова — landysh. От загрузки зм_ОчисткаАртикулов.epf решено отказаться — нецелесообразно ради разового действия добавлять в продуктивную базу новую обработку, согласовывать её установку с администратором и регистрировать в реестре. Работы решено выполнить агентом через MCP, без загрузки в Конфигуратор.
Это обеспечено инструментом batch_1c MCP ai-agent-1c, который принимает массив операций UPDATE/CREATE/DELETE_MARK/POST/UNPOST/WRITE_RECORDSET и применяет их в одной HTTP-сессии. Сервер 1С обрабатывает их параллельно (в данном случае — до 20 потоков), возвращая статус по каждой операции. Это полная замена внешней обработке для массовой правки реквизитов справочника.
4.4.1 Шаг 1 — массовая очистка «мусорных» артикулов через batch_1c
Тот же запрос «номенклатура с непустым артикулом без оборотов по 45 в иерархии у Ozon/РВБ за всё время», но теперь параметризованный для конкретной организации:
ВЫБРАТЬ Ном.Ссылка, Ном.Артикул, Ном.Код, Ном.Наименование
ИЗ Справочник.Номенклатура КАК Ном
ЛЕВОЕ СОЕДИНЕНИЕ (
ВЫБРАТЬ РАЗЛИЧНЫЕ ВЫРАЗИТЬ(Об.Субконто2 КАК Справочник.Номенклатура) КАК Номенклатура
ИЗ РегистрБухгалтерии.Хозрасчетный.Обороты(
, , ,
Счет В ИЕРАРХИИ (&Счет45), ,
Организация = &Организация
И ВЫРАЗИТЬ(Субконто1 КАК Справочник.Контрагенты).ИНН В ("7704217370", "9714053621")
) КАК Об
) КАК ЕстьОбороты
ПО Ном.Ссылка = ЕстьОбороты.Номенклатура
ГДЕ Ном.Артикул <> "" И НЕ Ном.ЭтоГруппа И ЕстьОбороты.Номенклатура ЕСТЬ NULL
В landysh обнаружено 244 кандидата (из 536 карточек с непустым артикулом у 292 были обороты Ozon/РВБ). Выборка выгружена в 260529/КандидатыНаОчисткуАртикула.xlsx для контрольного просмотра. После подтверждения выполнена массовая правка:
- Один пробный UPDATE на одной случайной карточке — для проверки работоспособности схемы
batch_1c: типСправочник.Номенклатура,refс UUID,data: {Артикул: ""}→ ответstatus: UPDATED. - Контрольный запрос — подтверждено, что артикул стал пустым.
- Остальные 243 операции разбиты в Python на 5 пакетов по ~50 операций и отправлены параллельно одним сообщением. Сервер 1С обработал их в режиме
mode: parallel, threads_used: 20. - Финальная верификация двумя запросами: (а) счётчик «номенклатура с непустым артикулом» (было 536 → стало 292, разница ровно 244); (б) фильтр «UUID из исходного списка из 244 AND Артикул <> ""» → 0 строк.
Итог: 244 артикула очищены, без EPF, без обращения к Конфигуратору. Запись каждой операции фиксируется в стандартном аудит-трейле MCP с привязкой к токену клиента.
4.4.2 Шаг 2 — поиск «настоящих» дублей с оборотами
Из 292 оставшихся карточек с артикулом запрос «артикул встречается > 1 раза среди тех, у кого есть обороты Ozon/РВБ» вернул 10 групп / 27 карточек. Данные выгружены в 260529/Дубли_СОборотами_исходный_27.xlsx:
- группировка по
lower(артикул)(как сравнивает 1С), - время создания каждой карточки через UUID v1,
- разбивка оборотов на Ozon и РВБ с количеством Дт/Кт и суммой,
- цветовое выделение групп с расхождением регистра, ведущих и очищаемых карточек.
Установлено следующее:
- 9 из 10 групп имели карточку, созданную 2026-05-03 15:21 — следы одной Ozon-загрузки. Это уже после развёртывания исправлений расширения. То есть исправление «MIN(Ссылка) + проверка коллизий» в данной среде не сработало. Открытый вопрос для отдельного разбора — по какой причине расширение в
landyshне отреагировало. - Часть групп представляет собой не дубли, а коллизии артикула: разные товары с одним и тем же артикулом. Например,
ar/150100/2fbsобъединял три разных товара: коврик в прихожую (WB), коврик в багажник Lada XRAY (Ozon), придверный коврик 150×100 темно-серый (Ozon, 49 419 ₽). Это указывает на то, что бухгалтер при ручной правке скопировал карточки и не очистил артикул.
4.4.3 Шаг 3 — ручной выбор лидеров (8 групп из 10)
Заказчик просмотрел таблицу и указал пары «Код-Артикул» — какую карточку в каждой группе оставить как корректную. По 8 группам решения определены сразу, у остальных карточек в группе артикул очищается:
A85287S → 00-00000720 (оставить)
AR/5040/2 → 00-00000583
AR/5070/1 → 00-00000589
AR/9050/5fbs → 00-00000611
AR/9060/1fbs → 00-00000626
RV-03-R → 00-00000219
sunblind.AR → 00-00000630
жидкая резина LS-540-RE → 00-00000634
Python-скрипт по списку ведущих карточек сформировал 13 UUID карточек на очистку. Выполнен один batch_1c UPDATE с 13 операциями, mode: parallel, threads_used: 13, все со статусом UPDATED. Контрольная верификация — в этих 8 группах повторяющихся артикулов нет.
4.4.4 Шаг 4 — установление истины через сторонние отчёты
По двум оставшимся группам (AR/150100/2fbs и AR/5040/5) заказчик решения не предоставил — соответствие товаров было неясно. В папке 260524/ у него находились 8 Excel-файлов с отчётностью Ozon за январь-апрель 2026:
- 4 файла «Реестр продаж юридическим лицам» (B2B-УПД),
- 4 файла «Отчёт о реализации товара» (агентский отчёт от ООО «Интернет Решения»).
Парсер на openpyxl обработал все 8 файлов, нашёл строки с искомыми артикулами и сгруппировал их по «артикул + название товара» с разбивкой по месяцам. Результат:
| Артикул в отчётах Ozon | Реальное название (одинаковое за 4 месяца) | Объём 2026 |
|---|---|---|
AR/150100/2fbs |
Коврик придверный; 150×100 см темно-серый | 280 шт / 577 784 ₽ |
AR/5040/5 |
Коврик для сушки посуды 50×40 коричневый | 196 шт / 80 570 ₽ |
Сопоставление с карточками в 1С дало однозначный результат:
AR/150100/2fbs: ведущая — карточка00-00000600 «Коврик придверный 150×100 темно-серый». Карточки247 «Коврик в прихожую»и541 «Коврик в багажник Lada XRAY»— другие товары, артикул присвоен ошибочно.AR/5040/5: ведущая — карточка00-00000582 «Коврик для сушки посуды 50×40, коричневый». Карточка532 «БЕЛЫЙ»— другой товар (не коричневый); карточка152 «коричневый»— фактический дубль того же товара. У обеих артикул очищается.
После подтверждения выполнен ещё один batch_1c с 4 операциями UPDATE. Финальная верификация: счётчик «группы дублей с оборотами Ozon/РВБ» → null (= 0).
4.4.5 Итог второго захода
Метрика второго захода (база landysh) |
Значение |
|---|---|
| Карточек с артикулом до | 536 |
| Карточек с артикулом после | 275 |
| Очищено за сессию | 261 (244 без оборотов + 17 дублей) |
| Групп дублей с оборотами до | 10 |
| Групп дублей с оборотами после | 0 |
Пакетов batch_1c UPDATE |
8 (5 на массовую очистку + 1 на 13 дублей + 1 на 4 дубля + 1 пробный) |
| Параллельность сервера 1С | до 20 потоков на пакет |
| Файлов EPF загружено в боевую базу | 0 |
| Визитов в Конфигуратор | 0 |
Артефакты — в landysh/ТоварныйУчет/260529/ (рядом с исходниками маркетплейс-отчётов в 260524/):
КандидатыНаОчисткуАртикула.xlsx— 244 строки на очистку,Дубли_СОборотами_исходный_27.xlsx— снимок до операции с выделением ведущих и помечаемых на очистку карточек,clear_candidates.json,Дубли_27_исходный.json— машиночитаемые копии для аудита.
Архитектурный вывод. Связка «
query_1cдля поиска кандидатов →batch_1cдля массовой правки» закрывает класс задач «массовая очистка и правка справочников», который традиционно решался отдельной разовой внешней обработкой. Из процесса исключается весь цикл: проектирование EPF, согласование с администратором продуктивной базы, регистрация в реестре дополнительных обработок, инструктаж бухгалтера. Цикл сокращается до: запрос → подтверждение списка человеком → batch_1c → верификация.
5. Инструменты
5.1 Использовали в этом кейсе
Все шаги выполнены через ai-agent-1c без подключения к Конфигуратору и без ручных выгрузок:
| Инструмент | Что делали |
|---|---|
query_1c |
Запросы к справочнику, регистрам, виртуальной таблице оборотов, фильтр по субконто, передача массива ссылок параметром |
batch_1c |
Массовая запись Артикул = "" пакетами по 13–50 операций UPDATE в одной HTTP-сессии. Сервер 1С обрабатывает параллельно в режиме mode: parallel, threads_used: 20. Полная замена внешней обработке для разовой массовой правки справочника |
session_info_1c |
Проверка прав/контекста сессии перед первым запросом |
metadata_1c |
Уточнение состава реквизитов и плана счетов перед формированием запросов |
Локальные инструменты, использованные совместно с MCP:
- v8unpack — распаковка и сборка
.cfeи.epf, чтение и правка BSL вне Конфигуратора; - openpyxl — выгрузка отфильтрованных выборок в Excel с выделением расхождений регистра и чередующимся фоном строк; парсинг маркетплейс-отчётов заказчика (B2B-УПД и агентский «Отчёт о реализации товара») для определения, какому реальному товару соответствует артикул;
- Python
uuid— извлечение времени создания из UUID v1.
5.2 Что осталось за рамками — но есть в арсенале
В данном кейсе задействована лишь часть возможностей продукта. Ниже — инструменты MCP ai-agent-1c, которые здесь не потребовались, но штатно работают и применимы в близких сценариях.
| Инструмент | Что делает | Когда пригодился бы в подобной задаче |
|---|---|---|
invoke_1c |
Вызов экспортной функции/процедуры общего модуля 1С прямо из агента | Вместо внешней EPF — вызов готовой серверной функции расширения для очистки; перепроведение документов; запуск регламентных заданий |
run_task / task_status / task_stop |
Длительные асинхронные задачи (минуты-часы) с поллингом и возможностью прервать | Полная зачистка справочника на сотни тысяч строк; фоновое перепроведение всех документов за период; восстановление последовательности |
get_skill |
Загрузить готовый «скилл» — переиспользуемый сценарий с инструкциями для агента (Skill Server, pgvector) | Если бы существовал скилл «диагностика дублей номенклатуры маркетплейсов» — применился бы с ходу, без проектирования с нуля |
skill_report |
Отчёт о результатах применения скилла обратно в библиотеку — для аналитики и улучшения скиллов | Зафиксировать, что скилл применён на данной базе, с такими-то метриками — пополняет коллективный опыт |
invalidate_knowledge |
Сброс семантического кэша знаний агента после структурных изменений в конфигурации | После заимствования новых объектов в расширении или переименований — чтобы агент не использовал устаревшую метамодель |
get_run_history |
История запусков и операций агента в этой базе | Аудит «кто из бухгалтеров что запускал»; разбор инцидентов; SLA-отчёты заказчику |
web_search |
Поиск в интернете через Tavily (с защищённым прокси под токеном клиента) | Поиск аналогичных проблем на форумах ИТС, документации 1С, методических материалов БСП |
Смежные компоненты продукта, тоже за рамками этого кейса:
| Компонент | Что даёт | Когда применим |
|---|---|---|
ai_ПанельАгента |
Нативная BSL-панель внутри 1С — бухгалтер взаимодействует с агентом, не выходя из своей программы | Заказчик самостоятельно выполняет dry-run очистки, видит результаты непосредственно в 1С, без участия разработчика |
| Skill Server | Каталог переиспользуемых скиллов с pgvector-поиском по описанию | Растущая библиотека готовых сценариев «диагностика…», «миграция…», «сверка…» — копится как капитал между проектами |
| Identity Server | Multi-tenant: один деплой обслуживает много клиентов, у каждого свои базы/токены/scope | Сервисная компания обслуживает 1С у десятков клиентов с одного контура, у каждого изолированные права |
| Audit-trail runtime | Все вызовы инструментов агентом — в журнал, с привязкой к токену клиента и пользователю | Соответствие требованиям к аудиту в регулируемых отраслях; доказательная база при разборе спорных ситуаций |
cfe-builder CLI |
Сборка .cfe под конкретного клиента с прошитыми credentials, артефакты с manifest.json (sha-цепочки) |
Когда расширение надо доставить с уже зашитыми параметрами подключения к серверу агента — без ручной настройки |
6. Результаты
6.1 Первый инцидент (расширение + EPF)
| Метрика | Значение |
|---|---|
| Карточек с непустым артикулом в базе | 544 |
| Из них с реальным движением Ozon/WB | 313 |
| Дублей всего (по 1С) | 33 группы / 116 карт. |
| Дублей с реальным движением Ozon/WB за 2026 | 10 групп / 24 карт. — на ручное объединение бухгалтером |
| Карточек к автоочистке артикула | 231 |
| Найдено независимых источников дублирования в коде | 3 |
| Доработана версия расширения | 2026.05.26.12 |
6.2 Второй заход — landysh через MCP, без EPF (2026-05-29)
| Метрика | Значение |
|---|---|
| Карточек с непустым артикулом до | 536 |
| Карточек с непустым артикулом после | 275 |
| Очищено артикулов за сессию | 261 (244 без оборотов + 13 ручных лидеров + 4 после анализа отчётов) |
| Групп дублей с оборотами Ozon/РВБ до | 10 |
| Групп дублей с оборотами Ozon/РВБ после | 0 |
Пакетов batch_1c UPDATE |
8 |
| Параллельность сервера 1С на пакет | до 20 потоков |
| Внешних обработок (EPF) загружено в боевую базу | 0 |
| Визитов в Конфигуратор | 0 |
| Маркетплейс-отчётов Ozon, использованных для установления истины | 8 (4 УПД-B2B + 4 агентских) |
Размер итогового .cfe |
122 207 байт |
| Тесты расширения | 21 / 21 зелёных |
| Выпущена внешняя обработка | зм_ОчисткаАртикулов.epf (7 941 байт), с dry-run |
| Очищено артикулов за один проход | 231 |
7. Что это даёт пользователю MCP ai-agent-1c
Один сценарий — три типа работы, ни один из которых не требовал открывать Конфигуратор:
- Расследование в продуктивной базе. Запросы к справочникам, виртуальным таблицам регистров бухгалтерии, фильтры по реквизитам субконто, параметры запросов как ссылки — всё это через
query_1c. Без ручных выгрузок CSV, без предоставления доступа по RDP. - Аналитика поверх запросов. Декодирование UUID v1, группировка с учётом регистронезависимости 1С, корреляция с оборотами в разрезе ИНН субконто — всё в Python поверх результата MCP. Готовый артефакт — Excel-файл, который можно передать бухгалтеру.
- Разработка и тестирование. Распаковка
.cfeчерез v8unpack, правка BSL, тесты во внешней EPF, сборка, повышение версии — без обращения к Конфигуратору. Конфигуратор требуется только для финального шага (обновление расширения из файла).
В совокупности — полный цикл «обращение заказчика → анализ → разработка → выпуск → сопровождение» в рамках одной сессии, без переключения инструментов и без ручных передач между ролями.
Приложения
A. Файлы кейса
| Файл | Назначение |
|---|---|
ТоварныйУчет/зм_ЗагрузкаМаркетплейсов.cfe |
Доработанное расширение, версия 2026.05.26.12 |
ТоварныйУчет/зм_ТестыРасширения.epf |
21 регрессионный тест |
ТоварныйУчет/зм_ОчисткаАртикулов.epf |
Внешняя обработка для очистки артикулов, с dry-run |
ТоварныйУчет/ДублиАртикулов_СВременемСоздания.xlsx |
Полная выгрузка всех 33 групп / 116 карточек |
ТоварныйУчет/ДублиАртикулов_СоборотамиOzonWB2026.xlsx |
Отфильтрованная выгрузка 10 групп / 24 карточек — на ручное объединение |
B. Карта проблемы
┌─────────────────────────────┐ ┌─────────────────────────────┐
│ Операционная практика │ │ Дефекты кода расширения │
│ бухгалтера │ │ (бенефициар дублей) │
│ │ │ │
│ Бездумное копирование │ зерно │ Поиск по артикулу без │
│ карточек, артикул не │ ─────► │ детерминизма; запись без │
│ очищается, иногда меняется │ │ проверки коллизий │
│ регистр │ │ │
└─────────────────────────────┘ └─────────────────────────────┘
│ │
└──────────────────┬────────────────────┘
▼
3 фикса в расширении
┌────────────────────┬──────────────────────┬─────────────────────┐
│ │ │ │
Фикс 1: Фикс 2: Фикс 3:
MIN(Ссылка) проверка коллизий ПриКопировании
при поиске при записи Артикул = ""
(срезает зерно) (не даёт записать (закрывает дыру в
второй дубль) операционной практике)
│
▼
Предотвращает НОВЫЕ дубли
│
▼
Уже накопленные дубли в базе (актуальное состояние)
│
┌───────────────┴───────────────┐
│ │
231 карточка без оборотов 10 групп / 24 карточки с оборотами
Ozon/WB → автоочистка → ручной мердж бухгалтером
через EPF (dry-run) (Excel со списком на руках)