Alibaba intervjuer: "Kažeš da tvoj projekat koristi RAG, nije li to stvar jedne linije koda?" — odgovaram: "Vektorsko skladištenje, hibridno pretraživanje, citiranje dokumenata — sve preko direktnog API poziva?"
U razvoju AI aplikacija dva najčešća poslovna scenarija su RAG i Agent.
Ako vam na biografiji stoji i RAG i Agent, u suštini ste već nepobedivi.
Neki možda misle da je, uz SpringAI, razvoj RAG-a stvar jedne linije koda, ali nije tako — vektorski chunk, vektorsko skladištenje, pretraga sličnosti, sklapanje Prompta i citiranje dokumenata skrivaju pravu nauku.

Uzeću PaiSmart RAG kao primer da vam rastavim ideju implementacije citiranja dokumenata u RAG-u, i kako na intervjuu tu tačku izložiti do kraja.
Ovo je stvarni scenario sa kojim se jedan učenik susreo na intervjuu.

01. Pozadina problema
U PaiSmart RAG projektu format citata koji koristimo je:
(izvor#broj: ime datoteke)
Na primer, kada RAG pronadje dokument, u odgovoru koji LLM generiše pojaviće se citat poput ovog:
Pozicija projekta: PaiFlow je opisan kao projekat "sličan Dify-ju, motor radnih tokova",
namenjen podršci razvoju aplikacija u AI eri
(izvor#2: ✅Šta PaiFlow donosi učenicima.docx).
Jezgro mehanizma: njegov motor radnih tokova počiva na dizajnu "DSL-pogonjen + odvojeni izvršioci čvorova + izolacija bazena promenljivih", pokreće proces izvršenja analizom JSON DSL-a koji generiše front-end (opisuje DAG graf čvorova i grana)
(izvor#4: ✅Šta PaiFlow donosi učenicima.docx).Kada korisnik klikne na citat, front-end šalje zahtev za preuzimanje, back-end na osnovu imena datoteke traži odgovarajući dokument u bazi, a zatim ga vraća korisniku.
Ali ovde postoji rupa.
Na primer, korisnik 1. februara otpremi datoteku pod imenom "test1.txt", sa sadržajem o tome kako se Wang Er popeo na drvo. Sistem generiše jedinstvenu MD5 heš vrednost za tu datoteku, recimo AAA.

- februara otpremi još jednu datoteku, takođe pod imenom "test1.txt", ali ovog puta o tome kako se Wang Er ponovo popeo na drvo ove sedmice. Sistem generiše drugu MD5 heš vrednost, BBB.
Zatim pita sistem: "Popeo li se Wang Er na drvo?"
RAG sistem tačno pronalazi relevantan sadržaj iz datoteka AAA i BBB, LLM daje odgovor i na kraj dodaje citat: "(izvor#1: test1.txt)".
Tada nastaje haos.
02. Rešenje
Gde je problem?
Kada back-end primi zahtev za preuzimanje, raščlani da je fileName test1.txt, zatim izvrši findByFileName("test1.txt"). U bazi postoje dve datoteke istog imena, pa zbog internog sortiranja baze i nedeterminizma findFirst(), može vratiti datoteku AAA, ali i datoteku BBB.
Koren problema je u tome što smo za pronalaženje dokumenta koristili samo fileName, polje koje se može ponavljati, umesto jedinstvenog ID-a.
Jezgro rešenja je: u celom lancu "pretraga — generisanje — citiranje" uvek prosleđivati jedinstveni identifikator datoteke, a ne fileName koji se može ponavljati.
Ovaj jedinstveni ID može biti MD5 heš datoteke, ali i auto-inkrementalni fileId iz baze.
Konkretno, kako to uraditi?
Prvi korak: izmeniti RAG pretragu i konstrukciju Prompta.
Kada HybridSearchService pronadje relevantne delove dokumenta, ne treba uzeti samo tekstualni sadržaj tog dela, već i jedinstveni ID i ime datoteke kojoj taj deo pripada.
Prilikom konstrukcije Prompta koji se šalje LLM-u, format konteksta treba izmeniti u:
[izvor 1, ID: 'BBB', ime datoteke: 'projektni izveštaj.pdf']
Prošle sedmice glavni rad istraživačkog odeljenja bio je završetak refactorizacije modula za plaćanje, uključujući...Drugi korak: izmeniti instrukcije za LLM.
U System Prompt-u instrukcija za generisanje citata od strane LLM-a treba da se ažurira u:
Kada citiraš izvor, moraš strogo koristiti sledeći format: (izvor#broj: ime datoteke, ID: jedinstveni ID).
Na primer: (izvor#1: projektni izveštaj.pdf, ID: 'BBB')Treći korak: izmeniti logiku analize citata i preuzimanja na back-end-u.
Kada LLM vrati odgovor koji sadrži citat u novom formatu, logika analize na back-end-u se mora nadograditi. Više nije dovoljno poklapati samo (izvor#broj: ime datoteke), već treba poklapati (izvor#broj: ime datoteke, ID: jedinstveni ID).
Nakon analize dobijaju se istovremeno fileName (za prikaz na front-end-u) i fileId (za pretragu na back-end-u).
Kada korisnik klikne na link za preuzimanje, front-end šalje jedinstveni fileId back-end-u.
Download interfejs na back-end-u se menja iz findByFileName(fileName) u findById(fileId).
Tako više neće biti pogrešno pronadjen dokument.
03. Kako ovo upisati na biografiju?
Kako ovu tehničku tačku upisati na biografiju?
Ime projekta: PaiSmart RAG — enterprise sistem za pametno pitanje-odgovor
Opis projekta: enterprise sistem za pitanje-odgovor nad bazom znanja, zasnovan na tehnologiji RAG (Retrieval-Augmented Generation). Podržava otpremanje dokumenata, vektorsko skladištenje, semantičku pretragu i pametno odgovaranje, a pruža i funkciju citiranja dokumenata radi obezbeđivanja proverivosti i tačnosti AI odgovora.
Jezgro tehnološkog steka: Java 17, Spring Boot 3.x, SpringAI, MyBatis-Plus, Redis, Milvus vektorska baza podataka, Vue 3
Jezgro odgovornosti:
- Dizajn i implementacija mehanizma citiranja dokumenata zasnovanog na jedinstvenom identifikatoru, kojim se rešava problem dvosmislenosti citiranja između datoteka istog imena i osigurava da korisnik klikom na link za citat tačno preuzme originalni dokument
- Izmena lanca RAG pretrage tako da rezultat vektorske pretrage uz tekstualni sadržaj istovremeno vraća i jedinstveni ID datoteke (MD5) i ime datoteke, a da se u fazi konstrukcije Prompta ID prosleđuje LLM-u
- Optimizacija System Prompt-a za LLM, standardizacija formata citata u
(izvor#broj: ime datoteke, ID: jedinstveni ID), radi potpunosti i sledljivosti informacija o citatu - Refactorizacija logike analize citata na back-end-u, uz korišćenje regularnih izraza za poklapanje novog formata citata i pretragu dokumenta na osnovu fileId-a umesto fileName-a, čime se izbegavaju greške u preuzimanju zbog datoteka istog imena
Priča za intervju:
U PaiSmart RAG projektu zadužen sam za dizajn i implementaciju funkcije citiranja dokumenata. U početku smo kao identifikator citata koristili ime datoteke, ali smo uočili problem: kada korisnik otpremi više datoteka istog imena, pojavljuju se greške u citiranju. Na primer, dve različite datoteke "projektni izveštaj.pdf" mogu dovesti do toga da sistem vrati pogrešnu.
Da bih rešio taj problem, dizajnirao sam rešenje celog lanca zasnovano na jedinstvenom identifikatoru. Već u fazi RAG pretrage prosleđuje se MD5 heš datoteke, pri konstrukciji Prompta se ID informacija ugrađuje u kontekst, a istovremeno se menja instrukcija za generisanje LLM-a, tako da citat izbacuje u fiksnom formatu. Prilikom analize na back-end-u izdvaja se fileId i na osnovu njega traži dokument, umesto preko fileName-a koji se može ponavljati.
04. Uobičajena dodatna pitanja na intervjuu
Pitanje 1: Zašto već pri otpremanju dokumenata ne zabranite datoteke istog imena?
Odgovor: U poslovnim scenarijima to nije realno. Različita odeljenja mogu generisati istoimene dokumente, npr. svi se zovu "projektni izveštaj.pdf", a prisilno preimenovanje bi narušilo korisničko iskustvo. Zato je naš pristup da dozvolimo isto ime, ali da ih razlikujemo preko jedinstvenog ID-a.
Pitanje 2: Ako se sadržaj datoteke ažurira, MD5 će se promeniti — šta je sa prethodnim citatima?
Odgovor: Trenutno, nakon što se datoteka ažurira i ponovo otpremi, generiše se novi MD5, a citati na stari dokument prestaju da važe. Za potpuno rešenje može se razmotriti uvođenje mehanizma verzija.
Pitanje 3: Kako izgleda regularni izraz za analizu citata?
Odgovor: Koristimo regularni izraz \((izvor)#(\d+):\s*([^,]+),\s*ID:\s*'([^']+)'\). On broj posle # hvata kao redni broj citata, a uhvati i ime datoteke i jedinstveni ID. U stvarnoj upotrebi dodata je i tolerancija na greške, npr. razmaci, velika i mala slova.
Završna reč
Ovaj problem sa citiranjem dokumenata, na površini deluje kao mali bag, ali u pozadini zapravo vodi ka inženjerskim razmišljanjima o konzistenciji podataka, dizajnu jedinstvenosti i prenošenju kroz čitav lanac.
To su stvari koje se ne uče na predavanjima — samo kada zaista radiš projekat i nagaziš na minu, stičeš osećaj za njih.
"Ono što te zaista može izdvojiti na intervjuu nisu kičasti nazivi, već tvoja kontrola detalja i duboko promišljanje o problemu."
Zato uvek naglašavam: projekat ne radi samo na površini — zaroni u svaki detalj, razumi zašto se radi tako i da li postoji bolje rešenje.
Na kraju, pošaljite vam Ergov moto: ništa me ne zadržava — osim cilja; iako na obali ima ruža, hlada i mirne luke, ja sam čamac bez vezanog užeta. Hrabro napred.
