Витрати
Тримайте витрати на моделі передбачуваними зі зростанням використання
Пропустіть кожне завдання через один endpoint, сумісний з OpenAI, маршрутизуйте до найдешевшої здатної моделі й логуйте використання токенів, яке повертає кожна відповідь.
Скопіювати промпт
Замініть поля в квадратних дужках і вставте в Claude Code, Codex або AI з доступом до термінала. Він встановить скіл Felo, запитає перед витратою кредитів і запустить процес.
Переглянь наші витрати на моделі й запропонуй план маршрутизації для цих завдань: [список завдань або функцій]. Обмеження: місячний бюджет [сума], ціль затримки [ціль], планка якості [рівень]. Прочитай живий каталог моделей, перш ніж щось рекомендувати. Створи: 1. Таблицю завдання -> рекомендована модель. 2. Які завдання можна опустити на рівень нижче й який ризик якості. 3. План логування використання за завданням і функцією. 4. Що виміряти перед зміною продакшену. Правила: - Читай актуальні ID моделей і ціни з живого каталогу; ніколи не цитуй тариф із пам'яті. - Не змінюй конфігурацію продакшену й не надсилай реальний трафік. - Питай перед витратою кредитів на тестові виклики. - Тримай план відкату й ліміт витрат на кожну функцію. - Запиши план у ./routing-plan.md і підсумуй його в чаті.
Копія також містить кроки встановлення й правила безпеки.
Що ви отримаєте
Приклад результату одного запуску. Не живе генерування.
| Завдання | Зараз | Пропозиція | Ризик |
|---|---|---|---|
| Класифікувати тікет | сильна модель | швидка модель | низький |
| Скласти відповідь | сильна модель | сильна модель | немає |
| Підсумувати changelog | сильна модель | швидка модель | середній |
Перед будь-якими змінами: тиждень логуйте використання за завданнями й порівняйте якість на 50 вибіркових виходах.
Точні виклики
Для розробників: той самий процес як код, у порядку виконання.
Показати справжні виклики API
Усі завдання через один endpoint
Використайте один endpoint, сумісний з OpenAI, і один ключ, без SDK на постачальника.
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);Приклад результату
{ "choices": [{ "message": { "content": "• …" } }], "usage": { "prompt_tokens": 812, "completion_tokens": 96, "total_tokens": 908 } }Маршрутизуйте модель за завданням
Виберіть швидку або потужну модель за складністю й спершу запишіть 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, }; }Приклад результату
{ "model": "claude-haiku-5-5", "text": "• …", "usage": { "prompt_tokens": 812, "completion_tokens": 96, "total_tokens": 908 } }Читайте й логуйте використання
Читайте usage з кожної відповіді й логуйте токени та затримку за функцією.
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());Приклад результату
{"model":"claude-haiku-5-5","kind":"summarize","promptTokens":812,"completionTokens":96,"totalTokens":908} { "claude-haiku-5-5": 18234, "claude-sonnet-5-5": 4201 }Один ключ для всіх постачальників
Викликайте моделі з каталогу тим самим ключем Felo і зменште керування постачальниками.
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); }Ціни з живого каталогу
Не фіксуйте тарифи; читайте поточні ціни з каталогу й сторінки цін.
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.Приклад результату
["claude-haiku-5-5", "claude-sonnet-5-5"]
Що входить
- Один endpoint і ключ
- Вибір швидкої або потужної моделі за завданням
- Лог токенів кожної відповіді
- Ціни з живого каталогу, не зашиті в код
Чого не робить
- Не гарантує нижчого рахунку
- Не перемикає продакшн-трафік автоматично
- ID і ціни змінюються; завжди читайте живий каталог
- Не оцінює якість за вас; потрібні ваші зразки
- Не замінює білінг чи observability
Запитання
Чи рахунок зменшиться?
Показує завдання, які можуть перейти на рівень нижче, але економія реальна лише після порівняння зразків і логування використання.
Чи викликає моделі автоматично?
Лише коли схвалите тестові виклики. Типово читає каталог і пише рекомендації, не торкаючись продакшену.
Як дізнатися, яка модель дешевша?
Читайте живий каталог моделей і сторінку цін; процес не фіксує тарифи, бо вони змінюються.
Чи можна закріпити постачальника?
Так, коли затримка важливіша за ціну. Закріплення — вибір, не стратегія retry; додайте власний fallback.
Що логувати?
На виклик: завдання, функцію, модель, prompt token, completion token, суму й затримку. Агрегуйте за функцією перед бюджетом.
Скільки коштує огляд?
Читання каталогу не створює викликів моделей. Тестові виклики оплачуються за використання; промпт просить схвалення заздалегідь.
Пов’язані процеси
Відповідайте на питання підтримки з власної документації
Створіть LiveDoc, завантажте центр допомоги й внутрішній runbook, отримайте уривки, що відповідають тікету, і дозвольте моделі відповідати лише з цих доказів.
Відкрити робочий процесДослідженняПеретворіть одне питання на дослідницький бриф із джерелами
Запитайте веб, збережіть сторінки за відповіддю як Markdown, додайте те, що кажуть практики на X, і тримайте докази в LiveDoc, який можна згодом переглянути.
Відкрити робочий процесОфісПеретворіть дослідницьку сторінку на презентацію
Вилучіть сторінку, збережіть як контекст LiveDoc, дозвольте PPT Task API збудувати дек і питайте, доки не буде готового посилання.
Відкрити робочий процесАдаптуйте
Той самий рецепт, підлаштований під те, як ви насправді працюєте.
Спершу лише логування
Перед продакшеном залогуйте тиждень використання, потім вирішуйте про downgrade.
Бюджет на функцію
Встановіть місячний ліміт на функцію й попереджайте або деградуйте при перевищенні.
Закріпіть постачальника через затримку
Коли затримка важливіша за ціну, закріпіть постачальника й додайте fallback.
Далі
Довідкові сторінки за цим рецептом і наступні кроки.