Felo API PlatformFelo API Platform

Koszty

Utrzymaj przewidywalne koszty modeli przy rosnącym użyciu

Przepuść każde zadanie przez jeden endpoint zgodny z OpenAI, kieruj do najtańszego zdolnego modelu i loguj użycie tokenów zwracane przez każdą odpowiedź.

Czas20 minutPoziomŚredniZaktualizowano2026-10-29
Dla kogoZespoły platformyWłaściciele produktu APILiderzy inżynierii

Skopiuj prompt

Podmień pola w nawiasach kwadratowych i wklej do Claude Code, Codex albo AI z dostępem do terminala. Instaluje skill Felo, pyta przed wydaniem kredytów i uruchamia workflow.

Przejrzyj nasze wydatki na modele i zaproponuj plan routingu dla tych zadań: [lista zadań lub funkcji].

Ograniczenia: miesięczny budżet [kwota], cel opóźnienia [cel], poprzeczka jakości [poziom].
Przeczytaj aktualny katalog modeli, zanim cokolwiek zaproponujesz.

Przygotuj:
1. Tabelę zadanie -> rekomendowany model.
2. Które zadania mogą zejść o poziom niżej i jakie jest ryzyko jakości.
3. Plan logowania użycia na zadanie i funkcję.
4. Co zmierzyć przed zmianą produkcji.

Zasady:
- Czytaj aktualne ID i ceny modeli z katalogu na żywo; nigdy nie cytuj stawki z pamięci.
- Nie zmieniaj konfiguracji produkcji i nie wysyłaj prawdziwego ruchu.
- Pytaj przed zużyciem kredytów na wywołania testowe.
- Utrzymuj plan rollbacku i limit wydatków na funkcję.
- Zapisz plan w ./routing-plan.md i podsumuj go w czacie.

Kopia zawiera też kroki instalacji i zasady bezpieczeństwa.

Co otrzymujesz

Przykładowy wynik jednego uruchomienia. Nie generowanie na żywo.

Przykładowy plan routingu (fragment)
ZadanieObecniePropozycjaRyzyko
Klasyfikacja ticketumocny modelszybki modelniskie
Szkic odpowiedzimocny modelmocny modelbrak
Streszczenie changelogumocny modelszybki modelśrednie

Przed jakąkolwiek zmianą: przez tydzień loguj użycie na zadanie i porównaj jakość na 50 próbkach wyników.

Dokładne wywołania

Dla deweloperów: ten sam workflow jako kod, w kolejności wykonania.

Pokaż rzeczywiste wywołania API
  1. Wszystkie zadania przez jeden endpoint

    Użyj jednego endpointu zgodnego z OpenAI i jednego klucza, bez SDK na dostawcę.

    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);

    Przykładowy wynik

    {
      "choices": [{ "message": { "content": "• …" } }],
      "usage": { "prompt_tokens": 812, "completion_tokens": 96, "total_tokens": 908 }
    }
  2. Kieruj model według zadania

    Wybierz szybki lub mocny model według złożoności i najpierw zapisz baseline.

    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,
      };
    }

    Przykładowy wynik

    {
      "model": "claude-haiku-5-5",
      "text": "• …",
      "usage": { "prompt_tokens": 812, "completion_tokens": 96, "total_tokens": 908 }
    }
  3. Czytaj i loguj użycie

    Czytaj usage z każdej odpowiedzi i loguj tokeny oraz opóźnienie po funkcji.

    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());

    Przykładowy wynik

    {"model":"claude-haiku-5-5","kind":"summarize","promptTokens":812,"completionTokens":96,"totalTokens":908}
    { "claude-haiku-5-5": 18234, "claude-sonnet-5-5": 4201 }
  4. Jeden klucz dla wszystkich dostawców

    Wywołuj modele z katalogu tym samym kluczem Felo i zmniejsz zarządzanie dostawcami.

    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. Ceny z żywego katalogu

    Nie ustalaj stawek; czytaj bieżące ceny z katalogu i strony cen.

    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.

    Przykładowy wynik

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

Co zawiera

  • Jeden endpoint i klucz
  • Wybór szybkiego lub mocnego modelu według zadania
  • Log tokenów każdej odpowiedzi
  • Ceny z żywego katalogu, nie zakodowane na stałe

Czego nie robi

  • Nie gwarantuje niższego rachunku
  • Nie przełącza ruchu produkcyjnego automatycznie
  • ID i ceny się zmieniają; zawsze czytaj żywy katalog
  • Nie ocenia jakości za ciebie; potrzebne twoje próbki
  • Nie zastępuje billing ani observability

Pytania

Czy rachunek spadnie?

Wskazuje zadania, które mogą zejść poziom niżej, ale oszczędność jest realna dopiero po porównaniu próbek i logowaniu użycia.

Czy wywołuje modele automatycznie?

Tylko gdy zatwierdzisz wywołania testowe. Domyślnie czyta katalog i pisze rekomendacje bez dotykania produkcji.

Skąd wiem, który model jest tańszy?

Czytaj żywy katalog modeli i stronę cen; workflow nie ustala stawek, bo się zmieniają.

Czy można przypiąć dostawcę?

Tak, gdy opóźnienie ważniejsze od ceny. Przypięcie to wybór, nie strategia retry; dodaj własny fallback.

Co logować?

Na wywołanie: zadanie, funkcję, model, prompt token, completion token, sumę i opóźnienie. Agreguj po funkcji przed budżetem.

Ile kosztuje przegląd?

Czytanie katalogu nie tworzy wywołań modeli. Wywołania testowe są rozliczane według użycia; prompt pyta o zgodę wcześniej.

Powiązane workflowy

Dostosuj

Ta sama receptura, dopasowana do tego, jak naprawdę dostarczasz.

Najpierw tylko loguj

Przed produkcją zaloguj tydzień użycia i wtedy zdecyduj o downgrade.

Budżet na funkcję

Ustaw miesięczny limit na funkcję i ostrzegaj lub degraduj po przekroczeniu.

Przypnij dostawcę dla opóźnienia

Gdy opóźnienie ważniejsze od ceny, przypnij dostawcę i dodaj fallback.

Strony referencyjne za tą recepturą i kolejne kroki.