UI in izvorna gradiva: Kako preprečiti halucinacije LLM-ja
UI in izvorna gradiva: Kako preprečiti halucinacije LLM-ja
TL;DR. „Halucinacija" LLM-ja je simptom, ne diagnoza. Diagnoza je: slabo pridobivanje in/ali slabo navajanje virov. Ta članek opisuje, kako zgraditi odgovore UI na dokumentih stranke tako, da ima vsaka trditev referenco na konkreten odlomek konkretnega dokumenta — in vsak razvijalec odgovor preveri v 10 sekundah. Pristop: obvezno navajanje virov pri generiranju + hibridno pridobivanje + strukturiran zajem + soliden eval-set.
1. Problem: „UI si je to izmislil"
Prizor: Asistent UI je bil uveden na dokumentih stranke. Teden pozneje vodja oddelka zapiše: „Rekel je, da naš pravilnik pravi X. Odprl sem pravilnik — X tam ni. Kaj zdaj?"
Če je odgovor ekipe „no, to je halucinacija LLM-ja, to se dogaja, bomo delali na pozivu" — je projekt mrtev. Stranka je izgubila zaupanje, zaupanje pa se redko vrne.
To je rešljiv problem. Rešitev je arhitekturna, ne „prositi LLM, naj bo bolj previden." Ključna ideja: Vsaka trditev v odgovoru mora imeti referenco na konkreten odlomek konkretnega dokumenta, referenca pa mora biti samodejno preverljiva.
2. Za koga je to relevantno
- Regulirane panoge: varnost pri delu, medicina, pravo, računovodstvo — kjer „UI se je zmotil" = škoda.
- Interne baze znanja: kjer zaposleni morajo zaupati sistemu in hitro preveriti.
- Podpora strankam: kjer napačen odgovor pomeni vračilo / pritožbo / izgubo stranke.
- Vsak projekt, kjer se „UI je odgovoril" sčasoma preveri s strani človeka — čas tega preverjanja pa se pomnoži s tisoč poizvedbami.
3. Pogosta napaka
- Vzeti standardno predlogo RAG: razdeljevanje → vdelave → top-K → LLM.
- Predpostavljati „LLM je pameten, sam bo poiskal vire."
- Prejemati odgovore brez navedbe virov. Ali navedbe v slogu „skladno z dokumentom X" — brez številke strani.
- Ko odvetnik vpraša „pokažite mi točno kje" — ni odgovora.
Dodatne pasti:
- Razdeljevanje po številu znakov. Struktura dokumenta se izgubi. Tabele se razdelijo na pol.
- Samo gostoto retrieval. Točnih kod in identifikatorjev ni mogoče najti.
- Poziv „odgovarjaj samo iz konteksta" — brez naknadne validacije. LLM ga ignorira, ko hoče.
- Ni eval-seta za „zavrnitve." Nihče ni preveril, ali sistem dejansko zavrne odgovor, ko vir ne vsebuje odgovora.
4. Tehnični pristop: Strukturiran zajem + obvezno navajanje virov
Pipeline, kakršen bi moral biti:
flowchart LR RAW[PDF / DOCX / HTML] --> PARSE[Strukturiran razčlenjevalnik<br/>stran, oddelek, tabela] PARSE --> CHUNK[Pametno razdeljevanje<br/>spoštovanje strukture] CHUNK --> META[Obogatitev metapodatkov<br/>stran, oddelek, jezik] META --> EMB[Vdelave + FTS] EMB --> PG[(Postgres + pgvector)] QUERY[Vprašanje uporabnika] --> HYBRID[Hibridno pridobivanje<br/>BM25 + gosta + RRF] HYBRID --> RERANK[Prečni encoder rerank] RERANK --> PROMPT[Poziv z obveznim navajanjem virov] PROMPT --> LLM[LLM] LLM --> VALIDATE[Validator navedbe virov] VALIDATE -- ok --> ANSWER[Odgovor z oznakami<br/>doc:42#p:18#§:4.2] VALIDATE -- fail --> RETRY[Ponovitev s top-3 prisilno] RETRY --> VALIDATE
4.1. Strukturiran razčlenjevalnik
Ne „PDF → besedilo." Ampak „PDF → zaporedje (stran, oddelek, razpon znakov, besedilo, tabela?, slika?)." Za to:
- PDF —
pdfplumberalipymupdfz ohranitvijo koordinat. - DOCX —
python-docxz obhodom slogov. - Kompleksni skenirani dokumenti — OCR (Tesseract ali PaddleOCR) z zaznavanjem jezika.
4.2. Pametno razdeljevanje
Pravila, ki jih uporabljamo:
- Ne razdeliti stavka na pol.
- Ne razdeliti tabele.
- Če je oddelek kratek (< 500 žetonov), je cel oddelek = en odlomek.
- Če dolg — drseče okno 400 žetonov s prekrivanjem 80, ponastavitev na mejah oddelkov.
- Vsak odlomek nosi metapodatke:
{stran, oddelek, nadrejeni oddelek, jezik, URI vira}.
4.3. Poziv z obveznim navajanjem virov
Predloga (poenostavljena):
Odgovarjate samo na podlagi spodnjih odlomkov.
Vsaka trditev v odgovoru MORA končati z oznako
v obliki [doc:ID#chunk:N].
Če odlomki ne vsebujejo odgovora — odgovorite:
„Zagotovljeni viri ne vsebujejo odgovora na to vprašanje."
Ne dodajajte dejstev, ki niso v odlomkih.
Odlomki:
[doc:42#chunk:7] (stran 18, §4.2) ... besedilo ...
[doc:42#chunk:8] (stran 19, §4.3) ... besedilo ...
...
Vprašanje: {vprašanje}
4.4. Naknadna validacija
Po generiranju — preprosta koda:
def validate_citations(answer: str, allowed_chunk_ids: set[str]) -> bool:
sentences = split_sentences(answer)
for s in sentences:
markers = re.findall(r"\[doc:(\d+)#chunk:(\d+)\]", s)
if not markers:
return False # stavek brez navedbe vira
for doc_id, chunk_id in markers:
if f"{doc_id}#{chunk_id}" not in allowed_chunk_ids:
return False # navedba napačnega vira
return True
Ob neuspešni validaciji — ponoven klic LLM s prisiljenimi top-3 odlomki in strožjim pozivom. Če tudi to ne uspe — sistem odgovori „Viri ne vsebujejo odgovora."
5. Tabela: Merila za „pravo" navajanje virov
| Merilo | Šibko | Dobro | Odlično |
|---|---|---|---|
| Dokument identificiran | „skladno s pravilnikom" | „skladno s pravilnikom X" | ID-dokumenta + ime |
| Stran identificirana | ne | na koncu odstavka | pri vsakem stavku |
| Oddelek identificiran | ne | poglavje | poglavje + paragraf |
| Navedba samodejno preverljiva | ne | regex | strojno berljivo + hiperpovezava |
| Zavrnitev pri odsotnosti vira | ne | včasih | vedno |
| Eval-set za zavrnitve | ne | 5–10 vprašanj | 30+ testnih vprašanj |
6. SINTARIS mini primer
Worksafety Superassistant — naša najzahtevnejša implementacija z navajanjem virov. Korpus: ~3000 strani predpisov o varnosti pri delu (RU + EAES + EU) ter interni SOP-i stranke.
Kar je bilo narejeno:
- Strukturiran razčlenjevalnik z ohranitvijo (stran, oddelek, paragraf).
- Hibridno pridobivanje z prioriteto BM25 (predpisi so besedno bogati).
- Poziv z obveznim navajanjem virov + validator.
- Testni set z 30 „pastmi" (npr. „Kakšne so norme OVO za podvodno varjenje na višini?" — takšna norma ne obstaja, pričakovan odgovor: „ni mogoče najti").
- Eval-set s 120 resničnimi vprašanji z referenčnimi navedbami.
Metrike po 6 mesecih:
- Natančnost navedbe virov (navedba vodi do odlomka, ki dejansko podpira trditev): 94 %.
- Pravilnost zavrnitve (na testnem setu — pravilne zavrnitve): 96 %.
- Mediana zakasnitve: 2,1 sek. (vključno z rerankanjem).
- Pritožbe varnostnih inšpektorjev na četrtletje: 0.
Podrobnosti: Worksafety § 6 RAG pipeline.
7. Kontrolni seznam (15 točk) za RAG z obveznim navajanjem virov
- Razčlenjevalnik ohranja strukturo (stran, oddelek, paragraf) — ne „cel PDF kot blob."
- Razdeljevanje spoštuje strukturo — ne razdeljuje stavkov in tabel.
- Metapodatki (stran, oddelek) shranjeni v vsakem odlomku.
- Hibridno pridobivanje (BM25 + gosta + RRF) — ne samo vdelave.
- Prečni encoder rerank — Top-12 → Top-5.
- Predloga poziva zahteva oznake navedbe virov.
- Naknadna validacija preverja prisotnost oznak.
- Vzorec zavrnitve — „ni v virih" kot prvovrstno vedenje.
- Eval-set — najmanj 30 vprašanj z referenčnimi navedbami.
- Testni set za zavrnitve — najmanj 20 vprašanj brez odgovora.
- Natančnost navedbe virov je izmerjena — prikazana v Grafana, ne „ročno včasih."
- Stopnja zavrnitve je izmerjena — ločeno od natančnosti.
- Monitor drsenja — tedensko preverja, ali metrike niso padle.
- Prag pridobivanja — pri Top-1 rezultatu < X zavrni.
- Hiperpovezave v odgovorih — uporabnik klikne in vidi izvorno gradivo.
8. Tveganja
- Zakasnitev. Prečni encoder rerank + validacija dodasta 200–400 ms. Za poslovne scenarije v redu, slabo za klepet v realnem času. Rešitev: pogosto poizvedbo predpomni.
- „Preveč previdno." Če je prag previsok — sistem pogosto reče „ne vem." Odpravite s kalibracijo na eval-setu.
- Strukturirano razčlenjevanje kompleksnih PDF-jev. Skenirana tabele so še vedno zahtevne. Načrtujte čas za pregled OCR.
- Večjezikovne navedbe. Če so predpisi v ruščini, odgovori pa v slovenščini — oznake navedbe morajo biti jezikovno stabilne. Raje numerični ID-ji kot „§4.2."
9. Kaj storiti naprej
Če že imate pilot RAG, ki občasno „laže" — začnite z dvema korakoma:
- Vklopite poziv z obveznim navajanjem virov + validator.
- Zgradite testni set z 20 vprašanji, na katera v korpusu ni odgovora, in izmerite pravilnost zavrnitve.
Pogosto ta dva koraka zadostujeta, da dvignete kakovost iz „včasih pravilno" na „vedno pravilno ali pošteno zavrne."
Za celoten cikel — UI-pilot v 4–8 tednih vključuje izgradnjo RAG z obveznim navajanjem virov kot standardni vzorec. Za slovenska podjetja −25 % od 1. do 30. junija 2026.
10. Viri
- Lewis, P. et al. (2020). Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks. arXiv:2005.11401.
- Karpukhin, V. et al. (2020). Dense Passage Retrieval for Open-Domain Question Answering. arXiv:2004.04906.
- Cormack, G., Clarke, C., Buettcher, S. (2009). Reciprocal Rank Fusion outperforms Condorcet and individual rank learning methods. SIGIR '09.
- Liu, N. F. et al. (2023). Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172.
- pdfplumber — https://github.com/jsvine/pdfplumber
- PaddleOCR — https://github.com/PaddlePaddle/PaddleOCR
Sintaris gradi sisteme RAG s preverljivimi navedbami virov za podjetja v EU in SND. Odkrivalni klic — brezplačno, 30 minut.