← Блог

4 мільйони записів за 200 мс: як ми побудували санкційний скринінг у Panoptic

OpenSanctions, Elasticsearch, fuzzy matching — як ми інтегрували 100+ санкційних списків світу в єдиний API і чому це змінює правила Due Diligence для українського бізнесу.

OSINT · 2026-04-07T14:00:00


OFAC, EU, UN, РНБО, Interpol, PEP-реєстри 200+ країн — усе в одному API. 4 мільйони сутностей. Fuzzy matching, що знаходить "Володимир Путін" навіть якщо ви написали "Vladimir Poutin". Ось як це працює.

Вступ: чому санкційна перевірка — це не "галочка" у чеклісті

Уявіть: ваша компанія підписує контракт з іноземним партнером. Юристи перевірили ЄДРПОУ, судовий реєстр — все чисто. Через три місяці приходить лист від комплаєнс-відділу банку: один із бенефіціарів контрагента — під санкціями OFAC. Контракт заморожено. Рахунки під ризиком блокування. Репутаційні та фінансові збитки — колосальні.

Це не гіпотетика. За даними Державної служби фінансового моніторингу, у 2025 році кількість порушень санкційного законодавства в Україні зросла на 40%. Причина не в злому намірі, а в неповноті перевірок.

Більшість компаній перевіряють контрагентів по одному-двох списках — зазвичай РНБО та, можливо, OFAC. Але санкційних списків у світі — понад сто. І підсанкційна особа може бути в списку Австралії, Швейцарії чи Японії, але не в українському реєстрі.

Ми побудували санкційний скринінг Panoptic, щоб закрити цю прогалину. Один запит — 100+ списків. 4 мільйони сутностей. Відповідь за мілісекунди.


Що таке OpenSanctions і чому це стандарт індустрії

OpenSanctions — це відкрита база даних, що агрегує санкційні списки, PEP-реєстри (Politically Exposed Persons) та дані правоохоронних органів з усього світу в єдиний стандартизований формат.

Що включено

| Категорія | Приклади джерел | Кількість записів | |-----------|----------------|-------------------| | Міжнародні санкції | OFAC (США), EU Consolidated List, UN Security Council | ~50,000 | | Національні санкції | РНБО (Україна), DFAT (Австралія), SECO (Швейцарія), METI (Японія) | ~30,000 | | PEP-реєстри | Глави держав, міністри, депутати, судді 200+ країн | ~3,500,000 | | Правоохоронні | Interpol Red Notices, FBI Most Wanted, EU Most Wanted | ~10,000 | | Корпоративні зв'язки | Підсанкційні компанії, їхні дочірні структури, бенефіціари | ~400,000 |

Загалом: 4,000,000+ сутностей — осіб, компаній, суден, літаків та інших об'єктів.

Чому не просто парсити списки самостійно?

Кожен санкційний список має свій формат: XML у OFAC, CSV у EU, JSON у РНБО, PDF у деяких азійських юрисдикціях. Імена записані різними мовами, в різній транслітерації, з різним порядком прізвище/ім'я.

OpenSanctions вирішує цю проблему, стандартизуючи всі дані у формат FollowTheMoney — граф сутностей з уніфікованими полями. Це означає, що "Путін Володимир Володимирович", "Vladimir Putin" та "بوتين فلاديمير" — це один і той самий запис.


Архітектура: Elasticsearch + yente

Для пошуку і матчингу по 4 мільйонах записів потрібен швидкий і гнучкий пошуковий рушій. Ми обрали зв'язку Elasticsearch 8.18 + yente — офіційний API-сервер OpenSanctions.

Як це працює

~~~ ┌──────────────────────────────────────────────────────┐ │ Panoptic Backend │ │ (FastAPI) │ │ │ │ │ ┌──────────┴──────────┐ │ │ ▼ ▼ │ │ /sanctions/search /sanctions/match │ │ (повнотекстовий) (fuzzy matching) │ │ │ │ │ │ └──────────┬──────────┘ │ │ ▼ │ │ OpenSanctions Adapter │ │ (backend/app/adapters/ │ │ opensanctions.py) │ │ │ │ │ ▼ │ │ yente API Server │ │ (FollowTheMoney API) │ │ │ │ │ ▼ │ │ Elasticsearch 8.18 │ │ (4,000,000+ documents) │ │ │ │ Datasets: civic manifest (free) │ │ Sources: OFAC, EU, UN, РНБО, Interpol, │ │ PEP registries, corporate data │ └──────────────────────────────────────────────────────┘ ~~~

Elasticsearch: чому саме він

Для задачі санкційного скринінгу критичні три речі:

1. Fuzzy search — пошук з толерантністю до помилок у написанні. Elasticsearch підтримує Levenshtein distance, фонетичний пошук і n-gram токенізацію.

2. Мультимовний пошук — людина може шукати "Путін", "Putin", "Poutine" або навіть "Pootin". Elasticsearch з правильними аналізаторами знаходить усі варіанти.

3. Швидкість на великих обсягах — 4 мільйони документів з десятками полів кожен. Full-text search за <200 мс.

yente: API для FollowTheMoney

yente — це офіційний API-сервер OpenSanctions. Він:
  • Індексує дані OpenSanctions в Elasticsearch
  • Надає REST API для пошуку та матчингу
  • Підтримує scoring — числову оцінку відповідності
  • Автоматично оновлює дані при виході нових версій датасету
  • Ми використовуємо civic manifest — безкоштовну версію даних, яка включає всі санкційні списки та PEP-реєстри.


    Три API-ендпоінти: пошук, матчинг, здоров'я

    1. POST /api/v1/sanctions/search — повнотекстовий пошук

    Класичний пошук за ім'ям або назвою організації. Ідеальний для швидкої перевірки "чи є хтось у санкціях".

    ~~~python

    Запит

    POST /api/v1/sanctions/search { "query": "putin", "limit": 10 }

    Відповідь (спрощено)

    { "total": 1549, "results": [ { "id": "Q7747", "name": "Vladimir Vladimirovich Putin", "schema": "Person", "datasets": ["us_ofac_sdn", "eu_fsf", "un_sc_sanctions", "ua_nsdc_sanctions"], "properties": { "nationality": ["Russia"], "position": ["President of Russia"], "birthDate": ["1952-10-07"] }, "score": 0.99 } ] } ~~~ 1549 результатів за запитом "putin" — це не лише сам Путін, а й пов'язані особи, компанії, судна і літаки.

    2. POST /api/v1/sanctions/match — fuzzy matching

    Ключова функція для Due Diligence. Матчинг порівнює ваші дані з базою, використовуючи нечіткий пошук, і повертає ступінь впевненості.

    ~~~python

    Запит

    POST /api/v1/sanctions/match { "name": "Petro Poroshenko", "birth_date": "1965-09-26", "schema": "Person" }

    Відповідь

    { "match_found": true, "is_sanctioned": false, "is_pep": true, "best_match": { "name": "Petro Oleksiyovych Poroshenko", "score": 0.95, "datasets": ["ua_nsdc_pep", "everypolitician"], "properties": { "position": ["President of Ukraine (2014-2019)"], "nationality": ["Ukraine"] } } } ~~~

    Зверніть увагу: Порошенко — не під санкціями, але визначений як PEP (Politically Exposed Person). Це критична різниця для комплаєнсу: PEP не заборонені, але вимагають посиленої перевірки (Enhanced Due Diligence).

    3. GET /api/v1/sanctions/health — перевірка системи

    ~~~python GET /api/v1/sanctions/health

    { "status": "healthy", "yente_available": true, "elasticsearch_status": "green", "indexed_entities": 4012847, "last_update": "2026-04-06T03:00:00Z" } ~~~


    Fuzzy Matching: як знайти того, хто ховається за транслітерацією

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

    Проблема транслітерації

    ~~~ Одна людина — десятки написань:

    Кирилиця: Путін Володимир Володимирович Латиниця: Putin Vladimir Vladimirovich Французька: Poutine Vladimir Арабська: بوتين فلاديمير Варіації: V. Putin, Vlad Putin, Wladimir Putin Помилки: Putn, Putiin, Vladmir Putin ~~~

    Як працює наш матчинг

    Ми використовуємо багаторівневий підхід:

    1. Точний матч — пряме співпадіння імені (score 1.0) 2. Фонетичний матч — Metaphone/Soundex алгоритми, що групують схожі за звучанням імена 3. Levenshtein distance — толерантність до 2 помилок у написанні 4. Cross-language matching — зіставлення через транслітераційні таблиці 5. Partial matching — "V. Putin" знаходить "Vladimir Putin" 6. Contextual boosting — додавання дати народження або країни підвищує точність

    Scoring

    Кожен результат отримує score від 0 до 1:

    | Score | Інтерпретація | Рекомендована дія | |-------|--------------|------------------| | 0.95-1.0 | Майже точне співпадіння | Негайний review | | 0.80-0.94 | Високий збіг | Ручна перевірка обов'язкова | | 0.60-0.79 | Можливий збіг | Рекомендована перевірка | | < 0.60 | Малоймовірний збіг | Зазвичай false positive |


    Реальні кейси: що знаходить Panoptic

    Кейс 1: Перевірка контрагента перед контрактом

    Компанія перевіряє потенційного партнера — юридичну особу з Кіпру.

    Запит: \


    Запустити OSINT-розвідку компанії →

    Теги: #Sanctions, #Due Diligence, #OpenSanctions, #PEP, #Compliance, #OFAC, #РНБО

    Схожі статті

    Повернутися до блогу | Panoptic