Verktøykontekst og promptbuffer
To ting gjelder for hver forespørsel den innebygde harnessen sender: verktøydefinisjonene er den største faste kostnaden i den, og nesten ingen av dem blir brukt. Denne siden forklarer hva Control Center gjør med det, og hvorfor svaret ikke bare er «send færre verktøy».
Problemet er oppmerksomhet, ikke byte
Seksjon med tittelen «Problemet er oppmerksomhet, ikke byte»Control Center registrerer omtrent 126 verktøy. Sendt i sin helhet koster definisjonene deres grovt regnet 23 000 tokens ved hver forespørsel — en kostnad ingen kompaktering kan røre ved, fordi verktøydefinisjonene reiser i en annen del av forespørselen enn samtalen.
Tokenregningen er den åpenbare klagen, og med promptbufring er den også den minste. Den virkelige kostnaden er valgnøyaktigheten. Publiserte evalueringer av verktøykall er enige om at modeller velger riktig verktøy pålitelig opp til et sted rundt 30–50 verktøy i konteksten, og blir gradvis dårligere utover det. Den navngitte årsaken er ikke antallet tokens, men semantisk overlapp: når en katalog inneholder flere verktøy med liknende beskrivelser, velger modellen mellom nesten identiske alternativer i stedet for å huske en evne.
Med 126 verktøy er en agent godt forbi det båndet i hver eneste tur — inkludert de mange turene der den bare trengte å lese en fil.
Flaten med to nivåer
Seksjon med tittelen «Flaten med to nivåer»En kjøring får derfor se to ting:
- et fast sett — rundt to dusin verktøy, sendt med fulle skjemaer ved hver forespørsel;
- en navneindeks over alt det andre, gruppert under overskrifter som «Tickets and projects» eller «Memory and knowledge», og som koster noen hundre tokens for hele katalogen.
Målt på den gjeldende katalogen tar det verktøyblokken fra ~23,1k tokens til ~5,0k, omtrent 78 % mindre, og plasserer det alltid synlige settet innenfor båndet der valget er pålitelig.
Det faste settet er verktøyene en kjøring bruker i de fleste kjøringer: fil- og shell-vokabularet (read, write, edit, search, bash, …), oppdagelsesverktøyene, oppgavesjekklisten, minnesøket og hvilket utdataverb den gjeldende modusen må kalle for å levere resultatet sitt. En modus’ eget utdataverb er alltid fast — en kjøring skal aldri måtte lete etter det ene kallet som produserer leveransen.
Utsatt betyr ikke utilgjengelig
Seksjon med tittelen «Utsatt betyr ikke utilgjengelig»Det er denne delen som gjør designet trygt og ikke bare billig. Et utsatt verktøy kan kalles fra første tur. Bare skjemaet holdes tilbake.
Agenten ser navnet i prompten sin. Hvis den kaller navnet direkte, laster harnessen skjemaet og kjører verktøyet i samme steg — ingen feil, ingen ekstra rundtur. Modellen trenger ikke å vite at verktøyet noen gang var «lastet ut».
Når agenten kjenner oppgaven men ikke navnet, tar search_tools imot en beskrivelse i klartekst («tilordne en sak til noen»), rangerer hele flaten til kjøringen og returnerer treffene med skjemaene sine allerede lastet, slik at neste tur kan kalle ett av dem. Hvis et søk ikke finner noe, sier det det rett ut og foreslår andre ord eller et bredere søk — med vilje, fordi en agent som tolker et tomt søk som «denne evnen finnes ikke», vil finne opp en erstatning i stedet for å lete igjen.
search_tools finnes bare i den innebygde harnessen. Eksterne MCP-klienter har search_tool_bm25 i stedet, som rangerer den samme indeksen, men bare beskriver treffene — de klientene har allerede fått alle skjemaene fra tools/list, så det er ingenting å laste.
Hva utsettelse aldri gjør
Seksjon med tittelen «Hva utsettelse aldri gjør»Utsettelse brukes etter modusens verktøyfilter, aldri i stedet for det. Det skjuler et skjema; det kan ikke avsløre et verktøy som modusen avviste. Et aktivert verktøy passerer fortsatt godkjenningstrinnet og tillatelsesreglene akkurat som et fast verktøy ville gjort, og et verktøy kan ikke laste et navn som ikke var på flaten til kjøringen i utgangspunktet.
MCP-flaten som eksterne klienter ser, blir ikke påvirket. tools/list returnerer fortsatt hele katalogen. Et tidligere forsøk på å skjære den ned ødela agentene fullstendig: MCP-klienter validerer verktøynavn mot sin egen bufrede liste og avviser alt som ikke står der, uten å spørre serveren, så et «skjult, men kallbart» verktøy var rett og slett uoppnåelig. Utsettelsen bor i harnessen, der det å laste et verktøy midt i en kjøring er noe harnessen faktisk kan gjøre.
Slå det av
Seksjon med tittelen «Slå det av»--tool-deferral=off (eller CC_SERVER_TOOL_DEFERRAL=off) gjør hvert tillatte verktøy fast igjen og gir nøyaktig de samme forespørslene som serveren sendte før utsettelsen fantes. Se CLI-referansen for cc_server.
Promptbufring
Seksjon med tittelen «Promptbufring»Agentarbeidsmengder er skjeve: de sender enorme prompter og får små svar, tur etter tur, med det samme prefikset hver gang. Leverandørene bufrer det prefikset, og en lesing fra bufferen koster omtrent en tidel av en fersk lesing. Treffprosenten på bufferen er derfor en førsteklasses egenskap ved harnessen og ikke en optimalisering — og hos Anthropic gir den også gjennomstrømning, fordi bufrende tokens ikke teller mot grensen for inndata per minutt.
Bufring bygger på et eksakt prefikstreff, og det gir én overordnet regel.
Skriv aldri om det som allerede er sendt
Seksjon med tittelen «Skriv aldri om det som allerede er sendt»Enhver byte som endres, gjør bufferen ugyldig fra det punktet og videre. Så harnessen legger bare til: nye meldinger på slutten, og nylig aktiverte verktøyskjemaer etter den bufrede verktøyblokken i stedet for å bli flettet inn i den. Den rekkefølgen er grunnen til at aktivering er billig — det bufrede prefikset forblir identisk, og kjøringen betaler bare for skjemaene den nettopp lastet.
Løkken trimmer også bort foreldet verktøyutdata fra eldre turer for å frigjøre kontekst. Den venter til det er nok å frigjøre til at omskrivingen er verdt det, slik at en trimming er en sjelden dyp omskriving i stedet for stadige bom på bufferen.
Hvor bruddpunktene ligger
Seksjon med tittelen «Hvor bruddpunktene ligger»En leverandør tillater et begrenset antall buffermarkører, og Control Center bruker dem med omhu:
| Markør | Dekker | Levetid |
|---|---|---|
| Siste faste verktøy | Verktøyblokken | 1 time |
| Siste systemblokk | Verktøy + systemprompt | 1 time |
| Halen av forrige tur | Historikk fram til den siste forespørselen | 5 min |
| Halen av gjeldende tur | Hele historikken | 5 min |
De to siste er et rullende par, og grunnen til paret er subtil: et bufferoppslag søker bakover et begrenset antall blokker etter noe en tidligere forespørsel lagret. En enkelt tur som kjører mange verktøy parallelt, kan sende ut flere blokker enn det vinduet, og da bommer den ene halemarkøren stille, og forespørselen betaler full pris uten at noe i svaret sier fra. Ved å markere det nøyaktige stedet der den forrige forespørselen stoppet, blir treffet strukturelt i stedet for et kappløp.
Prefikset for verktøy og system får den lange levetiden fordi det er konstant gjennom hele kjøringen, deles av hver kjøring og underagent med samme form, og fordi klokken starter når en forespørsel begynner — en tur som strømmer i flere minutter, har allerede brukt opp mesteparten av et kort vindu før den neste forespørselen dannes.
Underagenter deler ett prefiks
Seksjon med tittelen «Underagenter deler ett prefiks»Underagenter av samme type produserer byte-identiske promptprefikser, så de bør lese én bufferoppføring i stedet for at hver av dem skriver sin egen. Men en oppføring blir først lesbar når forespørselen som skrev den, begynner å svare, så en samtidig utsending av flere underagenter får hvert barn til å betale premien for et prefiks de alle deler.
Harnessen lar det første barnet av en gitt form starte, og slipper deretter søsknene løs så snart det begynner å strømme. Ventetiden er avgrenset: et tregt første barn koster ett buffertreff, aldri selve vifteutsendingen. Av samme grunn får hver underagent det samme faste verktøysettet uansett profil — å variere det per profil ville fragmentere det delte prefikset uten gevinst, siden profilen allerede har bestemt hva barnet får kalle.
Slik ser du det i arbeid
Seksjon med tittelen «Slik ser du det i arbeid»Begge halvdeler kan observeres i stedet for å antas:
- Kontekstutforskeren på en samtale rapporterer de faste verktøyene, indeksen over utsatte verktøy og hva hvert tilbakeholdte skjema ville koste, bygget fra den samme kodeveien som en ekte kjøring bruker.
- Hver kjøring registrerer hvilke utsatte verktøy den lastet, og hva som utløste det, slik at et søk som ikke finner noe, vises som et gjenfinningsbom i stedet for å forsvinne inn i en agent som stille gjør noe nærliggende.
- Observabilitet rapporterer Cache-rate som bufferlesinger delt på alle prompttokens som er behandlet, inkludert bufferskrivinger — en kjøring som stadig bygger opp prefikset sitt på nytt, skårer lavt i stedet for å skåre som en som aldri trengte en buffer.