- BrainTools - https://www.braintools.ru -
Что решает — дорогое и долгое дообучение узкой модели или хорошая обвязка вокруг обычной облачной?
На первый взгляд кажется очевидным, что модель от вендора, у которого привилегированный и неограниченный доступ к материалам, не оставит камня на камне от конкурентов. Но, может, мы уже дошли до того момента, когда разница в качестве ответов общих и специализированных моделей не оправдывает затрат на дообучение?
Попробуем сравнить нашего [1] интерактивного помощника на open-source стеке и Напарника [2] на обычных вопросах, с которыми ежедневно сталкиваются пользователи и разработчики 1С.
Выбор конкретной ЛЛМ оставим за скобками. Все топовые модели прекрасно работают с вызовами инструментов и имеют приличное контекстное окно. Тестировали на моделях уровня deepseek-v4-flash, gpt-6.1-sol, glm-5.3-flash.
Агентская обвязка — Deep Agents [3] на базе LangGraph. Из коробки получаем планирование задач, делегирование субагентам с изолированным контекстом и управление контекстным окном через суммаризацию истории.
Основа основ — хорошо структурированное индексное дерево базы знаний на RAG-индексах. Используем гибридный поиск. Полнотекстовая ветка построена на FTS PostgreSQL с русским словарём, векторная — на расширении pgvector с HNSW-индексом. Результаты обеих веток сливаем через Reciprocal Rank Fusion — кандидаты с высоким местом в каждой выдаче поднимаются в итоговом списке.
Для исходников типовых конфигураций используем быстрый поиск. Пять выгрузок типовых конфигураций — это около 236 тысяч файлов и 193 тысячи каталогов. С хорошими алгоритмами и на современном железе этот объём не составляет проблемы. Для ориентации в тысячах модулей написали парсер метаданных конфигураций, который собирает объекты, реквизиты и связи между ними.
Для поиска в интернете используем API Яндекса, который даёт гораздо более релевантную выдачу по России, чем поисковики, встроенные в чаты ЛЛМ. Агрегируем и суммаризируем сведения из всех найденных источников.
Все примеры собраны из реальных задач коллег по цеху 1С.
Агент дал конфигурацию журнала с фильтром длительных ожиданий, объяснил, как найти блокирующее соединение, и предложил дополнительные события для поиска причины долгой транзакции.
Для таймаутов управляемых блокировок нужно зафиксировать не только ошибку [4], но и соединение, которое удерживало блокировку. Начните с событий TTIMEOUT, TDEADLOCK и ожиданий TLOCK.
В logcfg.xml в каталоге conf используемой установки платформы задайте следующую конфигурацию. Ниже — содержимое XML.
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="D:TJLocks" history="4">
<event>
<eq property="name" value="TLOCK"/>
<gt property="duration" value="1000000"/>
</event>
<event>
<eq property="name" value="TTIMEOUT"/>
</event>
<event>
<eq property="name" value="TDEADLOCK"/>
</event>
<property name="all"/>
</log>
</config>
Это собирает
TLOCK — ожидания более 1 секунды; длительность задаётся в микросекундах.
TTIMEOUT — превышения времени ожидания блокировки.
TDEADLOCK — взаимоблокировки.
history="4" — хранение за четыре часа, не ограничение размера журнала.
Путь D:TJLocks — пример для Windows. Выберите каталог с запасом места и предоставьте учётной записи службы сервера 1С права записи. Для Linux нужен соответствующий путь. В многосерверном кластере настройте сбор на узлах, где работают рабочие процессы.
Если журнал уже настроен, добавьте секцию, не уничтожая существующую конфигурацию. Платформа перечитывает настройки автоматически; после изменения проверьте, что файлы журнала действительно появились.
Запишите время ошибки, пользователя и выполняемую операцию. В журнале найдите TTIMEOUT и посмотрите
|
Поле |
Что выясняем |
|---|---|
|
|
Какие соединения мешали получить блокировку |
|
|
Соединение, которое ожидало |
|
|
Пространство и данные блокировки |
|
|
Контекст кода, если он присутствует |
Не путайте номер соединения с номером сеанса. Для поиска блокирующего участника сопоставляйте значения из WaitConnections с t:connectID, учитывая базу и время.
Одних событий блокировок может быть недостаточно. На короткое время повторного воспроизведения добавьте сбор
CALL, SCALL — вызовы;
SDBL — обращения к данным на уровне платформы;
DBMSSQL либо DBPOSTGRS — работа с вашей СУБД.
Исследуйте блокирующее соединение, а не только получившее ошибку — что оно выполняло до таймаута и во время ожидания. Ищите длинные запросы, длительную обработку внутри транзакции и обращения к внешним сервисам.
Не включайте все события надолго — контролируйте объём, сохраните нужный интервал и отключите расширенный сбор. Увеличение таймаута само по себе причину не устраняет.
Источник по событиям и фильтрам — «Как отслеживать ожидания на управляемых блокировках» — разделы настройки и поиска причины [5].
Напарник тоже дал конфигурацию журнала и указал на WaitConnections, но подробнее остановился на сборе материалов для расследования, а не на разборе действий блокирующего соединения.
Чтобы настроить технологический журнал для поиска причин таймаутов управляемых блокировок, необходимо:
Включить следующие события в конфигурации технологического журнала:
EXCP — для регистрации исключений
TLOCK — для регистрации событий блокировок
TTIMEOUT — для регистрации таймаутов ожидания блокировок 1 [6]
Пример конфигурации (XML):
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://v8.1c.ru/v8/tech-log">
<log location="D:LOGSTech_logs" history="24">
<event>
<eq property="Name" value="EXCP"/>
</event>
<event>
<eq property="Name" value="TLOCK"/>
</event>
<event>
<eq property="Name" value="TTIMEOUT"/>
</event>
<property name="all"/>
</log>
</config>
Дополнительные рекомендации:
Храните журналы в отдельной директории без посторонних файлов, иначе запись может не выполняться 2 [7]
После настройки подождите 1 минуту и проверьте, что журналы начали создаваться 2 [7]
Для расследования также потребуется файл конфигурации (cf) и реестр кластера 1С ( 1CV8Clst.lst) 1 [6]
Идентификация ошибок:
Ошибки таймаута на управляемых блокировках имеют описание: «Превышено максимальное время ожидания предоставления блокировки» 2 [7]
В событии TLOCK ищите поле WaitConnections, указывающее на соединение, вызвавшее ожидание 3 [8]
Источники
Агент описал подключение к подсистеме БСП через определяемые типы, подписку на запись, обработчик менеджера и инициализацию формы. Приведены код и шаг включения истории в пользовательских настройках.
Чтобы подключить новый нетиповой справочник к подсистеме БСП «Версионирование объектов»
В определяемый тип ВерсионируемыеДанные добавьте тип
СправочникСсылка.<ВашСправочник>.
В определяемый тип ВерсионируемыеДанныеОбъект добавьте тип
СправочникОбъект.<ВашСправочник>.
Подписка ЗаписатьВерсиюОбъекта уже использует этот определяемый тип, событие ПередЗаписью и обработчик общего модуля «ВерсионированиеОбъектовСобытия». Поэтому отдельно добавлять справочник в источник подписки не требуется.
В модуле менеджера справочника добавьте экспортную процедуру
ПриОпределенииНастроекВерсионированияОбъектов. Пустой обработчик допустим. Если нужно скрыть технические реквизиты из отчёта по версиям, включите соответствующую настройку и реализуйте обработчик их получения.
В каждой форме элемента справочника вызовите инициализацию подсистемы из события формы ПриСозданииНаСервере
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ВерсионированиеОбъектов.ПриСозданииНаСервере(ЭтотОбъект);
КонецПроцедуры
// Модуль менеджера справочника
Процедура ПриОпределенииНастроекВерсионированияОбъектов(Настройки) Экспорт
КонецПроцедуры
Обновите конфигурацию базы данных, включите функциональность «История изменений», затем в настройках истории укажите вариант хранения для нового справочника.
Важно — для справочника используется подписка ЗаписатьВерсиюОбъекта. Подписка ЗаписатьВерсиюДокумента предназначена только для документов. Фрагмент и схема подключения подтверждены документацией БСП 3.2 и кодом подсистемы в выгрузке конфигурации.
Напарник описал другой механизм — историю данных платформы и регламентное обновление её очереди. Подключение справочника к типовой подсистеме БСП в ответе не разобрано.
Для подключения нового нетипового справочника к подсистеме хранения истории версий необходимо:
В конфигураторе установить свойство История данных справочника в значение **Использование ** 1 [9]. Это включит версионирование для всего справочника.
Создать регламентное задание, которое будет выполнять обновление истории данных по очереди изменений с помощью метода ИсторияДанных.ОбновитьИсторию() 1 [9]. Это необходимо для переноса данных из очереди версий в таблицы хранения истории.
Настроить выборочное версионирование (при необходимости):
Через встроенный язык с использованием метода УстановитьНастройки() и объекта НастройкиИсторииДанных
Можно указать конкретные реквизиты для включения/исключения из истории, включая реквизиты табличных частей ( указываются как ТабличнаяЧасть.Реквизит) 1 [9]
Управление настройками:
Альтернативно можно использовать внешнюю обработку “Настройка и перенос истории данных” для тонкой настройки версионирования объектов метаданных, включая выбор произвольных реквизитов 2 [10].
Источники
Агент дал обработчик отмены проведения с запросом расходных движений партии и выводом зависимых документов. Отдельно предупредил, что для защиты от одновременного списания нужна управляемая блокировка — в примере её нет.
Проверку нужно выполнять в модуле объекта документа-партии, в обработчике ОбработкаУдаленияПроведения(Отказ). Если найдены проведённые документы, которые расходовали эту партию, установите Отказ = Истина.
В «Рознице 2.3» отмена проведения также обрабатывается в ОбработкаУдаленияПроведения(Отказ), а наличие связанных записей проверяется запросом через РезультатЗапроса.Пустой().
// Модуль объекта документа, который образует партию.
Процедура ОбработкаУдаленияПроведения(Отказ)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Расходы.Регистратор КАК ДокументСписания
|ИЗ
| РегистрНакопления.ТоварыПоПартиям КАК Расходы
|ГДЕ
| Расходы.Партия = &Партия
| И Расходы.ВидДвижения =
| ЗНАЧЕНИЕ(ВидДвиженияНакопления.Расход)
| И Расходы.Активность
| И Расходы.Регистратор <> &Партия";
Запрос.УстановитьПараметр(
"Партия",
Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат;
КонецЕсли;
Отказ = Истина;
Выборка = РезультатЗапроса.Выбрать();
ТекстСообщения =
"Нельзя отменить проведение документа."
+ Символы.ПС
+ "Его партия использована в документах:";
Пока Выборка.Следующий() Цикл
ТекстСообщения =
ТекстСообщения
+ Символы.ПС
+ Строка(Выборка.ДокументСписания);
КонецЦикла;
Сообщить(ТекстСообщения);
КонецПроцедуры
ТоварыПоПартиям — ваш регистр накопления;
Партия — измерение регистра, в котором хранится ссылка на документ прихода;
документ партии должен иметь тип, совместимый с этим измерением.
Запрос выполняется по физической таблице регистра, а не по Остатки(). Это важно — остаток покажет только итоговое количество, но не документы-регистраторы, которые уже списывали партию.
В физической таблице регистра могут находиться неактивные движения. Условие
Расходы.Активность
оставляет только действующие движения проведённых документов.
Нет, если движения регистра корректно управляются механизмом проведения — у отменённого документа записи становятся неактивными или удаляются. Для надёжности проверка ведётся по Активность.
Сам факт расходного движения не всегда означает, что партия действительно списана — в регистре могут быть служебные расходные строки с нулевым количеством. Тогда добавьте условие по реальному ресурсу, например
| И Расходы.Количество <> 0
Имя ресурса Количество нужно заменить на фактическое.
При большом количестве зависимостей пользовательское сообщение может оказаться слишком длинным. В запросе можно указать
ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 10
и вывести пояснение, что показаны только первые десять документов.
Для строгого складского учёта одной проверки недостаточно — другой сеанс может провести документ списания одновременно с отменой проведения партии. В промышленной реализации перед чтением зависимых движений нужна управляемая блокировка по измерению Партия. Но основной обработчик и логика [11] отказа остаются такими же — проверка в ОбработкаУдаленияПроведения, затем Отказ = Истина.
Напарник указал нужный обработчик, но сообщил, что в найденных материалах нет конкретного решения. Код проверки зависимых документов не предложил.
В представленных документах отсутствует конкретное описание способа запрета отмены проведения документа при условии, что его партии уже списаны другими документами.
Хотя документы подробно описывают:
Общий механизм проведения и отмены проведения 1 [12]
Роль обработчиков ОбработкаПроведения() и **ОбработкаУдаленияПроведения() ** 1 [12]
Принципы формирования движений в регистрах 1 [12]
Однако ни один из документов не содержит информации о реализации бизнес-логики, которая бы проверяла, были ли партии товара уже списаны другими документами, и запрещала отмену проведения в таком случае.
Для реализации такой функциональности требуется дополнительная разработка в обработчике **ОбработкаУдаленияПроведения() **, включающая проверку наличия зависимых документов, что не описано в предоставленных материалах.
Источники
Агент объяснил работу флажка «Хранить версии» в БСП и разделил включение готового механизма и его подключение к собственному объекту. Показал код открытия списка версий.
В БСП 3.2 версионирование прикреплённых файлов уже реализовано «из коробки» в подсистеме Работа с файлами — отдельно разрабатывать ничего не нужно, нужно только включить/подключить механизм.
Как это устроено и как включить
У справочника хранения файлов есть булевский реквизит «Хранить версии». Пользователь ставит этот флажок в карточке файла (панель навигации карточки → «Версии файла»). Пока флажок не установлен, при повторном сохранении файла хранится только последняя редакция; если включить — при каждом окончании редактирования создаётся новая запись в подчинённом справочнике «Версии файлов», а активная версия хранится в отдельном реквизите карточки файла.
Если ваш объект (справочник/документ) уже подключён к общему справочнику «Файлы» через определяемые типы ВладелецПрисоединенныхФайлов/ВладелецПрисоединенныхФайловОбъект (типовой сценарий для большинства объектов) — версионирование доступно сразу, никаких доработок не требуется — достаточно, чтобы пользователь включил флажок «Хранить версии», либо можно программно проставлять его по умолчанию при создании файла ( ФайлОбъект.ХранитьВерсии = Истина).
Если для объекта используется отдельный справочник хранения файлов (вариант с RLS) — по документации нужно повторить у своего справочника ту же структуру, что у типового «Файлы» — булевский реквизит ХранитьВерсии и ссылочный реквизит на подчинённый ему собственный справочник версий (по образцу связки «Файлы» → «Версии файлов»).
Пример реального кода — команда карточки файла «Версии файла» (по коду командного модуля справочника «Файлы»), которая открывает список версий
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Файл", ПараметрКоманды);
ПараметрыФормы.Вставить("УникальныйИдентификаторКарточкиФайла",
ПараметрыВыполненияКоманды.Источник.УникальныйИдентификатор);
ОткрытьФорму("Справочник.ВерсииФайлов.Форма.ВерсииФайла", ПараметрыФормы,
ПараметрыВыполненияКоманды.Источник, ПараметрыВыполненияКоманды.Уникальность, ПараметрыВыполненияКоманды.Окно);
КонецПроцедуры
На сервере решение «создать новую версию или перезаписать файл» принимается в общем модуле работы с файлами именно по этому флажку — если у объекта ХранитьВерсии не установлен — данные файла просто обновляются на месте, если установлен — формируется новая запись версии, а прежняя остаётся в истории.
Если у вас свой объект метаданных, для которого файлы ещё не подключены вообще, скажите — подскажу конкретные шаги подключения (определяемые типы, реквизиты, подписки на события) под ваш объект.
Напарник предложил добавлять реквизиты и настраивать определяемые типы по инструкции перехода на БСП 2.4. Как включить уже существующее версионирование в пользовательском режиме, не объяснил.
Для включения версионирования присоединённых файлов в типовой конфигурации 1С необходимо:
Добавить реквизиты в справочник присоединённых файлов — в справочнике ПрисоединенныеФайлы добавить реквизит * ХранитьВерсии* по образцу из демонстрационной конфигурации 1 [13].
Настроить типы владельцев файлов — в определяемый тип ВладелецПрисоединенныхФайлов и * ВладелецПрисоединенныхФайловОбъект* включить объекты, для которых требуется вести версионирование 1 [13].
Управление настройками через модуль РаботаСФайламиПереопределяемый — использовать процедуру * ПриОпределенииНастроек*, чтобы настроить поведение [14] версионирования (например, разрешить синхронизацию или запретить очистку файлов) для конкретных объектов 1 [13].
(Рекомендуется) Использовать обработку ПереходНаВерсию241 для автоматического выполнения необходимых изменений при обновлении 1 [13].
Источники
Новое в редакции 2.4 [13]
Агент перечислил возможные причины — от неоформленного приобретения до несовпадения аналитик — и предложил проверять цепочку документов и протокол расчёта себестоимости.
В УТ 11.5 складской остаток и себестоимость ведутся разными контурами. Товар может появиться в регистре «Товары на складах» после складского документа, но не попасть в «Себестоимость товаров», пока не отражён в финансовом учёте.
Основные причины
Оформлена складская приёмка, но не проведено приобретение — проверьте связанные документы «Приобретение товаров и услуг» и «Поступление товаров на склад».
Не выполнено «Распределение затрат и расчет себестоимости» в закрытии месяца либо этап завершился с ошибкой. По коду УТ именно расчёт себестоимости заполняет партии и формирует движения регистра.
Товар принадлежит не вашей организации — комиссионный, ответственного хранения, неотфактурованная поставка. Его стоимость учитывается в другом разделе или по отдельной партии.
Не совпадают аналитики — организация, характеристика, назначение, вид запасов либо раздел учёта. Складской регистр ведётся по складу, а себестоимость — прежде всего по организации и ключам аналитики.
Остаток создан инвентаризацией или оприходованием излишков, но финансовый документ ещё не оформлен.
В списке регистра включён отбор только по конкретному разделу учёта или организации.
По выгрузке УТ 11.5 движения в «Себестоимость товаров» формируются отдельными этапами расчёта
// Подготовка и проверка исходных данных.
РасчетСебестоимостиПодготовкаДанных.ПодготовкаИсходныхДанныхКРасчету(ПараметрыРасчета);
РасчетСебестоимостиПрикладныеАлгоритмы.ПроверитьКорректностьИсходныхДанныхДоРасчета(ПараметрыРасчета);
// Этап формирует движения по регистру "Себестоимость товаров".
РасчетСебестоимостиЗаполнениеПартий.
ЗаполнениеПартийВРегистреСебестоимостьТоваров(ПараметрыРасчета);
// Для среднескользящей отдельно отражается фактуровка поставок.
РасчетСебестоимостиЗаполнениеПартий.
ФактуровкаПоставокПриСреднескользящей(ПараметрыРасчета);
Проверять нужно от документа, сформировавшего складской приход — откройте его движения и найдите финансовый документ по той же организации и номенклатуре. Затем запустите закрытие месяца за период поступления и изучите протокол этапа * *«Распределение затрат и расчет себестоимости»**.
Напарник связал расхождение с особенностями отдельных разделов учёта и выполнением закрытия месяца, но более широкий список причин и порядок диагностики не привёл.
Товар может числиться на остатках, но отсутствовать в регистре накопления Себестоимость товаров, если он учитывается в разделах, где не ведется расчет среднескользящей стоимости:
По запасам в разделе Незавершенное производство среднескользящая стоимость не рассчитывается — учет ведется в разрезе партий производства 1 [15]
По запасам в разделе Неотфактурованные поставки учет стоимости ведется по партиям документов поступления, а не по среднескользящей 1 [15]
В таких случаях данные в регистр Себестоимость товаров записываются только при выполнении регламентных операций процедуры Закрытие месяца, а до этого момента товар может быть на остатках, но отсутствовать в регистре себестоимости.
Источники
На этих примерах Агент чаще давал ответ, с которым можно продолжить работу. Он называл модули, показывал код и предлагал порядок проверки. Напарник в нескольких случаях ограничивался описанием механизма или отвечал про соседнюю технологию.
На часть запросов Напарник не дал конкретного решения, сославшись на отсутствие информации в найденных материалах. В таких случаях пригодился бы поиск в интернете, где можно найти практические решения, которых нет в официальной документации.
Тут напарник вне конкуренции. Наш агент тратит время на поиск материалов, чтение исходников и дополнительные вызовы модели. Предобученная ЛЛМ дает готовые ответы из своих знаний.
На огромном трафике собственная инфраструктура может оказаться выгоднее облачных API. Однако в расчёт нужно включать оборудование, его загрузку, сопровождение и обновление моделей. Затраты на создание и обучение [16] оставим за скобками. Об их размере остаётся только гадать.
Судя по тренду развития передовых ЛЛМ, топовая модель с хорошей обвязкой уже сейчас даёт результат как минимум не хуже специализированных дообученных решений, даже без доступа ко всей технологической документации 1С.
Сможет ли вендор догнать (и перегнать?) конкурентов в этой гонке, покажет время.
Если хороший результат даёт связка модели и обвязки без дообучения, значит порог входа стал заметно ниже. Повторить сценарий может любой энтузиаст даже без сложной архитектуры, начать можно с готового агента типа Codex или DeepSeek и подключив свои MCP.
Попробовать наш эксперимент можно на Aether Lab [1], он в публичном бесплатном доступе.
Автор: sokolov_e_s
Источник [17]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/36774
URLs in this post:
[1] нашего: https://aether-lab.ru/spravochnik-1c/obschiy/
[2] Напарника: https://portalchat.1c.ai/
[3] Deep Agents: https://github.com/langchain-ai/deepagents
[4] ошибку: http://www.braintools.ru/article/4192
[5] «Как отслеживать ожидания на управляемых блокировках» — разделы настройки и поиска причины: https://infoblog.mywebguide.ru/articles/page_375353.html
[6] 1: https://its.1c.ru/db/metod8dev/content/6005/hdoc
[7] 2: https://its.1c.ru/db/metod8dev/content/5809/hdoc
[8] 3: https://its.1c.ru/db/metod8dev/content/6006/hdoc
[9] 1: https://its.1c.ru/db/v8317doc/content/348/hdoc
[10] 2: https://its.1c.ru/db/metod8dev/content/5969/hdoc
[11] логика: http://www.braintools.ru/article/7640
[12] 1: https://its.1c.ru/db/metod8dev/content/2713/hdoc
[13] 1: https://its.1c.ru/db/updlib/content/15/hdoc
[14] поведение: http://www.braintools.ru/article/9372
[15] 1: https://its.1c.ru/db/updinfo/content/2257/hdoc
[16] обучение: http://www.braintools.ru/article/5125
[17] Источник: https://habr.com/ru/articles/1092738/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1092738
Нажмите здесь для печати.