Software Developer
  • Побудував Zero Trust AI-систему диспетчеризації для логістики. Рознесіть мою архітектуру!

    Дмитре, жодного зламу шаблонів, це просто сувора економіка логістичного бізнесу) Ви мислите з позиції B2C-додатків (як таксі), але у B2B Freight Brokerage інші правила гри.

    Щодо «в падлу натицяти»: Логістика — це висококонкурентний ринок, де йде боротьба за вільний транспорт. Водій часто за кермом, переписується з 5-ма різними диспетчерами у різних месенджерах. Якщо диспетчер А дає йому форму на 10 полів, а диспетчер Б каже «просто кинь мені текстом/голосом, де ти і що в тебе», водій поїде з диспетчером Б. LLM тут потрібна не для водія, а для диспетчера — щоб миттєво оцифрувати цей хаос, виграти час і забрати машину першим, не змушуючи водія робити зайві кліки. UX без тертя — це конверсія.

    Щодо клієнтської бази та «нахіба ховати»: Логістична компанія (експедитор) не має ні своїх фур, ні своїх заводів. Їхній єдиний актив і хліб — це інформація. Вони заробляють свою маржу саме на тому, що знають, ХТО везе, і знають, КОМУ треба перевезти. Якщо водій (перевізник) на етапі торгів отримує прямі контакти власника вантажу, експедитор просто виключається з ланцюжка при наступному рейсі. Тому анонімізація даних (PII Scrubber) у нашому ШІ-диспетчері — це базовий захист комерційної таємниці брокера, щоб AI випадково не «злив» контакти заводу водієві під час діалогу, або навпаки.

  • Побудував Zero Trust AI-систему диспетчеризації для логістики. Рознесіть мою архітектуру!

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

    Щодо NATS — ми поки туди не лізли. У нас пайплайн зараз досить лінійний (FastAPI -> Scrubber -> LLM -> Validation -> DB), і агенти між собою складно не спілкуються, тому обходимось без брокерів. Але якщо в майбутньому будемо масштабуватись і додавати окремих агентів (наприклад, для генерації інвойсів), то NATS з його envelope-level security — це прям те що треба, точно заберемо ідею в беклог.

    Щодо Validation gate — отут стовідсотковий плюс. Ми на ці граблі наступили ще на стадії прототипу, коли модель могла видати напівпорожній JSON або придумати своє поле. Зараз у нас стоїть жорсткий гейт на Pydantic v2. Якщо Gemini повертає щось не те (наприклад, губить поле з вагою або ліпить кривий тип) — Pydantic кидає ValidationError, пайплайн стопається і запит просто падає на живого диспетчера. Жодна галюцинація чи кривий стейт в базу не пролізе.

    А стосовно filesystem jail і тулів — нам тут трохи простіше. Наша LLM взагалі не має доступу до function calling. Вона працює суто як stateless-парсер: бере очищений текст від скруббера, дістає з нього логістичні параметри і віддає JSON. Вона нічого не пише на диск і не робить зовнішніх API-запитів. Відповідно, весь blast radius обмежується лише криво заповненим JSON’ом, який ми миттєво відловлюємо тим же Pydantic на попередньому кроці)

    Ще раз дякую за коментар, дуже круто, коли можна так предметно обговорити технічну внутрянку!

  • Побудував Zero Trust AI-систему диспетчеризації для логістики. Рознесіть мою архітектуру!

    О, цікава гіпотеза, але ви трохи промахнулися з нашою бізнес-моделлю) Ми взагалі не маркетплейс і не біржа вантажів типу «Тачки». Ми не зводимо водіїв із замовниками і не беремо відсоток за фрахт.

    Ми — чистий B2B SaaS для логістичних компаній та диспетчерських агенцій. Тобто ми просто продаємо їм софт (інфраструктуру з ШІ).

    Щодо приховування контактів (наш PII Scrubber): ми ховаємо номери та імена не один від одного, а від публічної LLM. Для будь-якої логістичної компанії клієнтська база — це найголовніший актив. Вони ніколи не віддадуть реальні контакти своїх водіїв чи замовників в умовний ChatGPT через API на розтерзання (і для подальшого навчання моделей).

    Тому наш бекенд «на льоту» вирізає всі чутливі дані, замінює їх на токени (типу [PHONE_0]), відправляє цей стерильний текст в модель суто для того, щоб витягнути логістичні параметри (тоннаж, маршрут, ADR), і отримує безпечну відповідь.

    А от у дашборді самого диспетчера (нашого B2B клієнта) ці дані деанонімізуються назад. Він бачить усі реальні номери і повністю контролює діалог.

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

  • Побудував Zero Trust AI-систему диспетчеризації для логістики. Рознесіть мою архітектуру!

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

    Суть у тому, що ми виходимо з принципу: «ніколи не довіряй публічній моделі чутливу інфу». Тому скруббер вирізає всі PII (телефони, імена) ще до того, як вони полетять в умовний Gemini. Ну і плюс на рівні бази у нас налаштований жорсткий RLS (Row-Level Security), щоб тенанти фізично не могли перетнутися даними. Згоден, що для маркетингу назва звучить трохи гучніше, але суть підходу вона передає)

    Щодо трьох кнопок — якби задача була тільки в трекінгу статусу поїздки, то 100% так би і зробили. Кнопковий UX там рулить. Але наш фокус саме на етапі переговорів та кваліфікації ліда.

    У реальному житті водій не буде клікати кнопки чи заповнювати формочки, коли йому треба швидко запропонувати машину. Він скоріше кине в месенджер суцільний текст типу: «є вільна машина в Любліні на завтра, рефка до −18, чи візьмете під свою хімію?». І отут якраз починається хаос. Наша задача — витягнути з цього неструктурованого тексту чітку JSON-схему (тоннаж, температуру, клас небезпеки ADR) і миттєво відсіяти нецільові запити за бізнес-правилами конкретної компанії. Тобто ми автоматизуємо рутину диспетчера на стадії онбордингу вантажу, де кнопки просто не працюють. Ну а якщо модель не впевнена у вхідних даних — от тоді вже чат падає на живу людину.

  • Побудував Zero Trust AI-систему диспетчеризації для логістики. Рознесіть мою архітектуру!

    Дмитре, ви влучно описали те, як воно зазвичай працює в логістиці зараз) Але наша головна мета — якраз максимально прибрати з цього ланцюжка отого «когось, хто щось робить».

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

    Тому в нашому рішенні флоу трохи інший:

    Водій кидає інфу як йому зручно (голосове, сленг, текст). Модель тут працює не як транслятор, а як NLU-процесор — розпізнає інтент і витягує сутності. Далі вже наш бекенд сам апдейтить базу (TMS) і відповідає водію. Людина на цьому етапі взагалі не бере участі.

    Живий диспетчер (Human-In-The-Loop) підключається тільки десь у 20% складних кейсів — ДТП, ADR-вантаж або якщо комунікація йде кудись не туди. При цьому алгоритм одразу передає йому весь готовий контекст.

    Щодо приватності та Zero Trust: щоб усе це працювало легально, ми імплементували Data Scrubber та Vault. Ніякі реальні імена, телефони чи номери машин до LLM фізично не летять — вони маскуються на льоту і відновлюються вже всередині нашого ізольованого контуру.

    Коротше кажучи, даємо бізнесу автономію рівня LLM, але з гарантіями безпеки на рівні інфраструктури.

  • Побудував Zero Trust AI-систему диспетчеризації для логістики. Рознесіть мою архітектуру!

    Суть якраз у тому, щоб показати концепт із практики та завалідувати архітектуру об сильне технічне ком’юніті перед запуском бета-тестування та масштабуванням на B2B-клієнтів.

    Бо в теорії «стандартний Zero Trust» і GDPR-compliance звучать просто. А на практиці, коли доходить до інтеграції LLM, більшість на ринку зараз просто ліпить базовий враппер над API і радісно зливає туди всю клієнтську базу без жодного маскування.

    Мені хотілося обговорити саме практичні нюанси реалізації (зв’язка Vault Agent через tmpfs + RLS + Scrubber в одному пайплайні) і послухати думки людей з досвідом, щоб знайти можливі «сліпі зони».

    Тож дякую за краш-тест і конструктивний діалог! 🤝

  • Побудував Zero Trust AI-систему диспетчеризації для логістики. Рознесіть мою архітектуру!

    Дякую за розгорнутий коментар. Давайте розберемо по пунктах, бо тут є фундаментальні непорозуміння того, як працюють реальні логістичні системи.
    По-перше, щодо персоналки і «абсурду». Суть не в тому, щоб просто повернути водію його ж дані. Водій присилає хаотичний текст із PII, який нам треба розпарсити і покласти в базу (TMS) клієнта. LLM тут працює суто як NLU-процесор. Scrubber маскує дані, LLM розпізнає намір і віддає JSON з токенами (типу [PHONE_0]), а бек вже підставляє реальні значення з пам’яті і пише в БД. Дані закритий контур не покидають, тому з GDPR тут все ок.

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

    По-третє, про Zero Trust. Сам Scrubber — це Data Privacy, так. А от Zero Trust у нас реалізований на рівні інфраструктури. Сервіси дефолтно не довіряють одне одному. API не має прямого доступу до бази чи LLM. Секретами рулить Vault Agent (через AppRole), який динамічно їх ротує через in-memory (tmpfs) volume. Плюс у базі налаштований PostgreSQL RLS. Навіть якщо API скомпрометують, без підписаного JWT і правильного tenant_id база фізично не віддасть чужі рядки.

    А з бенчмарками згоден на 100%. Власне, щоб не ловити мережеві затримки на кожному запиті до Vault, ми й затягнули Sidecar патерн — тепер читаємо все миттєво з оперативки.

  • Побудував Zero Trust AI-систему диспетчеризації для логістики. Рознесіть мою архітектуру!

    Тут нас рятує математика) Усі tenant_id у базі — це UUIDv4. Тому класичний брутфорс відпадає одразу.

    Навіть якщо уявити найгірший сценарій: хакер має RCE, дорвався до відкритого з’єднання з БД і починає в циклі слати SET LOCAL rls.tenant_id = ’рандомний_uuid’ — вірогідність влучити в існуючого клієнта прагне до нуля. Йому просто життя не вистачить перебрати варіанти.

    Щодо «дискавері» — у скомпрометованому контексті немає жодної таблиці, звідки можна було б витягнути загальний список цих ID (для загальних таблиць теж працює RLS або жорсткі гранти).

    Плюс, такий шквал запитів «навмання» моментально підніме алерти в моніторингу бази (наприклад, через аномальну кількість помилок чи нетипове навантаження). Тобто без знання конкретного UUID іншого тенанта зловмисник залишається сліпим і надійно замкненим у своїй пісочниці.

  • Побудував Zero Trust AI-систему диспетчеризації для логістики. Рознесіть мою архітектуру!

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

    Флоу працює десь так:

    Приходить запит від юзера (водія або диспетчера). Ми дістаємо його tenant_id з JWT і відразу на рівні з’єднання з БД робимо SET LOCAL app.current_organization_id = ’...’.
    В роботу вмикається Scrubber: він замінює чутливі дані на маски (наприклад, номер -> [PHONE_1]).
    Відправляємо анонімізований текст в LLM, отримуємо відповідь.
    Ми зберігаємо в базу сам лог діалогу і поруч у захищене поле (vault_snapshot) кладемо мапу підстановок {«[PHONE_1]»: «+380...»}.
    Коли авторизований диспетчер завантажує лог, бекенд прямо в пам’яті робить зворотну підстановку (де-маскування) і віддає на фронтенд чисті дані.
    Чому це безпечно при RCE: Оскільки для будь-якої транзакції у нас жорстко заданий правильний tenant_id (витягнутий з криптографічно підписаного JWT), RLS на рівні ядра Postgres фільтрує всі таблиці.

    Тобто, якщо зловмисник через RCE спробує виконати довільний запит типу SELECT * FROM messages (щоб вкрасти ті самі vault_snapshots), Postgres віддасть йому виключно дані того tenant_id, під яким зараз обробляється скомпрометований запит. Злити базу інших клієнтів (горизонтальне переміщення) він фізично не зможе. Якось так :)

  • Побудував Zero Trust AI-систему диспетчеризації для логістики. Рознесіть мою архітектуру!

    Слушне зауваження, від RCE жоден код не застрахований на 100%. Але ми якраз будували архітектуру з розрахунком на Assume Breach (периметр рано чи пізно можуть пробити). Тому «злити всі дані» буде проблематично:

    По-перше, у Vault налаштовані жорсткі політики. Навіть якщо поламати Scrubber і прочитати /vault/secrets/config.json чи знайти токен агента, витягнути з Vault щось інше не вийде. Токен просто не має доступу до чужих ключів (Least Privilege).

    По-друге, база. Припустимо, кредоси дістали, але там працює Row-Level Security. Без підписаного JWT і правильного Tenant ID Postgres фізично не віддасть рядки інших клієнтів, фільтрація йде на рівні ядра.

    Ну і третє — самі контейнери. API-контейнер крутиться від non-root юзера і з read_only: true. Закинути і виконати якийсь сторонній payload буде вкрай складно, коли файлова система тупо закрита на запис.

    Коротше кажучи, хакер дійсно може скомпрометувати конкретний вузол, але архітектура не дасть йому розповзтися далі (Lateral Movement). Що скажете про такий сетап?