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.
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.
| Taak | Nu | Voorstel | Risico |
|---|---|---|---|
| Ticket classificeren | sterk model | snel model | laag |
| Antwoord opstellen | sterk model | sterk model | geen |
| Changelog samenvatten | sterk model | snel model | middel |
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
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 } }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 } }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 }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); }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
Beantwoord supportvragen vanuit je eigen documentatie
Maak een LiveDoc, laad het helpcenter en de interne runbook, haal de passages op die het ticket beantwoorden en laat het model alleen uit dat bewijs antwoorden.
Workflow openenResearchMaak van één vraag een onderbouwde researchbrief
Vraag het web, bewaar de pagina’s achter het antwoord als Markdown, voeg toe wat practitioners op X zeggen en houd het bewijs in een LiveDoc dat je later opnieuw kunt doorzoeken.
Workflow openenKantoorMaak van een onderzoekspagina een presentatie
Extraheer de pagina, bewaar hem als LiveDoc-context, laat de PPT Task API het deck bouwen en vraag door tot de voltooide link.
Workflow openenMaak 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.
Verder
De referentiepagina’s achter dit recept en de volgende stappen.