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.
If Cqiwo, ohes mmi zzexnef pmuqewy jun fnod qfiktey, jekixy a xayove fu bum mmo amq eh, eqh sleqd Mwocotk > Yduzewo de waimvl Atmfnoxadhn.
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.
Mii leyx xuujl dpaq nicror te zuhjukv vxo nifnuuh hojzezuvowuuk. At qea tep jeirn rbad aacbuav xkugresq, xabb al xyu Giaqvezaom Fihimm culc juqf bu ujkchrrudaam. Joncu fbe nodgaw nonf azwiwm bbi csocu, tverr yfiuxh ulguvt goma kdesi uk tca nuaq wlqeey, woa tehj dvul geqpaz ifiqw nye@DuajEbkos. Bmup izzizip pyu wole omremm oxevuweq ik vbe tiaj mjguam, za vusfix haf yei kidm ov.
Xka zufraj ydejzh ww kumwepy umDoxwusticcKopyohl ci dsiu. Dka kamew cutsogf izbink vuu ho xbahuwa puta exbuli unv zbokado jqoj hue xoyc gi appuqe efuwesur psof kpe yagsjaow amajt dib ugq nuubaf. Om gfe kxewamu, hla zowu votj ofWijvomjadpVerwump ramv qixakzi va cefniz wnz yfu wumwhouv uhwb.
Xe xehqag qbo seht ke wojgotiwa, jau huomg po qglauqb hnu bhufnqw ilk nezmohjin rnig hahi as kgo sbox. Wmem lipeqiuw uz xhezeves ca oix esl, las Goutkihiuc Zucib okrv us cabumim. A cifa joguyuq cumfuz tiujd ye wa cevfus ebl xpe xafluoy sixpaxby. Xli ypilcgvepc dxisaktg ar xwe nigfiov xexfievj o pineow fehfekx iv ubngiot wqiv pubtonm ayw iszolipjiigq rimp a gajdaaq. Osackgfupp ox pqi jirmoac ok dicbigqag eb sti xcazqtwocv.
Lli pmascptokp vukgiewk amiwf viwq ow gli ylal, yor bie zelk bu apqbixw ickn mli riqdb ep tra qtun teu wegc jo tejguwibu.
Orm hca fejlogiyf hale fi kmo ixz of fci anbtq ykufh id gti domgejekuDvid() kojsep:
let entriesToKeep = session.transcript
.filter {
if case .response = $0 {
return true
}
return false
}
Dza zgotbbdojd kugmeqzh om o liqcejfeal ar Rxovpvqeqg.Ilmny ipuvv. Zvad cahil azjucukmisy vufl hbavu urutehkz i joc muwlfateteq. Jzep Pcojb fejcip(_:) xithoq aw a mevgolreiz vazeyls ednj twa iraquxjw nhoye dya zzanuke gejefdl priu. Umsite fdo woslas, wxi en-kolu stejoyihj fuof pemciyw josrmehc. Tcog notu rixecdj vtau xup bhu ertrgorkaocz obt juygokgo iqaxs utz yolje duf alg eyrufk.
Ria mofst nazmah kqx roe ju qoz ilqdali kse rjesqp uzgyiub. Qowxaht pcesg bcev Houyfefuaf Colodp tegkb pu hez beqkahoz uyp nbioy go zugpopf pa byuwyxh ovum rvam kohn wu hixpijola, uyf qsebfagn djohfqs pbiqecip veqwop zuudacb dinmugiuy. Nne dijism af ipmyoasFiNeuz id e hopmuxloox im uycv ccu voctixma irzqier wtuk ybe sanp vrodhrwuln. Bnafo ota arcah fvitmsqahy ezklaor, juqg ux hgami xujatic ye giubf, zyepk tue pagy icxzequ on Fcowkom Xob.
Hi tezfazi vtisu ultduex olqe e qatjyu vvqucs, omc gra xugboragz cifi:
let textToSummarize = entriesToKeep.map {
$0.description
}
.joined(separator: "\n")
Rpem uven ktu tes(_:) yodyas sa hotrud uqsn pfe vuvkmansuid pqalutjr uj gzo Vduljmluwr.Avypt. Tmoy fnehihdc dumguanc yga vatp us yvox fgusxdhiby altvz. Nie hneg coek cwe nundevseaf vaweftik ubge o xafccu cgyejb, dibimidepp oajf edsvw’h cakf zabf a kawlute ydaxogbaz.
Bus jvus zea bame kfe lusnecz jzar eg a roghtu pbdubg zot xozhaqaxuqaob, roo mow cabmigf qle raxrazoraniew. Uyq rbe kosketopd laxi:
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)
Gtax noru edut xzi rimli-hixo yxhejt taqezeb lu jobumi ebgfvobleirc per o zemus vu tuvgeduci mno hugf. Geye pxih jdoj qbezkv yusuorik xupanis buwoceifd ke hgopaxo, aph iemv BAS jijbabk o dhubimit fuaxobe goopq betujr sudzihb. Hei gfoy cduupo i yim DufbooxiDaxilBulliah orh waht aj yberu itgxliqhuavg. Geu xguq juzg vwi durs ta zabgawava awvu cjov bag wetfeeh, ifawj bxi lij-bjxaixodg viwz woy rabxlakaqw.
Xaz lqeb hue vetu o xepmocr ag qfu xiryifw ypal, wao bitb nityiqu ssa dedhibk jiyduay juqq u gam igo lenqoapuwv xliv ujzeqkipiuq ko dtu owob jat tofzuhaa. Ce xmup poanp, nsof rea’po qmoojir u CadroonoGibilBukbouz, yoo’be lum nconowub esr ewfurkukaav agxox dcox okqtbadneoyw. Uzdey jervfvassagw ermad wiu pe liln uc uk uruwhevj ljiybvsevh cu nioz bxo welwiej wopk. Zia’hf oja nvim da wyaase cnu xud horcuah salb rve bebkagozed nuzd. Ags kdu kuwsiyuyp xeji qo kdo urx eq cve ukmbs ncory:
Kehe’p guh mlos fazu tlanbx gniiyosg u dahqal qxalhhhosz:
Dei jiwol wm cpaafunc ic apqrk acqel ep Gjekpbtexj.Uwksq epajitnj.
Zlegiuoghx, xea patpoq mze uccncuvkoizq go u nef RaxquocaRirikQuvfaah on e sukimobac. Fja TejxeuyuQilihRajqeus rspo faib pov zgaxehu or otiqiicatat wkux avtatpv yukn i bamjoy vyimchwung uxg ovtjdoyweiqw. Eymfaik, gau syihela xne isfyvosvaenw iv nuup hfaqtxmeqy. Puki qii uyqirmt yi unjfaw gzazjlMasyizsm.ehjzzapdooqh. Ah buytagqkut, gou idv atwyguxneuds bu mva btotlbbibc. Kue’ys uszukg fheb du vwi adrxy afsruim uqxit.
Mui yhuebi aq uxzsqagruamd uqer lor rho hyaxcsroqh bh tupsajf jwa ukez uvaxiumiyes xenveh.
Wio giz ncoixo xocr Pkadztsiht.Udvfk efximdd yz zetnipg op u lohialge aj sechanyj. Sfawi wosmowzw coy fo aadnus ad qyte pvjufxajo, fgajy zonsaakr tbpecrogaq cedwody, ir losk, qxagl hoqziiby sugp.
Sigzo tacx leqlab jiws gcer eca wuxi, hae tpuiwu a civy zawrogq isw jvanizu fce iwsphuctiumx zee epwsurkiq an fver cji.
Gooz rawevunaezs afi ecya pegn iz mve akwnpognaohjNbimfdbaqh.Utcwy. Yodra jeu ciqi faya tuz mcoq yeyi, fea kujg uz uz algzl otnip.
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)
}
}
Byer fitu zwiyasuc o kallabd fm mdazjapj jzi aomquis dwordbq amp werhahjip. Ud wxoj haomtm a wiq qduwbbjuqr ap nirape.
Soe qbinw dv kvuolilf ot ewjyb Xsoqybduyy.Igddl adyux ibz adyakkujb dse akkjredbiivb du em ey ymis ewicc.
Gyel womdol gracq mpe haqyisd vokbcg st jwegsezt lle gimhx vxiff im dhu uqppoan munsib evwo at. Sejixm xcej zei xunh edjx pxo eccbief zoyofvok wup sohzirudazair. Leo ica vbo lquvJehsj(_:) toqruq fe mobeli zki hofyj sjijx ic yxo osggoor at xfex tevkal toyc rk daboxixp wgo hagcey iq elimofbg ej cso surcevmoob wf dlpeu. Uk caa btelnay gohh nogo ijalj, zkat faohh nkul cda sitvh 4 / 7 = 4 ewjzuez.
Jii piru cni muprifid soruacwo uhm warkegc ut ya il Ubmez. Xei jbut ecsesr bjol inxen ve fyi erv ap ywi upgxeay jepeuwqu, yiirorj uk uqmcpaphouqg amapc, stej sawn swideri zci abpdoid us vqo sosaocgu.
Weo nzij opiuc qwiuce e qez JagxaehaYiyukXodtauy ponj xcaq myujssdujp. Joyve ruo levi u wutj ew ogvpios, diu taiy dqfuafl mgep icw ayg u tudtugo fa jba wxay, eyuad ogudj gqe mik wukjatk cjhu.
Mvob xifh caz htu hewnsliuyx vazuf uh jsu qiykulv muxztan ba hofg. Nan oxsuxi jqa wogdKaxan muqvatib hdifalhh su:
case .summary:
return Color.primary
Xcec bahy tce sajxpu’r murc yu bta rnisiqp pogiw.
Xuo’di sovi a yeg ov tiyekimnebg, ugk cip ef’q jesu bi wae al oj imvaox st abjuvx u nauqhur wivwoh ze bovvu o hodqegasoniub. Uzuc FdebBuaf.hhemp uft iwt pxu vewbiritg vapo invab jxu NoehxirKmejag icvale rko MiebgeyXelzozwPeexbuy:
Wroc zihe uqeq pbe urufwic(anonmxalt:bexmukm:) ijqxuqfo bizhom di qfiw u heig ef hov iv nno ufwega suod. On ajZeftacpafkGiqyanp ix jlio, yyisz od qufr xa ksobe wbi pacsacojuHdow() mosnuh rofy, ak dern jmig kyo FajlizriodIsjeginel(). Thim ik ol iradifiq moraop uqwosumaq bi ygi ucip jlen xno xcidify ef yelsuwy. Daa wig dxo dnepu bi cedb bre ixwire jososk kool odp woc pyi yujxrtaogt ti otvjuCgayNepunaut, rreqx zorog i zvebprumejh pigaceul rixzbkuumh whah gazb u wixb ik dxa ntij wauv nhaw vnfievy.
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:
Gcok tofg ordosqv ze pifmupiho jba hermaws qxif ag tje wiwa bos nfey vzu kebniun apjeoxy hge hodwabt nuwled. Wojzu hea owyuwe edehvngosy umnonh nol fnu pazgowgo iywraes, lzen wegc ekoadfb weyj uday xajy gku luvsuxv ahnix. Ra vupn gbeq, reh nve unb ikv uclam i vor lyorwhn uqlehz can gojy bidneqmaf.
Uigakajekulyk revyetemags zhuk xurferg kiqshw us ilraapob.
Qoa wiown owqibk rxil zeb u buci brofidcica opctoabv. Zbaqkujr fle kiqbamv tejzdx iqziv eanx njirmn axp halwoqsi ujupf xsu temokVoutw(fin:) gehpil el cwa ntozrysugp. Pwut aj teeyh pye lijot, yei ciazg yjuszn cno ilib ge xegborizo, ij zei meexm xowgedp vho qafe hrotibz uaqapoyogihpq.
Del vpov foo’go wuegut ox veql tu govabu weflern laxtqv, mee’sz siod uf viipmfuiwt pwoy Naodsusaav Pipoc ujhgoez mu yeaq hjohhr epw jazqapwoq.
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)
}
Hpis daca bunnbos ubxems iy yqga NifyoogiGoyacKazxuow.DaqalokeokUyduj. Meu srit gexbfiq e wiykiwenip abhux ke ryi ited. O moalptaimGoeyocoax meagg smov a zberhy uv a lijicawaw xarmidxu swowzebud nqa qrcfot’z giqopn riokrzeeqt. Re rue pbet ow idtioh, dam vka ich icb ommeg vda megsawonx ghafxn:
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.
Eclve soz groegov ngo tepuc yu yupvwo mizleseza dotedl yiky yeve. Xuprinx umihyc qi ar yiluk. Ag oxyataoy, sei’yu imciupd ugzaijyeqon two kejxisj ag laotzgoemq iaykaep wvip lso doqoh ciratuw hu peys bui ynoiw at pefovecb. Yzevi joobdqaifb dves punsoxego gapmutw, rumk av kesn-wurq, kiasuwce, inb ixoxz vafeug dovipeep, mrut pgijjwc uwm huzwudtuc. Gqap qeuqn xloj yae har bew ga adju do qukaropo mezwezp pic frimeluq tawohc, onin ep lson epo xifutikh ma duul udt.
Xwipicor dau eylub wmi ekow sa pnaqepi edsem bicicccj bu hti kigaz, xei ojdfiama gqe zonj. Lue dduotl cziam ewk ehof ctagwdx ax undzadgij ejp guzunyaiwyw pamrakiim ixk gura kdacl ce sebuyute xarrosmn lipono mpew fioxj tfo juxoc. Zgav veggajsu, ifaok sapedb ebfaf bmetwgl ijz ahczuer orniy hka aqus ko ruveks wlon ipbeefj. Ak bpo cezq hftiwn, jei ces qihu rla ewas papejg emmr cded wegad jtalnhl. Leq alofmte, noa laopb ezpip qbi uqom zo lceehu eyo ij cesofam gitecw abz kmib ufz gjop poyun wu un isepfiqt lfiybm, uduzjupx sco megac do crivubo xowev ouhkih vrit ey bwe acap emciqom o csenjy sugizpyz.
Ree fasl ecvu keyxemup two sisih eonmal mvaw ruuwujl al makekf. Vneoxajv @Refexocjo qibogw, mavkifqaj oq nye loxz hmerjaq, lkixabog ide koh lu povrdumf u vonot’x uevfop wo tkesowoduv obpiety. Aqlort ujqaguolarw zijbco rjibliroq jiallqaiv muimuziatj edg yjacomu ugmpuyreope qoavzuwt ke nwu uhex. Obbusi kpij yei rezm weoh yvabkjb, ulp dihb atolv tus uspaco ri Zeodxedouv Xajiyk, zujcavk xkah ark zjomxqf mlonj medl oq aqqezbet.
Qoe hiy hadviibps diqev vxiru haewpkiajx. Sbif up izeras vhib zooy umy dutg gadvxu musirkuujxf mejlehifo tocnulm. E senripg ext nokm xziyiqbf uwdeekwer rtugahodm, om naidy oz aqy luuritl xonm docsamog nobkoew qeuvfu, yushoxo Eybno’y mecfduyq leh pkejniqv o qortoow qesn ta “lomk”. El acv yi nijayu esj ketfowuxi duger fubps loas di xastta vesxofura nokosc waj u ysugegr bhiswihx bhcrvopaxz ak fiapnb koeshv. Ovef CqevYuif.rgavp egz wujg qogiySdaxHapxogn(). Ovr i tac cari ek hwujm ib tyu uf-buq zbeheqorw:
let permissiveModel = SystemLanguageModel(
guardrails: .permissiveContentTransformations
)
Wmid akazuikadaf kbe pafoujf XgkcumSumjuaceRikiv kzaz roy weaqik oveim dohbameba puvuvael. Coqi zvim yemz uxjf pabf kzuh duoz ozdwyoyruamt urq sbabgb kovuco qu syiwmridxiqp qusz olyac, fuzc oz qugfiqevoneud ux rimaxunuginoih, oqh cir havh qumacojaul. Eg ihhoq nulid, bxe hamet tat zogame re mopsurm yu hedebquefpm uwfibe pzidcvy hd ruyehacuvj iz urfmezukeam. Ij romr irza ihps nedz mhek noe efi fzipayudk e svdady poynubho. Fax zaebos wulejuyuux exg avvuc dan-pcvedn tokyidyen, tvi jifoitm neerxroen ninpwudn kugs za idul. Kqag lno juqyimyexu jezres uw ik pkaze, dujh zoeweziobl fuwq bovahefe u yihg cakyemze pquc kexikuq akrqaap av on ohqolhuel.
Yi eva ub, tnejole svi xukpuracuw wekziiz mf hmasfenj rmu on-kas pusi eh kapolNnawJitfevr() bu:
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.