Перейти до основного вмісту
megapromotingПоговорімо

Рішення · Фінансові послуги

Агент, який класифікує грошові рухи, вибираючи з закритого списку, а не пишучи речення, яке потім хтось інтерпретує.

У фінансовій організації корисний агент не дає порад і нічого не схвалює: читає документи та транзакції, відносить їх до категорії з фіксованого набору, каже, наскільки впевнений, і має право відповісти «не знаю». Решта — рішення, схвалення, політика — лишається за людьми.

Пропозиція, з умовамиNu scriem „livrat”, pentru că nu avem un agent de acest fel pus în producție la un client din sectorul financiar. Ce avem, și arătăm exact ca atare, e o conductă proprie de ingestie care rulează pe datele noastre: cinci module Python, 1.526 de linii, care citesc notificări bancare din e-mail și extrase în PDF, clasifică fiecare tranzacție prin unelte și o scriu în PostgreSQL cu dedublare, plus patru fluxuri de automatizare pentru webhookuri de la trei procesatori de plăți. Starea reală, spusă în aceeași frază: depozitul nu e sub git, directoarele `tests/` și `webhook-server/` sunt goale, iar potrivirea aproximativă a numelor de contrapartidă folosește o euristică de n-grame marcată în cod ca „de înlocuit cu un serviciu de înglobare înainte de producție”. Partea de platformă financiară în producție — flux de cerere, contract, grafic de plăți, audit — e o lucrare separată, cu dovezile ei, și acolo scriem „livrat”.

Запити на AI-агентів у фінансових послугах майже завжди надходять у формі «щоб відповідали клієнтам на запитання про наші продукти». Це законний запит, але час не там виграється. Час губиться в іншому: хтось щодня відкриває десятки банківських повідомлень і виписок, дивиться на опис типу рядка великих літер із кодом і вирішує, чи це надходження від клієнта, зарплата, податок, платіж кредитору чи операційна витрата. Ця робота повторювана, нудна і, саме тому, сповнена помилок.

Мовна модель добре для цього підходить, за однієї умови: від неї не слід вимагати писати відповідь вільним текстом. Якщо ви попросите речення, ви самі його розберете, а розбір помилите. У нашій проводці модель не пише: вона отримує сім інструментів і має викликати рівно один — надходження від клієнта, зарплата, податок, платіж кредитору, операційна витрата, банківська комісія або невідомо. Кожен інструмент, окрім назви контрагента або категорії, вимагає показник упевненості між 0 і 1. «Невідомо» вимагає письмову причину. Вихід — це структура, а не думка.

Друге правило — ніщо не потрапляє двічі. Кожна транзакція, витягнута з повідомлення або з виписки, отримує зовнішній ідентифікатор, обчислений як префікс із 16 символів відбитка SHA-256 по її полях, колонка є унікальною в таблиці, а вставка виконується з `ON CONFLICT (external_id) DO NOTHING`. Практичний наслідок: поштову скриньку можна перечитувати скільки завгодно разів, а баланс не подвоюється. Без цього правила будь-яка фінансова ingest-проводка вже на третьому тижні починає породжувати дублікати, які хтось чистить вручну.

Чого такий агент не робить і чому важливо це писати на сторінці: він не схвалює платіж, не ухвалює кредитне рішення, не дає інвестиційних рекомендацій і не відповідає клієнту від імені установи. Показник упевненості, який він повертає, — це оцінка моделі про саму себе, а не вимірювання точності, зроблене нами — ця відмінність є різницею між інструментом і ілюзією контролю.

Що входить

Що конкретно змінюється у фінансових послугах

Документ потрапляє один раз, навіть якщо ми читаємо його десять разів

Повідомлення читаються з поштової скриньки через IMAP, виписки — з PDF. Кожна транзакція отримує зовнішній ідентифікатор із відбитка SHA-256 по її полях, колонка `external_id` є `NOT NULL UNIQUE` у таблиці, а вставка виконується з `ON CONFLICT (external_id) DO NOTHING`, з окремим журналом для вставленого рядка і для того, що був пропущений як дублікат. Перечитування тієї самої скриньки не створює жодного дубліката.

Класифікація виконується через інструменти, із закритим списком результатів

Сім інструментів, не вільний текст: надходження від клієнта, зарплата, податок, платіж кредитору, операційна витрата, банківська комісія, невідомо. Модель має викликати лише один. Перші шість обов’язково вимагають, окрім назви або категорії, показник упевненості між 0,0 і 1,0, заявлений у схемі інструмента; сьомий вимагає причину. Модель, що використовується, оголошена в коді, а не схована в конфігурації.

«Невідомо» — це легітимний вихід, із причиною

Класифікатор, якому не можна сказати «не знаю», помилково віднесе, з великою впевненістю, саме нестандартні транзакції — тобто ті, що мають значення. Тому інструмент невідомого доступний так само, як і інші, і вимагає письмову причину, яка потрапляє в рядок. Рядки невідомого — це робочий список людини, а не збій системи.

Приблизне зіставлення назв контрагента, з його реальним станом

Те саме підприємство з’являється у виписках у трьох написаннях. Понад класифікацією є зіставлення за косинусною схожістю між векторами. Ми сьогодні точно кажемо, що це за вектори: евристика n-грам символів, написана в коді з коментарем, що для продукції її треба замінити на реальний виклик до сервісу вбудовування. Вона працює для варіацій написання; це не семантичне зіставлення.

Webhookи від процесорів платежів потрапляють у ту саму таблицю

Чотири потоки автоматизації, по одному для трьох процесорів платежів і один для щоденної звірки, з 7 до 10 вузлів кожен. Ідея архітектури в тому, що різні джерела — e-mail, PDF, webhook — не створюють три таблиці, які потім треба узгоджувати, а ряди в одній таблиці, з тим самим правилом дедубляції.

Споживання моделі перебуває під бюджетом на ключ, а не під рахунком

Виклики проходять через власний шлюз на `api.megapromoting.com/v1`, із 44 налаштованими моделями, кожна з вартістю за токен і лімітом контексту. Проєктний ключ має білий список моделей, бюджет і період, його можна ротувати, зберігаючи історію, а споживання щоденно консолідується за користувач × ключ × модель. Деталь, що дивує всіх: моделі міркування утворюють внутрішні кроки, які система відстеження не бачить, але постачальник їх тарифікує — отже, брутто-бюджет на ключ встановлюється нижче бажаної межі.

Що можна запускати без того, щоб дані виходили з машини

Для кроків, які не потребують великої моделі — витягування полів із відомого формату, зіставлення назв, перевірки узгодженості — не потрібен жоден зовнішній постачальник; це звичайний код. Модель викликається лише для кроку класифікації. Коли ваша політика забороняє вихід даних, питання в тому, що саме надсилається моделі, а не в тому, чи використовується AI: можна надіслати опис транзакції без ідентифікаторів рахунку.

Що не робить і не робитиме такий агент

Не схвалює платіж і не виконує переказ. Не ухвалює кредитне рішення — правила, пороги та схвалення є політикою установи. Не дає інвестиційних рекомендацій і не відповідає клієнтові від вашого імені без окремого маршруту схвалення. І не гарантує вам точність: скор упевненості — це вихід моделі про саму себе, а не незалежне вимірювання.

Traseul

Як запит проходить через систему.

01

Фіксуємо закритий список результатів, до будь-якого коду

Перша поставка — це не агент, а список: категорії, до яких йому дозволено відносити, які обов’язкові поля вимагає кожна, і що означає «невідомо» у вас. Якщо список не можна записати на одній сторінці, завдання не підходить для агента — і краще дізнатися це зараз.

02

Будуємо інжест і дедуплікацію без моделі

Читання з e-mail, PDF або webhook, витягування полів, обчислення зовнішнього ідентифікатора та запис у базу виконуються і перевіряються без жодного виклику моделі. Ми постачаємо конвеєр, який коректно інжестить і не дублює. Якщо цей крок не надійний, модель зверху лише породжує переконливіші помилки.

03

Додаємо класифікацію і вимірюємо її на ваших кейсах

Поверх працюючого конвеєра ми ставимо інструменти класифікації й запускаємо на наборі ваших реальних транзакцій, із правильним результатом, визначеним людиною, яка сьогодні виконує цю роботу. Ми постачаємо таблицю зі збігами та розбіжностями, а не твердження про точність. Поріг, від якого рядок іде до людини, обирається з цієї таблиці.

04

Ставимо бюджет, журнал і ворота

Проєктний ключ із білим списком моделей і бюджетом, щоденна консолідація споживання, журнал із викликаним інструментом і балом, та ворота, які скеровують до людини все, що нижче порога або невідоме. Ми постачаємо доступи, документ введення в експлуатацію та письмовий список того, що агент робить сам і чого не робить.

1E-mail, PDF sauwebhook2extragerea câmpurilor3amprentă SHA-2564scriere cu ONCONFLICT DO NOTHING5încadrare prin unadin șapte unelte, cuscorrândurile„necunoscut” către om
Traseul, în 6 pași

Дані

Чого торкаємося, де воно лежить і скільки лишається

Правила відрізняються від однієї галузі до іншої. Це ті, що застосовуються у фінансових послугах.

Які саме дані він зачіпає
Грошові рухи з датою, сумою, валютою, описом і контрагентом. Частина контрагентів — фізичні особи — зарплата містить ім’я працівника — отже, таблиця містить персональні дані працівників, а не лише комерційні дані. Це змінює, хто має право відкривати таблицю.
Що потрапляє до моделі і що залишається вдома
До моделі надходять текст опису транзакції та сума. Ідентифікатори рахунку, IBAN-номери та решта полів не мають чого шукати в запиті, щоб класифікація працювала, тож їх можна залишити поза ним. Правило, яке ми застосовуємо загалом: те, що не потрібне для відповідного кроку, не надсилається, бо те, що не пішло, ніхто не може зберегти.
Де зберігаються витягнуті дані
PostgreSQL, з унікальним `external_id` і індексом на ньому. База залишається вашою, на вашій інфраструктурі або на тій, яку ми для вас обслуговуємо. Спільного сховища між клієнтами не існує, бо немає технічної причини, чому воно мало б існувати.
Слід автоматичного рішення
Кожен рядок зберігає, який інструмент було викликано, з яким балом і, коли це доречно, причину «невідомо». Це мінімум, необхідний, щоб через шість місяців хтось міг відповісти на запитання «чому цю транзакцію віднесли до операційних витрат» — з відповіддю, а не з розводінням руками.
Строк зберігання, який тут ви самі не обираєте
Фінансові документи мають строки зберігання, визначені бухгалтерським і податковим законодавством, а не нашими чи вашими вподобаннями. У фінансовому проєкті строк береться з цих правил, записується в реєстр обробок і лише потім реалізується видалення. Зворотний порядок — спочатку реалізувати, потім перевірити — породжує системи, які видаляють те, що слід було зберегти.

Випадок

Конвеєр інгестії, який можна без страху перезапустити

Ситуація

Банківські сповіщення та щомісячні виписки надходили до поштової скриньки й читалися людиною, яка розподіляла їх за категоріями. Перша очевидна версія — скрипт, який читає скриньку і записує в базу, — має проблему, що стає помітною лише на третій тиждень: під час будь-якого перезапуску або повторного читання ті самі транзакції потрапляють знову.

Що ми збудували

Ми написали п’ять модулів, 1.526 рядків Python: два аналізатори сповіщень через IMAP, екстрактор PDF-виписок, класифікатор через інструменти та запис у PostgreSQL. Центральне правило — зовнішній ідентифікатор — 16-символьний префікс із SHA-256-відбитка над полями транзакції — з унікальним стовпцем у таблиці та вставкою `ON CONFLICT DO NOTHING`. Класифікація не повертає текст: модель викликає одну із семи інструментів, з обов’язковим балом упевненості, а «невідомо» потребує причини.

Що вийшло

Поштову скриньку можна перечитати будь-коли, а рядки, які вже оброблені, пропускаються й позначаються як дублікати в журналі. Транзакції, які модель не може класифікувати, з’являються як список роботи, з причиною поруч, замість того щоб їх проштовхували в категорію, аби здавалося, що все спрацювало.

Чого цей випадок не каже

Це внутрішній конвеєр, а не система, передана фінансовому клієнту: він не під git, каталоги тестів порожні, а приблизне зіставлення назв використовує евристику n-грам, яку код явно позначає як тимчасову. Я описав це тут, тому що це показує метод, а не тому, що це продукт.

Питання

Що запитує хтось із фінансових послуг

Агент схвалює платежі або кредити?

Ні, і це не технічне обмеження, яке ми подолаємо в наступній версії. Схвалення — це рішення з юридичними наслідками, яке належить уповноваженій особі в установі. Агент готує: класифікує, заповнює, сигналізує, що не збігається. Система, яка схвалює сама, мала б мати змогу відповідати перед контролером, а бал упевненості — не відповідь.

Як я знаю, що він класифікував правильно?

Не з балу упевненості — це оцінка моделі самої себе, а не вимірювання. Це видно з порівняння з рішеннями людини, яка виконує цю роботу сьогодні, на наборі реальних транзакцій, зробленому до запуску чогось у автоматичному режимі. Результат цього порівняння — таблиця, яку ми передаємо, включно з рядками, де агент помилився.

Що відбувається, коли він не впевнений?

Викликайте інструмент «невідомо» і вкажіть причину. Рядок потрапляє до списку роботи людини, а не в категорію, обрану навмання, щоб здавалося, що система спрацювала. Класифікатор без виходу «не знаю» помиляється саме там, де помилка коштує: на незвичних транзакціях.

Якщо прочитати одне й те саме сповіщення двічі, сума подвоїться?

Ні. Кожна транзакція має зовнішній ідентифікатор, обчислений як відбиток за її полями, колонка є унікальною, а вставка використовує `ON CONFLICT (external_id) DO NOTHING`. Пропущений рядок позначається в журналі як дубль, тож видно, що його було перечитано.

Наші дані йдуть до постачальника моделі?

Для кроку класифікації — так: опис транзакції та сума йдуть до обраної моделі через наш gateway, з ключем проєкту, білим списком моделей і бюджетом. Решта кроків — читання, витяг, дедублікація, зіставлення імен — це звичайний код і нікуди не виходять. Що саме має право виходити, визначається письмово до початку, а не з’ясовується з журналів потім.

Ви можете читати виписки у PDF, не лише сповіщення електронною поштою?

Так, це один із модулів конвеєра. Що треба знати — PDF-виписка це крихкий формат: вона читається за структурою, яку формує відповідний банк, а коли банк змінює шаблон, модуль треба коригувати. Тому він пишеться з перевірками, які падають гучно, а не які здогадуються.

Чому на цій сторінці написано «пропозиція», а не «доставлено»?

Тому що наше правило вимагає щонайменше двох власних впроваджень, щоб писати «доставлено», а описаний тут конвеєр працює на наших даних, а не в продакшені у клієнта з фінансового сектору. Є й недоліки, які ми називаємо: це не під git, немає тестів, а зіставлення імен використовує евристику, позначену в коді як тимчасову. Коли ми зможемо посилатися на дві впровадження у клієнтів, змінемо слово.

Що нам потрібно від вас, щоб почати роботу?

Три речі: закритий список категорій, до яких він має право відносити, набір реальних транзакцій із правильною відповіддю, наданою людиною, яка сьогодні виконує цю роботу, і письмове рішення про те, які поля мають право виходити з вашої мережі. Без третього пункту ми не починаємо, бо це єдине, що не можна виправити згодом.

Що вам хотілося б налагодити?

Розкажіть про свій процес. Разом визначимо, що варто збудувати, що можна підключити і як перевіримо результат.

Поговорімо