Финтех · Внутренняя система
Tallim
Сверка платежей со счетами в финансовом отделе платёжной компании: строгие правила, похожесть и модель работают по очереди. Спорное подтверждает человек.
- Роль
- Бэкенд, интеграции, ИИ-сопоставление
- Срок
- 8 недель
- Стек
- Python · PostgreSQL · OpenAI API
Что изменилось
- 8,7% → 1,9%
- платежей остаётся на ручную сверку. Остальные закрываются без человека.
- 120 → 31 час
- в месяц у финансовой команды на сверку целиком. Раньше уходило от 110 до 130.
- 97,8%
- автоматических сопоставлений подтверждались без исправлений.
- 6,4 минуты → 48 секунд
- на один платёж, дошедший до разбора: вместо чтения выписки — подтверждение готовых вариантов.
Банковскую инфраструктуру и основную ERP не меняли: выписка приходит как приходила, учёт остался там же. Модель не получила права проводить и отменять операции — она называет вероятное соответствие, критичное осталось детерминированным.
Что было до
Через компанию проходило около 31 000 платежей в месяц, и почти все они сходились со счетами по правилам. Оставшиеся 8,7% попадали в очередь к финансовой команде: сотрудник открывал выписку, читал назначение платежа и искал, к какому счёту и какому клиенту он относится. На это уходило 110–130 человеко-часов в месяц, и до 2,4% платежей на первом заходе привязывались не туда.
- Около 31 000 платежей в месяц. При таком потоке ручная работа считается не случаями, а процентами: любая доля, оставленная людям, превращается в очередь, которая не кончается.
- 8,7% платежей не сопоставлялись со счётом автоматически. Часть закрывалась быстро, часть уходила в разбор: открытая выписка, чтение назначения глазами и решение, принятое человеком.
- На сверку уходило 110–130 человеко-часов в месяц. Отложить её было нельзя: пока платёж не привязан, счёт в учёте остаётся неоплаченным.
- До 2,4% платежей сотрудник сначала связывал не с тем счётом или не с тем клиентом. Ошибку находили позже, но до этого она стояла в учёте — и в истории плательщика, по которой разбирали его следующий платёж.
Что сделали
Порядок вместо одной модели: сначала точные правила по идентификатору счёта, сумме, контрагенту, дате и реквизитам, затем нечёткое сопоставление, и только потом AI — на том, что осталось.
Confidence score у каждого варианта: выше порога сопоставление проводится само, ниже — платёж уходит на экран разбора, к сотруднику.
Модель предлагает, а не проводит: операции остались за детерминированным кодом, и это условие стояло в начале проекта, а не появилось после первой ошибки.
Результат
Ручная сверка не исчезла, а сжалась: 8,7% платежей превратились в 1,9%, а 120 часов в месяц — в 31. Это часы всей сверки, а не только тех платежей, что дошли до человека. Из этих часов ушёл поиск: сотрудник больше не разбирает выписку с нуля, он смотрит готовые варианты с обоснованием и подтверждает или отклоняет — 48 секунд вместо 6,4 минуты. 97,8% автоматических сопоставлений после запуска не пришлось исправлять. Проводить платежи модель по-прежнему не может: она называет наиболее вероятное соответствие, а всё, что меняет деньги, делает детерминированный код.
Кто заказчик
Платёжная компания. Через неё проходит около 31 000 платежей в месяц, и каждый должен сойтись со счётом: пока платёж не привязан, счёт не закрыт — ни у клиента, ни в бухгалтерии, а любая цифра в отчёте держится на том, что кто-то это соответствие нашёл.
Заказчик здесь внутренний — финансовый отдел той же компании. Он эту сверку и вёл: платежи, не сошедшиеся сами, разбирали руками — по выписке и по тому, что о плательщике уже известно. Эти же люди стали пользователями системы.
Задача
- Как ставил заказчик
- Взять AI и находить по банковской выписке назначение платежа: модель читает строку и определяет, к чему платёж относится. Задача пришла в форме классификации — на входе текст, на выходе счёт.
- Как задача выглядела после разбора
- Классификации не хватило. В назначении могло стоять «INV 43821», «payment according contract 22/11», название юридического лица, старый номер счёта, опечатка — или ничего полезного. Часть строк сходится по точным полям и без модели; часть не сходится ничем, и из пустой строки не достать того, чего в ней нет. Поэтому задачей стал не разбор текста, а порядок, в котором правила, похожесть и AI работают по очереди.
Почему нельзя было в лоб
Строку назначения пишет плательщик, а не система, и отвечать за то, как её прочитали, приходится деньгами. Отсюда пять условий, и каждое видно в архитектуре.
- LLM не может быть источником истины
- Для финансовой операции ответ модели — мнение, а не факт: его нельзя ни проверить постфактум, ни повторить дословно. Значит, модель не могла стоять в начале цепочки и решать за всех. Ей оставалось место там, где строгие правила уже ничего не дают.
- Назначение платежа — свободный текст
- «INV 43821», «payment according contract 22/11», название юридического лица, опечатка. Регулярное выражение работает здесь до первого плательщика, который написал по-своему, — а плательщики, пишущие по-своему, и есть вся задача.
- Старый номер счёта
- Часть плательщиков указывает номер, который относится не к этому счёту. Точное правило срабатывает на нём уверенно и указывает не туда. Поэтому даже совпадение по идентификатору должно было приносить вес, а не приговор.
- Ручные решения — не эталон
- Первая неделя ушла в историю того, что решали люди: другого материала, показывающего, как платёж связывают со счётом, не существует. Но до 2,4% этих решений были ошибочными, поэтому история годилась как источник правил и примеров, а не как правильный ответ, с которым сверяются.
- Банк и ERP остаются как есть
- Ни то, ни другое не трогали: банк отдаёт выписку в своём виде, ERP остаётся учётной системой. Система встала между ними — нормализует то, что приходит, и пишет результат туда, где его ждут.
Как шла работа
- 01
Разбор истории
Неделя 1Смотрели, что происходило с платежами до нас: как выглядят назначения, какие сходились по правилам, какие сотрудник связывал вручную и на что при этом опирался. Из недели вышел не список требований, а порядок проверок — что решается точно, что похоже, что остаётся модели.
- 02
Ядро сверки и нормализация
Недели 2–3Reconciliation engine на строгих правилах: идентификатор счёта, сумма, контрагент, дата, банковские реквизиты. Перед правилами — нормализация банковских данных: пока поля из выписки не приведены к одному виду, сравнивать нечего, а ошибка сравнения выглядит как ошибка правила.
- 03
Сопоставление моделью и оценка уверенности
Неделя 4Модель подключили к остатку — к тому, что правила не закрыли. Она смотрит назначение платежа, историю клиента и связанные документы, а на выходе даёт не один ответ, а список вариантов, и у каждого confidence score: число, по которому дальше расходятся пути.
- 04
Экран разбора
Неделя 5Интерфейс для спорных платежей: варианты с обоснованием, почему предложен именно этот счёт, история плательщика рядом, решение в одно действие. Экран считался не по красоте, а по времени: сотруднику нечего искать — есть что подтвердить или отклонить.
- 05
ERP и бухгалтерия
Неделя 6Результат сопоставления должен доехать туда, где ведут учёт. ERP не меняли: система пишет в неё через API то, что раньше сотрудник вносил руками после разбора, — и это единственное место, где сверка касается учётного контура.
- 06
Shadow mode
Неделя 7Неделю система работала на реальных данных, ничего не проводя: считала сопоставления параллельно с людьми, обе версии сравнивали. Так проверялась не точность на истории, а поведение на потоке — на платежах этого дня и рядом с решением, которое принял по ним сотрудник.
- 07
Автоматический режим
Неделя 8Сопоставления выше порога стали проводиться без человека, остальные — уходить на экран разбора. Ручная сверка не отменилась, а стала тем, чем задумывалась: очередью спорных случаев вместо разбора всего потока.
Технические решения
Стек разделён по тому, где кончаются строгие правила: Python держит pipeline и интеграции, PostgreSQL хранит платежи, счета и решения вместе с обоснованием, OpenAI API отвечает за один участок — тот, где строгие правила уже сдались.
Порядок, а не выбор между правилами и AI
Сначала точные правила, затем нечёткое сопоставление, затем модель. Порядок нужен не ради экономии: чем раньше сработало правило, тем проще объяснить результат. Модель получает не поток, а остаток — там, где идентификатор не нашёлся, сумма не сошлась, а контрагент назван иначе, чем в счёте.
Нормализация до первого правила
Данные из выписки приводятся к одному виду прежде, чем к ним применяется хоть одно правило: иначе правило спорит не с платежом, а с формой записи. Самая скучная часть pipeline и единственная, ошибка в которой одинаково портит и точные правила, и модель.
Модель видит контекст, а не строку
На вход идут назначение платежа, история клиента и связанные документы. Похожие случаи ищутся не текстом, а векторами: embeddings лежат в pgvector, в той же PostgreSQL, что платежи и счета, — кандидат и данные, на которых он предложен, не разъезжаются по двум хранилищам.
Confidence score и порог
У каждого варианта есть число, и одно сравнение решает его судьбу: выше порога сопоставление проводится само, ниже уходит на экран разбора. Порог — установленное значение, а не свойство модели: это ручка, которой двигают соотношение автоматики и ручной проверки.
Разбор вместо поиска
Сотрудник не ищет счёт, а проверяет предложенные: варианты отсортированы по уверенности, у каждого написано, чем он подтверждается — совпал идентификатор, сошлась сумма, похоже назначение из прошлого платежа этого клиента. Отсюда 48 секунд вместо 6,4 минуты: подтверждение занимает меньше, чем поиск.
Модель предлагает, проводит код
AI не проводит и не отменяет ни одной финансовой операции. Он называет наиболее вероятное соответствие, а всё, что меняет деньги и учёт, делает детерминированный код по правилам, которые можно прочитать и повторить. Ограничение принято до первой строки, а не после первой ошибки.
Что осталось за рамками
Часть работы осталась снаружи по решению, принятому до старта, а не по итогам восьмой недели.
Банковская инфраструктура. Ни то, как приходит выписка, ни её состав мы не меняли: система нормализует то, что есть, и не просит банк присылать иначе.
Основная ERP. Осталась учётной системой: мы пишем в неё результат сопоставления, а не переносим бухгалтерию в свой контур.
Проведение и отмена операций. Ни того, ни другого модель не делает — это детерминированный код и сотрудник, и менять здесь ничего не планировалось.
Качество назначений. Строку пишет плательщик, и проект на неё не влияет: пустое назначение осталось пустым, разбирает его человек.
Оставшиеся 1,9%. Это не промежуточная цифра по дороге к нулю: порог выбран так, чтобы платёж, которому не хватает уверенности, доходил до человека, а не закрывался похожестью.
Система работает в автоматическом режиме с восьмой недели. Роль человека в ней осталась одна и последняя: платёж, которому не хватило уверенности, проводится только после того, как сотрудник подтвердил соответствие.
Другие проекты
Строительство
Prokta
Разбор тендерной документации для коммерческого отдела генподрядчика: на входе архив файлов, на выходе отчёт по условиям со ссылкой на страницу для каждого пункта.
91%
критичных условий из контрольной выборки система нашла сама
Python · Qdrant · OpenAI API
Рестораны
Ostera
Сеть из 64 ресторанов: показатели пяти систем сведены в один слой, а вопрос о вчерашней прибыли задают словами и получают ответ вместе с исходными данными.
64 ресторана
считают показатели по одним определениям
NestJS · ClickHouse · OpenAI API
Контакты
Пришлите описание задачи
Ответ с объёмом работ, сроками и оценкой бюджета придёт в течение 24 часов.
Первый звонок — 30 минут, без обязательств с вашей стороны.