Ugotovite sproti: načrtovanje programske opreme v dobi umetne inteligence
Esej

Ugotovite sproti: načrtovanje programske opreme v dobi umetne inteligence

Osama Alghanmi · 21. februar 2026

Ne potrebujete popolnega načrta že na začetku. Potrebujete smer in voljo, da izboljšujete, dokler se stvari ne zbližajo.

To sem se naučil, ko sem isto aplikacijo zgradil dvanajstkrat, jo zrušil in zgradil znova, dokler me sistem ni naučil, kaj želi biti.

Mit popolnega načrta vnaprej

Vsak programski projekt se začne enako: nekdo nariše škatle na tablo in razglasi: »To je arhitektura.« Običajno je veliko prikimavanja. Včasih se pojavi še druga tabla.

Potem pa dejansko začnete graditi in resničnost se pojavi nepovabljena.

Škatle ne pasejo. Podatki tečejo v napačno smer. Storitev, za katero ste mislili, da bo preprosta, ima sedemnajst robnih primerov. Do tretjega tedna pišete kodo, ki se tiho opravičuje tabli.

Trda resnica je: polne oblike svojega sistema ne morete poznati, preden ne zgradite njegovih delov. Zahteve lažejo. Uporabniki vas presenetijo. Obseg razkrije stvari, ki jih noben diagram ni napovedal.

In to je v redu. Težava ni v tem, da je bil vaš načrt napačen. Težava je v tem, da prvotni načrt obravnavate kot svetinjo.

Sčasoma doseženo ujemanje, a za vašo kodno zbirko

Če ste delali s porazdeljenimi sistemi, poznate pojem eventual consistency (sčasoma doseženo ujemanje): različna vozlišča v sistemu lahko v nekem trenutku vidijo podatke drugače, a ob dovolj časa in komunikacije se vsa zbližajo v isto stanje.

Z oblikovanjem vaše programske opreme je enako.

Začnete z nepopolnimi informacijami. Vaša arhitektura ima vrzeli. Vaše razumevanje področja je delno. Toda če ponavljate, in vsak krog naredi načrt malo bolj iskren, malo bolj usklajen z resničnostjo, se zbližate z nečim, kar res ustreza.

Cilj ni, da bi bilo takoj prav. Cilj je biti vedno manj zmoten.

Imenujmo to razvoj »Figure-It-Out-As-You-Go« (FIAYG), torej »ugotovi sproti«. Ni tako privlačno kot TDD ali DDD, a precej bolj iskreno glede tega, kako se programska oprema dejansko gradi.

Bistvo je: vsakič, ko se naučite kaj novega, iz hrošča, iz odziva uporabnikov, iz trka z mejo obsega, to znanje vgradite v arhitekturo. Ne popravite samo simptoma. Popravite sistem, da se simptom ne more ponoviti.

Kako smo zgradili Almadar (ali: zgodba o produktivnem kaosu)

Almadar je deklarativni okvir, ki sheme avtomatov stanj prevede v celovite aplikacije. Ena sama datoteka .orb opisuje vaše entitete, vedenja in uporabniški vmesnik, prevajalnik pa ustvari delujoč frontend v Reactu, zaledje v Expressu in modele podatkovne baze.

Tak je zdaj. Takole smo prišli do tja.

Stopnja 1: En sam projekt

Začelo se je preprosto. Imeli smo en projekt, stranko, ki je potrebovala poslovno aplikacijo z veliko operacijami CRUD. Napisali smo jo ročno, na običajen način: komponente React, poti Express, entitete TypeORM. Ponavljajoča se koda povsod.

Opazili smo, da vedno znova pišemo iste vzorce: tabelo za izpis zapisov, modalno okno za njihovo ustvarjanje, obrazec za urejanje in potrditev za brisanje. Kopiraj. Prilepi. Preimenuj. Ponovi.

Mora obstajati boljši način.

Zato smo poskusili: kaj če bi podatke in vedenje opisali v shemi JSON in iz nje ustvarili ponavljajočo se kodo?

Bilo je grobo. Shema je bila komaj strukturirana. Generator je bil nizovna predloga s klici fs.writeFileSync. A je delovalo. Stranka je bila zadovoljna. Oddajali smo hitreje.

Kar smo se naučili: teh 80 % vsake aplikacije, ki je ponavljajoča se koda, je mogoče opisati deklarativno. Tistih 20 %, ki je edinstvenih, pa je tisto, čemur dejansko želite posvetiti čas.

Stopnja 2: Druga stranka vse podre

Druga stranka je imela drugačne zahteve. Naš generator je bil preveč tesno vezan na vzorce prve stranke. Povsod smo trdo zapisali predpostavke: poimenovalne konvencije, strukturo datotek, hierarhijo komponent.

Lahko bi ga zakrpali. Namesto tega smo se ustavili in vprašali: Kako bi izgledala splošna različica tega?

Tu se je arhitektura začela kristalizirati. Uvedli smo pojem Orbitals, samostojne funkcijske module, ki združujejo entiteto (obliko podatkov), lastnost (trait, vedenje kot končni avtomat) in stran (pot). Shemo smo ločili od generiranja kode.

Kar smo se naučili: v trenutku, ko imate drugi primer uporabe, se vaše abstrakcije razkrijejo. Če se ne posploši, ni bila abstrakcija. Bila je naključje.

Stopnja 3: Monorepozitorij in omejitve

Ko je število projektov raslo, je rasel tudi kaos. Vsak projekt stranke je imel svoj oblikovalski sistem, svoje različice komponent, svojo predstavo o tem, kako izgleda »gumb«. Vzdrževali smo deset različic iste komponente.

Zato smo vse preoblikovali v monorepozitorij z izrecnimi pravili:

  • Jedrne komponente živijo v @almadar/ui, skupne, z verzijami, nikoli podvojene
  • Oblikovalski sistemi strank živijo v projects/{name}/design-system/, razširjajo jedro in ga ne nadomeščajo
  • Prevajalnik je v orbital-rust/, svet, brez razprave ga ne spreminjamo
  • Ustvarjena koda gre v projects/{name}/app/, nikoli se je ne ureja neposredno

Še pomembneje, dodali smo omejitve. Stroga pravila, ki jih ekipa zapiše v datoteko CLAUDE.md in jih mora upoštevati vsak razvijalec (človek ali umetna inteligenca):

  • Nikoli ne uporabljajte golih elementov HTML, vedno uporabite komponente oblikovalskega sistema
  • Najprej shema, uredite datoteko .orb, ponovno prevedite, ustvarjene kode se nikoli ne dotikajte
  • Prevajalnik je svet, dodajanje pravila zahteva izrecno odobritev

Te omejitve smo uveljavili z lastnim vtičnikom ESLint (@almadar/eslint). Ne neobvezna priporočila, ampak pravi errorji, ki blokirajo kavelj pred potrditvijo (pre-commit hook). Opozorila niso dovoljena. Nekatera pravila, ki smo jih zgradili:

PraviloKaj ujame
no-raw-dom-elementsPrepove <div>, <span>, <button> in podobno. Namesto tega uporabite VStack, Typography, Button
no-as-anyPrepove pretvorbe tipov as any. Popravite dejansko težavo s tipom
no-import-generatedPrepove uvoz iz projects/*/app/. Ustvarjena koda ni API
require-closed-circuit-propsVsaka komponenta mora sprejemati className, isLoading, error, entity
require-event-busInterakcije morajo uporabljati useEventBus(), ne golega onClick
require-display-nameVsaka komponenta mora nastaviti displayName za razhroščevanje
require-storiesVsaka nova komponenta mora priti z datoteko .stories.tsx
event-naming-conventionDogodki uporabniškega vmesnika morajo slediti vzorcu UI:EVENT_NAME
template-no-hooksKomponente predlog so čiste. Brez useState, brez useEffect
template-no-iterationPredloge ne ponavljajo zank. Iteracijo opravi organizem
organism-no-callback-propsOrganizmi komunicirajo prek vodila dogodkov, ne prek povratnih klicev v lastnostih

Kavelj pred potrditvijo požene ESLint na vsaki pripravljeni datoteki .ts/.tsx. Če se sproži katero koli pravilo, je potrditev blokirana. Brez izjem. Vsako pravilo ima resnost 2 (error), ne opozorila. Opozorila so želje. Errorji so arhitektura.

Rezultat: nov razvijalec, človek ali umetna inteligenca, po naključju ne more kršiti oblikovalskih načel. Linter reče ne, še preden je zahtevek za združitev sploh odprt.

Omejitve zvenijo omejujoče. V resnici osvobajajo. Ko so pravila jasna, so odločitve hitrejše, neskladja so ujeta prej in novi člani ekipe lahko prispevajo, ne da bi kaj pokvarili.

Kar smo se naučili: monorepozitorij brez omejitev je le vljuden monolit. Omejitve so arhitektura, linting pa je način, kako jih naredite resnične.

Stopnja 4: Umetna inteligenca spremeni pravila

Tu postane zanimivo.

Ko so se pojavili pomočniki za programiranje z umetno inteligenco, se je naša arhitektura, zasnovana na omejitvah, izkazala za natanko tisto, kar potrebujejo, da dobro delujejo. Veliki jezikovni model (LLM) z jasno shemo za urejanje, registrom vzorcev za preverjanje, linterjem, ki blokira slabe vzorce, in prevajalnikom, ki reče »ne« pokvarjenemu izhodu? To je produktiven agent umetne inteligence.

LLM, ki dela v prosti kodni zbirki brez pravil? To je zelo samozavesten agent, ki samozavestno stori napačno stvar.

To smo formalizirali: umetna inteligenca dobi omejitve v CLAUDE.md, pred dodajanjem komponent preveri register vzorcev, na vsaki spremenjeni datoteki požene ESLint in shemo preveri s prevajalnikom Orbital, preden razglasi, da je kaj končano. Prevajalnik je pregledovalec kode umetne inteligence, nikoli ni utrujen, nikoli ne spregleda primera in teče v manj kot 50 ms.

Arhitektura, na katero smo naleteli z iteracijo, se je izkazala za pravo arhitekturo za razvoj s pomočjo umetne inteligence. Tega nismo načrtovali. Zbližali smo se z njo.

Kar smo se naučili: umetna inteligenca ojača vsako strukturo (ali kaos), ki v vaši kodni zbirki že obstaja. Omejitve niso birokracija. So razlika med umetno inteligenco, ki pomaga, in umetno inteligenco, ki samozavestno kvari stvari.

Priročnik FIAYG

Če ste začetnik, takole to uporabite, ne da bi okvir gradili iz nič:

1. Začnite preprosto. Neprijetno preprosto.

Vaša prva različica naj naredi eno stvar. Ne stvari plus obravnave napak plus predpomnjenja plus sistema nastavitev. Samo stvar. Z oddajo nečesa majhnega se boste naučili več kot z načrtovanjem nečesa velikega.

2. Opazite ponavljanje, to je sporočilo

Ko isto kodo napišete tretjič, vam kodna zbirka pove, da bi se nekaj rado abstrahiralo. Ne abstrahirajte ob prvem ponavljanju (prezgodaj). Ne prezrite tretjega (malomarnost). Drugič je znak, tretjič potrditev.

3. Svoja spoznanja zapišite kot omejitve

Ko najdete vzorec hrošča, na primer modalno okno, ki lahko obtiči odprto, ne popravite samo tega okna. Ugotovite, katero pravilo bi ta razred hroščev preprečilo v celoti. Zapišite ga. Uveljavite ga. Pri Almadarju smo »vsako modalno okno mora imeti prehod CANCEL« spremenili v pravilo za preverjanje v prevajalniku, »nikoli ne uporabljajte golih elementov HTML« pa v napako linterja. V vašem projektu je to lahko lastno pravilo ESLint, kavelj pred potrditvijo ali kontrolni seznam za pregled kode. Medij ni pomemben. Pomembno je, da je pravilo samodejno. Če si ga mora zapomniti človek, bo sčasoma pozabljeno.

4. Vaša arhitektura naj sčasoma postaja manjša

Vsakič, ko opazite vzorec in ga posplošite, bi morali za isto stvar pisati manj kode. Če vaša kodna zbirka za vedno raste z enako hitrostjo, kopičite kompleksnost, ne upravljate je. Cilj je več funkcionalnosti na vrstico, ne več vrstic.

5. Ne bojte se zasuka

Stvari smo preimenovali. Izbrisali smo cele pakete. Oblikovalski sistem smo dvakrat premaknili. Vsakič je sistem postal čistejši in pravila jasnejša. Zasuk ni neuspeh. Je dokaz, da se je vaše razumevanje izboljšalo.

Kako izgleda zbližanje

Po več letih in mnogih projektih strank smo se zbližali s tem:

  • Ena shema na projekt, edini vir resnice
  • En prevajalnik, deterministični, preverja več kot 50 pravil in ustvari vso ponavljajočo se kodo
  • En oblikovalski sistem z razširitvami za posamezne projekte
  • En lasten vtičnik ESLint, 17 pravil, uveljavljenih ob vsaki potrditvi
  • Ena standardna knjižnica večkrat uporabnih vedenj (CRUD, čarovniki, glavni-podrobnosti, številčenje strani)
  • Ena omejitev, ki ji sledi vsak razvijalec in vsak agent umetne inteligence

Sklep

Najboljša programska arhitektura ni tista, ki jo zasnujete, preden začnete. Je tista, ki nastane iz poslušanja, kaj vam sistem poskuša povedati, prek hroščev, prek ponavljanja, prek trenja, ki ga začutite, ko nekaj ni prav.

Ugotovite sproti. Zapišite, kar se naučite. Bodite vedno manj zmotni.

Ujemanje pride sčasoma. Oddajte vseeno.

Prvič objavljeno na Dev.to.

Osama Alghanmi

Znanje je svoboda. Sistemi morajo biti odprti ljudem, ki jim vladajo.

© 2026 Osama Alghanmi. Ljubljana, Slovenija.