EU GPT logo
EU GPT

Public preview — Deze API is in public preview. Endpoints, schemas en limieten kunnen wijzigen vóór general availability.

API

Tools gebruiken

Een end-to-end-voorbeeld van een model dat naar web_search grijpt en hoe je dat rendert in je UI.

Tools draaien server-side en duiken op via de stream. Er is niets per request te configureren — het model beslist, het platform draait, jij kijkt mee.

Deze gids loopt één realistisch voorbeeld door: een vraag waarbij het model het web moet doorzoeken en bronnen moet citeren.

De request#

const stream = await client.responses.create({
  model: "auto",
  input: "What was Apple's revenue in Q4 2025? Cite your source.",
  stream: true,
});

Het model heeft geen interne kennis van de resultaten van dat kwartaal. Het zal web_search aanroepen.

De event-sequence#

Je ontvangt events ongeveer in deze volgorde (sequence numbers tussen haakjes zijn illustratief):

(0) response.created
(1) response.output_item.added       function_call "web_search" begins
(2) response.output_item.done        function_call "web_search" completes with results
(3) response.content_part.added      assistant text begins
(4) response.output_text.delta       "Apple"
(5) response.output_text.delta       " reported"
(...) more deltas
(N) response.output_text.done        full text assembled
(N+1) response.completed

Meerdere tool calls kunnen interleaven — het model kan ook web_fetch aanroepen op een result-URL voordat het antwoordt. Gebruik output_index om ze gescheiden te houden.

Renderen#

Een redelijk chat-UI-patroon:

const state = {
  tools: new Map(),  // call_id -> { name, status, summary }
  text: "",
};

for await (const event of stream) {
  switch (event.type) {
    case "response.output_item.added":
      if (event.item.type === "function_call") {
        state.tools.set(event.item.call_id, {
          name: event.item.name,
          status: "running",
        });
        render();
      }
      break;

    case "response.output_item.done":
      if (event.item.type === "function_call") {
        const tool = state.tools.get(event.item.call_id);
        if (tool) {
          tool.status = event.item.status;
          tool.summary = summarise(event.item.output);
        }
        render();
      }
      break;

    case "response.output_text.delta":
      state.text += event.delta;
      render();
      break;

    case "response.completed":
      // klaar
      break;
  }
}

Render de tool-pills (één per call_id) boven of naast de text. Update ze ter plekke wanneer ze overgaan van running naar completed.

De tool-output-shape#

Het output-veld op output_item.done is een string. Voor web_search en web_fetch is het een JSON-gecodeerde structuur. Je kunt het parsen als je de resultaten visueel wilt surface’n:

const tool = event.item;
if (tool.name === "web_search" && tool.status === "completed") {
  const hits = JSON.parse(tool.output); // [{ title, url, snippet }, ...]
  renderHits(hits);
}

Voor calculator is het het numerieke resultaat als string. Voor current_datetime is het een ISO 8601-timestamp.

Tools uitschakelen voor een request#

Er is vandaag geen per-request “geen tools”-vlag. De beste hefboom is het instructions-veld:

instructions: "Answer from your own training data only. Do not use web_search or web_fetch."

Het model voldoet meestal. Voor absolute controle: draai prompts die duidelijk niet kunnen profiteren van tools (bv. samenvatting van input die de gebruiker zelf gaf) — het model zal niet speculatief tools aanroepen.

Tool-failures#

Als een tool mid-uitvoering faalt, ontvang je response.output_item.done met status: "failed" en een beschrijving in output. Het model handelt dit af — het zal óf:

  • De tool retryen met andere argumenten (je ziet dan opnieuw output_item.added voor dezelfde tool-naam).
  • Excuseren en antwoorden zonder de tool.
  • Een andere tool kiezen.

Je UI zou “search failed” gracefully moeten surface’n — de meeste gebruikers verkiezen “Ik kon niet zoeken op het web, dus dit is wat ik weet” boven een stille afwezigheid van citations.

Alles samenvoegen#

Een minimaal end-to-end-script dat naar de terminal streamt en tool-activiteit inline print:

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.EUGPT_API_KEY,
  baseURL: "https://chat.eugpt.ai/v1",
});

const stream = await client.responses.create({
  model: "auto",
  input: "What's the latest news on the EU AI Act enforcement?",
  stream: true,
});

for await (const event of stream) {
  switch (event.type) {
    case "response.output_item.added":
      if (event.item.type === "function_call") {
        process.stderr.write(`\n[tool] ${event.item.name} …`);
      }
      break;
    case "response.output_item.done":
      if (event.item.type === "function_call") {
        process.stderr.write(` (${event.item.status})\n`);
      }
      break;
    case "response.output_text.delta":
      process.stdout.write(event.delta);
      break;
    case "response.completed":
      process.stdout.write("\n");
      break;
  }
}