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ź.
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.
| Zadanie | Obecnie | Propozycja | Ryzyko |
|---|---|---|---|
| Klasyfikacja ticketu | mocny model | szybki model | niskie |
| Szkic odpowiedzi | mocny model | mocny model | brak |
| Streszczenie changelogu | mocny model | szybki 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
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 } }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 } }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 }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); }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
Odpowiadaj na pytania wsparcia z własnej dokumentacji
Utwórz LiveDoc, wczytaj centrum pomocy i wewnętrzny runbook, pobierz fragmenty odpowiadające ticketowi i pozwól modelowi odpowiadać tylko z tych dowodów.
Otwórz workflowBadaniaZamień jedno pytanie w brief badawczy ze źródłami
Zapytaj web, zapisz strony stojące za odpowiedzią jako Markdown, dodaj to, co mówią praktycy na X, i zachowaj dowody w LiveDoc, który można później przeszukać.
Otwórz workflowBiuroZamień stronę badawczą w prezentację
Wyekstrahuj stronę, zapisz jako kontekst LiveDoc, pozwól PPT Task API zbudować deck i pytaj, aż link będzie gotowy.
Otwórz workflowDostosuj
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.
Idź dalej
Strony referencyjne za tą recepturą i kolejne kroki.