Agents via de API¶
Het concept achter agents staat in Agents.
Op deze pagina leg je een agent vast met de API, voeg je versies toe en roep je hem aan vanuit een verzoek. Een agent bewaart de instellingen van een modelaanroep onder een naam: een model, instructies, een promptversie, skills en tools. Je applicatie noemt de agent en geeft de invoer mee, zodat je de instellingen bijwerkt zonder de applicatie opnieuw uit te rollen.
Je sleutel heeft de capability agents nodig, en de capabilities van wat de agent gebruikt,
bijvoorbeeld prompts voor een opgeslagen prompt. Hetzelfde doe je met de muis in
Agents in de console.
Elke wijziging krijgt een versie. Een verzoek kan de nieuwste versie gebruiken of een specifieke versie vastzetten. Een veld dat de agent vastlegt houdt de waarde van de agent, wat het verzoek ook stuurt; skills, tools en een eigen instructie kun je wel aanvullen.
Een agent maken¶
curl -s -X POST "$CORE_URL/agents" \
-H "Authorization: Bearer $CORE_KEY" -H "Content-Type: application/json" \
-d '{"name": "triage",
"description": "Classificeert een binnenkomend ticket.",
"model": "<een model-id>",
"instructions": "Antwoord in één zin.",
"prompt": {"id": "triage", "version": 1},
"skills": ["facturatie"],
"tools": [{"type": "toolset", "name": "support"}],
"temperature": 0.2}'
Een geslaagd verzoek geeft 201 en maakt de agent met versie 1 aan.
| Veld | Wat het doet |
|---|---|
name |
uniek binnen je organisatie; waar een aanroep naar verwijst |
description |
waar deze agent voor is; puur voor lezers |
metadata |
een eigen ondoorzichtig object, maximaal 16 KiB geserialiseerd; Core bewaart en geeft het terug en leest het nooit |
model |
het model-id waarop een beurt draait als het verzoek er zelf geen noemt |
instructions |
een staande instructie met developer-autoriteit; {{ $naam }} markeert een invulwaarde |
install_values |
optioneel: een waarde voor elke {{ $naam }} in instructions, zoals {"bedrijf": {"type": "string", "value": "Acme"}}, getypeerd zoals bij een prompt |
prompt |
{"id": "<promptnaam of prm_-id>", "version": <nummer>}; version is verplicht |
skills |
skillnamen of skill_-ids die deze agent aanbiedt |
tools |
tool-, toolset- en agent-parameters; een function-tool hoort bij de aanroep, niet bij de agent |
tool_choice, max_tool_rounds, temperature, max_output_tokens, text |
dezelfde velden als op een verzoek |
tool_search |
of een beurt van deze agent zijn tools direct of achter de toolrouter aanbiedt, zoals op een verzoek; de eigen tool_search van een verzoek gaat erboven (Een agent met veel tools) |
tool_approval |
welke tools op goedkeuring van een persoon wachten voordat ze worden uitgevoerd, per modus, zoals op een achtergrondverzoek. Een verzoek kan het alleen strenger maken: een default of modus die het stuurt en die losser is dan die van de agent, of een langere wachttijd, wordt genegeerd en staat in interpretation.agent.overridden van de trace; een verzoek zonder default neemt die van de agent. Een agenttool of builtin__subagent draait alleen zonder te wachten als elke optie die hem noemt, die van de agent en die van het verzoek, hem exact noemt met "never". Een agent met tool_approval draait alleen op de achtergrond: bij elke andere beurt geeft het verzoek 400 op agent, of op model als je de agent daar noemt |
memory_injection |
optioneel: uit welke geheugenopslag een beurt van deze agent records krijgt, in de vorm van memory.injection van de sleutel; het vervangt het blok van de sleutel in zijn geheel voor die beurt, en "enabled": false geeft de beurt er geen (Elke assistent een eigen opslag geven) |
routing_config_id |
optioneel: de routeringsconfiguratie waarlangs een beurt van deze agent terugvalt, een van je organisatie met een gepubliceerde versie; ze vervangt die van de sleutel voor de beurt, en een eigen routing_config_id op het verzoek gaat voor (Een configuratie voor één agent of één beurt) |
live_checks |
hooguit 16 regels waaraan elke beurt van deze agent wordt gehouden, op de vraag van de beller of op het antwoord (Live checks via de API) |
blocked_reply |
het standaardantwoord, hooguit 1000 tekens, waarmee een beurt antwoordt als een blokkerende check op de invoer faalt; verplicht zodra er een is |
recover_attempts |
hoe vaak een antwoord dat faalde voor een check met recover opnieuw wordt gevraagd, 1 tot 3; 2 als je het weglaat |
working_state_schema |
optioneel: een JSON Schema (Draft 2020-12) waaraan het werkgeheugen van het gesprek moet voldoen in een beurt van deze agent, gecontroleerd bij het opslaan; null laat elk JSON-object toe, en een verzegelde kopie leest het als null |
Het veld name is verplicht; de velden van de definitie zijn optioneel. Een agent die alleen een model en een instructie vastlegt, is net zo geldig
als een die een hele toolset meebrengt.
Een {{ $naam }} in instructions is een invulwaarde: een waarde die je één keer vastlegt in
install_values, met zijn type (string, number of enum), en die Core invult voordat de instructie aan een beurt wordt toegevoegd, als deel
van de instructie zelf. Elke {{ $naam }} heeft een waarde nodig, elke waarde moet worden
gebruikt, en een waarde mag geen {{ of }} bevatten. Deel je de agent via een publicatie, dan
vult wie hem installeert zijn eigen invulwaarden in
(Delen).
De prompt wordt meteen bij het aanmaken opgezocht en op die versie vastgezet. Bestaat de prompt of
de versie niet, of noemt het beleid van je sleutel die prompt niet, dan krijg je hetzelfde 404 als
een beurt die de prompt rechtstreeks noemt.
metadata hoort bij de agent, niet bij één versie: een nieuwe versie die het veld weglaat, houdt
wat er staat, en {} wist het. Zet er neer wat je eigen applicatie nodig heeft — een icoon, een
kleur, een eigen referentie — Core kijkt er nooit in.
Een versie toevoegen¶
curl -s -X POST "$CORE_URL/agents/agt_5Nj2.../versions" \
-H "Authorization: Bearer $CORE_KEY" -H "Content-Type: application/json" \
-d '{"model": "<een model-id>", "instructions": "Antwoord in twee zinnen."}'
Versies worden genummerd vanaf 1 en kunnen na het aanmaken niet worden gewijzigd. Een versie is de hele definitie: wat je niet opnieuw meegeeft, staat er in die versie niet meer in.
| Aanroep | Antwoordt |
|---|---|
GET /agents |
je agents, elk met de laatste versie voluit |
GET /agents/{agent_id} |
één agent met zijn laatste versie |
GET /agents/{agent_id}/versions |
zijn versies, gepagineerd op versienummer, oudste eerst; voeg ?order=desc toe voor nieuwste eerst |
GET /agents/{agent_id}/versions/{version} |
één versie |
DELETE /agents/{agent_id} |
204; elke versie gaat mee |
Een agent kopiëren¶
Wil je een nieuwe agent beginnen vanuit een die je al hebt, kopieer hem dan onder een nieuwe naam:
curl -s -X POST "$CORE_URL/agents/agt_5Nj2.../copy" \
-H "Authorization: Bearer $CORE_KEY" -H "Content-Type: application/json" \
-d '{"name": "support-desk-nl", "version": 2}'
Het antwoord is 201 met de nieuwe agent, op zijn eigen versie 1. Laat je version weg, dan
kopieer je de laatste versie. De kopie neemt de hele definitie van die versie over, en de
beschrijving, labels en metadata van de agent; hij pint dezelfde promptversie, dezelfde
skillversies en dezelfde agents als tool, en kopieert die zelf niet. Vanaf dan is het je eigen
agent: wat je eraan verandert, verandert het origineel niet, en latere versies van het origineel
komen er niet in.
Je sleutel moet de agent die je kopieert kunnen lezen, en onder de nieuwe naam met dezelfde labels
een agent mogen maken. Een kopie die een publicatie verzegeld installeerde, en een kopie waarvan de
publicatie losmaken niet toestaat ('fork': false), hem voor haar eigen agents houdt of hergebruik niet toestaat, kun je niet kopiëren: 403. Een agent die zichzelf als tool noemt, noemt na het kopiëren de kopie.
Een agent aanroepen¶
{
"input": "Mijn kaart is twee keer belast.",
"agent": { "id": "triage", "variables": { "ticket": "Mijn kaart is twee keer belast." } }
}
Stel id in op de agentnaam of het agt_-id. Laat version weg om de nieuwste versie op het
moment van aanroepen te gebruiken. Geef een versienummer op om die versie te blijven gebruiken nadat
er nieuwe zijn gepubliceerd. variables vult de prompt die deze agentversie vastzette.
model mag je weglaten zodra de agent er een vastlegt. Noemt het verzoek zelf geen model en legt de
agent er geen vast, dan is dat 400 met model in error.param.
Een sleutel waarvan het beleid settings.agents_required zet, moet in elke beurt een agent noemen, en voor
een beurt zonder agent wordt geen model aangeroepen: POST /responses antwoordt 403 met agent
in error.param, en POST /messages antwoordt 403 met een melding die begint met agent: (de
fout van Anthropic heeft geen param).
Zo'n sleutel draait zijn agents ook zoals ze zijn gedefinieerd, dus de regel in het volgende
onderdeel geldt voor hem niet: een beurt die eigen tools, skills, instructions of een prompt
toevoegt (op POST /messages: system, tools of skills) is op dezelfde manier 403 met dat
veld erbij. Instructies die gelijk zijn aan die van de agent voegen niets toe en gaan door, behalve
bij een verzegelde kopie, die ze allemaal weigert. Een model uit de catalogus dat afwijkt van dat
van de agent blijft de 400 die het onder elke sleutel is; de temperatuur en de tokenlimiet mag je
nog zetten waar de agent ze openlaat, en waar hij ze vastlegt draait de beurt op zijn waarde. De
agent als model noemen telt als hem noemen. Een codeeromgeving die een
eigen systeemprompt meestuurt wordt op zo'n sleutel geweigerd: geef hem een gewone sleutel waarvan
het beleid de agent bereikt.
Tooluitvoer insturen zet de beurt voort waar die bij hoort; dat gaat
door als die beurt een agent noemde en wordt geweigerd als dat niet zo was. Een planning onder zo'n
sleutel moet in haar verzoek een agent noemen, en de sleutel kan geen
tool rechtstreeks aanroepen. Een agent noemen die de
regels van de sleutel niet toestaan, blijft 404. Zie Sleutels.
Wil je alleen van sommige personen een agent eisen, schrijf dan in plaats daarvan een forbid over
de soort direct_turn met een voorwaarde op de persoon (Een persoon niet met een kaal model laten
praten). Hun beurten die geen agent noemen
krijgen dezelfde 403 op agent, terwijl hun rechtstreekse toolaanroepen en kenniszoekopdrachten
toegestaan blijven.
Noem de agent als model¶
Een client die alleen een model, zijn eigen instructies en zijn eigen tools kan sturen — een
codeeromgeving, een SDK die je niet zelf in de hand hebt — bereikt een agent via model:
agent:<naam>, of het agt_-id van de agent. GET /models noemt elke agent die je sleutel zo kan
gebruiken, na de modellen, met owned_by: "agent".
from openai import OpenAI
client = OpenAI(base_url="https://<jouw-omgeving>/api/v1", api_key="ack_...")
response = client.responses.create(
model="agent:triage",
instructions="Je draait in mijn editor.",
input="Mijn kaart is twee keer belast.",
)
print(response.model) # het model van de agent, nooit "agent:triage"
Het is dezelfde verwijzing als het veld agent en wordt op dezelfde manier geweigerd: 404 voor
een agent die je sleutel niet mag gebruiken. Een kale naam zoals triage wordt nooit als agent
gelezen, want het kan een model zijn, en iets na agt_ dat geen id van Core is evenmin. De agent
moet zelf een model vastleggen — een agent die dat niet doet is 400 op model en staat niet in
de lijst; noem hem dan in agent naast een model. Stuur je beide vormen, dan moeten ze dezelfde
agent noemen, anders is de aanroep 400 op model. Hetzelfde werkt op POST /messages met de SDK
van Anthropic, waar je system je eigen instructie is.
Een verzoek vult aan, het overschrijft niet¶
skills en tools van het verzoek komen bij die van de agent. Noemen beide dezelfde tool, dan
telt die één keer. Je instructions komen er ook bij: het model leest eerst die van jou en dan die
van de agent, als twee aparte instructies, en het antwoord geeft alleen de jouwe terug. Een
instructie die gelijk is aan die van de agent wordt één keer verstuurd.
Elk ander veld dat de agentversie vastlegt — temperature, max_output_tokens, max_tool_rounds,
tool_choice, text, reasoning — houdt de waarde van de agent. Zet je verzoek er een op een
andere waarde, dan draait de beurt toch, op de waarde van de agent, en noemt de
trace van de aanroep het veld onder interpretation.agent.overridden, zodat
je ziet wat niet is gebruikt. De definitie is het punt van een agent; de beurt wordt niet geweigerd
zodat een client die altijd zijn eigen standaardwaarden meestuurt er toch een kan gebruiken.
{ "agent": { "id": "triage" }, "temperature": 0.9 }
Legt triage een temperature van 0.2 vast, dan draait deze beurt op 0.2 en is overridden in de
trace ["temperature"]. Wil je een andere waarde, maak dan een nieuwe versie van de agent of
gebruik een andere agent.
Twee dingen worden nog wel geweigerd. Een model uit de catalogus dat afwijkt van dat van de agent
is 400 op model: noem alleen de agent, of noem hem als model. En jouw skills en die van de agent
samen zijn er hoogstens 32, dezelfde grens die een verzoek op zichzelf heeft; meer is 400 op
skills.
Niets meesturen voor een vastgelegd veld, null, "auto" voor tool_choice (de standaard) of
dezelfde waarde als de agent vastlegt verandert niets en wordt niet als overschreven genoemd, dus
een client die zijn hele verzoekobject serialiseert werkt gewoon.
Wat de agent meebrengt, wordt op precies dezelfde manier gecontroleerd als wat je zelf opschrijft. Een skill, tool of prompt die het beleid van je sleutel niet noemt, blijft buiten bereik, ook als de agent hem noemt.
Een agent als tool aan een beurt geven¶
Een beurt kan een andere agent als één tool aan haar model geven. Noem hem in tools, op het
verzoek of in de definitie van een agent zelf — dat tweede is hoe de ene agent werk doorgeeft aan
de andere:
{
"model": "<een model-id>",
"input": "Een klant is twee keer afgeschreven.",
"tools": [{ "type": "agent", "name": "facturatie" }]
}
Het model ziet een tool agent__facturatie, beschreven met de description van de agent. De
argumenten zijn de variabelen van de prompt die de agent vastzet, elk van het type en met de enum
die het invoerschema declareert, plus input: vrije tekst met wat
het model de agent vraagt. input is alleen verplicht als de agent geen prompt vastzet. version
werkt als bij agent: laat hem weg voor de laatste.
Roept het model de tool aan, dan draait Core één beurt van die agent, met het eigen model, de eigen instructie, prompt en skills van de agent, en geeft het antwoord van de agent terug als resultaat van de tool. Die beurt:
- draait onder jouw sleutel: elk model, elke prompt, skill en tool die ze bereikt, wordt getoetst
aan het beleid van je sleutel, precies zoals wanneer je de agent zelf op
agentnoemt; - krijgt de eigen tools van de agent, behalve andere agents,
builtin__subagentencore__-tools, zodat een agent die als tool draait nooit op zijn beurt weer een agent aanroept. Agents mogen elkaar dus in een kring noemen, of zichzelf: Core slaat dat op zoals het er staat, en de kring breekt na één aanroep; - telt als één niveau in een keten van beurten die beurten aanroepen. Een keten die via verzoeken
doorgaat -- een tool van een agent die de eigen API van Core bereikt, die een beurt start die
weer een agent aanroept -- stopt op vijf niveaus: daar leest het model
This turn is too deep in a chain of calls to start another.als resultaat van de tool, en de beurt gaat door (de grenzen opcore__-tools); - heeft een eigen antwoord-id en eigen verbruik, en de auditgebeurtenis van de aanroep noemt die
als
agent_response_id; de modelaanroepen staan in de trace van de aanroepende beurt; - mag standaard tot twee minuten duren. Een fout, een weigering voordat ze begon of te weinig rondes bereikt het model als één vaste zin, nooit als fout op jouw verzoek.
Het antwoord van de agent wordt behandeld als het resultaat van elke tool: als informatie voor het
model, nooit als instructie. Je sleutel heeft agents nodig, en het tools-beleid van je sleutel
moet de naam agent__<naam> toestaan.
Een agent waarvan de versie background heeft met de modus allowed of always, kan ook als taak
worden gestart: het model krijgt meteen een taak-id en het antwoord van de agent komt later terug
in de thread. Zie Een tool op de achtergrond draaien.
Een agent met tool_approval kan niet als tool draaien: zijn beurt kan niet op een persoon wachten, dus die wordt geweigerd voor hij begint en het model leest de vaste zin Agent could not be run. als resultaat van de tool.
Een agent verwijderen waaraan een andere agent werk doorgeeft, geeft 409, met de agents die hem
nog gebruiken.
Dezelfde tool staat in je toolcatalogus, dus je bereikt hem ook bij naam. GET /tools toont
agent__facturatie met de argumenten hierboven; een toolsetpatroon zoals agent__* biedt hem aan
een beurt aan precies zoals het agent-item dat doet (een agent die op beide manieren genoemd
wordt, wordt één keer aangeboden); en POST /tools/agent__facturatie/call draait de beurt van de
agent voor je en geeft zijn antwoord terug. Zo gebruikt een applicatie buiten Core, of een
MCP-client die een van je toolsets krijgt, hem. Alleen de
agents die je sleutel mag gebruiken worden getoond of aangeroepen; een agent die alleen op de
achtergrond draait, kun je buiten een beurt niet aanroepen. Zie
Een tool rechtstreeks aanroepen.
Fouten¶
| Status | Oorzaak |
|---|---|
404 |
geen zo'n agent, geen zo'n vastgezette versie, een agent die het beleid van je sleutel niet noemt, of agents geldt niet voor je sleutel — ook voor een agent die in tools staat |
403 |
de naam die je aanmaakt, valt buiten wat het beleid van je sleutel noemt; er wordt niets opgeslagen |
403 op agent |
de beurt noemt geen agent terwijl het beleid van je sleutel er een vereist (settings.agents_required), of een forbid over direct_turn geldt voor de persoon voor wie de beurt is |
403 op tools, skills, instructions of prompt |
het beleid van je sleutel vereist een agent, en de beurt voegt dat veld eraan toe |
409 |
de naam is al bezet — of, op DELETE /prompts/{id}, een agentversie zet een versie van die prompt nog vast — of, op DELETE /agents/{id}, een andere agent geeft nog werk door aan deze |
400 op model |
het verzoek noemt geen model en de agent legt er geen vast, noemt een ander catalogusmodel dan dat van de agent, noemt als model een agent die er geen vastlegt, of noemt twee verschillende agents in model en agent |
400 op agent of model |
tool_approval requires background: de agent heeft tool_approval en de beurt draait niet op de achtergrond; op model als je de agent daar noemde |
400 op prompt |
het verzoek noemt een prompt terwijl de agentversie er al een vastzet |
400 op agent.variables |
er zijn variabelen meegegeven terwijl deze agentversie geen prompt rendert, een verplichte variabele van de vastgezette prompt heeft geen waarde, of een waarde past niet bij zijn property in het invoerschema van de prompt |
400 op skills |
jouw skills en die van de agent samen zijn er meer dan 32 |
422 op live_checks, blocked_reply of recover_attempts |
een live check die de versie niet kan hebben; zie Live checks via de API |
422 op install_values |
bij het schrijven: een {{ $naam }} zonder waarde, een waarde die instructions niet gebruikt, een waarde met {{ of }}, of een waarde die niet bij zijn type past |
In een beurt komt elk van deze weigeringen binnen in het foutobject van
OpenAI, met het veld in error.param; dezelfde weigeringen
bij het schrijven naar /agents zijn problem+json, met het veld in errors.
Een prompt verwijderen die een agentversie vastzet, lukt niet: verwijder eerst de agent, dan komt de prompt vrij.
Terugvinden welke agent er draaide¶
Een opgeslagen antwoord bewaart de agent die daadwerkelijk draaide — id, naam en versie — naast de
skills en tools waarmee de beurt liep; de trace van elke aanroep draagt
hetzelfde als interpretation.agent, met in overridden de velden van je verzoek die niet zijn
gebruikt ([] als dat er geen zijn). response.model is altijd het model dat draaide. Bij een achtergrondrun draait het hervatten
verder op diezelfde vastgelegde combinatie, dus een nieuwe agentversie verandert een run die al
loopt niet.