Цифровая трансформация
и ИИ под ключ

Автоматизация процессов, корпоративные системы, частные языковые модели, импортозамещение. Разворачиваем в вашем контуре — данные и исходники остаются у вас.

12 лет в разработке·100+ проектов·100% исходного кода у заказчика

  • PythonМодели, разбор данных, конвейеры
  • GoШлюзы и обмены под нагрузкой
  • RustСборщики телеметрии, потоки
  • JavaУчётные и биллинговые системы
  • KotlinБэкенд и мобильные клиенты
  • TypeScriptКабинеты, витрины, админки
  • C#Промышленные АРМ и .NET-контуры
  • C++Зрение и обработка на месте
  • SwiftПриложения под iOS
  • PHPПорталы на существующем стеке
  • ScalaПотоковая обработка событий
  • 1С:ПредприятиеОбмены и доработки учёта
  • PostgreSQLОсновное хранилище
  • ClickHouseАналитика и события
  • TimescaleDBВременные ряды с оборудования
  • RedisКэш, очереди, сессии
  • OpenSearchПолнотекстовый поиск
  • pgvectorВекторный поиск по документам
  • MinIOОбъектное хранилище в контуре
  • KafkaШина событий
  • RabbitMQОчереди задач
  • NATSЛёгкий обмен между службами
  • gRPCСинхронные вызовы служб
  • OPC UAСъём данных со станков
  • Modbus TCPСтарые стойки и контроллеры
  • MQTTТелеметрия и датчики
  • vLLMИнференс языковых моделей
  • PyTorchОбучение моделей
  • ONNX RuntimeИнференс на своём железе
  • TensorRTУскорение на видеокартах
  • MLflowРеестр версий моделей
  • AirflowРасписания и конвейеры данных
  • dbtВитрины и слои данных
  • TesseractРаспознавание сканов
  • KubernetesРазвёртывание служб
  • DockerСборка и запуск
  • AnsibleРазвёртывание в закрытом контуре
  • Astra LinuxОтечественные ОС
  • KeycloakЕдиный вход и роли
  • PrometheusМетрики и пороги
  • GrafanaПанели наблюдения
  • GitLab CIСборка и прогоны проверок
  • Компьютерное зрение
  • Обработка естественного языка
  • Большие языковые модели
  • Поиск по документам
  • Агенты с действиями
  • Дообучение моделей
  • Инференс на месте
  • Векторные базы
  • Промышленная аналитика
  • Предиктивное обслуживание
  • Распознавание документов
  • Речевые интерфейсы
  • Временные ряды
  • Рекомендательные системы
  • Финтех и биллинг
  • Логистика и маршруты
  • Энергетика и сети
  • Госсектор и КИИ
  • Ритейл и склады
  • Медицина и лаборатории

Что мы делаем

Двенадцать направлений,
один центр ответственности

Работаем на стыке ИИ и прикладных задач: компьютерное зрение, обработка языка, поиск по документам, промышленная аналитика, учётные и производственные контуры. От оцифровки одного процесса до переноса всего стека — исходники и доступы остаются у вас.

Оставить заявку

Портфолио

Сдано и работает без нас

Назвать заказчиков не можем, договоры это запрещают. Зато можем показать, что у них изменилось в работе после сдачи и каким документом это проверяется. Крупным в карточке — то, что теперь происходит само, без человека.

МашиностроениеОбследование и дорожная карта

Проверяется: карта процессов и дорожная карта этапов

Обследование процессов перед внедрением ИИ

Задача, решение и что передали
Задача
Руководство требовало предложений по ИИ, а внутри спорили, с чего начинать: задачи были описаны словами «ускорить» и «разгрузить людей».
Решение
Разобрали процессы до шагов и данных и по каждому проверили, есть ли история, на которой можно измерить качество ответа. Часть задач после разбора закрылась обычным обменом данными, без модели.
Сдано 3
  • Карта процессов и данных
  • Перечень задач с оценкой применимости
  • Дорожная карта по этапам
Как делали
  1. Обследование процессов Прошли по цепочке от конструкторской подготовки до отгрузки: говорили с технологами, диспетчерами цеха, снабжением и ОТК, разбирали выгрузки из учётных систем. Каждую формулировку «ускорить» и «разгрузить людей» разложили до шага процесса, исполнителя и документа — маршрутной карты, спецификации, заявки.
  2. Архитектура разбора Решили описывать каждую задачу одинаковым паспортом: вход, шаг процесса, источник истории и признак правильного ответа. Задачи без сохранённой истории вынесли отдельно, а часть перевели в обычный обмен данными между системами — модель там была не нужна.
  3. Разработка карты Собрали карту процессов и данных, заполнили паспорта задач и по каждой проверили, есть ли история, на которой можно измерить качество ответа. Черновик перечня и дорожной карты прошли с владельцами процессов до того, как показывать руководству.
  4. Проверка выводов Повторили выгрузки и вернулись к исполнителям с готовой картой, чтобы сверить описанные шаги с тем, как работа идёт на самом деле. Провалом считали задачу, оставшуюся в перечне без выгрузки, на которой измеряется правильность ответа: применимость, обоснованную словами, в дорожную карту не пускали.
  5. Передача карты Передали карту процессов и данных, перечень задач с оценкой применимости и дорожную карту по этапам, разобрав их с руководством и владельцами процессов. Показали, как читать паспорт задачи, добавлять новые и переносить их между очередями.
Архитектура
Стенд обследования собран отдельно от боевых систем: выгрузки из учётных баз снимаются по ODBC в staging-схему PostgreSQL, откуда модели dbt раскладывают их в таблицы шагов процесса, участников и документов. Профилирование гоняется в DuckDB по файлам выгрузок — считаются доли пустых полей и распределения по всей истории, а колоночный движок читает только нужный столбец, тогда как строчная таблица поднимала бы запись целиком на каждый агрегат. Проверки полноты и связности оформлены наборами Great Expectations и прогоняются на каждой новой выгрузке, результаты выводятся в Metabase рядом с картой шагов. Стенд поднимается Docker Compose на отдельной машине: при её отказе теряется только копия выгрузки, повторный съём делается тем же скриптом с тем же срезом дат.
Стек
Python · pandas · PostgreSQL · DuckDB · ODBC · Docker Compose · dbt · Great Expectations · Metabase
Оптовая торговляАвтоматизация и AI-агенты

Реквизиты со скана заводятся в учётную систему сами, вручную закрываются только несошедшиеся строки

Проверяется: очередь ручной проверки и журнал операций

Агент, заносящий первичные документы в учётную систему

Задача, решение и что передали
Задача
Накладные, счета и акты приходили сканами, сотрудники переносили реквизиты в 1С руками, а опечатки находились уже в отчётности.
Решение
Развернули распознавание внутри контура. Агент сверяет контрагента по ИНН и номенклатуру по таблице соответствий, проверяет арифметику и заводит документ черновиком, спорные поля отдаёт оператору.
Сдано 4
  • Исходный код агента
  • Правила разбора под формы заказчика
  • Очередь ручной проверки
  • Журнал операций
Как делали
  1. Разбор первички Собрали архив сканов накладных, счетов и актов и разложили по формам поставщиков, отметив, где реквизиты расположены нестандартно. С бухгалтерией разобрали, на каких полях возникали опечатки, доходившие до отчётности, и выгрузили справочники контрагентов и номенклатуры.
  2. Архитектура агента Распознавание разместили внутри контура, наружу сканы не уходят; агент отделён от учётной системы и общается с ней через HTTP-сервис, документы ждут разбора в очереди. Правила сверки контрагента по ИНН и номенклатуры по таблице соответствий вынесли из кода, а от автопроведения отказались — документ создаётся только черновиком.
  3. Сборка по слоям Сначала подняли разбор форм и заполнение реквизитов, затем проверку арифметики по строкам и итогу, затем очередь ручной проверки и журнал операций. Всё это гоняли на стенде с копией базы 1С, прежде чем подключать боевую.
  4. Проверка на архиве Прогнали архив сканов и сверили заполненные поля с документами, заведёнными бухгалтерами вручную. Провалом считали не только неверный реквизит, но и уверенно разобранное спорное поле, не ушедшее оператору; черновик с несходящейся суммой строк и итога — причина не принять работу.
  5. Передача бухгалтерии Передали исходный код агента, правила разбора под формы заказчика, очередь ручной проверки и журнал операций. Бухгалтеров научили работать с очередью, а администратора — добавлять форму нового поставщика и пополнять таблицу соответствий номенклатуры.
Архитектура
Приёмник на FastAPI кладёт скан в MinIO и ставит задачу в RabbitMQ, распознавание и разбор идут отдельными воркерами: OCR занимает узел надолго, и на прямом вызове он держал бы HTTP-соединение, а очередь ещё и переживает перезапуск воркера. Разобранные реквизиты попадают в PostgreSQL черновиком со статусом, сверка контрагента по ИНН и номенклатуры по таблице соответствий выполняется там же запросами к справочникам, арифметика документа пересчитывается перед записью. В 1С документ уходит через HTTP-сервис с идемпотентным ключом из хеша файла и номера документа — повтор после таймаута не создаёт второй черновик. Поля ниже порога уверенности в 1С не отправляются, а встают в очередь оператора со ссылкой на исходный скан; каждое действие агента пишется в журнал операций, узлы подняты контейнерами.
Стек
Python · FastAPI · PostgreSQL · MinIO · RabbitMQ · Docker · PaddleOCR · 1С HTTP-сервис · Prometheus
Финансовый секторЧастные LLM в контуре

Ответ по внутренним регламентам собирается поиском внутри контура: перелистывать письма регулятора уже незачем

Проверяется: расчёт железа и регламент эксплуатации

Языковая модель в изолированном контуре

Задача, решение и что передали
Задача
Сотрудники искали ответы по внутренним регламентам и письмам регулятора вручную, а выносить эти документы во внешний ИИ-сервис было нельзя.
Решение
Посчитали конфигурацию по памяти видеокарт и числу одновременных запросов, развернули инференс и поиск внутри контура. Права применяются на этапе отбора фрагментов, до попадания текста в контекст модели.
Сдано 4
  • Развёрнутая система
  • Расчёт железа
  • Регламент эксплуатации и переноса моделей
  • Обученные администраторы
Как делали
  1. Обследование контура Определили состав базы — внутренние регламенты, распоряжения, письма регулятора — и с подразделением безопасности зафиксировали, что за пределы контура не уходит ничего. Собрали профиль обращений: какие подразделения спрашивают, какой длины документы и сколько запросов ожидается одновременно.
  2. Расчёт конфигурации Конфигурацию считали от памяти видеокарт и числа одновременных запросов — отсюда размер модели, длина контекста и число параллельных сессий. Поиск и инференс развели по разным службам, а права применили на этапе отбора фрагментов, до того как текст попадёт в контекст модели, а не фильтрацией готового ответа.
  3. Развёртывание в контуре Подняли инференс на GPU-сервере заказчика, затем индекс с гибридным поиском по регламентам и письмам, затем слой прав и веб-интерфейс. На стенде смотрели поведение при одновременных обращениях и при выгрузке моделей из памяти.
  4. Проверка доступа Прогнали вопросы, составленные методологами, и отдельно проверку прав: под учётной записью без доступа к документу его фрагмент не должен появиться ни в ответе, ни в ссылках. Единственное такое попадание считалось провалом и возвращало систему на доработку; ответ без ссылки на пункт регламента тоже не приняли бы.
  5. Обучение администраторов Передали развёрнутую систему, расчёт железа и регламент эксплуатации и переноса моделей. Администраторы научились заводить новую модель, пересобирать индекс и разбирать журнал обращений сами.
Архитектура
Контур собран из трёх служб: шлюз на FastAPI, поисковый узел и инференс на vLLM, поднятый на GPU-сервере заказчика. Права применяет поисковый узел — фильтр по группам пользователя из LDAP уходит прямо в запрос к OpenSearch и pgvector, поэтому закрытый фрагмент не доходит до сборки контекста, а не вырезается из готового ответа. Запросы к картам выстроены в Redis Streams с ограничением числа одновременных генераций: прямая раздача на карту при всплеске упирается в память под KV-кеш, а очередь удерживает лишние запросы вместо отказа. Конфигурация памяти под модель и предельная длина контекста зафиксированы в compose-файле; при перезапуске узла очередь сохраняется, незавершённые запросы берутся заново, метаданные документов и журнал обращений лежат в PostgreSQL.
Стек
Python · FastAPI · PostgreSQL · OpenSearch · Redis Streams · Docker Compose · vLLM · pgvector · LDAP
РозницаИнтеграции и сопровождение

Расхождение по строке видно в сверке сразу, до ручного разбора выгрузок дело не доходит

Проверяется: журнал операций и схема соответствия полей

Обмен 1С с сайтом и торговыми площадками

Задача, решение и что передали
Задача
Остатки, цены и заказы жили в 1С, на сайте и на площадках одновременно и расходились, а спорные строки разбирали по выгрузке в Excel.
Решение
Зафиксировали, какая система владеет каждым полем. Собрали передачу через очередь с повтором при отказе и ключом идемпотентности на заказ, добавили сверочную витрину и оповещение при неприменившейся выгрузке.
Сдано 4
  • Исходники обмена
  • Схема соответствия полей
  • Журнал операций
  • Инструкция администратору
Как делали
  1. Сверка систем Сопоставили карточку товара в 1С, на сайте и в кабинетах площадок: где живёт цена, где остаток, где статус заказа. Подняли те самые Excel-выгрузки, по которым разбирали спорные строки, и выделили расхождения, которые повторяются из раза в раз.
  2. Владение полями Зафиксировали, какая система владеет каждым полем: цена и остаток идут из 1С, статус заказа приходит с площадки. Прямые вызовы между системами заменили очередью с повтором при отказе и ключом идемпотентности на заказ, от ночной полной выгрузки отказались в пользу событий с периодической сверкой.
  3. Сборка обмена Собрали адаптеры к 1С и к API площадок, затем очередь и обработчики, затем сверочную витрину и оповещение о неприменившейся выгрузке. На стенде гоняли обмен на копии номенклатуры, намеренно обрывая ответы площадки.
  4. Проверка повторов Повторяли одну и ту же выгрузку и один и тот же заказ, проверяя, что дубля не возникает, и сверяли остатки после схождения очереди. Провалом считали расхождение остатка между 1С и площадкой при пустой очереди и задвоенный заказ при повторной отправке.
  5. Передача администратору Передали исходники обмена, схему соответствия полей, журнал операций и инструкцию администратору. Показали, как подключить новую площадку, как читать сверочную витрину и что делать по оповещению о неприменившейся выгрузке.
Архитектура
Обмен собран как набор адаптеров на Go за общей шиной: коннектор 1С ходит по OData, коннекторы сайта и площадок — по их HTTP-контрактам, между ними стоит NATS JetStream. Прямой вызов из 1С в площадку заменён публикацией события, потому что площадка отвечает не всегда и её недоступность иначе останавливала бы проведение документа — сообщение лежит в потоке и повторяется с возрастающей паузой. Владение полем зафиксировано таблицей в PostgreSQL: остатки и цены пишет только 1С, статус заказа — только площадка, встречная запись отбрасывается на входе адаптера. Заказ проводится по идемпотентному ключу «площадка плюс внешний номер», уникальный индекс не даёт повтору создать дубль; справочники кешируются в Redis, сверочная витрина считает расхождения и шлёт оповещение о неприменившейся выгрузке, метрики очередей уходят в Prometheus и Grafana.
Стек
Go · chi · PostgreSQL · Redis · NATS JetStream · Docker Compose · 1С OData · Prometheus · Grafana
ПромышленностьРазработка AI-решений

Действующая редакция находится по децимальному номеру, а не выясняется обходом папок, архива и шкафов

Проверяется: словари обозначений и правила разбора

Поиск по конструкторской и технологической документации

Задача, решение и что передали
Задача
Чертежи, паспорта оборудования и регламенты лежали в папках, архиве СЭД и в шкафах, а какая редакция действующая — знали два человека.
Решение
Собрали конвейер: распознавание сканов, извлечение основной надписи и спецификации в поля, нормализация обозначений, привязка извещений об изменениях. Поиск точный по децимальному номеру и смысловой по тексту.
Сдано 4
  • Поисковый сервис в контуре
  • Правила разбора и словари обозначений
  • Конвейер дозагрузки
  • Исходники
Как делали
  1. Обход хранилищ Прошли по местам хранения — сетевые папки, архив СЭД, бумажные шкафы — и описали, что где лежит. С архивариусом и конструкторами разобрали, как обозначается редакция, как оформляются извещения об изменениях и по каким признакам документ ищут на практике.
  2. Архитектура конвейера Конвейер разделили на распознавание, извлечение полей и индекс: основную надпись и спецификацию решили класть в поля, а не в общий текст, чтобы поиск по децимальному номеру был точным. Смысловой поиск по тексту вынесли отдельно, а извещения привязали к документу так, чтобы они меняли признак действующей редакции.
  3. Сборка поиска Сначала подняли распознавание сканов и извлечение основной надписи, затем нормализацию обозначений по словарям, затем привязку извещений и объединение точного и смыслового поиска. Конвейер дозагрузки собирали и обкатывали на оборудовании заказчика.
  4. Проверка выдачи Искали документы по списку, собранному конструкторами, — и по децимальному номеру, и по описанию узла. Провалом считали выдачу отменённой редакции выше действующей и ненайденный документ при точном обозначении, даже если он находился по тексту.
  5. Передача архиву Передали поисковый сервис в контуре, правила разбора, словари обозначений, конвейер дозагрузки и исходники. Архив научили сам класть новые сканы и извещения в конвейер и проверять, что редакция сменилась.
Архитектура
Конвейер разбит на узлы: приёмник новых файлов, распознаватель на OpenCV и Tesseract, извлекатель основной надписи и спецификации, индексатор. Узлы связаны RabbitMQ, а синхронные обращения идут по gRPC; распознавание вынесено отдельным сервисом с собственным пулом процессов, потому что скан большого формата занимает узел на минуты и в общем потоке блокировал бы дозагрузку остальных документов. Поля основной надписи, децимальные номера и связи с извещениями об изменениях лежат в PostgreSQL, векторы описаний — в pgvector рядом, чтобы точный поиск по обозначению и смысловой по тексту собирались одним запросом без второго хранилища и без рассинхронизации индексов. Модели подняты через ONNX Runtime на оборудовании заказчика; при падении узла сообщение возвращается в очередь и документ переиндексируется целиком, частичный разбор в индекс не попадает.
Стек
C++ · gRPC · PostgreSQL · pgvector · RabbitMQ · Docker · OpenCV · Tesseract · ONNX Runtime
ПроизводствоКорпоративные системы

Проверяется: инструкция по подключению оборудования

Съём данных со станков и сменный отчёт

Задача, решение и что передали
Задача
Выработку и простои считали в конце смены по бумажным журналам, причины восстанавливали по памяти, сводку собирали руками.
Решение
Сняли сигналы через OPC UA и свели в модель смен, заказов и причин простоя. Мастер фиксирует причину на месте, сменный отчёт собирается сам, справочники и права разделены по цехам.
Сдано 4
  • Развёрнутая система
  • Схема данных
  • Исходный код
  • Инструкция по подключению оборудования
Как делали
  1. Обход парка Обошли станки и записали, что каждый отдаёт по OPC UA, а что не отдаёт вовсе и требует ручного ввода. С мастерами и нормировщиками разобрали бумажные журналы смен и выписали список причин простоя, каким он существовал на словах.
  2. Модель смены Сигналы решили не хранить как есть, а сводить в модель смен, заказов и причин простоя; справочники и права развели по цехам. Ручной ввод оставили только там, где сигнала нет: причину фиксирует мастер на месте, а не восстанавливает по памяти в конце смены.
  3. Сборка съёма Подняли сбор по OPC UA и запись в базу, затем модель смен и заказов, затем интерфейс мастера у линии и автоматическую сборку сменного отчёта. На стенде подключали станки по одному, начиная с тех, что отдают состояние без доработок.
  4. Сверка со сменой Сменный отчёт сверяли с бумажным журналом и показаниями станка по одним и тем же сменам. Провалом считали простой, потерянный при обрыве связи с оборудованием, и смену, где сумма работы и простоев не сходится с её длительностью.
  5. Передача цехам Передали развёрнутую систему, схему данных, исходный код и инструкцию по подключению оборудования. Мастера ведут справочник причин, а служба АСУ подключает новые станки без нашего участия.
Архитектура
На каждом участке стоит сборщик на Rust: он держит сессии OPC UA со станками, старые стойки опрашивает по Modbus TCP, приводит теги к общей модели сигнала и публикует их в NATS. Между сборщиком и хранилищем поставлена очередь, потому что обрыв связи до серверной не должен ронять опрос стойки — сборщик копит отсчёты локально и досылает после восстановления. Сырые отсчёты пишутся в гипертаблицу TimescaleDB, а смены, заказы и причины простоя — в обычные таблицы PostgreSQL рядом: временной ряд режется по времени и сворачивается окнами, справочная часть меняется редко и живёт на внешних ключах. Панель мастера на Axum показывает простои за смену и принимает причину на месте, сменный отчёт собирается по расписанию из уже уложенных агрегатов, справочники и права разделены по цехам, состояние линий выведено в Grafana.
Стек
Rust · Axum · PostgreSQL · TimescaleDB · NATS · Docker · OPC UA · Modbus TCP · Grafana
БанкЗащита и аудит ИИ

Проверяется: набор проверок и регламент повторной проверки

Проверка ИИ-ассистента перед допуском в рабочую сеть

Задача, решение и что передали
Задача
Служба безопасности не пропускала готового ассистента в промышленную сеть: критериев приёмки не было, спор шёл о впечатлениях.
Решение
Составили набор проверок на данных заказчика: подмена инструкций, выдача фрагментов вне прав доступа, поведение на вопросах без ответа в базе. Замерили и зафиксировали пороги допуска.
Сдано 3
  • Набор проверок и протокол замеров
  • Пороги допуска
  • Регламент повторной проверки
Как делали
  1. Разбор возражений С безопасностью и владельцем ассистента разобрали, что именно мешает допуску: какие документы он видит, к каким системам просится и на каких ответах шёл спор. Собрали на данных банка те вопросы, вокруг которых обсуждение держалось на впечатлениях.
  2. Критерии допуска Договорились, что допуск описывается набором проверок с порогами, а не мнением: подмена инструкций, выдача фрагментов вне прав доступа, поведение на вопросах, ответа на которые в базе нет. Каждая проверка сделана воспроизводимой — сохраняются вход, параметры генерации и ответ.
  3. Сборка проверок Собрали наборы сценариев на данных заказчика, подняли прогон с журналированием и оформили протокол замеров. Сначала гоняли на копии базы, затем на боевом индексе под учётными записями разных ролей.
  4. Прогон и пороги Прогнали набор целиком и зафиксировали пороги допуска в протоколе. Провалом считали любую выдачу фрагмента, к которому у учётной записи нет прав, и ответ на вопрос без основания в базе, поданный как факт вместо отказа.
  5. Передача безопасности Передали набор проверок, протокол замеров, пороги допуска и регламент повторной проверки. Служба безопасности проводит прогон сама при смене модели, шаблона промпта или состава базы.
Архитектура
Стенд стоит отдельным контуром: раннер на pytest обращается к ассистенту по его же HTTP-контракту, наборы проверок лежат файлами и версионируются вместе с кодом. Прогон разложен на задачи Celery, потому что каждый сценарий — это ожидание генерации, и последовательный запуск растягивал бы приёмку; вердикты сходятся в PostgreSQL, полные входы и ответы кладутся в MinIO, чтобы срабатывание воспроизводилось дословно, а не по одной строке отчёта. Проверки прав идут от тестовых учётных записей в Keycloak с разными группами: один и тот же вопрос задаётся от пользователя с доступом и без, сравниваются наборы выданных фрагментов. Прогон вызывается из GitLab CI на обновление модели или шаблона промпта, пороги допуска вынесены в конфигурацию, отчёт собирается Allure, стенд поднимается Docker Compose из того же описания, что и проверяемый контур.
Стек
Python · pytest · PostgreSQL · MinIO · Celery · Docker Compose · GitLab CI · Allure · Keycloak
ГоссекторМиграция на СУБД и Linux

Перенос сверен построчно и по контрольным суммам, а откат отрепетирован до дня переключения

Проверяется: реестр зависимостей и протокол сверки

Перенос учётной системы с MS SQL на PostgreSQL

Задача, решение и что передали
Задача
Дата перехода была задана нормативно, а перечня того, что держится на MS SQL, внутри не было: процедуры, планировщик, отчётность и приложения без исходников.
Решение
Сняли фактические запросы трассировкой, переписали несовместимый код, перевели задания и отчётность. Сверили строки и контрольные суммы, отдельно проверили порядок сортировки, отрепетировали откат.
Сдано 3
  • Реестр зависимостей
  • Перенесённая база с протоколом сверки
  • План перехода и процедура возврата
Как делали
  1. Трассировка запросов Перечня зависимостей внутри не было, поэтому фактические обращения к MS SQL сняли трассировкой на работающей системе — так нашли и приложения, у которых нет исходников. Отдельно выписали хранимые процедуры, задания планировщика и отчётные формы.
  2. Стенд-двойник Решили переносить по собранному реестру зависимостей, а не по документации, и подняли стенд-двойник, чтобы репетировать переход и возврат столько раз, сколько потребуется. Порядок сортировки вынесли в отдельный вопрос: правила сравнения строк задали явно, не полагаясь на настройки по умолчанию.
  3. Перенос кода Перенесли схему и данные, переписали несовместимый код процедур, перевели задания планировщика и отчётность на PostgreSQL. Приложения без исходников подключали через совместимый слой доступа и по трассировке убеждались, что уходят те же запросы.
  4. Сверка и откат Сверили строки и контрольные суммы по таблицам, отдельно прогнали сортировку и отчётные формы, отрепетировали возврат на исходную базу. Провалом считали расхождение контрольной суммы хотя бы по одной таблице и отчёт, где строки встали в другом порядке; без успешной репетиции отката переход не согласовали бы.
  5. Передача администраторам Передали реестр зависимостей, перенесённую базу с протоколом сверки, план перехода и процедуру возврата. Администраторы прошли переход и откат на стенде-двойнике своими руками, прежде чем работать с боевым контуром.
Архитектура
Реестр зависимостей собран не из документации, а из трассировки: сборщик на Kotlin читает поток фактических запросов с боевого MS SQL Server и раскладывает вызовы по объектам, приложениям и учётным записям в PostgreSQL. Схема и данные переносятся pgloader, дальнейшие изменения структуры идут только миграциями Liquibase, потому что часть приложений поставляется без исходников и правки руками на стенде терялись бы при следующем накате. Сверка построчная: служба на Ktor читает обе базы по JDBC пачками по ключу и сравнивает контрольные суммы полей, порядок сортировки проверяется отдельно на ICU-коллациях — выборки с ORDER BY по русским строкам расходились с прежним сервером. Стенд-двойник разворачивается плейбуками Ansible из того же описания, что и целевой контур, поэтому репетиция перехода и процедура возврата выполняются одними и теми же шагами.
Стек
Kotlin · Ktor · PostgreSQL · MS SQL Server · JDBC · Ansible · Liquibase · pgloader · ICU-коллации
Разработчик ПОПортирование под доверенные ОС

Проверяется: воспроизводимая сборка и протоколы проверок

Портирование прикладного продукта под отечественную ОС

Задача, решение и что передали
Задача
Продукт работал на Windows и зависел от библиотек, которых нет в отечественных дистрибутивах, а держаться нужно было в реестре российского ПО.
Решение
Разобрали дерево зависимостей, заменили несовместимые компоненты, перенесли сборку на Linux и собрали пакеты под целевые дистрибутивы с функциональными проверками на каждом.
Сдано 4
  • Собранные пакеты
  • Воспроизводимая сборка
  • Протоколы проверок
  • Комплект документации
Как делали
  1. Дерево зависимостей Разобрали дерево зависимостей продукта и отметили библиотеки Windows, у которых нет пары в отечественных дистрибутивах. Сверились с требованиями к включению в реестр российского ПО, чтобы понимать, что должно быть доказано на выходе.
  2. Выбор замен Несовместимые компоненты заменили на те, что есть в репозиториях целевых дистрибутивов, вместо сборки из исходников на стороне заказчика. Сборку перенесли на Linux и сделали воспроизводимой с зафиксированными версиями, чтобы пакет собирался одинаково у нас и у заказчика.
  3. Сборка пакетов Сначала собрали продукт под один целевой дистрибутив и прошли функциональные проверки, затем добавили второй и развели различия в пакетировании. Пакеты собирали с зависимостями из репозитория каждого дистрибутива.
  4. Проверка установки Ставили пакеты на чистые системы каждого дистрибутива и проходили функциональные сценарии продукта. Провалом считали установку, потребовавшую ручной доустановки библиотек, и расхождение поведения между дистрибутивами; сборку не приняли бы, если бы она не повторялась при повторном запуске.
  5. Передача сборки Передали собранные пакеты, воспроизводимую сборку, протоколы проверок и комплект документации. Команда разработчика выпускает следующую версию под оба дистрибутива своими силами.
Архитектура
Продукт разложили по границам: серверная часть на Go с HTTP-интерфейсом на chi, локальный агент со встроенной SQLite, внутренние вызовы по gRPC. Нативные зависимости, тянувшие Windows-библиотеки, заменены реализациями на чистом Go — сборка перестала требовать cgo, поэтому один исходник собирается под каждый целевой дистрибутив без набора кросс-компиляторов на агенте. Прикладные данные остаются в PostgreSQL, пути к конфигурации и каталогам приведены к принятой в дистрибутивах раскладке, установка и обновление идут пакетами deb и rpm вместо собственного инсталлятора. Конвейер GitLab CI собирает пакеты для Astra Linux и РЕД ОС и на каждой ОС прогоняет функциональные проверки в чистой виртуальной машине, поэтому расхождение между дистрибутивами видно до выпуска, а сборка повторяется из зафиксированных версий зависимостей.
Стек
Go · chi · PostgreSQL · SQLite · gRPC · GitLab CI · Astra Linux · РЕД ОС · deb/rpm
ПромышленностьВывод пилота в продуктив

Качество меряется на постоянном наборе задач, и выход в продуктив опирается на письменный критерий

Проверяется: эталонный набор задач и протокол замера

Разбор ИИ-пилота, застрявшего в демонстрации

Задача, решение и что передали
Задача
Пилот показали, эффект признали, и полгода он жил в демонстрационном режиме: качество ни разу не мерили на общем наборе задач.
Решение
Собрали эталонный набор задач с ожидаемыми ответами и замерили то, что было. Разложили ошибки по корзинам: данные, промпты и модель, процесс. Достроили конвейер данных, журналирование и откат.
Сдано 4
  • Набор тестов и протокол замера
  • Письменный критерий приёмки
  • Реестр разрывов
  • Обвязка эксплуатации
Как делали
  1. Разбор пилота Подняли, что показывали на демонстрации и на каких примерах, поговорили с теми, кто пилот собирал, и с теми, кто должен им пользоваться. Выяснилось, что общего набора задач нет и мерить качество не на чем — отсюда и спор об эффекте.
  2. Критерий приёмки Первым решением стали письменный критерий приёмки и эталонный набор задач с ожидаемыми ответами. Ошибки договорились раскладывать по корзинам — данные, промпты и модель, процесс, — а версии промптов вынесли отдельно от кода, чтобы откат не требовал пересборки.
  3. Достройка обвязки Собрали эталонный набор и замерили то, что уже было, затем достроили конвейер данных, журналирование каждого вызова и откат на предыдущую версию. Правки вносили по корзинам и после каждой прогоняли набор заново.
  4. Замер на наборе Мерили только на общем эталонном наборе, а не на удачных примерах из демонстрации. Провалом считали правку, которая улучшает показ и ухудшает результат на наборе, и ответ, который нельзя восстановить по журналу.
  5. Передача команде Передали набор тестов и протокол замера, письменный критерий приёмки, реестр разрывов и обвязку эксплуатации. Команда заказчика сама пополняет набор задач и прогоняет его перед каждой выкаткой.
Архитектура
Вокруг существующего пилота достроены три части: конвейер данных в Airflow, сервис замера на FastAPI и хранилище прогонов. Эталонный набор задач с ожидаемыми ответами лежит в PostgreSQL, входные документы и полные ответы модели — в MinIO, версия промпта и параметры генерации привязаны к прогону через MLflow, потому что без этой привязки нельзя сказать, изменилось качество от данных или от правки шаблона. Запросы к модели идут через очередь в Redis с ограничением параллельности: пилот делит карту с другими задачами, и прямой залп на инференс выбивал его по памяти. Ошибки помечаются на записях прогона по корзинам — данные, промпт и модель, процесс, — метрики выводятся в Grafana, откат на предыдущий шаблон делается сменой версии в реестре без пересборки образа; узлы подняты контейнерами.
Стек
Python · FastAPI · PostgreSQL · MinIO · Redis · Docker · Airflow · MLflow · Grafana
БанкОбследование и дорожная карта

Проверяется: карта сценариев и перечень блокеров

Карта сценариев ИИ по потоку клиентских обращений

Задача, решение и что передали
Задача
Обращения приходили в почту, чат и на телефон, единой темы у них не было, а решения об автоматизации принимались по ощущениям руководителей групп.
Решение
Выгрузили обращения за сопоставимый период из почтового архива, чата и карточек CRM, привели к одному формату и разметили выборку вручную вместе с операторами. Построили черновую таксономию тем и для каждой темы описали, чем обращение заканчивается: ответом по регламенту, запросом в смежную систему или ручным разбором. Отдельно зафиксировали, где сценарий упирается не в модель, а в отсутствие API у мастер-системы и в права доступа оператора.
Сдано 4
  • Таксономия тем
  • Размеченная выборка
  • Карта сценариев с оценкой готовности данных и интеграций
  • Перечень блокеров по смежным системам
Как делали
  1. Выгрузка обращений Выгрузили обращения за сопоставимый период из почтового архива, чата и карточек CRM и привели к одному формату. Разметили выборку вручную вместе с операторами и услышали, чем обращение заканчивается на деле, а не по описанию процесса.
  2. Таксономия и исходы Построили черновую таксономию тем и для каждой описали исход: ответ по регламенту, запрос в смежную систему или ручной разбор. Отдельно решили оценивать не только данные, но и доступность мастер-системы — где нет API и не хватает прав оператора, сценарий упирается не в модель.
  3. Сборка карты Собрали сведение трёх каналов в общий формат, разметочный контур для операторов и группировку близких обращений. На этой основе достроили карту сценариев с оценкой готовности данных и интеграций и перечень блокеров по смежным системам.
  4. Перепроверка разметки Перепроверили таксономию на новой порции обращений и дали операторам разметить её заново, не показывая прежние решения. Провалом считали тему, в которую разные операторы раскладывают одни и те же обращения по-разному, и сценарий, попавший в карту без подтверждённого способа получить данные из мастер-системы.
  5. Передача руководителям Передали таксономию, размеченную выборку, карту сценариев и перечень блокеров по смежным системам. Руководители групп ведут карту дальше и добавляют темы по той же разметочной процедуре.
Архитектура
Обращения из почтового архива по IMAP, выгрузки чата и карточки CRM приводятся загрузчиком на C++ к одной записи: канал, время, текст, автор, исход. Тексты и производные признаки лежат в ClickHouse, потому что разбор идёт агрегатами по темам и каналам за длинный период и упирается в чтение отдельных колонок, а разметка и версии таксономии живут в PostgreSQL, где нужны обновления по одной строке и внешние ключи. Эмбеддинги считает отдельный сервис на ONNX Runtime, вызываемый по gRPC, соседей для черновой группировки ищет Faiss — модель вынесена в свой процесс, поэтому загрузчик не тащит веса и модель меняется без пересборки конвейера. Операторы размечают выборку в настольном инструменте на Qt, который читает пачки из ClickHouse и пишет решения в PostgreSQL; узлы подняты контейнерами, повторный прогон загрузки идемпотентен по идентификатору обращения.
Стек
C++ · Qt · ClickHouse · PostgreSQL · gRPC · Docker · ONNX Runtime · Faiss · IMAP
БанкМиграция на СУБД и Linux

Проверяется: плейбуки развёртывания и инструкции по откату

Перенос прикладных сервисов с Windows Server на Linux

Задача, решение и что передали
Задача
Внутренние сервисы работали на Windows Server — IIS, задания планировщика, файловые шары SMB и доменная аутентификация, — а обновление шло ручными операциями на каждом узле.
Решение
Приложения на .NET пересобрали под Linux и упаковали в контейнеры, IIS заменили на nginx с systemd-юнитами, задания планировщика перевели на таймеры, доменную аутентификацию оставили на Kerberos через keytab с автоматическим обновлением билетов. Файловые шары вынесли в объектное хранилище с S3-совместимым интерфейсом, пути в коде заменили на клиента хранилища, для унаследованных интеграций оставили шлюз с ограниченным SMB-доступом. Развёртывание описали в Ansible, состояние узлов и сервисов вывели в общий мониторинг.
Сдано 4
  • Передали образы сервисов
  • Плейбуки развёртывания
  • Схему аутентификации и доступа к хранилищу
  • Инструкции по переключению и откату
Как делали
  1. Опись Windows-обвязки Переписали, что держит внутренние сервисы на Windows Server: сайты в IIS, задания планировщика, файловые шары SMB, доменная аутентификация. Посмотрели, какими ручными операциями идёт обновление на каждом узле и какие интеграции ходят в шары напрямую.
  2. Замены и хранилище Приложения на .NET решили пересобрать под Linux и упаковать в контейнеры, IIS заменить на nginx с systemd-юнитами, задания планировщика — на таймеры, а доменную аутентификацию оставить на Kerberos через keytab с автообновлением билетов, чтобы не трогать доменную модель. Файловые шары вынесли в объектное хранилище с S3-совместимым интерфейсом, для унаследованных интеграций оставили шлюз с ограниченным SMB-доступом.
  3. Пересборка сервисов Пересобрали и контейнеризовали сервисы, перевели задания на таймеры, заменили пути в коде на клиента хранилища. Развёртывание описали в Ansible, состояние узлов и сервисов вывели в общий мониторинг.
  4. Стенд с обрывами Гоняли сервисы на стенде под доменными учётными записями, роняя билеты Kerberos и прогоняя унаследованные интеграции через SMB-шлюз. Провалом считали отказ аутентификации после истечения билета без автоматического обновления, недоступность файла для унаследованной интеграции после переноса в объектное хранилище и узел, состояния которого не видно в мониторинге.
  5. Передача сопровождению Передали образы сервисов, плейбуки развёртывания, схему аутентификации и доступа к хранилищу, инструкции по переключению и откату. Сопровождение раскатывает обновление плейбуком и возвращает прежнюю версию само.
Архитектура
Сервисы разобрали по узлам: HTTP-фронт на nginx вместо IIS, прикладные службы в контейнерах под systemd-юнитами, новые и переписанные части — на Swift с Vapor, остальные пересобраны из .NET под Linux. Файловые шары SMB заменены объектным хранилищем MinIO с доступом по S3 API, пути в коде уступили место клиенту хранилища: примонтированная шара привязывала службу к конкретному узлу и к доменному монтированию, из-за чего перезапуск на другом узле требовал ручных операций. Доменная аутентификация осталась на Kerberos — служба ходит с keytab, билет обновляется таймером, поэтому переезд не потребовал менять модель доступа в смежных системах; прикладное состояние лежит в PostgreSQL, локального состояния на узлах нет. Задания планировщика Windows переведены на systemd-таймеры, развёртывание описано плейбуками Ansible, для унаследованных интеграций оставлен шлюз с ограниченным SMB-доступом.
Стек
Swift · Vapor · PostgreSQL · MinIO · S3 API · Docker · Ansible · nginx · Kerberos
Всё портфолио — 312 работ с фильтром по отрасли и технологии
Разработка

Что разрабатываем на заказ: ИИ, веб-сервисы, SaaS

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

Услуга

Разработка ИИ на заказ

Нейросети, языковые модели и машинное обучение под вашу задачу, с проверкой качества на ваших данных.

  • Поиск по документам
  • Агенты и ассистенты
  • Прогноз и зрение
Подробнее →
Услуга

Разработка LLM-приложений

ИИ-продукты и функции в вашем приложении: поиск по базе знаний, агенты, программный интерфейс.

  • RAG и агенты
  • Оценка качества
  • Контроль стоимости
Подробнее →
Услуга

Разработка ML-моделей

Прогноз спроса, классификация, поиск аномалий: модель, которую принимают по выборке, а не по красивой цифре.

  • Проверка по времени
  • Без утечки данных
  • Мониторинг после запуска
Подробнее →
Услуга

Разработка веб-сервисов

Порталы, внутренние сервисы и веб-приложения с бизнес-логикой, правами и обменом с 1С.

  • Порталы и сервисы
  • Роли и журнал
  • Интеграции
Подробнее →
Услуга

Разработка SaaS-платформы

Ядро платформы с подписками, ролями и разделением данных клиентов: от обследования до MVP.

  • Мультиарендность
  • Тарифы и счета
  • MVP за 2–3 месяца
Подробнее →
Услуга

Разработка API и бэкенда

Серверная часть и интеграционные сервисы: документированный API, повторы запросов, журнал.

  • REST и вебхуки
  • Версии и ошибки
  • Приёмка под нагрузкой
Подробнее →
Услуга

Разработка CRM

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

  • Своя или готовая
  • Миграция данных
  • Обмен с 1С
Подробнее →
Услуга

Личный кабинет

Кабинеты клиентов, партнёров и поставщиков с данными из 1С и ролевой моделью.

  • Заказы и счета
  • Цены и остатки
  • Вход и безопасность
Подробнее →

Расскажите, что нужно построить

Разберём задачу на созвоне за сорок минут: назовём объём работ, ограничения вашего контура и числа, по которым вы будете принимать результат. Если задача не наша, скажем об этом сразу, а не на третьем месяце.

Оставить заявку Ответим в течение рабочего дня. Работаем по NDA.
Отзывы

Что говорят после сдачи

Заказчиков не называем — договоры это запрещают. Оставляем должность и отрасль: по ним понятно, с чьей стороны сказано.

Мы просили не презентацию, а прототип на нашей выгрузке. Через три недели спорили уже о том, где модель ошибается, а не о том, заработает ли она вообще.
Технический директорМашиностроение
Прошлые подрядчики отдавали чёрный ящик. Здесь исходники и инструкция по развёртыванию лежали в нашем репозитории с первой недели — стенд мы подняли сами, без них.
Руководитель ИТ-службыЭнергетика
Из трёх задач одну сразу отказались брать и объяснили почему. После этого к срокам по остальным двум вопросов у нас не возникало.
Директор по цифровизацииЛогистика
Присылали сборку каждую пятницу, даже когда неделя выходила неудачной. Мы привыкли, что подрядчик пропадает и появляется в конце с готовым, — здесь было наоборот.
Начальник отдела АСУ ТПМеталлургия
Первый разговор закончился списком того, чего у нас нет: ни описания процесса, ни доступа к историческим данным. Неприятно было слушать, но начали именно с этого.
Заместитель генерального директораПищевое производство
Отдельно просили не выносить ничего в облако. Ни один компонент наружу не пошёл — проверяли по трафику своей службой безопасности.
Начальник службы информационной безопасностиБанк
Документацию писали по ходу, а не в последнюю неделю. Когда через полгода у нас сменился администратор, передача заняла один день.
Руководитель ИТРозничная сеть
Модель ошибалась на редких случаях, и показали нам это сами, до приёмки. Договорились, как эти случаи разбирает человек.
Главный технологХимическое производство
Требования у нас менялись трижды, и каждый раз называли, что это сдвигает и на сколько. Без сюрприза в конце.
Директор по развитиюЛогистический оператор
Про наш регламент допуска и категорирование спросили раньше, чем про бюджет. Для нас это был знак, что человек уже работал на таких объектах.
Заместитель директора по ИБЭнергосбыт
Доступ просили по минимуму: конкретные таблицы, конкретный сегмент, на время работ. Другие подрядчики просили администратора на весь домен.
Системный администраторПриборостроение
Стенд подняли на нашем железе и показали, что всё работает с отключённым интернетом. Только после этого мы подписали следующий этап.
Начальник ИТ-отделаМашиностроительный холдинг
Когда мы попросили ускориться, сказали, что можно, и перечислили, что именно тогда останется непроверенным. Мы решили не ускоряться.
Операционный директорДистрибуция
Отдали не только код, но и то, как его собирать и разворачивать. Через год мы дорабатывали систему своими силами.
Технический директорТранспортная компания
Ни одного процента и ни одного обещания в презентации не было. Были сроки и список того, что мы сможем проверить на приёмке.
Финансовый директорАгропромышленный холдинг
Блог

Разбираем то, что делаем сами

Пишем про прикладные задачи, а не про исследования: компьютерное зрение, обработка языка, поиск по документам, промышленная аналитика, учётные контуры. Только то, что сами собирали и сдавали.

Практика8 мин

Своя LLM или ChatGPT API

Сравниваем по безопасности, стоимости и контролю — что выбрать, когда данные нельзя отдавать наружу.

Читать
Технологии7 мин

Что такое RAG простыми словами

Как модель отвечает по вашим документам без выдумок и где это уже применяют.

Читать
Безопасность8 мин

Требования КИИ к ИИ-системам

187-ФЗ, категорирование и закрытый контур для ИИ на значимых объектах.

Читать
Практика7 мин

Компьютерное зрение для контроля качества

Как система находит дефекты на линии в реальном времени и что нужно от вас, чтобы она заработала.

Читать
Промышленность7 мин

Предиктивное обслуживание оборудования

Что нужно от датчиков и истории ремонтов, чтобы предсказание отказов было не гаданием.

Читать
Суверенитет7 мин

Импортозамещение ERP: с чего начать

Практический план миграции на отечественный стек без остановки производства.

Читать
Все статьи блога