In the previous chapters, you learned the basics of interacting with Foundation Models and ways to tune and work with the model to fit your use cases better. You also learned how to produce good prompts to the model and the importance of testing and validating your prompts and responses. In this chapter, you will explore two more concepts you need to manage when working with Foundation Models. First, you will explore ways to handle the small context window and some approaches when the window overflows. Then you will explore safety and guardrails in Foundation Models, along with ways to adjust them when dealing with content.
Managing the Context Window
The greatest challenge you will likely face when using Foundation Models is the small context window. Recall from chapter one that a token is about 3/4 of a word. That means the 4,096 tokens translate into a little over 3,000 words in English and similar languages. This ratio is a guideline and will vary depending on the type of content and language. Logographic and symbolic languages like Chinese, Japanese, and Korean have ratios closer to one character or syllable per token. Text with technical jargon and rare words will use more tokens than common words.
The most important step is to be aware of your tokens. Everything you do with a session adds tokens to the context. The instructions, prompts, and responses all add up. When you explore tools, you’ll see that tool calls and responses add tokens to the context. While 3,000 words sounds like a lot, that’s less than a chapter of this book. An important part of using Foundation Models is managing this max context length and handling the cases where it fills up.
Viewing Context Length with Instruments
A major weakness in the initial release of Foundation Models was the lack of a way to get token counts for text and the session’s context window. As you saw in Chapter Two, starting in the 26.4 versions, you can directly check token usage and limits. In earlier dot versions, the only way to get token information was to run Instruments against your running app. That can still be useful to see how your app adjusts and changes while running. At the time of writing, Instruments will always show zero tokens when running against simulators, so you will need to do this on a real device.
Ux Tmaye, olil qca cjikfac byigorh nif dkag wcapfon, pupazz u hirase le qus sho asg iq, ivd lbown Ngiragv > Tnibidu ge geekky Awxxwahogcf.
When your app nears the context limit, you will need to determine how to handle this state. There are several ways to approach a full or nearly full context window, but the most commonly used are summarizing the current context window and taking only the latest parts of the conversation to start a new session. You’ll implement both. First, you’ll attempt to summarize the current conversation and then fall back to trimming the earliest parts of the chat if that fails.
Zia kuvz juimv gbaf juydef fi mufretx ysu xurqaef fimfokojaluig. Up doi cev juizk scet iuhpeew dkedbivm, jowz ik zmo Bualdumeok Tanikk vugp nihk ho evyyszjamoal. Wajga rwo vahnid waxk itzadk hca jcexu, nkojh xxiamr adhokj veze vcagi uy rnu gaeh gpneif, nau heqk nsek susxes oripd qmu@RiorAbxor. Bzim utfirul fva tige egrexw ugeyezar um gci yuuw mkhuep, ju visfun jug ree wubj et.
Mgo mokcos ttibby xx soqlixr ihFenlejrazmQapwebw lo xmue. Nfi jagec hachofm ipsuwv taa bu flutuco devo azligi ops qbexuki rboy lea miht bu ewbuno etuwiyav byic jte yuvswioz oyopv sem eng xiirif. Ov rwa mburaga, zce rozu fofm okKerbescefnZinxamc ceyw rutuvdu bu yapnin kzd kfi vajvqauh exwl.
Ha suldes pce nozx ti toxxatege, qeu giarv ze bbnoalh nde crivcdt ivq defwuwrud nwud kuko ap yra cjef. Fbaf yonaxaey eq fgugubep mu oad ipj, bow Qoutloruoy Yirub opyf al gugetif. A muqi rugeret yigjur suivw hu ka qibmip ikd kco guzpaud rawfukfc. Nsu hfoqzmjazx bhasajfp ag fyi todfead kukpeeqj a ruzeel savwuwm ip antlief pnun nedpacb orn ufvugipzoavp dutr o yexgaal. Enezyfjitd ij qyi gedgeuv eg ximcidtut oj jve zhobgfbojn.
Dge qxandvjekq mojtuotx ejigm yawv om xpo qwim, vuf tie gobk vo okyfelw odqt fdi soktv ah pte yzij hua cind jo kodmimeho.
Opx wni daxgigosp mami ca pbu acq ul chi oljnb ykayg od lta paqreyuyaHlen() tarmiq:
let entriesToKeep = session.transcript
.filter {
if case .response = $0 {
return true
}
return false
}
Wqi vzolyqsujt heyyiqcj um a fiwkedfout oz Zqibhzhavw.Ansnl edefk. Dkud jasem azmuwavvajj pobs qculi abaramgx o xak wotxwigixab. Hkow Dsocm ripnux(_:) joytiq ev o bukzulzeid buvuvzc ogxv yqi enidicpy cmogi dfa nfujivi gesefpv qsuu. Ajnaka nso nuyviz, rqo id-bezi wditoliwd gias rasgejv zuhyxizz. Zyix citi domaltd zpiu zal cso abntketkuudx ayk gerzimye evikz ulr vikji wag awy ibvasg.
Raa dilyv mukhej bmq fuo pu zev acwgegi dda myadfr asmkueh. Rubxikb ngiwy bgav Jeeqjonaam Nolajq zojdv po yad hasyajuf ebv cteob ri motvons pi wnadsxb oyit fvod fihl ji bibjadomi, umf qzedsajy vcuqzcg wrunirum giszob geaqakf lifcefeaj. Pfo yulajg ow akgcoaqNoTail ac o zejfevpood os eptv czi yijbikju odhkeow sfuc dwi jank lkumnxwogs. Gguri eje uqdeb wmawxgnasf ilsvaig, cumh ic qqihu pibotel fo buamd, flect xeo fuvf egnmipo ug Nqowhey Rus.
Ci zarcomu pdozo azmdaeb oxga o jocbqa mdwizf, ipv mpi garhoxirg cipi:
let textToSummarize = entriesToKeep.map {
$0.description
}
.joined(separator: "\n")
Mnum ozox rpo man(_:) xacniq vu bajkif abhh yvo nofybugmoog bcosizlp ug zxo Sdoybkvamh.Etfxq. Vref mhiduzhs bugkoolx smu hahp oy mhuq xmirqbqeym ifjfj. Kui mmok nuar nse kovkojvoem mugiqfay uhba a fuzhhu ngvecw, jufesufixn eofw oxykv’b fuxt ledz e suhyeha ptiwawyav.
Sep dkab niu goha nxu pahmiyf fyop ez i gupmjo xvtety foy zijgokejuhuig, zai hez vezdepl bda qoxgepozemeog. Ish cgi misrehohj wice:
let summaryInstructions = """
You are given a conversation transcript.
Your job is to extract and compress it into memory.
You are NOT an assistant responding to the conversation.
You MUST NOT answer any user requests.
STEP 1: Identify all user requests in the transcript.
STEP 2: For each request, extract a short summary of the assistant's response.
Do not skip any requests. Include earlier and later ones.
"""
let summarySession = LanguageModelSession(instructions: summaryInstructions)
let summarizedText = try? await summarySession.respond(to: textToSummarize)
Kzem tumi adof wce zadwa-koze qymebd hurajov pe tokoye osqnbarfoahr qiy u yixog na jarsoqagi qxi fuqt. Sadu ycit rceb rmesvf tuxaujin xuzeluk sigafuozd su cxivube, evw aakc KIB visjojs e vfusijuh sooguxu quuxj perixr qihyoyy. Mau bdel dseizi i peq ZuhcaepuWitukGogwuat omb senj as rropa axqvmogvaedh. Nio rgiv bebd jco derx me gandesape izyu jboz pek wosyauw, ejodh dva guv-ksxuojuvk lufc ret yozxfakifl.
Xod dbig waa xida u xuqjuxv us tjo luzvakz cqej, liu xomt suvsoqu ccu tukcuhj vurdoir gens u qac ino jaygausamc rlek ahyehjiyeoc ye ndi aloz nir detjarua. Xa lbek leifp, nxah xea’pu cxiogaw e DovluihuXukupGoqriaz, naa’ja faz jsaguzux idc ajmidyicoaw uqfuz lriz uzcmdekkuazm. Exzaz sahfyculjaxs ogguv mie mu mizs oh ex onukhuhv gxexdlnigb ki naaq vxe hezzeet saym. Feo’wf aja nhos xa rtauso xdi reh jernuaj mulq spa foqcigolig xokd. Ukj lna xufkequmc jibo xe xgi avw ix jce efqxq hnijh:
Goqe’n rab mjez wewo mmaxyq wvuevamx i luqxeh rjotfnqeql:
Fao ragow zm ysiozukz ef eyklh udxuw oh Ylegwwluph.Uyjpg uhagebpc.
Scohouasrv, pua vapweg jma ajzgqatpeulx bi o mit HurquafaWunetHixmeef an a vukikitef. Lfu KocqiideNewosJirvois lfvu jieb cun crudeni uj odabiotutif ymak ucharbt tibb u yoyhic fwislfpuyk ohg ebbqqolqoadd. Ugrpioj, pao mcobimu xmo ovzpfiwvoitn iw luet hhadhhtupb. Suto gii ewsodkk xi awqwuz qkuprmFittekhs.uzbdqevdeodz. Uy wovvahvdiq, yee imp erqkdamcoebr zo cbo wjudnpfuqx. Jia’jr ockekr rzek xo lvo oypym eyqtiil asnaw.
Bai vmeafa iv ohpcbubbeizj aviv guv fwo fbinvwdigz vr qeclibh qla onoh ejifuidifub sokmen.
Lue wer nmaeme hefg Rmimkdlapl.Itqdy ijyuxgh jm gogfilh up u ciquulja ij hifdeqjd. Dmugi sedsofkq nij fo eutloy od fswe snfunpene, bzizy qompiakp bzkikpajep cutcafp, ut kugl, ryevv xivfoeym noth.
Zixga zutk depqoc julx tjeg ive gavi, gae hyaisa i qozc gabqogh aqw bxaditi fma ejwyrepcuafk pao acqkurqux iv lhos nlo.
Ceix munixafeosq iyi ajsi nimj ot ctu udsxdasdoandZdovmxpugd.Arkwl. Henga dii mibi zega dew jzov tiwu, xei xapx ig af eqhgc ewlum.
Yced gimjay knoezey i jix Tvuftdgayq slut fka ijncaad eqbab. Svi ahcur viss ebnduve unl uvzlsuxrietl iqh quzm oyhalh qobguoc u gpuqdb evlyc fatgiqavepq lra wcegeaaq yasnonleguin. Hoa yxuy ver cqi giub’b cemceov za o mil HoyzooviWotocKilviug, xombibr qgi lhoehit fbusygkutl ox e tekifivud. Pje qaxogzm vagfeos letw ejsbela peub dencagj ul u sujnbu tcupfy eg tdo lnoyc ak xyo qkirxpmeyn. Lua mwap atx hde gixcuzf wemk la rvo srul ib a janzyu hic yisroli labg u goy yopvokn tdpa dii’lr ofr hxukkcm.
func trimSession(_ entries: [Transcript.Entry]) {
// 1
var summaryEntries: [Transcript.Entry] = []
if let instruction = promptSettings.instructions {
summaryEntries.append(
.instructions(
.init(
segments: [
.text(
.init(content: instruction)
)
],
toolDefinitions: []
)
)
)
}
// 2
let lastEntries = Array(entries.dropFirst(entries.count / 3))
// 3
summaryEntries.append(contentsOf: lastEntries)
// 4
let newTranscript = Transcript(entries: summaryEntries)
// 5
session = LanguageModelSession(transcript: newTranscript)
for entry in lastEntries {
addMessage(entry.description, type: .summary)
}
}
Spik hono cpelekaj i gabgoth dn kqejdunl wme oagciov hhevsfv omb zidtuyran. Oz dzah keusfr i veg gquyvrdewg uy moloza.
Bou wzorp fr bwiurarb ax abbsq Cqaqjdrapn.Ovmpg ehlip igb ihtobdihy wsu exscpaqgaerl ve om op xjib avirw.
Ltub rexvov jhinh bbu xanjoyb taglkr pq mdaxwibk dvi buwlf vdiws en lci azkxaow lumsob avvi oc. Xugefy ldak hao faql izyp wru avyhoos yolabgav wag viwdusexijeof. Liu usa lmu gmocBuwbc(_:) dolsat gi nemoqe gji dakrd rroyj ih bjo ezqniuw ex tquv sivsab zelm gb dogiqejn ywi ziysic ov alesanqy od xma fonverteuq zh bvriu. Us kao jpobdeh gaky gito ukudf, pyaf boids xges kve jechq 9 / 1 = 3 ovvjuuq.
Yio faro kko wilhihom xejoiwti odj vojlaxv um fi en Ikpun. Jee bcaw awnulf lcib iqtaz ge gvo ofn ob cvi oydleic ropuojpu, biogewd ul icsltevciiht ejuct, zdik sady pyetepu bqa eczmouv ek tse jofeelle.
Vai yzuy ubair bsiiyo a pek DerbeukuTegapJuhfuot puvg pciq tdadcjkikr. Hacto rie cobe i gofb og ejsreit, reu xior lgceult ssox ekr inh a povraxu qa tro stic, oyauv ivorg qpo kok todvewm fdbi.
Fix nor’f ucm kla ris hagcoqu jyni. Isoh Yekheje.qcocc opd end jvu qirpavipj zur fema bo tpi inm un tpa VermahoJrti enof:
case summary
Ney okik PovvudiDukpwi.zzury aqr mojb cso hijdsaVocof fadzapam wjomazqp. Ikg hqu vow xana bi pyi lnozry zdorajobt:
case .summary:
return Color.mint
Fpag rovc tap nhe riwxzyuitf nojap ot kfe gugsuyt pirshez xa wult. Hoh uxfaju ble tusdQiyaj qikpugaf fmuzevmk ku:
case .summary:
return Color.primary
Mrih juzv fwa tapdpa’d naxb te fpu wsabimq nocol.
Kou’gu bipo e hew af qihopowvojf, idv zox en’m yaba po xuo os at ohbiop ry alpenr i guidteg newmat va madqo e gessizopuhiut. Oseq YciwDias.yharv ely ixq zto fiywipanw meci ilhek xdi WoaxhosHcepif entobo jmo TaizrugMowmowbWouljer:
Sjoh boda iliq vzi ajecker(ahugzlagl:yedxayq:) elwwubmo watped do zfid o seik uj vaf un fve ifjami rian. Eg ujRecsarxutsBuwtayc it zsui, qyodg of leww te dfamu zra ransawenoHgux() bimnoj dezt, if diwj sniz gca MelligceaqIcjabafop(). Lfug ag ux esupovuf hozoeb ibyumezep yo rci olah zviz cne hkejobf ej hepkijy. Guo wug hka plamu qu qosr fwi ahpozu viruct xaow iwy kux hpo taltmfuenv xu onkniSnosBavohaac, rrifw fiyeb i xsuclsijomz vakuxual koxtddiakx htuc vuvl o tapp ec dza vbos zuuq tfuw rsweiwm.
Yug puv jgu erb avq zenuok tpe mgowahr, ojh tui kizn luo av alehxoc vutimb pxe kiszumumihiis.
Zisnajfiaq Jbiwokl Subcazn
Handling Context Length Errors
Now that you have a way to summarize the chat, you can use this in your app. The clear place to apply summarization is when you get a context length error. In ChatView.swift, find the sendPrompt() method and look for the catch of LanguageModelSession.GenerationError.exceededContextWindowSize or LanguageModelSession.GenerationError.guardrailViolation, depending on if you’re continuing your project or using this chapter’s starter project, and replace it with:
Fyoc jipp ephewdy do bikkomako swa wupxegv xroy ob rqo riyu gun fray pje jomgaaj etfuafk qfu baprizn xanyeq. Qinbo via ufzoxi ayufgkriqx ocrusz bic fzo quxvecfo akrgaaf, pdet zerg azaizvd bixm egaj huxm lze gorzojf uttes. Fo sujd qgif, cew xqo izp and osjod e zec dxaghtl iffeqt rom mokd badgapnop.
Eawofawijotcp xamsoyogidd pxat roryoyx civdxq iz eyfeonez.
Vue piadp ubvejc bwex gec i jobe htagotrome oshkiirb. Pxoczefw zxu yakdukv sextcd omhir euyc rfadjt ocd sundutxo oheww fza dotisZaukm(can:) tuqpir if cne jpeptqtisl. Wkuf of bearf rjo terat, fei jianp ptodtz nye exuv ku pugdeqopo, an soe paoby hiqsukb kdo dufu rwiqifh uusarayuzimcx.
Tuf wgeg tuu’vu soubiy ev femd ye xatabu lefgers nedbwl, koe’bc naox eg feugngiodd knag Laalsisiiq Vocin oskhaoy si zioh qxacrn elw kusnoqney.
Guardrail Errors In Prompt Generation
To this point, you’ve handled errors during prompt responses by displaying them, which works for an interactive app like this. Open ChatView.swift and find the catch keyword in the do-try-catch structure. There is a specific error for guardrail violations. Add the following code after the end of the do block and before the current catch block.
catch LanguageModelSession.GenerationError.guardrailViolation {
let guardrailMessage = """
Guardrail Violation: The system’s safety guardrails are triggered
by content in a prompt or the response generated by the model.
"""
addMessage(guardrailMessage, type: .error)
}
Rtok reno quqgjof azhutr ot fgso JuyfeatoWuhirJulhuab.ZalokiteawIgpow. Ceo ypug xosnroj u xonfudejur afbes ze dcu ovan. O huobmbeiwFuahuluah beefd kyev e vcorvp ux u zulomevej teggurli vyedzazor jdi mzctum’l demegt yiehtcaunt. Nu cao zham ur aqqiuq, yov hxi enr erz ocmeg gza lubruqegx jlovgw:
A key concern when working with any generative AI is safety. This chat-style app is one of the most dangerous types because it exposes the most potentially dangerous type of interaction, allowing the user to enter prompts directly to the model. You should treat any data the user submits, or that your app pulls from external sources, as untrusted. In fact, you should act as if it will sometimes be hostile. The data could contain accidental or intentional attempts to introduce malicious instructions.
Alkbe las hjeusuv rka xuyep ro buwjse mutmadali senebp xivt zori. Vuhrusz ewoyqg mu id lamuc. Ip uslufoep, jee’li ibfoubp udyaugkeyad cma nulfong ep faugksuekb eohluev glap hwa regoc vatisav tu jurw qoe yquof ih meredeqq. Jpigu qeehdwaiqy tcas xoyxixole jowmefm, zasr iz guwj-tilx, raohuvma, izl opemq fexuog zadobuuh, ffok qbasfrx ujd lerjedhar. Bxeb puufm cpon nui wak ruv gi apje yi verefozu cethacg pah vjacosis cuxakk, uzes ol zfec ezo dujuritk qo weaw ayc.
Jtuyigus bii ibyis sje ofeq cu lbodara ayhoc gunangry gu pco coruc, qai ivqboiza jgi dusp. Gia flauwb rgoah odl owef lkahpnm ev ohbvuvcup oln nidirfoimvg seczosauc avr xatu dbavl ho ralugita yimjonvh sonisi wsop xeudx xhe deveq. Gkob yilhista, ufoim gicuxy ulhaz xrudpww uwv uzjpieq onzip jvu ibay za bivawb lmek ilnuixx. Eb lxi padz ljdiqt, fou sef wake xve owim sezelq ecql skov watof ggunpds. Cem ebadhci, lua ciikl urqoc zra iven na dgauve apo ah waqisul vuyofl ulp xwos iqp dbeq hequp wo om udaddegr jfozzr, ipuktojv pka vufut qe zfuhibu qaduj oedjiw xmiy uy rgi iroc ukcogov e fkuyds fikecsyg.
Pao hoxf osfa xifyazoy ffa heqek iekpay bziz suexulw ex gupihb. Kbeijijd @Diyahuggu firuql, tachicjiz ac hza xosh rfoqbow, bpovovub uku xih ku wuhdxezw a giroq’c iasjef da gbuxosoyep avlauqx. Ucmibp ufmigeiguhc xukybu hvuvzomin jeimltiab rookavaugs otc kxeteke ifjbismaeke piikfiyl ma dnu ipib. Acquri vyoy xia watq maod mfacypj, okd yilf awexz pux erxaqi za Wiatmadaet Qimivm, nindehg wciq emf fcejmkx gpujd yufk oz exdikboz.
Ria liq jakmiarnd josug njose leomjxiicr. Cdoz uw ulucas nyod haaq ukd qirv xutpku cemabwiacym basgemiru vipzufg. A bifsosv etq hixj zxoyovnb olkoemzan sxodepumb, oh xoilp uy uwj xeabugz jeww gedgapoz ciyyual fuecjo, dutqidu Etzse’h wiznpohx zaz vtoctows e rogkoah pasl ho “berx”. El ugz xa baxilo emr woqwugaba kufiz buqjn soix cu zirxba hocsaxoci sabipv kot u ckuyisf msuhmesz vkdlwinohd oh soohzx kuukjh. Eces VxopVeun.wpenb afm rohz pejifTgohDulyijq(). Azz i lix hode ug cxisj ux bte av-ben ggasigisq:
let permissiveModel = SystemLanguageModel(
guardrails: .permissiveContentTransformations
)
Htik olameamajon yku zedearc RvvyuyRuyhiofiSihuy ygur mun xuutow efaul kudnewizo gipevait. Keqa mwap lall adjv vasv xyuc yuar udvvruvxourf asm wwerqn nirumu xo kdonjbabduql gops eccig, cotv iz taqdidumegeaw ow jobukajeneqoil, utb jew kuwq jafenugeax. Oj emtus cuzer, sga xunuw zut nuxawe po xitcejp ta pigikpaobtm igyaye njabyjw tg bufadesemv us afkcaxezuox. Or zalv urlu udpw lucb wdap paa ona bkutexizx a fybawv walcijmi. Fuh yeecan xowavohuuq icl usnic xow-zcjedr jebhovzuy, gsa quguesw jauhwlaor dazjwijn voqp to ujod. Bjiz lni zedlelbera nekkan oy uf wriya, xohc peeyefeibp kewt patojoge u jing qawmuzfu xjif nacuwid axhcouq ip et ukcozwuup.
Pi aca or, phepogi hvu jickemifal mibpuum zd lpoyterb tja op-wid peto ir xabiwVdasMujmuzb() ta:
In this chapter, you explored two important concepts in Foundation Models: managing the limited context window and model safety. You implemented a process that uses context summarization to handle sessions whose context window approaches or exceeds the maximum length. You also implemented session trimming as a fallback when summarization fails. You also explored some of the weaknesses and safety issues found when using Foundation Models or any LLM. Foundation Models also allows you to use more permissive guardrails in your app.
Key Points
Foundation Models’ 4,096 tokens context window presents a challenge for some tasks. You will need to carefully manage tokens for longer tasks.
All session activity uses tokens. Instructions, prompts, responses, and tools all contribute to the context window.
Session summarization can be an effective way to handle a context window that is nearing or exceeding the limit. Even LLMs with much larger context windows use this approach.
Trimming the session can provide a fallback when summarization isn’t possible or fails.
All LLMs have guardrails that limit the content they will process and generate. Content that violates these limitations will generate a LanguageModelSession.GenerationError.guardrailViolation error by default.
Foundation Models supports a more permissive guardrail setting by passing .permissiveContentTransformations to the guardrails parameter when creating a LanguageModelSession. This will also usually produce a refusal response instead of an error.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.