De la model la agent: Echiparea API-ului Responses cu un mediu informatic
De Bo Xu, Danny Zhang și Rohit Arunachalam
În prezent, trecem de la utilizarea modelelor, care excelează la sarcini specifice, la utilizarea agenților capabili să gestioneze fluxuri de lucru complexe. Folosind solicitări pentru modele, poți accesa doar inteligența instruită. Totuși, dacă modelul dispune de un mediu informatic, se pot realiza o varietate mult mai mare de scenarii de utilizare, cum ar fi rularea de servicii, cererea de date de la API-uri sau generarea de artefacte mai utile, precum foi de calcul sau rapoarte.
Câteva probleme practice apar când încerci să construiești agenți: unde să pui fișierele intermediare, cum să eviți lipirea unor tabele mari într-o solicitare, cum să-i oferi fluxului de lucru acces la rețea fără a crea probleme de securitate și cum să gestionezi expirările și reîncercările fără a construi tu însuți un sistem de fluxuri de lucru.
În loc să le cerem dezvoltatorilor să-și construiască propriile medii de execuție, am construit componentele necesare pentru a echipa API-ul Responses(se deschide într-o fereastră nouă) cu un mediu informatic care să execute în mod fiabil sarcini reale.
API-ul Responses de la OpenAI, împreună cu instrumentul shell și un spațiu de lucru într-un container găzduit, este conceput pentru a aborda aceste probleme practice. Modelul propune pași și comenzi; platforma le execută într-un mediu izolat, dotat cu un sistem de fișiere pentru intrări și ieșiri, un spațiu de stocare structurat opțional (cum ar fi SQLite) și acces limitat la rețea.
În această postare, vom explica pas cu pas cum am creat un mediu informatic pentru agenți și vom împărtăși câteva lecții preliminare despre cum se poate utiliza pentru fluxuri de lucru de producție mai rapide, mai ușor de repetat și mai sigure.
Un flux de lucru eficient pentru agenți începe cu o buclă de execuție strânsă: modelul propune o acțiune, cum ar fi citirea fișierelor sau preluarea datelor prin API, platforma o execută, iar rezultatul furnizează următorul pas. Vom începe cu instrumentul shell — cea mai simplă modalitate de a vedea această buclă în acțiune — și apoi vom aborda spațiul de lucru al containerului, rețelele, competențele reutilizabile și compactarea contextului.
Pentru a înțelege instrumentul shell, în primul rând trebuie să înțelegem cum utilizează un model lingvistic instrumentele în general: pentru a efectua operațiuni precum apelarea unei funcții sau interacțiunea cu un computer. În timpul instruirii, unui model i se arată exemple despre cum sunt utilizate instrumentele și efectele rezultate, pas cu pas. Acest lucru ajută modelul să învețe să decidă când să folosească un instrument și cum să o facă. Când spunem „folosirea unui instrument”, ne referim la faptul că modelul, de fapt, doar propune o apelare de instrument. Nu poate executa apelarea de unul singur.
Instrumentul shell face modelul mult mai puternic: interacționează cu un computer prin linia de comandă pentru a efectua o gamă largă de sarcini, de la căutarea de text până la trimiterea de cereri API pe computer. Construit pe baza unor instrumente Unix familiare, instrumentul nostru shell poate face orice te-ai aștepta, cu utilitare precum grep, curl și awk disponibile imediat.
În comparație cu interpretorul nostru de cod existent, care execută doar Python, instrumentul shell permite o gamă mult mai largă de scenarii de utilizare, cum ar fi rularea programelor Go sau Java sau pornirea unui server NodeJS. Această flexibilitate îi permite modelului să îndeplinească sarcini agentice complexe.
De unul singur, un model poate doar să propună comenzi shell, dar cum sunt executate aceste comenzi? Avem nevoie de un orchestrator care să preia ieșirea modelului, să invoce instrumente și să transmită răspunsul instrumentului înapoi către model într-o buclă, până când sarcina este finalizată.
API-ul Responses este modul în care dezvoltatorii interacționează cu modelele OpenAI. Când este utilizat cu instrumente personalizate, API-ul Responses cedează controlul clientului, iar clientul necesită propriul sistem de gestionare pentru rularea instrumentelor. Totuși, acest API poate și să orchestreze imediat, fără configurare suplimentară, între model și instrumentele găzduite.
Când API-ul Responses primește o solicitare, asamblează contextul modelului: solicitarea utilizatorului, starea conversației anterioare și instrucțiunile instrumentului. Pentru ca execuția shell-ului să funcționeze, solicitarea trebuie să menționeze utilizarea instrumentului shell , iar modelul selectat trebuie să fie instruit să propună comenzi shell — modelele GPT‑5.2 și versiunile ulterioare sunt instruite pentru acest lucru. Având în vedere tot acest context, modelul decide apoi care este următoarea acțiune. Dacă alege execuția shell-ului, returnează una sau mai multe comenzi shell către serviciul API-ului Responses. Serviciul API-ului redirecționează acele comenzi către runtime-ul containerului, transmite în flux datele de ieșire ale shell-ului și le furnizează modelului în contextul următoarei cereri. Modelul poate apoi inspecta rezultatele, emite comenzi ulterioare sau produce un răspuns final. API-ul Responses repetă această buclă până când modelul returnează o completare fără comenzi shell suplimentare.
Când API-ul Responses execută o comandă shell, menține o conexiune de streaming la serviciul container. Pe măsură ce este produsă ieșirea, API-ul o transmite modelului în timp aproape real, astfel încât modelul să poată decide dacă să aștepte mai multe ieșiri, să ruleze o altă comandă sau să treacă la un răspuns final.
API-ul Responses transmite în flux ieșirea comenzilor shell
Modelul poate propune mai multe comenzi shell într-un singur pas, iar API-ul Responses le poate executa simultan folosind sesiuni separate de container. Fiecare sesiune transmite în flux ieșirea în mod independent, iar API-ul multiplexează aceste fluxuri înapoi în ieșiri structurate ale instrumentelor ca context. Cu alte cuvinte, bucla agentului poate paraleliza munca, cum ar fi căutarea fișierelor, preluarea datelor și validarea rezultatelor intermediare.
Atunci când comanda implică operațiuni cu fișiere sau procesarea datelor, datele de ieșire ale shell-ului pot deveni foarte mari și pot consuma bugete de context fără a adăuga semnale utile. Pentru a controla acest lucru, modelul specifică o limită de ieșire per comandă. API-ul Responses impune această limită și returnează un rezultat delimitat care păstrează atât începutul, cât și sfârșitul rezultatului, marcând în același timp conținutul omis. De exemplu, ai putea limita rezultatul la 1000 de caractere, cu începutul și sfârșitul păstrate:
text la început ... 1000 de caractere trunchiate ... text la sfârșit
Împreună, execuția concurentă și ieșirea limitată fac ca bucla agentului să fie atât rapidă, cât și eficientă din punct de vedere al contextului, astfel încât modelul să poată continua să dezvolte un raţionament asupra rezultatelor relevante, în loc să fie copleșit de jurnalele brute ale terminalului.
O problemă potențială cu buclele agentului este că sarcinile pot rula pentru o perioadă lungă de timp. Sarcinile de lungă durată umplu fereastra contextuală, ceea ce este important pentru a oferi context de-a lungul mai multor ture și între agenți. Imaginează-ți un agent care apelează o competență, primește un răspuns, adaugă apelări de instrumente și rezumate de raţionament — fereastra contextuală limitată se umple rapid. Pentru a evita pierderea contextului important pe măsură ce agentul continuă să ruleze, avem nevoie de o modalitate de a păstra detaliile cheie și de a elimina ceea ce este inutil. În loc să le cerem dezvoltatorilor să proiecteze și să întrețină sisteme personalizate de rezumare sau de păstrare a stării, am adăugat compactare nativă în API-ul Responses, concepută să se alinieze cu modul în care se comportă modelul și cu modul în care a fost instruit.
Cele mai recente modele ale noastre sunt instruite să analizeze starea anterioară a conversației și să producă un element de compactare care păstrează starea anterioară esențială într-o reprezentare criptată, eficientă din punct de vedere al tokenurilor. După compactare, fereastra de context următoare cuprinde acest element de compactare și porțiunile cu valoare ridicată din fereastra anterioară. Acest lucru permite ca fluxurile de lucru să continue coerent peste limitele ferestrelor, chiar și în sesiuni extinse, în mai mulți pași și bazate pe instrumente. Codex se bazează pe acest mecanism pentru a susține sarcini de programare de lungă durată și execuția iterativă a instrumentelor fără a degrada calitatea.
Compactarea este disponibilă fie încorporată pe server, fie printr-un punct final `/compact` independent. Compactarea pe partea serverului îți permite să configurezi un prag, iar sistemul gestionează automat momentul compactării, eliminând necesitatea unei logici complexe pe partea clientului. Aceasta permite o fereastră contextuală de intrare efectivă puțin mai mare pentru a tolera mici depășiri chiar înainte de compactare, astfel încât cererile apropiate de limită să poată fi totuși procesate și compactate, în loc să fie respinse. Pe măsură ce instruirea modelului evoluează, soluția nativă de compactare evoluează odată cu aceasta pentru fiecare lansare de model OpenAI.
Codex ne-a ajutat să dezvoltăm sistemul de compactare, fiind în același timp unul dintre primii utilizatori ai acestuia. Când o instanță Codex întâmpina o eroare de compactare, porneam o a doua instanță pentru a investiga. Astfel, Codex a obținut un sistem de compactare nativ și eficient doar prin faptul că s-a ocupat de acea problemă. Această capacitate a lui Codex de a se inspecta și de a se rafina a devenit o parte deosebit de interesantă a activității la OpenAI. Majoritatea instrumentelor cer doar ca utilizatorul să învețe cum să le folosească; Codex învață alături de noi.
Acum să abordăm starea și resursele. Containerul nu este doar un loc pentru a rula comenzi, ci și contextul de lucru pentru model. În interiorul containerului, modelul poate citi fișiere, poate interoga baze de date și poate accesa sisteme externe sub controlul politicilor de rețea.
Prima parte a contextului containerului este sistemul de fișiere pentru încărcarea, organizarea și gestionarea resurselor. Am construit API-uri pentru containere și fișiere(se deschide într-o fereastră nouă) pentru a-i oferi modelului o hartă a datelor disponibile și a-l ajuta să aleagă operațiuni specifice pe fișiere, în loc să efectueze scanări ample și neclare.
Un anti-model comun este să înghesui toate intrările direct în contextul solicitării. Pe măsură ce intrările cresc, umplerea excesivă a solicitării devine costisitoare și dificil de parcurs pentru model. Un model mai bun este să pregătești resursele în sistemul de fișiere al containerului și să lași modelul să decidă ce să deschidă, să analizeze sau să transforme cu comenzi shell. La fel ca oamenii, modelele funcționează mai bine cu informații organizate.
A doua componentă a contextului containerului o reprezintă bazele de date. În multe cazuri, le sugerăm dezvoltatorilor să stocheze date structurate în baze de date precum SQLite și să le interogheze. În loc să copiezi o foaie de calcul întreagă în solicitare, de exemplu, îi poți oferi modelului o descriere a tabelelor — ce coloane există și ce înseamnă acestea — și să-l lași să extragă rândurile de care are nevoie.
De exemplu, dacă întrebi: „Ce produse au avut vânzări în scădere în acest trimestru?”, modelul poate interoga doar rândurile relevante, în loc să scaneze întregul tabel. Acest lucru este mai rapid, mai ieftin și mai scalabil pentru seturi de date mai mari.
A treia parte a contextului containerului este accesul la rețea, o parte esențială a volumelor de lucru ale agentului. Fluxul de lucru al agentului poate necesita preluarea datelor în timp real, apelarea unor API-uri externe sau instalarea de pachete. În același timp, acordarea accesului nerestricționat la internet containerelor poate fi riscantă: poate expune informații către site-uri web externe, poate atinge în mod neintenționat sisteme confidențiale interne sau de la terți sau poate face mai dificilă protejarea împotriva scurgerilor de acreditări și a exfiltrării datelor.
Pentru a aborda aceste preocupări fără a limita utilitatea agenților, am creat containere găzduite care folosesc un proxy de ieșire sidecar. Toate cererile de rețea de ieșire trec printr-un strat de politici centralizat care impune liste de permisiuni și controale de acces, menținând traficul observabil. Pentru acreditări, folosim injectarea de secrete la nivel de domeniu la ieșire. Modelul și containerul văd doar substituenți, în timp ce valorile brute ale secretelor rămân în afara contextului vizibil pentru model și se aplică doar destinațiilor aprobate. Acest lucru reduce riscul de scurgere, permițând în același timp apelări externe autentificate.
Comenzile shell sunt puternice, dar multe sarcini repetă aceleași modele în mai mulți pași. Agenții trebuie să redescopere fluxul de lucru la fiecare rulare — replanificând, reemițând comenzi și reînvățând convenții — ceea ce duce la rezultate inconsecvente și execuție irosită. Competențele agentului(se deschide într-o fereastră nouă) grupează acele modele în blocuri de construcție reutilizabile și compozabile. Concret, o competență este un pachet de foldere care include ‘SKILL.md(se deschide într-o fereastră nouă)’ (conținând metadate și instrucțiuni) plus orice resurse de sprijin, cum ar fi specificațiile API și resursele UI.
Această structură se potrivește în mod natural arhitecturii runtime descrise anterior. Containerul furnizează fișiere persistente și contextul de execuție, iar instrumentul shell furnizează interfața de execuție. Cu ambele implementate, modelul poate descoperi fișiere de competențe folosind comenzi shell (`ls`, `cat` etc.) atunci când este nevoie, poate interpreta instrucțiuni și poate rula scripturi de competențe, toate în aceeași buclă a agentului.
Oferim API-uri(se deschide într-o fereastră nouă) pentru gestionarea competențelor în platforma OpenAI. Dezvoltatorii încarcă și stochează folderele de competențe ca pachete versionate, care pot fi ulterior regăsite după ID-ul competenței. Înainte de a trimite solicitarea către model, API-ul Responses încarcă competența și o include în contextul modelului. Această secvență este deterministă:
- Preia metadatele competenței, inclusiv numele și descrierea.
- Preia pachetul de competențe, îl copiază în container și îl dezarhivează.
- Actualizează contextul modelului cu metadatele competențelor și calea containerului.
Atunci când decide dacă o competență este relevantă, modelul își explorează progresiv instrucțiunile și își execută scripturile prin comenzi shell în container.
Pentru a pune toate piesele cap la cap: API-ul Responses oferă orchestrare, instrumentul shell oferă acțiuni executabile, containerul găzduit oferă context runtime persistent, logică reutilizabilă a fluxului de lucru la nivelul competențelor , iar compactarea îi permite agentului să ruleze pentru o perioadă lungă de timp cu contextul de care are nevoie.
Cu aceste elemente de bază, o singură solicitare se poate extinde într-un flux de lucru complet: descoperă competența potrivită, preia date, le transformă în stare structurată locală, le interoghează eficient și generează artefacte durabile.
Diagrama de mai jos arată cum funcționează acest sistem pentru a crea o foaie de calcul din date în timp real.
API-ul Responses orchestrează o sarcină agentică
Pentru un exemplu detaliat de combinare a instrumentului shell și a mediului computerizat pentru fluxuri de lucru complete, consultă postarea noastră de pe blogul dezvoltatorilor(se deschide într-o fereastră nouă) și ghidul practic(se deschide într-o fereastră nouă), care prezintă pas cu pas crearea unei competențe și executarea acesteia prin intermediul API-ului Responses.
Abia așteptăm să vedem ce vor crea dezvoltatorii folosind acest set de elemente de bază. Modelele lingvistice sunt concepute să facă mai mult decât să genereze text, imagini și conținut audio. Vom continua să ne dezvoltăm platforma pentru a o face mai capabilă să gestioneze la scară largă sarcini complexe reale.


