← Natrag
Tehnologija

BEFORE INSERT triggeri: kako zaštititi DB od LLM halucinacija

RiNET Engineering· 15. lipnja 2026.· 4 min čitanja· 20 pregleda
BEFORE INSERT triggeri: kako zaštititi DB od LLM halucinacija
🎧 Poslušaj članak

U laboratorijskim uvjetima LLM modeli izgledaju savršeno. Daju koherentne odgovore, citiraju dokumente i rijetko priznaju neznanje. Ali kad ih spojiš na produkcijsku bazu podataka, dogodi se nešto što nijedan test set ne predviđa — model počinje generirati podatke koji izgledaju stvarno, a nisu. To nije bug. To je inherentna osobina generativne arhitekture. Model ne zna što ne zna. On samo nastavlja niz tokena. I kad mu nedostaje kontekst, on ga izmisli. Zato smo u RiNET Engineering razvili dual layer zaštitu koja kombinira PostgreSQL BEFORE INSERT triggere s persona-specific output filterom. Ne riječ je o teoriji. Ovo je arhitektura koju smo izvukli iz vatre nakon što smo doslovno vidjeli kako jedna izmišljena riječ putuje kroz šest tablica prije nego što smo je ulovili.

Priča počinje s deplojem RAG pipelinea za jednu infrastrukturnu firmu. Imali su dobro dokumentiranu tehničku dokumentaciju, clean vector embedding i solidan retrieval. Na papiru sve pet. Ali prvi tjedan produkcije pokazao je anomaliju. U tablici `incident_logs` pojavio se zapis s poljem `root_cause` koje je sadržavalo riječ "kavitacijska rezonanca". Problem? Taj termin ne postoji u njihovom vokabularu. Nije u dokumentaciji, nije u schemi, nije u povijesnim podacima. Model ga je generirao jer je fonetski i semantički zvučao uvjerljivo u kontekstu vibracija pumpe. Taj jedan red je prošao sve validacije na aplikacijskom layeru jer je bio JSON-validan i formatiran točno prema specifikaciji. Aplikacija nije imala šansu — ona provjerava strukturu, ne semantiku.

Problem je eskalirao brže nego što smo očekivali. Taj jedan termin je ušao u `materialized view` za izvještavanje. Odatle u `analytics_aggregates`. Pa u `alerts_config`. Pa u `dashboard_cache`. Pa u `export_reports`. Šest tablica u tri dana. I svaki put kad bi netko pogledao dashboard i vidio "kavitacijska rezonanca" kao validan uzrok kvara, dobio bi lažni signal. Netko bi mogao poslati tim na teren, naručiti opremu, pokrenuti proceduru. Sve na temelju podatka koji nikad nije postojao. To nije samo data quality problem. To je operativni rizik koji se mjeri u izgubljenim satima i potencijalno opasnim odlukama. I sve je krenulo iz jednog LLM outputa koji je prošao kroz aplikacijsku logiku neokrznut.

Naš odgovor je bio arhitektonski — schema-level zaštita koja ne ovisi o aplikacijskom kodu. Prvi layer je PostgreSQL BEFORE INSERT trigger na svakoj tablici koja prima LLM-generirane podatke. Trigger ne provjerava samo tip podataka ili format. On provjerava sadržaj protiv denylist vokabulara koji se dinamički puni iz audit loga. Svaki put kad model generira termin koji nije u referentnom rječniku, trigger baca EXCEPTION i zapisuje ga u `rejected_inserts` tablicu. Ključna stvar — trigger ne blokira samo očite gluposti. On blokira i fonetski slične konstrukcije, kombinacije riječi koje izgledaju kao da pripadaju domeni, a zapravo su halucinacija. To radimo preko regex patterna koji se generiraju iz svakog odbijenog unosa.

Drugi layer je dabi-persona output filter. To nije generički filter. To je skup persona-specific pravila koja definiraju što model smije reći u kontekstu određene domene. Na primjer, za infrastrukturnu firmu imamo personu "tehnički analitičar" koja ima strogo definiran vokabular i nikad ne koristi termine izvan tog skupa. Dabi filter radi na razini izlaznog tokena — prije nego što odgovor uopće stigne do aplikacije, on se presijeca kroz persona matricu. Ako termin nije u matrici, filter ga zamjenjuje s placeholderom ili odbija cijeli odgovor. Ovo nije post-processing. Ovo je integralni dio inference pipelinea koji smo ugradili u naš sovereign AI operativni sustav.

Ovaj pristup razvijamo na rinet.one — za detalje slobodno se javi.

Kombinacija ova dva layera daje ono što zovemo dual layer protection. Trigger na bazi hvata podatke koji su već prošli kroz aplikaciju — to je safety net za slučaj da filter propusti nešto ili da netko direktno upiše podatke kroz admin panel. Filter na izlazu hvata halucinacije prije nego što uopće dođu do baze. Zajedno pokrivaju 99.97% lažnih unosa prema našim internim mjerenjima. Preostalih 0.03% su rubni slučajevi koje rješavamo kroz manualni review queue. Nismo još došli do savršenstva, ali smo dovoljno blizu da operativni timovi mogu spavati mirno.

Audit log za rejected inserts je ključni dio arhitekture. Svaki odbijeni unos dobiva ID, timestamp, source query, generirani tekst i razlog odbijanja. Taj log ne služi samo za debugging. On je input za kontinuirano učenje triggera. Svaki tjedan pokrećemo batch job koji analizira rejected unose, traži obrasce i automatski ažurira denylist vokabular. Ako primijetimo da model sistematski generira termine iz određene semantičke grupe, dodajemo cijelu grupu u denylist. To je zatvorena petlja — što više model pokušava halucinirati, to trigger postaje precizniji. Nema više ručnog dodavanja riječi. Sustav uči iz vlastitih grešaka.

Konkretna implementacija nije komplicirana. Trigger funkcija u PostgreSQL-u ima manje od stotinu linija PL/pgSQL koda. Prima JSONB objekt, parsira ga rekurzivno, traži stringove, uspoređuje ih s denylist tablicom i baca EXCEPTION ako nađe match. Performanse su zanemarive — dodatnih 2-3 milisekunde po INSERT-u na tablicama s milijunima redova. Dabi filter dodaje još 5-10 milisekundi na strani aplikacije. Ukupno kašnjenje je ispod 15 milisekundi po transakciji. To je cijena koju svaki ozbiljan sustav plaća za integritet podataka. Pogotovo kad uzmeš u obzir da jedna halucinacija može pokrenuti lančanu reakciju koja košta više od cijele infrastrukture za monitoring.

Ovdje nema srebrnog metka. LLM halucinacije su inherentna karakteristika tehnologije, ne bug koji će netko popraviti u sljedećoj verziji. Možeš trenirati modele na čistijim podacima, možeš poboljšavati retrieval, možeš dodavati prompt engineering trikove — ali uvijek će postojati rubni slučaj gdje model izmisli nešto što zvuči uvjerljivo. Jedini način da se zaštitiš je da pretpostaviš da će se halucinacija dogoditi i da izgradiš arhitekturu koja je otporna na tu pretpostavku. BEFORE INSERT triggeri su jedan od najjeftinijih i najefikasnijih alata za to. Ne štite samo bazu. Štite odluke koje ljudi donose na temelju tih podataka. I to je, na kraju, jedina stvar koja stvarno vrijedi.

Ako te zanima ovakva arhitektura ili gradiš nešto slično za svoju instituciju — javi se preko rinet.one.

PostgreSQL triggersdata integrityschema protectionLLM hallucinationRi.NETsovereign AIAI operativni sustavCroatian AItehnologija

Zanima vas ovakva AI tehnologija?

RiNET gradi sovereign AI rjesenja za javni sektor i poduzeca - od civic intelligence do automatizacije nabave.

Kontaktirajte nas →
0 komentara

Komentari