Contextul instrumentelor și cache-ul prompturilor
Două lucruri sunt adevărate pentru fiecare cerere pe care o face harness-ul integrat: definițiile de instrumente sunt cel mai mare cost fix din ea și aproape niciuna dintre ele nu va fi folosită. Această pagină explică ce face Control Center în privința asta și de ce răspunsul nu este pur și simplu „trimite mai puține instrumente”.
Problema este atenția, nu octeții
Secțiune intitulată „Problema este atenția, nu octeții”Control Center înregistrează aproximativ 126 de instrumente. Trimise integral, definițiile lor costă aproximativ 23.000 de tokeni la fiecare cerere — un cost pe care nicio compactare nu îl poate atinge, pentru că definițiile de instrumente călătoresc într-o parte separată a cererii față de conversație.
Factura de tokeni este nemulțumirea evidentă și, odată cu cache-ul de prompturi, este și cea mai mică. Costul real este acuratețea selecției. Evaluările publicate privind apelarea instrumentelor confirmă că modelele aleg instrumentul potrivit în mod fiabil până la aproximativ 30–50 de instrumente în context, iar dincolo de acest prag se înrăutățesc progresiv. Cauza numită nu este numărul de tokeni, ci suprapunerea semantică: odată ce un catalog conține mai multe instrumente ale căror descrieri se citesc la fel, modelul alege între instrumente care seamănă, în loc să-și amintească o capacitate.
Cu 126 de instrumente, un agent este cu mult peste acest interval la fiecare tură, inclusiv în numeroasele ture în care avea nevoie doar să citească un fișier.
Suprafața pe două niveluri
Secțiune intitulată „Suprafața pe două niveluri”O rulare vede, așadar, două lucruri:
- un set rezident — aproximativ două duzini de instrumente, trimise cu scheme complete la fiecare cerere;
- un index de nume cu tot restul, grupat sub titluri precum „Tichete și proiecte” sau „Memorie și cunoștințe”, care costă câteva sute de tokeni pentru întregul catalog.
Măsurat pe catalogul actual, asta duce blocul de instrumente de la ~23,1k tokeni la ~5,0k, cu aproximativ 78% mai puțin, și aduce setul mereu vizibil în intervalul în care selecția este fiabilă.
Setul rezident este format din instrumentele pe care o rulare le folosește în majoritatea rulărilor: vocabularul de fișiere și shell (read, write, edit, search, bash, …), instrumentele de descoperire, lista de verificare a sarcinilor, căutarea în memorie și orice verb pe care modul curent trebuie să îl apeleze pentru a-și livra rezultatul. Verbul de ieșire propriu al unui mod este întotdeauna rezident — o rulare nu trebuie niciodată să caute apelul care îi produce livrabilul.
Amânat nu înseamnă indisponibil
Secțiune intitulată „Amânat nu înseamnă indisponibil”Aceasta este partea care face proiectarea sigură, nu doar ieftină. Un instrument amânat poate fi apelat din prima tură. Doar schema îi este reținută.
Agentul vede numele în promptul său. Dacă apelează direct acel nume, harness-ul încarcă schema și rulează instrumentul în același pas — fără eroare, fără dus-întors. Modelul nu trebuie să știe că instrumentul a fost vreodată „descărcat”.
Când agentul știe sarcina, dar nu știe numele, search_tools preia o descriere în limbaj natural („atribuie un tichet cuiva”), clasează întreaga suprafață a rulării și returnează potrivirile cu schemele lor deja încărcate, astfel încât chiar următoarea tură să poată apela una dintre ele. Dacă o căutare nu găsește nimic, spune asta direct și sugerează o formulare diferită sau o căutare mai largă — în mod deliberat, pentru că un agent care citește o căutare goală drept „această capacitate nu există” va inventa un substitut în loc să caute din nou.
search_tools există doar în harness-ul integrat. Clienții MCP externi au în schimb search_tool_bm25, care clasează același index, dar doar descrie potrivirile — acei clienți au primit deja fiecare schemă din tools/list, așa că nu este nimic de încărcat.
Ce nu face niciodată amânarea
Secțiune intitulată „Ce nu face niciodată amânarea”Amânarea se aplică după filtrul de instrumente al modului, niciodată în locul lui. Ascunde o schemă; nu poate dezvălui un instrument pe care modul l-a refuzat. Un instrument activat trece în continuare prin solicitarea de aprobare și prin guardrail-urile de acțiune exact ca unul rezident, iar un instrument nu poate încărca un nume care nu se afla de la început pe suprafața rulării.
Suprafața MCP pe care o văd clienții externi nu este afectată. tools/list returnează în continuare catalogul complet. O încercare anterioară de a-l reduce a stricat agenții de-a dreptul: clienții MCP validează numele instrumentelor față de propria listă memorată în cache și refuză orice nu apare în ea fără să întrebe vreodată serverul, așa că un instrument „ascuns, dar apelabil” era pur și simplu inaccesibil. Amânarea trăiește în harness, unde încărcarea unui instrument la mijlocul rulării este ceva ce harness-ul poate face cu adevărat.
Dezactivarea
Secțiune intitulată „Dezactivarea”--tool-deferral=off (sau CC_SERVER_TOOL_DEFERRAL=off) face ca fiecare instrument admis să redevină rezident, producând exact cererile pe care le făcea serverul înainte să existe amânarea. Vezi referința CLI cc_server.
Cache-ul prompturilor
Secțiune intitulată „Cache-ul prompturilor”Sarcinile agenților sunt dezechilibrate: trimit prompturi uriașe și primesc răspunsuri mici, tură după tură, de fiecare dată cu același prefix. Providerii memorează acel prefix în cache, iar o citire din cache costă cam o zecime dintr-una proaspătă. Rata de potrivire în cache este, așadar, o proprietate de primă clasă a harness-ului, nu o optimizare — iar pe Anthropic aduce în plus și debit, pentru că tokenii din cache nu se scad din limita de intrare pe minut.
Memorarea în cache se bazează pe o potrivire exactă a prefixului, ceea ce duce la o singură regulă care guvernează totul.
Nu rescrie niciodată ce a fost deja trimis
Secțiune intitulată „Nu rescrie niciodată ce a fost deja trimis”Orice octet care se schimbă invalidează cache-ul din acel punct înainte. Așa că harness-ul doar adaugă la final: mesajele noi la sfârșit, iar schemele de instrumente nou activate după blocul de instrumente memorat în cache, nu contopite în el. Această ordonare este motivul pentru care activarea este ieftină — prefixul din cache rămâne identic, iar rularea plătește doar schemele pe care tocmai le-a încărcat.
Bucla elimină, de asemenea, ieșirile învechite ale instrumentelor din turele mai vechi pentru a recupera context. Așteaptă până când este suficient de recuperat pentru ca rescrierea să merite, așa că o eliminare este o rescriere profundă rară, nu o ratare continuă a cache-ului.
Unde se plasează punctele de întrerupere
Secțiune intitulată „Unde se plasează punctele de întrerupere”Un provider permite un număr limitat de marcaje de cache, iar Control Center le folosește cu intenție:
| Marcaj | Acoperă | Durată de viață |
|---|---|---|
| Ultimul instrument rezident | Blocul de instrumente | 1 oră |
| Ultimul bloc de sistem | Instrumente + prompt de sistem | 1 oră |
| Coada turei precedente | Istoricul până la ultima cerere | 5 min |
| Coada turei curente | Istoricul complet | 5 min |
Ultimele două formează o pereche glisantă, iar motivul pentru care există perechea este subtil: o căutare în cache merge înapoi un număr limitat de blocuri pentru ceva ce o cerere anterioară a stocat. O singură tură care rulează multe instrumente în paralel poate emite mai multe blocuri decât acea fereastră, moment în care un marcaj de coadă ratează în tăcere, iar cererea plătește prețul întreg fără ca răspunsul să spună ceva. Marcarea locului exact unde s-a oprit cererea precedentă face potrivirea structurală, în loc să fie o cursă.
Prefixul de instrumente și sistem primește durata lungă de viață pentru că este constant pe toată rularea, este partajat de fiecare rulare și subagent cu aceeași formă și pentru că ceasul pornește când o cerere începe — o tură care transmite în flux timp de câteva minute a consumat deja cea mai mare parte a unei ferestre scurte înainte să se formeze cererea următoare.
Subagenții împart un singur prefix
Secțiune intitulată „Subagenții împart un singur prefix”Subagenții de același tip produc prefixe de prompt identice octet cu octet, așa că ar trebui să citească o singură intrare de cache în loc să scrie fiecare a sa. Dar o intrare devine citibilă abia când cererea care a scris-o începe să răspundă, așa că un fan-out lansat dintr-o dată face ca fiecare copil să plătească suprataxa pentru un prefix pe care îl împart toți.
Harness-ul lasă primul copil de o anumită formă să pornească, apoi îi eliberează pe frații lui imediat ce începe să transmită în flux. Așteptarea este limitată: un prim copil lent costă o potrivire în cache, niciodată fan-out-ul în sine. Din același motiv, fiecare subagent primește același set rezident de instrumente indiferent de profilul său — varierea lui pe profil ar fragmenta prefixul partajat fără niciun câștig, întrucât profilul a decis deja ce poate apela copilul.
Cum se vede că funcționează
Secțiune intitulată „Cum se vede că funcționează”Ambele jumătăți sunt observabile, nu presupuse:
- Exploratorul de context al unei conversații raportează instrumentele rezidente, indexul amânat și cât ar costa fiecare schemă reținută, construite pe aceeași cale de cod pe care o folosește o rulare reală.
- Fiecare rulare consemnează ce instrumente amânate a încărcat și ce a declanșat asta, așa că o căutare care nu găsește nimic este vizibilă ca o ratare de recuperare, în loc să dispară într-un agent care face în tăcere ceva apropiat.
- Observabilitate raportează Rată cache ca citiri din cache raportate la toți tokenii de prompt procesați, inclusiv scrierile în cache — o rulare care își reconstruiește mereu prefixul obține un scor mic, în loc să aibă unul ca o rulare care nu a avut niciodată nevoie de cache.