AI · Automatizacija · Inženjering

Agent koji radi bez čoveka: primer sa fakturama od A do Ž

Piše Lazar MilićevićOctober 22, 202610 min čitanja
Laptop and paper invoices on a desk, illustrating automated invoice processing with an AI agent

Najčešći zahtev koji dobijam od firmi je zapravo isti: "imamo jedan dosadan posao koji neko radi svaki dan, može li to da radi AI". Skoro uvek može, ali odgovor na pitanje "kako" retko uključuje reč "agent". U ovom tekstu prolazim kroz jedan realan primer korak po korak, uključujući zamke koje sam sâm pokupio i način na koji proveravam da sistem ne radi gluposti dok niko ne gleda.

Prvo odluči da li ti uopšte treba agent

Većini dosadnih poslova ne treba agent nego workflow: unapred definisan niz koraka u kodu, u kome LLM obavlja jedan ili dva koraka koja traže razumevanje teksta. Agent, gde model sam odlučuje koje alate zove i kojim redom, opravdan je tek kad putanja zadatka ne može da se predvidi unapred.

Anthropic u vodiču "Building effective agents" preporučuje da se krene od najjednostavnijeg rešenja i da se složenost dodaje samo kad je potrebna, a to ponekad znači da agentskog sistema uopšte nema (Building effective AI agents, Anthropic). Razlikuju workflows (LLM i alati vođeni putanjama definisanim u kodu) od agents (LLM sam usmerava svoj proces i korišćenje alata). Ja tu razliku koristim kao prvi filter na svakom projektu.

Moj test od tri pitanja:

Pitanje Ako je odgovor "da"
Mogu li da nacrtam sve korake na papiru, uključujući grane? Workflow, bez agenta
Da li ulaz uvek ima isti oblik (isti tip dokumenta, isti format)? Workflow
Da li broj i redosled koraka zavisi od onoga što se usput otkrije? Tek tada razmisli o agentu

Primer koji koristim u nastavku je tipičan za domaće SMB firme: obrada ulaznih faktura koje stižu mejlom. Neko u računovodstvu ili administraciji svako jutro otvara inbox, preuzima PDF-ove, prepisuje dobavljača, iznos, broj fakture i rok plaćanja u tabelu ili ERP, i traži one koje se ne poklapaju sa narudžbenicom. Posao je dosadan, repetitivan i skup po satu, a pritom ima prirodnu tačku gde zatreba prosuđivanje (neobična faktura).

Ovde je prava arhitektura hibrid: workflow za većinu slučajeva, a agentski deo samo za izuzetke. Tačan odnos zavisi od tvojih podataka, a kako ga izmeriti, opisujem u prvom koraku. Ostatak vodiča je zato o tome kako se to gradi.

Korak 1: Izmeri posao pre nego što napišeš liniju koda

Pre bilo kakvog koda zapiši tri broja: koliko stavki dnevno ili nedeljno, koliko minuta po stavki i koliko košta greška. Bez toga nikad nećeš znati da li je automatizacija uspela, a ni da li je vredela.

Na projektu sa 4-system automation ecosystem-om, koji je doneo 73+ sati uštede mesečno i 192% Year-1 ROI, najvažniju stvar uradio sam pre prve linije koda: nedelju dana sam samo posmatrao ljude kako rade i beležio vreme. Većina "dosadnog posla" nije bila ono što su mi na početku opisali. Ljudi su precenili vreme na prepisivanje, a potcenili vreme na "traženje onoga što fali" i na slanje mejlova dobavljačima.

Za fakture bih zapisao:

  • broj faktura nedeljno i procenat u kome je format isti (isti dobavljač, isti šablon)
  • prosečno vreme po fakturi i vreme po izuzetku
  • šta je "izuzetak" (nema narudžbenice, iznos se ne poklapa, nova valuta, nečitljiv sken)
  • cena greške: kasno plaćanje, dupla uplata, pogrešan konto

Ako iz ovoga ispadne da je ukupna količina rada mala, nemoj ništa automatizovati, bolje je da vreme uložiš negde drugde. Automatizacija ima svoj trošak održavanja i on mora biti manji od uštede.

Korak 2: Napravi deterministički kostur, LLM stavi samo gde mora

Kostur je običan kod: ulaz, validacija, ekstrakcija, provera, upis, izlaz. LLM zove samo korak koji zahteva razumevanje nestrukturiranog teksta, u ovom slučaju ekstrakciju polja iz fakture.

def obradi_fakturu(pdf_bytes: bytes) -> Rezultat:
    tekst = izvuci_tekst(pdf_bytes)            # OCR/parser, bez LLM-a
    polja = llm_ekstrakcija(tekst)             # jedini LLM korak
    greske = validiraj(polja)                  # čist kod, pravila
    if greske:
        return u_red_za_ljude(pdf_bytes, polja, greske)
    if not poklapa_narudzbenicu(polja):
        return u_red_za_ljude(pdf_bytes, polja, ["nema_poklapanja_np"])
    upisi_u_erp(polja)
    return Rezultat(status="automatski", polja=polja)

Nekoliko odluka koje se isplate:

  1. Ekstrakcija vraća strogu šemu (JSON sa tipovima), ne slobodan tekst. Odbaci sve što ne prolazi šemu pre nego što dotakne ostatak sistema.
  2. Validacija je kod, ne model. Zbir stavki mora da bude jednak iznosu, PIB mora da ima ispravnu dužinu, datum mora da bude u razumnom opsegu. Model ne proverava sam sebe.
  3. Svaki "ne znam" ide čoveku. Red za ljude nije neuspeh sistema, to je njegov najvažniji deo.

Ovaj princip, determinizam oko LLM-a, isti je onaj koji koristim u ContentStudio-u, mom autonomnom sistemu za sadržaj i SEO: model piše i procenjuje, ali kod odlučuje šta sme da se objavi.

Korak 3: Dodaj agenta samo za izuzetke, sa čvrstim ogradama

Agent ulazi tek za slučajeve koje kostur ne može da reši, na primer "faktura nema narudžbenicu, pronađi najverovatniju ili objasni zašto je nema". Tu putanja zaista zavisi od onoga što se otkrije, pa je agentska petlja opravdana.

Za gradnju možeš da koristiš Claude Agent SDK. To je biblioteka koja pokreće Claude Code binarni fajl sa njegovim ugrađenim alatima, dozvolama, sesijama i hook-ovima, namenjena ugradnji agenta u sopstvenu Python ili TypeScript aplikaciju (Agent SDK overview). Možeš koristiti i druge okvire, princip ograda je isti.

Agentu dajem minimalan skup alata, ne više nego što posao traži:

  • čitanje: pretraga narudžbenica, pretraga dobavljača, čitanje istorije faktura
  • pisanje: samo "predloži" (upisuje predlog u red za ljude), nikad "knjiži"

Poslednja stavka je ključna. Agent za izuzetke ne sme da menja finansijske podatke, samo da priprema predlog koji čovek brzo potvrđuje. Ilustrativno: posao koji je ranije tražio dugo traženje po sistemu svodi se na kratko odobravanje. Rizik time ne nestaje, ali se bitno smanjuje, jer poslednju reč ima čovek, a i on može da pogreši, zato ostaje i audit trag.

Korak 4: Zaključaj dozvole, jer neće biti nikoga da klikne "Allow"

Agent koji radi bez čoveka mora imati dozvole definisane unapred, jer u neinteraktivnom režimu nema ko da odobri prompt. Claude Code u sesijama koje ne mogu da prikažu prompt (npr. pozadinski subagenti u neinteraktivnom režimu) ipak pokreće PermissionRequest hook-ove, a ako nijedan ne vrati odluku, poziv alata se odbija (Hooks reference). Dakle, ako ne napišeš pravila, agent će stajati i odbijati, što je bezbedno, ali beskorisno.

Tri zamke koje sam sâm video ili izbegao:

Zamka 1: allowed_tools nije ograda. Ta opcija samo automatski odobrava navedene alate, ne ograničava agenta na njih. Za blokiranje se koristi disallowed_tools (Agent SDK reference, Python). Ko pomisli da je listom dozvoljenih alata zaključao agenta, ostaje sa agentom koji ima pristup svemu ostalom.

Zamka 2: redosled pravila. U Agent SDK dokumentaciji deny ima prednost nad ask, a ask nad allow, a ako bilo koji hook vrati deny, operacija je blokirana bez obzira na ostale hook-ove (Hooks, Claude API Docs). Zato opasne stvari stavljaj u deny pravila: ona ostaju blokirana čak i u bypassPermissions režimu (Configure permissions).

Zamka 3: nema audit traga. PreToolUse hook može da blokira ili izmeni poziv alata (npr. da zaustavi opasnu shell komandu), a PostToolUse služi za audit trail, na primer logovanje svake izmene (Hooks, Claude Code Docs). Svaki poziv alata u produkciji logujem sa ulazom, izlazom i vremenom. Kad se nešto čudno dogodi u tri ujutru, log je jedino što imaš.

Ovo nije paranoja. OWASP je u izdanju 2025 svoje liste Top 10 za LLM aplikacije proširio stavku LLM06 "Excessive Agency" zbog sve veće upotrebe agentskih arhitektura, uz upozorenje da neproverene dozvole mogu dovesti do neželjenih ili rizičnih akcija (OWASP Top 10 for LLM Applications 2025). Preporuka je jednostavna: daj agentu najmanje što mu treba.

Korak 5: Verifikuj pre nego što pustiš da radi sam

Verifikacija ima tri sloja i svaki hvata drugu vrstu greške. Preskočiš li bilo koji, prvi put ćeš za grešku saznati od oštećene strane.

Sloj 1: zlatni skup. Uzmi nekoliko desetina do stotinak stvarnih faktura iz prošlosti čiji su tačni podaci već uneti ručno (to je moja praktična smernica, ne pravilo). Pusti sistem preko njih i uporedi polje po polje. Tačan broj nije magija, bitno je da skup sadrži i čiste slučajeve i ružne (iskrivljeni skenovi, dve valute, faktura bez broja). Ako postoji dobavljač koji ti uvek pravi probleme, njegove fakture moraju biti u skupu.

Sloj 2: senka (shadow mode). Nedelju-dve sistem radi paralelno sa čovekom, ali ništa ne upisuje. Samo beleži šta bi uradio. Na kraju svakog dana uporediš. Senka hvata ono što zlatni skup ne može: nove formate, nove dobavljače i probleme koji nastaju tek kad se pojavi stvarni obim.

Sloj 3: postepeno puštanje. Prvo automatski upisuje samo najsigurniji deo (poznati dobavljači, mali iznosi, savršeno poklapanje), sve ostalo ide u red za ljude. Prag se pomera tek kad podaci pokažu da je bezbedno. Jedna stvar koju radim uvek: nasumično uzorkujem i proveravam i ono što je prošlo automatski, jer sistem koji nikad ne greši na papiru obično greši tiho.

Šta mereći pratim posle puštanja:

  • procenat faktura koje prođu bez čoveka (stopa automatizacije)
  • procenat ispravki koje ljudi naprave nad onim što je sistem upisao
  • vreme od prijema do upisa
  • broj izuzetaka po dobavljaču (otkriva dobavljača koji menja format)

Ako se stopa ispravki penje, sistem se kvari ili se svet promenio. Alarm mora da postoji pre nego što se to desi.

Pravni okvir koji se ne sme preskočiti

Ovde ne dajem pravni savet, nego tačke koje treba proveriti sa pravnikom. Dve stvari su relevantne za agente koji rade bez nadzora.

Prvo, GDPR član 22(1) daje pravo da se ne bude podvrgnut odluci zasnovanoj isključivo na automatskoj obradi koja proizvodi pravne ili slično značajne efekte, uz pravo na ljudsku intervenciju, izražavanje stava i osporavanje odluke (Article 22 GDPR). To se odnosi na obradu podataka lica u EU i ne važi automatski za svaku firmu u Srbiji. Srpski Zakon o zaštiti podataka o ličnosti takođe uređuje automatizovano odlučivanje; konkretne odredbe proveri u važećem tekstu zakona (Službeni glasnik RS) ili kod pravnika. Faktura sa podacima dobavljača pravnog lica retko pogađa ovo pravilo, ali agent koji odlučuje o ljudima (zaposlenima, kandidatima, klijentima) pogađa.

Drugo, EU AI Act. Posle Digital Omnibus-a (Regulation (EU) 2026/1744, objavljen u Službenom listu EU 24. jula 2026, na snazi od 27. jula 2026) obaveze za samostalne visokorizične sisteme iz Aneksa III primenjuju se od 2. decembra 2027, umesto ranije od 2. avgusta 2026 (Cooley, FPF). Obaveze transparentnosti iz člana 50 (obaveštavanje ljudi da komuniciraju sa AI sistemom, označavanje AI sadržaja) važe od 2. avgusta 2026, uz odlaganje do 2. decembra 2026 samo za zahtev za označavanje sadržaja iz člana 50(2) za sisteme koji su već na tržištu (Cloud Security Alliance). Za interni agent za fakture to verovatno nije presudno, ali ako agent komunicira sa dobavljačima ili klijentima (šalje mejlove u tvoje ime), obaveštavanje da razgovaraju sa AI postaje tema. Pre citiranja konkretnog člana proveri tekst na EUR-Lex-u.

Šta bih ja uradio

Da me firma pozove sutra sa pitanjem "automatizuj nam ovaj dosadan posao", ovo je redosled kojim bih išao:

  1. Nedelju dana merenja, bez ijedne linije koda. Brojevi odlučuju da li se posao uopšte isplati.
  2. Workflow pre agenta. Kostur u običnom kodu, LLM samo za ekstrakciju. Agent tek ako izuzeci to stvarno traže.
  3. Agent samo predlaže, čovek potvrđuje za sve što dotiče novac ili podatke o ljudima. Autonomija se zaslužuje podacima, ne unapred.
  4. Dozvole napisane pre prvog pokretanja, sa deny pravilima za opasne stvari i audit logom svakog poziva.
  5. Senka pa postepeno puštanje, sa metrikama koje alarmiraju kad se kvalitet pomeri.

Ne preporučujem da počneš od najambicioznijeg procesa. Biraj onaj koji je dosadan, čest, dobro definisan i gde greška nije katastrofalna. Prva pobeda gradi poverenje u firmi, a bez poverenja sledeći projekat nikad ne dobije budžet.

Ako imaš u firmi jedan takav posao i nisi siguran da li mu treba agent, workflow ili ništa od toga, javi se na lazar-milicevic.com/#contact. Rado ću ti reći šta bih ja uradio, i ako je odgovor "ne automatizuj", i to ću ti reći.

Često postavljana pitanja

Da li mi za automatizaciju dosadnog posla uopšte treba AI agent?

Najčešće ne, jer većini repetitivnih poslova više odgovara workflow, odnosno unapred definisan niz koraka u kodu u kome LLM obavlja samo jedan ili dva koraka. Agent, gde model sam bira alate i redosled, opravdan je tek kada putanja zadatka ne može da se predvidi unapred. Kao prvi filter koristim tri pitanja: mogu li sve korake da nacrtam na papiru, ima li ulaz uvek isti oblik i zavisi li redosled koraka od onoga što se usput otkrije. Ako je odgovor na prva dva "da", dovoljan je workflow.

Kako izgleda automatizacija obrade ulaznih faktura koje stižu mejlom?

Gradim je kao deterministički kostur: ulaz, validacija, ekstrakcija, provera, upis i izlaz. LLM se poziva samo za ekstrakciju polja iz fakture, a sve ostalo, uključujući proveru zbira stavki, PIB-a i datuma, radi običan kod. Ako validacija ili poklapanje sa narudžbenicom ne prođu, faktura ide u red za ljude umesto da se upiše u ERP. Tako većina faktura prolazi automatski, a izuzeci stižu do čoveka.

Šta treba da izmerim pre nego što automatizujem neki posao?

Pre prve linije koda zapišem tri broja: koliko stavki ima dnevno ili nedeljno, koliko minuta traje jedna stavka i koliko košta greška. Kod faktura beležim i procenat onih sa istim formatom, vreme po izuzetku i šta se smatra izuzetkom. Na jednom projektu sam nedelju dana samo posmatrao ljude kako rade i ispostavilo se da su precenili vreme prepisivanja, a potcenili vreme traženja onoga što fali i slanja mejlova dobavljačima. Ako je ukupna količina rada mala, automatizacija se ne isplati jer ima trošak održavanja.

Zašto validaciju podataka iz LLM-a treba raditi kodom, a ne modelom?

Model ne proverava sam sebe, pa pravila proveravam običnim kodom. Zbir stavki mora da bude jednak iznosu, PIB mora da ima ispravnu dužinu, a datum mora da bude u razumnom opsegu. Ekstrakcija treba da vraća strogu JSON šemu sa tipovima, a sve što ne prolazi šemu odbacujem pre nego što dotakne ostatak sistema. Svaki slučaj "ne znam" ide čoveku, što je najvažniji deo sistema, a ne njegov neuspeh.

Kada u automatizaciji faktura treba uvesti agenta i kakve ograde mu postaviti?

Agenta uvodim samo za izuzetke koje kostur ne može da reši, na primer kada faktura nema narudžbenicu pa treba pronaći najverovatniju ili objasniti zašto je nema. Tu putanja zaista zavisi od onoga što se otkrije, pa je agentska petlja opravdana. Agentu dajem minimalan skup alata: čitanje (pretraga narudžbenica, dobavljača i istorije faktura) i samo opciju "predloži", nikad "knjiži". Finansijske podatke menja čovek koji brzo potvrđuje pripremljen predlog.

Lazar Milicevic

Lazar Milićević

Senior Technical Engineer. Gradim AI automatizaciju, GenAI/LLM sisteme i cloud arhitekturu — autonomne sisteme koji rade dok spavaš. Osnivač BizFlowAI.

Gradiš nešto teško sa AI-jem ili automatizacijom? Otvoren sam za razgovor.

Javi se

← Svi postovi