Computers via de API¶
Het concept achter tools staat in Tools.
Geef een beurt een eigen computer: een afgeschermde machine waarop het model opdrachten uitvoert en bestanden leest en schrijft. Het model kan zo een script schrijven, het draaien, de uitvoer lezen en het opnieuw proberen — om een bijgevoegd CSV-bestand door te rekenen, een grafiek te maken of code te testen. Wat het maakt, krijg je terug als artefact.
Een computer hoort bij één antwoord. Hij wordt gemaakt bij de eerste computer-tool-aanroep van dat antwoord, blijft voor elke volgende aanroep in hetzelfde antwoord dezelfde machine, en verdwijnt als het antwoord klaar is. Een beurt die geen computer-tool aanroept, kost niets.
Dezelfde computer draait ook de eigen programma's van je organisatie, elk aangeboden als één tool:
zie Scripts via de API. Een script heeft de capability computer nodig, maar niet
de drie tools hieronder.
Wat je sleutel nodig heeft¶
- De capability
computer. Die hangt af vantooling, dus zet die ook aan. - De systeemtool
computerin de configuratietoolingvan de sleutel. Die ene schakelaar zet alle drie de computer-tools aan; in de console heet hij Computer gebruiken (Sleutels). filesals het model je bijlagen moet kunnen lezen, enartifactsals je bestanden van de computer terug wilt krijgen.
{
"name": "Rapportage",
"capabilities": {
"tooling": { "system_tools": ["computer"] },
"computer": {},
"files": {},
"artifacts": {}
}
}
Je organisatie moet computer ook toestaan.
Een organisatie die bestond voordat computers er waren, staat het niet vanzelf toe: code laten
uitvoeren is een bewuste keuze van wie de organisatie erboven beheert, of van je operator.
Je installatie moet ook computers draaien voor je organisatie. Doet hij dat niet, dan weigert Core een
verzoek dat een computer-tool noemt met 400 en "This tool is not configured on this
deployment.", nog voordat het model draait. De 400 draagt "computer_not_configured" als error.code. Zo'n tool
rechtstreeks aanroepen met POST /tools/{name}/call geeft in plaats daarvan 422 op name, met
"reason_code": "computer_not_configured" in de body.
De drie tools¶
| Tool | Wat het model ermee doet |
|---|---|
builtin__computer_exec |
één opdracht uitvoeren in een POSIX-shell, in /workspace; het antwoord bevat de exitcode, stdout en stderr. Met timeout_seconds kan het model de tijdslimiet voor die ene opdracht korter maken, nooit langer |
builtin__computer_write_file |
een tekstbestand schrijven (path, content), inclusief de map; een bestaand bestand wordt vervangen |
builtin__computer_read_file |
een bestand lezen (path): standaard als tekst voor het model, met export: true als artefact voor jou |
Een relatief pad valt onder /workspace. Aanroepen in één ronde lopen na elkaar, in de volgorde
waarin het model ze schreef, dus een script dat wordt geschreven en daarna uitgevoerd, werkt zoals
bedoeld.
Een verzoek¶
Bied de drie tools aan zoals elke andere tool, en voeg de bestanden toe waarmee het model moet werken:
{
"model": "<een model-id>",
"input": [
{
"role": "user",
"content": [
{ "type": "input_text", "text": "Tel de omzet per maand op en maak er een staafdiagram van." },
{ "type": "input_file", "file_id": "src_3Wq8..." }
]
}
],
"tools": [
{ "type": "tool", "name": "builtin__computer_exec" },
{ "type": "tool", "name": "builtin__computer_write_file" },
{ "type": "tool", "name": "builtin__computer_read_file" }
]
}
Of bied ze aan via een toolset met het patroon builtin__computer_*.
Bestanden erin en eruit¶
Erin. Bij de eerste computer-aanroep kopieert Core wat het gesprek bevat naar de computer, nieuwste eerst:
- Bestanden: eerst die dit verzoek bijvoegt — de
input_file- eninput_image-items — en dan die de laatste 5.000 berichten van het gesprek bijvoegden, ook de berichten die het model niet meer ziet omdat het gesprek is samengevat. Elk bestand komt in/workspace/inputs/<file id>/<bestandsnaam>. Daarvoor isfilesnodig, en alleen bestanden die de sleutel ook viaGET /files/{id}/contentmag lezen worden gekopieerd: een bestand dat het beleid van de sleutel niet noemt, van een andere persoon is of intussen is verwijderd, wordt overgeslagen. - Artefacten die de nieuwste 200 antwoorden in het gesprek exporteerden, in
/workspace/artifacts/<artifact id>/<bestandsnaam>. Daarvoor isartifactsnodig, en een artefact kopiëren telt als downloaden: als de regels van je sleutel artefacten downloaden weigeren, wordt geen enkel artefact gekopieerd en wordt de weigering één keer vastgelegd, zoals bij een download.
Samen vallen ze onder de limieten van de deployment, standaard 50 bestanden en 256 MiB. Het kopiëren stopt bij het aantal; een bestand dat de nog resterende bytes zou overschrijden wordt overgeslagen, en oudere, kleinere bestanden worden nog wel gekopieerd. Als latere antwoorden de computer van het gesprek hergebruiken, wordt een bestand dat er al staat niet opnieuw gekopieerd.
Eruit. Een bestand verlaat de computer alleen als het model het exporteert, met
builtin__computer_read_file en export: true. Het wordt een artefact van je sleutel, met hetzelfde
maximum als elk ander artefact (25 MiB). Zonder artifacts wordt het niet bewaard en hoort het
model dat. Vind de artefacten van een antwoord met:
GET /api/v1/artifacts?response_id=resp_...
GET /artifacts/{id}/content geeft daarna de bytes (Bestanden).
De schijf van de computer is kladpapier. Wat niet is geëxporteerd, is weg als de computer stopt.
Rijen afgeleverd op de computer¶
Een SQL-tool of de query-tool van een
datastore kan zijn rijen op de computer schrijven in plaats van ze aan het model te geven. Noem hem
met "deliver": "computer":
{"type": "tool", "name": "sql__orders", "deliver": "computer"}
De rijen komen in /workspace/results/<call id>.csv, met een kopregel, en het model leest alleen
{"columns": ["id", "status", "total"], "row_count": 18234, "truncated": false,
"path": "/workspace/results/call_7.csv"}
zodat het het bestand met builtin__computer_exec kan openen. Waarden worden geschreven zoals het
gewone antwoord van de tool ze schrijft (een decimaal getal als tekst, een tijd als ISO 8601, bytes
als [binary]), een lege cel voor null. De eigen max_rows van een SQL-tool geldt niet; de
limieten van de deployment gelden wel, standaard een miljoen rijen en 64 MiB CSV, en
truncated: true zegt dat er rijen zijn weggelaten. Core voert per server een paar afleveringen
tegelijk uit; zit het op dat aantal, dan leest de aanroep niets en krijgt het model te horen dat
het de tool zo dadelijk opnieuw moet aanroepen.
deliverwordt alleen geaccepteerd op eensql__-tool waarvan de query leest en de__query-tool van een datastore, en alleen in een beurt waarin je sleutelbuiltin__computer_execaangeboden zou krijgen; anders wordt het verzoek geweigerd met422optools.<n>.deliver.- Op een computer die internet bereikt worden rijen alleen afgeleverd als je organisatie
computer_internet_bulk_rowsheeft aangezet. Anders leest de aanroep geen enkele rij en krijgt het model te horen:Rows are not delivered to a computer that reaches the internet unless the organisation allows it with its computer_internet_bulk_rows setting.De weigering staat in de audit trail. Op een computer zonder netwerk worden rijen altijd afgeleverd. - Een sleutel die persoonsgegevens verbergt, levert de rijen onverborgen af op de computer. Wat een commando ervan afdrukt, komt verborgen bij het model terug, zoals elk toolresultaat.
Wat een computer niet kan¶
- Geen netwerk. De computer bereikt internet niet, en ook je eigen systemen niet. Wat hij nodig
heeft, stuur je mee als bijlage. De uitzondering is een omgeving waarvan de beheerder computers
aanbiedt die internet bereiken, voor een organisatie die
computer_internetheeft aangezet, net als elke organisatie erboven: daar kan code op de computer verbinding maken met de buitenwereld en zijn argumenten en bestanden overal heen sturen. Zonder die schakelaar krijg je een computer zonder netwerk, of geen als de omgeving alleen open computers heeft. Ook mét de schakelaar krijg je zo'n computer niet als je beleid toegestane regio's of leveranciers noemt, de hosts beperkt die het mag bereiken, of eist dat persoonsgegevens verborgen worden, of als je sleutel persoonsgegevens verbergt. Een organisatie die toegestane hosts heeft ingesteld, wordt ook geweigerd. Een regio-uitzondering verandert dat niet; elke computeraanroep antwoordtDenied by policy.. - Via de proxy van Core, waar de omgeving er een draait. Een computer die internet bereikt,
krijgt dan de opdracht de egress-proxy van Core te gebruiken:
HTTPS_PROXY,HTTP_PROXYen varianten staan voor elk commando ingesteld, met toegangsgegevens die alleen van die computer zijn. Verkeer dat via de proxy gaat, wordt vastgelegd -- host, bytes, tijd -- en de proxy weigert wat de regels van je organisatie weigeren; waar de omgeving een limiet instelt, wordt het per organisatie begrensd, en een begrenzer die niet antwoordt laat verbindingen door. Je leest het logboek metGET /computers/{computer_id}/egressofGET /computer-egress, te versmallen methost,opened_afterenopened_before. Verkeer dat om de proxy van Core heen gaat -- een programma dat de proxyvariabelen negeert, een socket die zelf verbinding maakt -- bereikt het internet nog steeds, en wordt niet vastgelegd, niet begrensd en niet getoetst aan de blokkeerlijst of de regel voor privéadressen. - De toegangsgegevens van de proxy zijn zichtbaar voor code op de computer. Ze staan in de
omgeving van de computer en in
/workspace/.artific/proxy.env, dus een opdracht die ze afdrukt, zet ze in de uitvoer van de beurt, en daarmee in de items en de trace van die beurt. Ze horen bij die ene computer, en waar de operator dat inricht is de proxy alleen bereikbaar vanaf het adres waarvandaan computers naar buiten verbinden. Ze openen de proxy niet meer zodra de computer wordt verwijderd of zijn levensduur voorbij is, en ook niet als de sleutel is verwijderd, verlopen of uitgezet, als de organisatie niet actief is, of als de schakelaar niet meer telt; de proxy controleert dat ongeveer elke 30 seconden. - Geen gesprek overspannen. Elk antwoord krijgt een nieuwe computer. Het volgende antwoord in dezelfde conversatie begint met een lege schijf; wat het model daar nodig heeft, moet in een artefact of in de conversatie staan, en dat krijgt de nieuwe computer mee (zie Bestanden erin en eruit). De enige uitzondering is een computer die een shelltaak laat staan: de beurten van de thread vinden hem zolang hij blijft staan.
- Niet buiten een eigen beurt. Een computer-tool die je rechtstreeks
aanroept of in een geneste beurt noemt, wordt geweigerd
met
A computer tool runs only in a turn of its own.Een stap van een evaluatie is een gewone beurt en kan wel een computer gebruiken.
Hoe lang een computer leeft¶
- Een synchrone beurt houdt haar computer tot de beurt eindigt, hoe die ook eindigt: met een antwoord, een fout, een afbreking of een stop.
- Een achtergrondrun houdt haar computer tot de run klaar, mislukt of
geannuleerd is. Wacht de run op de uitkomst van een
function-tool die jij uitvoert (requires_action), dan verdwijnt de computer; de hervatte run krijgt een nieuwe. - Een shelltaak houdt de computer van het gesprek vast zolang ze loopt en nog een paar minuten daarna, zodat de beurt die haar resultaat beantwoordt hem vindt.
- Nooit langer dan de limiet van de deployment, standaard een uur. De sleutel kan die korter maken, zie hieronder.
Je kunt een computer ook zelf stoppen, met een sleutel die computer heeft. GET /computers geeft
de computers van je organisatie die nog leven; ?status=all geeft ze allemaal, ook gestopte, en
?response_id= die van één antwoord. DELETE /computers/{computer_id} stopt er een en geeft 204. Was hij al weg, dan krijg je 409;
kan Core de machine niet bereiken, dan 503 — Core ruimt hem dan later zelf op. De beurt die hem
gebruikte, verliest hem meteen.
Limieten per sleutel¶
De configuratie van de capability computer maakt de limieten van de installatie kleiner, nooit
groter. Een waarde boven de limiet wordt teruggebracht tot de limiet.
| Veld | Wat het begrenst | Standaard van de installatie |
|---|---|---|
exec_timeout_seconds |
hoe lang één opdracht mag draaien | 120 seconden |
lifetime_seconds |
hoe lang een computer mag bestaan | 3600 seconden |
disk_mb |
de schijf waarmee een computer begint, in megabytes | 2048 MB |
{
"capabilities": {
"tooling": { "system_tools": ["computer"] },
"computer": { "exec_timeout_seconds": 30, "lifetime_seconds": 600 },
"files": {},
"artifacts": {}
}
}
Je operator kan andere standaarden hebben ingesteld. Processor en geheugen liggen vast per installatie en zijn niet per sleutel in te stellen.
Wat het model te horen krijgt¶
Uitvoer van een opdracht en tekst uit een bestand zijn onvertrouwd, zoals elk toolresultaat (Vertrouwen in toolresultaten). Elke tool antwoordt in een vaste opmaak:
-
builtin__computer_execgeeft de exitcode, dan standaarduitvoer, dan standaardfout:exit_code: 0 stdout: 3 files written stderr:Een opdracht die zijn tijd overschrijdt, geeft wat hij tot dan toe schreef, met
timed out after <n> secondsin plaats van de eerste regel. Elke stroom wordt tot 1 MiB gelezen; heeft de computer er een afgekapt, dan eindigt het antwoord met een regel[output cut by the computer]. Het hele antwoord wordt daarna afgekapt op 32 KiB, en een afgekapt antwoord eindigt met een regel[truncated]. -builtin__computer_write_filegeeftWrote <n> bytes to <path>.-builtin__computer_read_filegeeft de tekst van het bestand, afgekapt op 32 KiB zoals hierboven. Een bestand met een NUL-byte geeft[binary file: <n> bytes; read it again with export to keep it]. Metexport: truegeeft hetExported <n> bytes from <path>.en hangt het bestand als bewaard artefact aan het resultaat; voor een sleutel zonderartifactswordt niets bewaard en volgt de regel[binary output omitted: <n> bytes]. - Een tool die rijen afleverde geeft{"columns": [...], "row_count": <n>, "truncated": <bool>, "path": "/workspace/results/<call id>.csv"}.
Gaat er iets mis, dan krijgt het model een vaste zin van Core:
| Wat er gebeurde | Wat het model te horen krijgt |
|---|---|
| de argumenten klopten niet, of een pad wijst geen bestand aan | Tool arguments were not valid. — er wordt geen computer gemaakt |
| je sleutel mag de regio waar de computer draait niet bereiken | Denied by policy. — er wordt geen computer gemaakt |
de computer zou internet bereiken en je beleid beperkt waar gegevens heen mogen, of je sleutel verbergt persoonsgegevens, of je organisatie heeft computer_internet niet aangezet |
Denied by policy. — er wordt geen computer gemaakt voor de aanroep |
| de computer kon niet worden gemaakt of bereikt | Computer is unavailable. |
| het gevraagde bestand bestaat niet | File not found. |
| het bestand is te groot (1 MiB als tekst, 25 MiB als export) | File is too large. |
Geen van deze fouten beëindigt de beurt; het model kan verder.
Regio's¶
Beperkt het beleid van je sleutel of je organisatie de regio's (policy.settings.regions_allow), dan
moet de regio waar je organisatie haar computers draait in die lijst liggen. Die regio stelt je
operator in; vraag hem waar je computers draaien. Ligt hij erbuiten, dan geeft elke computer-aanroep
Denied by policy., wordt er niets gemaakt en staat de weigering in je auditspoor. Noem
builtin:computer als regio-uitzondering om computers toch toe
te staan zonder de hele regio open te zetten.
Verbruik en audit¶
Per computer schrijft Core één verbruiksrij van soort sandbox_seconds als hij stopt: de hele
seconden van het moment dat hij klaarstond tot het moment dat hij verdween, naar boven afgerond, op
naam van de sleutel wiens beurt hem maakte. Stopt iemand hem via DELETE, dan blijft de rekening bij
die sleutel. Met een prijs per seconde telt het mee voor de maandlimiet.
In de console heet deze soort Sandboxtijd.
Het auditspoor legt vast: computer.created en computer.destroyed (met
de seconden die hij draaide), computer.destroy_requested als iemand hem via de API of de console
stopte, en per aanroep computer.executed met de soort (exec, write_file, read_file), de duur
en bij een opdracht de exitcode, en computer.egress_rate_limited als de egress-proxy van Core een
verbinding weigerde omdat je organisatie haar deel had gebruikt. De opdracht zelf, de uitvoer en bestandsnamen staan nooit in het
auditspoor; die staan in de beurt zelf en in haar trace, onder de bewaartermijn van je organisatie.