Felo API PlatformFelo API Platform

Kosten

Houd modelkosten voorspelbaar bij groeiend gebruik

Stuur elke taak door één OpenAI-compatibel endpoint, route naar het goedkoopste model dat de taak aankan en log het tokengebruik dat elke respons teruggeeft.

Tijd20 minutenNiveauGevorderdBijgewerkt2026-10-29
Voor wiePlatformteamsAPI-producteigenarenEngineeringleads

Prompt kopiëren

Vervang de velden tussen blokhaken en plak in Claude Code, Codex of een AI met terminaltoegang. Die installeert de Felo-skill, vraagt voor credits en voert de workflow uit.

Beoordeel onze modeluitgaven en stel een routingplan voor voor deze taken: [lijst taken of functies].

Beperkingen: maandbudget [bedrag], latentiedoel [doel], kwaliteitslat [lat].
Lees de live modelcatalogus voordat je iets aanbeveelt.

Lever:
1. Een tabel taak -> aanbevolen model.
2. Welke taken een niveau lager kunnen en het kwaliteitsrisico.
3. Een plan voor gebruikerslogging per taak en functie.
4. Wat je moet meten voordat je productie wijzigt.

Regels:
- Lees actuele model-ID’s en prijzen uit de live catalogus; citeer nooit een tarief uit je geheugen.
- Wijzig geen productieconfiguratie en stuur geen echt verkeer.
- Vraag het voordat je credits uitgeeft aan testaanroepen.
- Houd een rollbackplan en een uitgavenplafond per functie aan.
- Schrijf het plan naar ./routing-plan.md en vat het samen in de chat.

De kopie bevat ook de installatiestappen en veiligheidsregels.

Wat je krijgt

Voorbeelduitvoer van een run. Geen live generatie.

Voorbeeld-routingplan (fragment)
TaakNuVoorstelRisico
Ticket classificerensterk modelsnel modellaag
Antwoord opstellensterk modelsterk modelgeen
Changelog samenvattensterk modelsnel modelmiddel

Voordat je iets wijzigt: log een week lang gebruik per taak en vergelijk kwaliteit op 50 steekproefoutputs.

De exacte aanroepen

Voor ontwikkelaars: dezelfde workflow als kopieerbare code in uitvoeringsvolgorde.

Exacte API-aanroepen tonen
  1. Alle taken via één endpoint

    Gebruik één OpenAI-compatibel endpoint en sleutel, zonder SDK per provider.

    routing.ts
    const BASE_URL = "https://openapi.felo.ai/api/v1";
    const headers = {
      Authorization: `Bearer ${process.env.FELO_API_KEY}`,
      "Content-Type": "application/json",
    };
    
    type Completion = {
      choices: { message: { content: string } }[];
      usage: { prompt_tokens: number; completion_tokens: number; total_tokens: number };
    };
    
    async function chat(model: string, prompt: string): Promise<Completion> {
      const res = await fetch(`${BASE_URL}/chat/completions`, {
        method: "POST",
        headers,
        body: JSON.stringify({ model, messages: [{ role: "user", content: prompt }] }),
      });
      if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
      return res.json() as Promise<Completion>;
    }
    
    const summary = await chat(
      "claude-haiku-5-5",
      "Summarize this changelog in three bullets: …",
    );
    console.log(summary.choices[0].message.content);

    Voorbeelduitvoer

    {
      "choices": [{ "message": { "content": "• …" } }],
      "usage": { "prompt_tokens": 812, "completion_tokens": 96, "total_tokens": 908 }
    }
  2. Route het model per taak

    Kies een snel of sterk model op basis van complexiteit en leg eerst de basislijn vast.

    routing.ts
    type TaskKind = "classify" | "extract" | "summarize" | "draft" | "review";
    
    const MODEL_ROUTES: Record<TaskKind, string> = {
      classify: "claude-haiku-5-5",
      extract: "claude-haiku-5-5",
      summarize: "claude-haiku-5-5",
      draft: "claude-sonnet-5-5",
      review: "claude-sonnet-5-5",
    };
    
    export async function route(kind: TaskKind, prompt: string) {
      const model = MODEL_ROUTES[kind];
      const result = await chat(model, prompt);
      return {
        model,
        text: result.choices[0].message.content,
        usage: result.usage,
      };
    }

    Voorbeelduitvoer

    {
      "model": "claude-haiku-5-5",
      "text": "• …",
      "usage": { "prompt_tokens": 812, "completion_tokens": 96, "total_tokens": 908 }
    }
  3. Lees en log het gebruik

    Lees usage uit elke respons en log tokens en latency per functie.

    routing.ts
    type UsageRecord = {
      model: string;
      kind: TaskKind;
      promptTokens: number;
      completionTokens: number;
      totalTokens: number;
    };
    
    const usageLog: UsageRecord[] = [];
    
    function logUsage(kind: TaskKind, model: string, usage: Completion["usage"]) {
      const entry: UsageRecord = {
        model,
        kind,
        promptTokens: usage.prompt_tokens,
        completionTokens: usage.completion_tokens,
        totalTokens: usage.total_tokens,
      };
      usageLog.push(entry);
      console.log(JSON.stringify(entry)); // ship this line to your metrics store
      return entry;
    }
    
    export function tokensByModel() {
      return usageLog.reduce<Record<string, number>>((totals, entry) => {
        totals[entry.model] = (totals[entry.model] ?? 0) + entry.totalTokens;
        return totals;
      }, {});
    }
    
    const result = await route("summarize", "Summarize this changelog in three bullets: …");
    logUsage("summarize", result.model, result.usage);
    console.log(tokensByModel());

    Voorbeelduitvoer

    {"model":"claude-haiku-5-5","kind":"summarize","promptTokens":812,"completionTokens":96,"totalTokens":908}
    { "claude-haiku-5-5": 18234, "claude-sonnet-5-5": 4201 }
  4. Eén sleutel voor alle providers

    Roep modellen uit de catalogus aan met dezelfde Felo-sleutel en verminder providerbeheer.

    routing.ts
    async function chatOnChannel(model: string, prompt: string, channel?: string) {
      const res = await fetch(`${BASE_URL}/chat/completions`, {
        method: "POST",
        headers: {
          ...headers,
          ...(channel ? { "X-Felo-Channel": channel } : {}),
        },
        body: JSON.stringify({ model, messages: [{ role: "user", content: prompt }] }),
      });
      if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
      return res.json() as Promise<Completion>;
    }
    
    // Leave `channel` undefined for the default supplier.
    export function routePinned(kind: TaskKind, prompt: string, channel?: string) {
      return chatOnChannel(MODEL_ROUTES[kind], prompt, channel);
    }
  5. Prijzen uit de live catalogus

    Zet tarieven niet vast; lees actuele prijzen uit modelcatalogus en prijspagina.

    routing.ts
    type Catalog = {
      data: { id: string; owned_by: string; model_kind: string }[];
    };
    
    export async function chatModelIds() {
      const res = await fetch(
        `${BASE_URL}/models?exclude_video_and_decisions=true`,
        { headers },
      );
      if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
      const catalog = (await res.json()) as Catalog;
      return catalog.data
        .filter((model) => model.model_kind === "chat")
        .map((model) => model.id);
    }
    
    // Price `tokensByModel()` against https://openapi.felo.ai/pricing and
    // https://openapi.felo.ai/models. Keep the links, not the rates, in your code.

    Voorbeelduitvoer

    ["claude-haiku-5-5", "claude-sonnet-5-5"]

Wat inbegrepen is

  • Eén endpoint en sleutel
  • Keuze van snel of sterk model per taak
  • Tokenlog per respons
  • Prijzen uit de live catalogus, niet vast in code

Wat het niet doet

  • Garandeert geen lagere factuur
  • Schakelt productieverkeer niet automatisch om
  • Model-id’s en prijzen veranderen; lees altijd de live catalogus
  • Beoordeelt kwaliteit niet voor je; eigen samples nodig
  • Vervangt geen facturering of observability

Vragen

Wordt de factuur lager?

Het wijst taken aan die een goedkopere laag aankunnen, maar de besparing is pas echt na vergelijken van samples en loggen van gebruik.

Roept het modellen automatisch aan?

Alleen als je testaanroepen goedkeurt. Standaard leest het de catalogus en schrijft aanbevelingen zonder productieverkeer aan te raken.

Hoe weet ik welk model goedkoper is?

Lees de live modelcatalogus en prijspagina; de workflow zet tarieven niet vast omdat ze veranderen.

Kan ik een provider vastzetten?

Ja, wanneer latency belangrijker is dan prijs. Vastzetten is een keuze, geen retrystrategie; voeg je eigen fallback toe.

Wat moet ik loggen?

Per aanroep: taak, functie, model, prompttoken, completiontoken, totaal en latency. Aggregeer per functie voor je budgetten zet.

Wat kost een review?

Catalogus lezen veroorzaakt geen modelaanroep. Testaanroepen worden op gebruik gefactureerd; de prompt vraagt goedkeuring vooraf.

Gerelateerde workflows

Maak het van jou

Hetzelfde recept, aangepast aan hoe je echt oplevert.

Eerst alleen loggen

Log voor productie een week gebruik en beslis daarna over downgrades.

Budget per functie

Zet een maandlimiet per functie en waarschuw of degradeer bij overschrijding.

Provider vastzetten voor latency

Als latency belangrijker is dan prijs, zet de provider vast en voeg je eigen fallback toe.

De referentiepagina’s achter dit recept en de volgende stappen.