Een platform bouwen op Core¶
Deze pagina is voor wie een eigen product bouwt met Core eronder: jouw applicatie heeft een eigen gebruikersinterface, je klanten werken daarin en zien de console van Core nooit. Je backend roept Core aan met API-sleutels; jij en je beheerders gebruiken de console om in te richten en mee te kijken.
Zo'n product vraagt een paar keuzes die je beter vooraf maakt dan halverwege: hoe je klanten indeelt, hoe Core weet voor welke persoon een verzoek is, wat elke persoon mag zien, en hoe je een oplossing bij een volgende klant uitrolt. De secties hieronder volgen die volgorde. Elke sectie zegt kort wat het onderdeel is, welke keuze je als platformbouwer maakt, en waar je verder leest.
Je product, vertaald naar Core¶
| In je product | In Core | Lees verder |
|---|---|---|
| een klant | een organisatie onder de jouwe | Organisaties en klanten |
| je backend, werkend voor die klant | een sleutel in de organisatie van die klant | Sleutels, capabilities en policy |
| een gebruiker van je product | een subject: een id dat jij kiest, met attributen | Bouwen voor personen |
| de browser of app van die gebruiker | een subject-token (ast_...), je sleutel versmald tot die ene persoon |
Een token voor de browser |
| een assistent of proces in je product | een agent, een workflow en hun tools | Agents, Workflows, Tools |
| de documenten en gegevens van een klant | kennis, datastores, geheugen en bestanden | Kennis, Datastores, Geheugen |
| een rapport of overzicht dat je toont | een artefact of een pagina | Gestructureerde antwoorden, artefacten en pagina's |
| je abonnementen en prijzen | limieten per organisatie en sleutel, markups per organisatie | Inzicht, Modellen en routering |
| je oplossing, bij elke klant hetzelfde | een publicatie | Delen en hergebruik |
Je klanten als organisaties¶
Geef elke klant een eigen organisatie onder de jouwe. Een organisatie is een afgesloten ruimte: een sleutel van klant A bereikt niets van klant B en niets van jouw eigen organisatie. Wat je als bovenliggende organisatie wel doet, is beheren: organisaties aanmaken, hun sleutels uitgeven, hun plafond van capabilities zetten (welke functies hun sleutels mogen aanzetten) en hun kostenlimiet bepalen. Heeft een klant zelf afdelingen of eigen klanten die gescheiden moeten blijven, dan maak je onder zijn organisatie nog een laag.
Richt je klanten in vanuit je eigen systeem, dan doet een sleutel van je eigen organisatie met de
capability management dat met POST /organisations. Zo'n sleutel beheert organisaties maar leest
hun inhoud niet via de gewone routes; om in een klantorganisatie te werken, registreert hij daar
een sleutel en roept hij aan als die sleutel
(Werken in een organisatie onder je).
Een sleutel per klant, en daarbinnen een per applicatie. Je backend bewaart voor elke klant de
secret van een sleutel in de organisatie van die klant, en kiest bij elk verzoek de sleutel van de
klant voor wie het is. Zo valt elk verzoek automatisch binnen de juiste organisatie, met haar
gegevens, haar policy en haar limiet. Gebruikt een klant meer dan één deel van je product, zoals een
chatvenster voor bezoekers en een script dat het handboek bijwerkt, geef dan elk deel een eigen
sleutel in die organisatie. Verbruik, kostenlimieten en het auditspoor worden per sleutel
bijgehouden, en elke sleutel krijgt alleen de capabilities en regels die dat deel nodig heeft. Een
sleutel voor bezoekers die je niet kent, krijgt de instelling Agent verplicht: elke beurt moet
dan een agent noemen die de regels toestaan en voert die uit zoals hij is vastgelegd, zonder tools,
skills of instructies die de aanroeper toevoegt. Directe toolaanroepen en kenniszoekopdrachten
buiten een beurt weigert de sleutel dan met 403.
Installeren bij elke klant. Wat je één keer bouwt, zet je met een publicatie in de organisaties van je klanten. Met de zichtbaarheid Onderliggende organisaties en Automatisch installeren begint elke nieuwe klantorganisatie meteen met je standaardopzet. Organisaties buiten je eigen boom bereik je via de marktplaats.
Stap voor stap: Richt een nieuwe klantorganisatie in.
Wie de gebruiker is¶
Core beheert geen accounts voor de gebruikers van je product. Je backend weet wie er is ingelogd en
vertelt dat aan Core met een subject: een id dat jij kiest, nooit een naam of e-mailadres, plus
optionele attributen zoals een afdeling. Het reist in de header X-Core-Subject. Zonder subject is
een verzoek van de applicatie als geheel; met een subject weet Core van wie een gesprek, een
geheugenrecord of een upload is, en welke regels voor die persoon gelden.
Kies hoe je de persoon noemt:
- Je backend noemt de persoon. Het verzoek gaat van je backend naar Core, en je backend zet
X-Core-Subjectmet de JSON van het subject. Dit is de eenvoudigste vorm. - Je identity provider noemt de persoon. Heeft je product al een token van een eigen identity
provider, dan registreert de organisatie die provider en stuur je dat token in
X-Core-Subject. Core leest de persoon en de attributen dan uit wat je provider ondertekende (Een token van je identity provider). - De browser praat zelf met Core. Een browser of mobiele app mag je sleutel nooit dragen. Je
backend vraagt met
POST /subjects/tokenseen subject-token aan, dat begint metast_en hoogstens een uur geldig is, en geeft dat aan het apparaat. Dat token bereikt alleen de gegevens van die ene persoon en kan niets beheren (Een token voor de browser).
Met de policy-instelling Een subject is verplicht weigert een sleutel elk verzoek dat niemand noemt. Gebruik die op een sleutel die alleen voor ingelogde gebruikers werkt.
Wat een persoon noemen bewaart. Core bewaart het id als eigenaar van wat het verzoek aanmaakt:
een gesprek, een geheugenrecord, een upload, een datastore-record. De attributen bewaart Core niet;
ze gelden voor het ene verzoek. DELETE /subjects/{id} wist alles wat onder een id staat
(Wat een persoon noemen bewaart).
Toegang per persoon¶
Achter één sleutel kunnen honderden gebruikers zitten. Wat elk van hen bereikt, regel je met
labels op wat je in Core opslaat en regels in de policy die die labels vergelijken met de
attributen van de persoon. Een regel over agent met de voorwaarde dat het label department een
van de afdelingen van de persoon is, laat Anna van salarisadministratie de payroll-agent gebruiken
en verbergt hem voor Bob van de receptie.
Twee soorten dingen dragen een label:
- Wat je bibliotheek bevat: agents, prompts, skills, workflows, planningen, collecties, indexen,
grafen en alles wat een tool oplevert. Die hebben een veld
labels. Modellen en ingebouwde tools label je viaPUT /labels/.... - Rijen die een verzoek schrijft: gesprekken, antwoorden, geheugenrecords, kennisbronnen,
opgeslagen bestanden en datastore-records. Die hebben ook een veld
labels, en een regel leest daarnaast hun eigenaar.
Naast labels kiest een regel op naam. Zo beperk je ook opgeslagen bestanden op hun bestandsnaam en
datastores op hun naam, bijvoorbeeld tot klanten-*. Onder de standaardregels bereikt een persoon
haar eigen rijen en de gedeelde, en nooit die van een ander. Hoe je een regel schrijft, staat in
Je eerste regel schrijven; in
de console doe je het bij Regels over een persoon.
Labels, metadata en overerving¶
Het meeste wat je opslaat draagt twee mappen, en die hebben elk een eigen taak:
labelsbepalen de toegang. Van de twee mappen lezen regels alleenlabels. De woordenlijst van de organisatie controleert ze, en op gesprekken, antwoorden, records, bronnen en bestanden beperktwritable_labelswelke waarden een persoon mag schrijven. Een label heeft één waarde of een lijst van hoogstens 32:{"project": ["apollo", "gemini"]}wordt bereikt door een regel overapolloen door een overgemini.metadatais van jou. Gebruik het om te sorteren, te filteren en aantekeningen te maken. Zodra de overstap hieronder voorbij is, leest geen regel het; tot dan zet je namen die je regels gebruiken niet inmetadata, tenzij dezelfde naam ook inlabelsstaat.
{"metadata": {"order": "7"}, "labels": {"project": ["apollo", "gemini"]}}
Je geeft beide mee wanneer je een gesprek, een antwoord, een geheugenrecord, een kennisbron of een
datastore-record aanmaakt, en je leest beide terug. Een upload naar een collectie neemt ook beide,
als formulier, dus labels en metadata gaan elk als JSON-tekst. POST /files neemt labels en
een purpose, en geen metadata.
Van metadata naar labels. Rijen die geschreven zijn voordat rijen labels hadden, hielden hun
toegangssleutels in metadata. Eén release lang leest een regel nog de metadata van een rij
onder een naam die haar labels niet dragen, alleen één tekstwaarde, en het schrijven van zo'n
string door een persoon valt onder writable_labels en wordt geweigerd op metadata.<naam>, dus
voor wat je eerder schreef verandert niets. Een naam in beide mappen wordt alleen uit labels
gelezen. Core kopieert ook zelf de sleutels die je regels noemen van metadata
naar labels, één keer per organisatie. Om over te stappen schrijf je de sleutel in labels
overal waar je hem voor toegang in metadata schreef; in metadata mag hij blijven voor je eigen
gebruik. In een latere release lezen regels alleen nog labels; de release notes daarvan zeggen
het.
Wat in een gesprek ontstaat, erft de labels ervan. Label een gesprek één keer, en wat erin
gebeurt krijgt dezelfde labels, zodat een regel over project ook de antwoorden, geheugenrecords
en bestanden erin bereikt. Met een
vocabulaire leg je het label vast
voor elk van die soorten, anders kan geen regel over die soort het lezen.
POST /threadsmetlabels, ofPOST /responsesmetlabelsals de beurt een nieuw gesprek opent, labelt het gesprek.- Elk antwoord erin begint met de labels van het gesprek. De geheugenrecords die een beurt schrijft, de bestanden die haar tools maken, de taken die ze start en de achtergrondruns die ze in de wachtrij zet, beginnen met de labels van die beurt.
- Een taak en een workflowrun tonen hun labels als je ze opvraagt, maar geen regel leest ze; de gesprekken die ze openen dragen ze wel. Geheugenrecords die Core achteraf uit een gesprek haalt, beginnen zonder labels.
- Een verzoek mag een label toevoegen of een waarde wijzigen op wat het aanmaakt: stuur
labelsmee met een beurt in een bestaand gesprek, en dat antwoord draagt de labels van het gesprek plus de jouwe. Het haalt er nooit een weg, dus een label waar een regel op leunt, valt nooit weg van wat ontstaat. Voor een persoon valt alleen wat je toevoegt of wijzigt onderwritable_labels; een label dat het gesprek al draagt blijft staan, ook als zij het zelf niet had mogen schrijven. - Het is een kopie bij het aanmaken. Wijzig je later de labels van een gesprek, dan houden de antwoorden, records, bestanden en taken die er al in staan de hunne. Een geheugenrecord of bestand label je apart opnieuw waar nodig; een antwoord en een taak houden de labels waarmee ze ontstonden.
{"thread_id": "thr_...", "input": "Vat de laatste cijfers samen", "labels": {"stage": "draft"}}
In een gesprek met {"project": "apollo"} draagt dit antwoord
{"project": "apollo", "stage": "draft"}, en het gesprek houdt {"project": "apollo"}.
Workflowruns geven hun labels door. Start je een run met labels
(POST /workflows/{id}/runs), dan draagt elk gesprek dat de stappen openen, en elke run die ze
starten, die labels. Een run zonder labels geeft er geen door, en de eigen labels van een workflow
beschrijven de workflow, niet het werk dat hij doet, dus die gaan niet mee. Een run die een agent
als taak start, krijgt de labels van de beurt van die agent. Is de run voor een persoon, dan vallen
de labels onder haar writable_labels voor thread, omdat elk gesprek dat de stappen openen ze
draagt. Workflowruns die een schema, een gebeurtenis of een webhook start, dragen geen labels.
Wat je oplossing doet¶
De bouwstenen van je oplossing zijn dezelfde als voor elke toepassing op Core. Voor een platform telt bij elk vooral de vraag of het voor elke klant gelijk is, of van de klant zelf.
- Agents leggen model, instructies, skills en tools vast onder een naam. Bouw ze één keer in je eigen organisatie en installeer ze met een publicatie; wat per klant verschilt, zoals de bedrijfsnaam of het model, wordt een parameter die de installatie invult.
- Tools laten een agent handelen: een API-koppeling, een MCP-server, een script, een
ingebouwde tool. Een koppeling naar het systeem van een klant hoort met haar eigen inloggegevens
bij die klant; een publicatie kan erom vragen bij het installeren. Een
SQL-koppeling voert één vastgelegde query uit op een
database van de organisatie zelf, en een mailkoppeling
leest een mailbox van de organisatie of van de persoon voor wie de beurt is, en verstuurt er
desgewenst mee. Beide richt je via de API in, met
POST /sql_connectorsenPOST /mail_connectors. - Kennis is wat een agent doorzoekt: de documenten van een klant in een collectie, doorzoekbaar met een index of een graaf. Kennis die voor iedereen gelijk is, kan in een publicatie; de documenten van een klant horen in haar eigen organisatie.
- Geheugen is wat een agent onthoudt tussen gesprekken, per persoon of voor de hele organisatie. Een agent schrijft geen geheugen tot de policy het toestaat.
- Workflows voeren een proces uit over agents, tools en mensen, op de achtergrond, gestart door je applicatie, een planning, een gebeurtenis of een webhook.
- Datastores houden gestructureerde records bij die je applicatie en een agent allebei lezen en schrijven, zoals de instellingen van een klant of een lijst afspraken.
Rijke antwoorden¶
Je eigen interface toont meer dan een tekstballon. Drie mogelijkheden, uitgelegd in Gestructureerde antwoorden, artefacten en pagina's:
- Gestructureerde uitvoer: je geeft een JSON Schema mee en krijgt JSON terug die je interface zelf opmaakt, zoals een formulier of een tabel.
- Artefacten: bestanden die een tool maakt, zoals een grafiek of een document, die je applicatie downloadt of toont.
- Pagina's: een HTML-rapport onder een vaste naam, dat je opent met een weergaveadres of buiten
je organisatie deelt met een link, en dat bij een nieuwe versie hetzelfde adres houdt. Een pagina
in een frame binnen je eigen product tonen kan alleen als je installatie de origin van je product
toestaat (de instelling
artifacts_view_frame_ancestors). Standaard staat die geen enkele origin toe; je operator zet hem.
Verbruik en limieten¶
Core meet verbruik per sleutel en per persoon, en rekent het om naar euro. Dat is de basis voor wat je je klanten in rekening brengt. Twee soorten kostenlimiet per maand begrenzen het:
- op de organisatie van een klant, over al haar sleutels samen. Die zet jij als organisatie erboven; de klant kan hem niet verruimen. Standaard telt een limiet ook het verbruik van de organisaties eronder, dus een limiet bovenaan stopt die ook;
- op een sleutel, voor één deel van je product.
Is een limiet bereikt, dan antwoordt Core op een nieuwe beurt 429 tot de volgende maand, of tot
de limiet wordt verhoogd. Met een markup bepaal je de prijs die een klant voor verbruik ziet.
Een markup zet je per organisatie, niet per sleutel: op je eigen organisatie, of op alles eronder.
Lees verder in
Inzicht, Gebruik en audit via de API en
Opslagen: een markup op de prijs zetten.
Een oplossing delen¶
Een publicatie is je oplossing als bundel: agents, prompts, skills, toolsets, API-, MCP- en
SQL-koppelingen, scripts, kennis en workflows, met parameters voor wat per klant verschilt.
Datastores en mailkoppelingen gaan niet mee; die maakt elke klant zelf. Elke klant krijgt kopieën,
en een nieuwe versie rolt Core uit naar elk abonnement dat de laatste versie volgt. Op de
marktplaats bied je een bundel aan organisaties buiten je eigen boom aan, nadat Artific hem als
operator van het platform heeft beoordeeld. Het commando artific publiceert een bundel vanuit
bestanden in je repository, zodat een pipeline een nieuwe versie uitbrengt zoals bij elke andere
release (Een bundel uitbrengen met het artific-commando).
Lees verder in Delen en hergebruik, en volg de tutorial Bouw als partner één oplossing die je bij meerdere klantorganisaties kunt gebruiken.
Verder¶
| Je wilt | Lees |
|---|---|
| zien hoe de bouwstenen samenhangen | Het model van Core |
| een klantorganisatie inrichten | Richt een nieuwe klantorganisatie in |
| klanten inrichten vanuit je eigen systeem | Organisaties beheren via de API |
| personen noemen en per persoon toegang regelen | Bouwen voor personen |
| één oplossing bij elke klant installeren | Bouw als partner één oplossing die je bij meerdere klantorganisaties kunt gebruiken |
| de API opzoeken | API-referentie |