Kjo është pjesë e një serie në vazhdim: shikoni postimet e para dhe të dyta .
Parimi III: Modularizimi i kërkesave
Një monstruozitet i tmerrshëm. Çdo inxhinier me përvojë ka parë një: kod që është aq i gjerë, me rrezik të lartë dhe i vështirë për t'u kuptuar sa askush nuk guxon ta prekë. Nuk ka teste njësi, çdo ndryshim është shkak për një atak të vogël në zemër. Të vetmit që i afrohen atij janë kohëmatësit e vjetër - ata që ishin aty kur u ndërtua përbindëshi dhe afrohen vetëm kur nuk ka alternativë. Është i ndenjur, i pamodularizuar dhe varësitë janë të vjetruara. Komponenti është shumë i rrezikshëm për t'u ndryshuar seriozisht.
Më kujtohet monstruoziteti i parë që hasa. Një funksion me 5000 linja që ishte qendror për operacionet e një biznesi me vlerë qindra milionë dollarë; pothuajse askush nuk kishte besim ta prekte atë. Kur shpërtheu, ekipe të tëra u zgjuan në mes të natës. I gjithë zhvillimi në kompani u ngadalësua për shkak të një varësie nga ky komponent kyç. Miliona dollarë u shpenzuan duke u përpjekur për të menaxhuar përbindëshin.
Çfarë lidhje ka e gjithë kjo me kërkesat e LLM? Ata gjithashtu mund të bëhen monstruozë! Aq e frikshme për të ndryshuar, sa askush nuk i prek. Ose anasjelltas, ekipet përpiqen t'i rregullojnë ato dhe shkaktojnë një ortek incidentesh.
Çfarë kanë nevojë klientët
Klientët nuk duan të paguajnë për softuerin që funksionon si duhet vetëm të martën dhe të enjten; ato kërkojnë besueshmëri të vazhdueshme dhe një rrymë karakteristikash të reja. Kur ndërtoni sisteme afatgjatë me besueshmëri të lartë, është thelbësore të mundësoni zhvillimin e aplikacionit, duke i mbajtur vazhdimisht dritat ndezur. Kjo vlen për aplikacionet e fuqizuara nga Gen AI po aq sa softveri tradicional.
Pra, si të merrni një aplikacion të shëndetshëm me AI dhe jo një monstruozitet? Ka mbi një duzinë qasjesh të mbuluara të gjitha në këtë seri. Ata të gjithë fillojnë me një parim: në vend të një kërkese madhështore, ju dëshironi disa kërkesa më të vogla të fokusuara që secila synon të zgjidhë një problem të vetëm.
Çfarë është modularizimi
Modularizimi është praktika e zbërthimit të një sistemi kompleks në komponentë më të vegjël, të pavarur dhe të ripërdorshëm. Në inxhinierinë tradicionale të softuerit, kjo nënkupton shkrimin e funksioneve, klasave dhe shërbimeve që secili trajton një detyrë specifike. Në kontekstin e inxhinierisë së shpejtë për LLM-të, modularizimi nënkupton ndarjen e një urdhri të madh, monolit në kërkesa më të vogla dhe të fokusuara – secila e krijuar për të kryer një punë të vetme, të mirëpërcaktuar.
Përfitimet e modularizimit
Modularizimi ju lejon të futni në mënyrë të sigurt ndryshimet në sistemin tuaj me kalimin e kohës. Rëndësia e tij rritet kur:
- Kohëzgjatja e mbajtjes së aplikacionit rritet.
- Numri dhe kompleksiteti i veçorive që pritet të shtohen rritet.
- Kërkesat e besueshmërisë në sistem bëhen më të rrepta.
Të gjitha këto dimensione duhet të kuptohen gjatë planifikimit të sistemit.
Por si ndihmon konkretisht modularizimi në mirëmbajtjen e sistemit? Përfitimet kryesore janë përshkruar më poshtë.
Reduktimi i rrezikut
Performanca e shpejtë e LLM është në thelb e paqëndrueshme. Natyra e tyre është e tillë që çdo ndryshim mund të ndikojë në prodhim në mënyra të paparashikueshme. Ju mund ta menaxhoni këtë rrezik duke i ndarë kërkesat e mëdha në komponentë, ku një ndryshim mund të ndikojë vetëm në performancën e një pjese të sistemit. Edhe nëse një urdhër është i prishur, pjesa tjetër e sistemit do të funksionojë si përpara ndryshimit.
Por, çka nëse kërkesat funksionojnë si një zinxhir? A nuk do ta thyente akoma zinxhirin thyerja e një komponenti? Po, do, por dëmi është ende i reduktuar në këtë skenar. Një dalje e gabuar në një zinxhir të shpejtë mund t'i furnizojë kërkesat e rrjedhës së poshtme me hyrje të gabuara, por secili komponent do të funksiononte ende si përpara ndryshimit në grupin e hyrjeve të vlefshme. Krahasoni këtë me ndryshimin e një prompt gjigant - ndryshimi mund (dhe do!) të ndikojë në çdo pjesë të logjikës së koduar në atë kërkesë. Ju nuk keni thyer një aspekt të sistemit - ju potencialisht keni thyer çdo pjesë të tij.
(Operimi i sigurt i zinxhirëve të kërkesave është një kapitull i ardhshëm i serisë. Ju duhet të planifikoni për lloje të ndryshme dështimesh dhe të keni plane emergjence. Por kjo është përtej qëllimit këtu)
Testueshmëri e përmirësuar
Kushdo që ka shkruar teste njësie e di se një funksion i thjeshtë që bën një gjë të vetme është shumë më i lehtë për t'u testuar sesa një funksion kompleks që përpiqet të bëjë shumë gjëra të ndryshme. E njëjta gjë vlen edhe për kërkesat - një urdhër i vogël, i fokusuar mund të testohet shumë më tërësisht si manualisht ashtu edhe në një mënyrë plotësisht të automatizuar.
Performancë më e mirë
Një grup i gjerë provash tregojnë se kërkesat më të shkurtra kanë tendencë të tejkalojnë ato më të gjata: 1 , 2 , 3 .
Hulumtimet mbi efektet e kryerjes së shumë detyrave në performancën e shpejtë janë më të përziera: 4 , 5 . Një kërkesë e optimizuar në mënyrë të përsosur, në rrethanat e duhura, mund të kryejë shumë detyra. Megjithatë, në praktikë, është shumë më e lehtë të optimizosh kërkesat e fokusuara, ku mund të gjurmosh performancën përgjatë një dimensioni të vetëm kryesor. Ju duhet të synoni për kërkesa më të fokusuara kudo që të jetë e mundur.
Lehtësia e ndarjes së njohurive
Shpjegimi i ndërlikimeve të një super të shpejtë me 3 mijë fjalë për një anëtar të ri të ekipit është një udhëtim. Dhe sado të shpjegoni, të vetmit që kanë një ndjenjë për këtë bishë do të jenë autorët kontribuues.
Një sistem kërkesash, me secilën pjesë relativisht të thjeshtë, mund të futet në bord shumë më shpejt; inxhinierët do të fillojnë të jenë produktivë më shpejt.
Optimizimi i Kostos
Duke përdorur modele të ndryshme në pjesë të ndryshme të sistemit, mund të arrini kursime të konsiderueshme të kostos dhe vonesës pa ndikuar në cilësinë e përgjigjes.
Për shembull, një kërkesë që përcakton gjuhën e hyrjes nuk duhet të jetë veçanërisht e zgjuar - nuk kërkon modelin tuaj më të fundit dhe më të shtrenjtë. Nga ana tjetër, kërkesa që gjeneron përgjigjen e bazuar në dokumentacion mund të përfitojë nga një zinxhir i integruar i arsyetimit të mendimit të ngulitur në modele të nivelit të lartë.
Kur të MOS modularizohet
Shumica e aplikacioneve me softuer kërkojnë shtimin e sigurt të veçorive për periudha të gjata kohore. Megjithatë, ekziston një përjashtim. Aplikacionet e prototipit nuk synohen të mbahen për një kohë të gjatë; ato nuk do të marrin veçori të reja dhe nuk janë të destinuara për besueshmëri të lartë. Pra, mos humbni kohë me modularizimin kur ndërtoni prototipe. Në fakt, shumica e modeleve në këtë seri nuk zbatohen për aplikacionet prototip. Kur ndërtoni një prototip - shkoni shpejt, verifikoni të panjohurat kritike dhe më pas hidhni kodin.
Një konsideratë tjetër është të dish se kur të ndalosh modularizimin. Ka shumë shpenzime për menaxhimin e kërkesave shtesë dhe nëse përfitimet e modularizimit të mëtejshëm janë të ulëta - duhet të ndaloni prishjen e mëtejshme të sistemit.
Infrastruktura për modularizim
Nëse modularizimi i kërkesave do të ishte i parëndësishëm - të gjithë do ta bënin atë. Për të menaxhuar shumë kërkesa në një sistem, ju duhet të investoni në infrastrukturë - pa të do të keni kaos. Këtu janë kërkesat minimale për infrastrukturën e shpejtë LLM:
Aftësia për të shtuar kërkesa shpejt dhe pa dhimbje në një mënyrë të standardizuar. Veçanërisht e rëndësishme kur kërkesat ngarkohen nga jashtë bazës së kodeve. Shihni Parimin II: Ngarkoni kërkesat në mënyrë të sigurt (nëse vërtet duhet) .
Aftësia për të vendosur kërkesat në një mënyrë të automatizuar.
Aftësia për të regjistruar dhe monitoruar hyrjet/daljet e kërkesave individuale.
Aftësia për të shtuar teste të automatizuara që mbulojnë kërkesat.
Një mënyrë për të gjurmuar me lehtësi token/$ shpenzimet në kërkesa të ndryshme.
Rast Studimi
Le të shohim se si ndërtimi i një sistemi të fuqizuar nga Gen AI luan në praktikë me dhe pa modularizim.
Nuk ka modularizim
Ju po ndërtoni një aplikacion për mbështetje teknike dhe jeni të vendosur ta zbatoni atë me një kërkesë të vetme. Në versionin më të thjeshtë, mund të imagjinoni një kërkesë monolit që gjeneron përgjigje gjatë ngarkimit të dokumentacionit përkatës përmes RAG .
Duket bukur dhe e lehtë, apo jo? Por ndërsa shtoni veçori - shfaqen probleme me këtë arkitekturë:
Ju dëshironi t'u përgjigjeni mesazheve në një listë fikse gjuhësh, por jo të trajtoni të tjerat. Për ta arritur këtë, ju shtoni udhëzime të menjëhershme për t'u përgjigjur vetëm në gjuhë të caktuara dhe kërkoni që LLM të kthejë fushën "gjuhë" për qëllime raportimi.
Ju dëshironi të klasifikohen të gjitha bisedat. Shtoni një fushë "etiketë" në daljen e shpejtë.
Kur përdoruesi është i pakënaqur - përshkallëzojeni rastin në mbështetje njerëzore. Shtoni variablin e daljes "escalate_to_human" së bashku me udhëzimet në prompt.
Duhet një përkthim i të gjitha mesazheve të dërguara për auditim të brendshëm. Kthejeni fushën "e përkthyer" me një mesazh në anglisht.
Keni nevojë për mbrojtje për t'u siguruar që aplikacioni nuk i pyet kurrë përdoruesit për vendndodhjen e tyre dhe për kë votuan në zgjedhjet e fundit. Shtoni udhëzime të menjëhershme dhe provojeni manualisht.
Keni nevojë për një përmbledhje për çdo bisedë? Shtoni fushën "përmbledhje" në çdo dalje.
Ndoshta po filloni ta shihni problemin - kjo kërkesë tani ka gjashtë dalje. Testimi i tij do të jetë një makth. Ju shtoni mbështetje për një gjuhë tjetër dhe papritmas aplikacioni juaj fillon të kthejë përmbledhjen në spanjisht në vend të anglishtes. Pse? Kush e di, rezultatet e LLM janë të paqëndrueshme, kështu që ndryshimi i kërkesës ka rezultate të paparashikueshme.
Urime - keni krijuar një përbindësh! Me kalimin e kohës do të rritet dhe do të shkaktojë edhe më shumë dhimbje.
Me modularizim
Përdoret si Zinxhiri Prompt ashtu edhe një kërkesë klasifikimi tërësisht e ndarë. Prompti origjinal i madh është i modularizuar sa më shumë që është praktik.
Një kërkesë zbulon gjuhën, tjetra siguron përkthim, tjetra përcakton nëse përdoruesi është i mërzitur dhe përshkallëzohet te njerëzit, kërkesa e përgjigjes gjeneron përgjigjen, parmaku verifikon përputhjen e përgjigjes. Daljet e një prompt janë të lidhura me zinxhir për të qenë hyrje të tjetrës; kodi tradicional mund të funksionojë ndërmjet këtyre kërkesave, për shembull, për të kontrolluar përshtatshmërinë e gjuhës, pa përfshirë LLM-të.
Një ndryshim ende mund të thyejë një kërkesë të caktuar, por rreziqet reduktohen shumë sepse:
- Një ndryshim në një pjesë nuk rrezikon të prishë çdo pjesë të logjikës së aplikacionit.
- Testimi është shumë më i lehtë dhe gjasat për të kapur dështimin herët janë të larta.
- Çdo kërkesë është relativisht e thjeshtë, kështu që është më e lehtë për t'u kuptuar dhe ka më pak gjasa të dëmtoni me një ndryshim.
- Ndryshimet janë më të lehta për t'u rishikuar.
Ju merrni të gjitha përfitimet e Gen AI, por rreziqet janë reduktuar shumë. Plus, mund të përdorni modele më të lira për disa komponentë për të kursyer para.
konkluzioni
Modularizimi ju lejon të izoloni gabimet, të përmirësoni mirëmbajtjen dhe të ndërtoni një sistem më të besueshëm. Edhe aplikacionet me përmasa mesatare do të kenë dhjetëra, nëse jo qindra, kërkesa të komponentëve. Ndarja e kërkesave derisa secili të kryejë një detyrë të vetme dhe derisa përfitimet e modularizimit të mëtejshëm të tejkalohen nga kompleksiteti i shtuar operacional. Modularizimi i kërkesave tuaja është një domosdoshmëri nëse aplikacionet tuaja të drejtuara nga AI duhet të mbeten të besueshme dhe të vazhdojnë të shtojnë veçori për një periudhë afatgjatë. Ka shumë sisteme "përbindësh" përreth tashmë - kujdesuni të mos krijoni të reja!
Nëse ju ka pëlqyer kjo seri - regjistrohuni për më shumë postime.