Автоматический поиск документов из 1С:ДО
Контекстный RAG-ассистент над архивом 1С:Документооборот: точные факты из каталога, текст файлов из гибридного поиска, ответы со ссылками на источники и без выдумок.
О проекте
Обратились с запросом: дать сотрудникам возможность спрашивать по архиву 1С:Документооборот обычным языком. Какие файлы входят в карточку и какая редакция действующая, что менялось между редакциями, кто и с какими замечаниями согласовывал документ, что с ним связано и как ответить на замечание. Каждый ответ должен вести к источнику, а при отсутствии данных система обязана прямо об этом сказать.
Это AI/RAG-ассистент поверх боевой базы 1С:Документооборот КОРП 3.0. Каждую ночь система выгружает карточки, файлы, редакции и их тексты, визы, задачи согласования, переписку и связи документов через OData, складывает их в собственный каталог на PostgreSQL, индексирует текст в Qdrant и отвечает на вопросы через локальную LLM. Главный принцип: языковая модель не является источником фактов. Существует ли документ, какие у него файлы, сколько редакций у каждого файла и кто согласовал последним, определяет код точными запросами к каталогу, текст файлов приходит из гибридного поиска, а модель только формулирует ответ по пронумерованному контексту. Прямого доступа к базе 1С нет по условиям заказчика, поэтому выгрузка построена как отдельный отказоустойчивый конвейер для архива около 182 тысяч документов. Развёртывание on-prem: Docker Compose или Kubernetes, модели Qwen3.8-27B и BAAI/bge-m3 на сервере моделей в контуре, данные не покидают периметр.
Технологии
- Python
- FastAPI
- PostgreSQL
- Qdrant
- SQLAlchemy
- Alembic
- React
- TypeScript
- Vite
- React Flow
- Qwen3.8-27B
- BAAI/bge-m3
- fastembed
- Jina Reranker
- 1С OData
- APScheduler
- Prometheus
- Docker
- Kubernetes
Что разработано
- Бэкенд на FastAPI (Python 3.12) с асинхронным PostgreSQL (asyncpg, SQLAlchemy), миграциями Alembic и JWT-авторизацией
- OData-клиент к 1С:ДО КОРП 3.0: постраничное чтение, повторы, адаптивное уменьшение страницы при 5xx, чтение $metadata, поимённый выбор полей
- Потоковый конвейер выгрузки: скан ключей и DataVersion, индексы файлов, виз и связей, затем документы пачками по 500 с фиксацией каталога и индекса по каждой пачке
- Отдельный процесс-воркер с ночным инкрементом по расписанию (APScheduler) под Postgres advisory lock: ручной и плановый прогоны не накладываются
- Каталог со схемой «документ, файл, редакция файла»: у каждого файла своя нумерация редакций и своя действующая редакция, как в 1С
- Полнотекст редакций из регистра «ТекстыВерсийФайлов» (бинарь файла OData не отдаёт); дата регистрации и дата создания хранятся раздельно
- Диффы соседних редакций по каждому файлу: на вопрос «что изменилось» ответ строится по сравнению текстов, а не по служебному комментарию
- Маршрут согласования: визы, 9 видов бизнес-процессов и задачи исполнителей превращаются в шаги, резолюции и результаты в истории документа
- Переписка: входящие и исходящие письма становятся документами каталога со связями «переписка» и «ответ на письмо»
- Связи документов из регистра «СвязиОбъектов» с именем типа связи из 1С: в выдачу попадают доп. соглашения, претензии и акты к договору
- Переиндексация из каталога без обращения к 1С: пересборка поиска за полтора часа вместо одиннадцати часов полной выгрузки
- Индексация в Qdrant: dense-вектор bge-m3 и sparse-вектор BM25 у каждого фрагмента, payload-фильтры по виду документа, файлу, редакции и источнику
- Гибридный поиск: dense и BM25 в одном запросе, слияние RRF, reranking cross-encoder’ом jina-reranker-v2-base-multilingual
- Маршрутизатор источника данных: отдельный вызов LLM возвращает строгий JSON (postgres, qdrant, hybrid, clarify, none) и фильтры, а SQL строит код по белому списку полей
- Защита маршрутизатора: номера, имена и даты, которых нет в вопросе, отбрасываются; документ с номером всегда проверяется по каталогу
- Три сценария (документ и редакции, история согласования, черновик ответа на замечание) с автоопределением по тексту вопроса
- Диалоги на сервере: уточняющая реплика раскрывается в полный вопрос, номер карточки держится в контексте чата
- Очередь вопросов: в одном чате вопросы идут по порядку и дочитываются без открытой вкладки, разные чаты считаются параллельно
- Инструменты расчёта для модели (calculate, days_between): суммы, разницы и сроки между датами в ответе считает Python, а не LLM
- Проверки после генерации: перевод при уходе модели в иероглифы, повтор при ложном отказе, запасной ответ перечнем источников
- Роли и права: сценарии и виды документов задаются ролям из админки, фильтр работает в поиске, карточке, графе и по прямой ссылке
- Веб-интерфейс на React + TypeScript + Vite: чат со статусом запроса, источники под ответом, перечень найденных документов, копирование черновика
- Карточка документа: реквизиты, файлы и их редакции с действующей, согласования с цветом решений, комментарии, связанные документы
- Граф связей на React Flow: документ, редакции файлов, визы, комментарии и связанные документы
- Админ-панель: инструкция для ответов, роли и права, запуск выгрузки и переиндексации, расписание ночного прогона, журнал событий и журнал обращений
- Прогон выборки на сервере: по каждому документу задаются контрольные вопросы, ответы с источниками, вызовами расчёта и маршрутом сохраняются для оценки качества
- Наблюдаемость: метрики Prometheus, статус выгрузки и индекса по источникам фрагментов, журнал обращений с request_id, rate limiting
- Развёртывание: Docker Compose и Kubernetes-манифесты, миграции в initContainer, скрипты бэкапа и восстановления, 649 автотестов
Ключевые фичи
- Факты из базы, а не из модели: существование документа, состав файлов и число редакций определяет SQL-запрос к каталогу
- Ответ только по документам заказчика: если документа или текста файла нет, ассистент называет причину (скан, PDF без текстового слоя, текст не сохранён в 1С), а не сочиняет
- Ссылки на источники в каждом ответе: номер [1], [2] ведёт к фрагменту, рядом перечень найденных документов с пометкой, какие вошли в ответ
- Редакция принадлежит файлу: ответ идёт по файлам (файл, сколько у него редакций, какая действующая), как в самой 1С
- Гибрид смысла и реквизитов: BM25 ловит номера и фамилии, dense ловит формулировки по смыслу, RRF и reranker сводят их вместе
- Связи вместо совпадений: претензия или доп. соглашение находятся через регистр связей 1С, даже если номера договора в их тексте нет
- Счёт без ошибок: суммы редакций, разницы и сроки между датами считает код
- Единый чат с автомаршрутизацией: сценарий и источник данных определяются по вопросу, переключать режимы не нужно
- Полностью локальный контур: LLM, эмбеддинги, BM25 и reranker работают внутри периметра заказчика, без внешних API
- Работа без доступа к БД 1С: только OData-публикация, с обходом её ограничений
- Устойчивость к сбоям 1С: таймаут или 5xx на части сущностей не рушит прогон, недочитанное не пишется, прерванный прогон продолжается с пачки
- Ролевая видимость: закрытый роли вид документа не появится ни в поиске, ни в карточке, ни в графе
Решение задачи
Архив 1С:Документооборот стал источником, к которому сотрудники обращаются на естественном языке: юрист спрашивает про договор и получает состав файлов с действующими редакциями, изменения между редакциями, ход согласования, связанные документы и черновик ответа на замечание, со ссылками на источники вместо ручного обхода карточек в 1С.
Модель отделена от фактов: существование документа, файлы, редакции и согласующих определяет каталог, числа считает код, а при нехватке данных ассистент называет причину. Устойчивый конвейер выгрузки через OData держит архив около 182 тысяч документов актуальным по ночному расписанию без доступа к базе 1С.
Качество подтверждено прогоном на рабочем контуре: 2000 документов второго полугодия 2024 года (14 815 файлов, 31 604 редакции), 4000 вопросов о составе файлов и истории редакций, автоматическая сверка с эталоном из каталога и ручная проверка 600 пар редакций. Все основные метрики на уровне 95% и выше; единичные расхождения возникают только на шаге, где модель формулирует текст из уже верно подготовленных данных.
Метрики
Результаты
Синтетические данныеДанные на скриншотах вымышленные: реальные цифры, названия контрагентов и персональные данные заменены на синтетические.
Заказать похожий проект
Оставьте заявку, обсудим задачу и предложим решение под ваш бизнес.
Оставить заявку

















