anoman
MasukDapatkan API Key
Recipes
Beranda Dokumentasi

Arahkan mudah → murah, sulit → premium.

Dua pola: classifier-first memilih model di awal, confidence-based hanya eskalasi saat diperlukan. Keduanya memangkas biaya 80%+ dibanding perutean naif ke satu model premium saja.

Kenapa perlu — Sebagian besar permintaan itu mudah

Distribusi trafik produksi sangat timpang. Di sebagian besar trafik chatbot + support, ~60% permintaan berupa pencarian faktual atau pemformatan sederhana — model kelas hemat menanganinya dengan sempurna. Mengarahkan itu ke claude-sonnet-4-6 berarti membayar ~15× lebih mahal dari yang diperlukan.

Triknya: model mungil untuk memutuskan model mana yang dipakai. Atau: coba yang murah dulu dan eskalasi saat confidence rendah.

Pola 1 — Classifier lebih dulu — Pilih model di awal

Model 7B mengklasifikasikan tingkat kesulitan pertanyaan. Classifier menambah ~$0.000_05 per permintaan — dapat diabaikan dibanding panggilan sonnet seharga $0.012.

Perutean classifier-first

import os
import json
from openai import OpenAI
 
client = OpenAI(base_url="https://api.anoman.io/v1", api_key=os.environ["ANOMAN_API_KEY"])
 
# Tiny, cheap classifier. ~$0.000_05 per call.
CLASSIFIER_MODEL = "qwen-2.5-7b"
 
# Heavy model for hard requests.
HEAVY_MODEL = "claude-sonnet-4-6"
# Cheap model for easy requests.
LIGHT_MODEL = "gpt-4o-mini"
 
CLASSIFIER_SYSTEM = """
Classify the difficulty of the user's question as one of:
  easy      — Factual lookup, simple instruction, short formatting task
  medium    — Multi-step reasoning, document summarization, code generation
  hard      — Algorithm design, math proof, multi-turn planning, long context
 
Respond with ONLY the single word. No explanation.
""".strip()
 
def classify(question: str) -> str:
    response = client.chat.completions.create(
        model=CLASSIFIER_MODEL,
        messages=[
            {"role": "system", "content": CLASSIFIER_SYSTEM},
            {"role": "user",   "content": question},
        ],
        max_tokens=10,
        temperature=0,
    )
    return response.choices[0].message.content.strip().lower()
 
def ask(question: str) -> str:
    difficulty = classify(question)
    model = {
        "easy":   LIGHT_MODEL,
        "medium": LIGHT_MODEL,
        "hard":   HEAVY_MODEL,
    }.get(difficulty, HEAVY_MODEL)  # safe default: escalate
 
    response = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": question}],
        # Track which path took for monitoring
        metadata={"routed_via": "classifier", "difficulty": difficulty},
    )
    return response.choices[0].message.content
 
print(ask("Capital of Indonesia?"))                            # easy → cheap
print(ask("Prove that the halting problem is undecidable."))   # hard → premium

Mode kegagalan: classifier salah mengarahkan pertanyaan sulit ke model murah. Setel system prompt agar cenderung eskalasi, atau gunakan pola hybrid di bawah.

Pola 2 — Eskalasi confidence — Coba murah, eskalasi saat menyerah

Menginstruksikan model murah untuk merespons dengan ESCALATE saat tidak yakin. Model murah mendapat kesempatan menangani setiap permintaan; kita hanya membayar premium saat ia secara eksplisit menyerah. Tingkat eskalasi ~5% umum untuk setup dengan prompt yang baik.

Eskalasi berbasis confidence

# Try the cheap model first. Only escalate when the cheap model says
# "I'm not sure" or doesn't follow the output format.
 
CHEAP = "gpt-4o-mini"
HEAVY = "claude-sonnet-4-6"
 
ASK_SYSTEM = """
Answer the user's question. If you're not confident, respond with
exactly: ESCALATE
 
Otherwise, give the answer.
""".strip()
 
def ask_with_escalation(question: str) -> tuple[str, str]:
    """Returns (answer, model_used)."""
    response = client.chat.completions.create(
        model=CHEAP,
        messages=[
            {"role": "system", "content": ASK_SYSTEM},
            {"role": "user",   "content": question},
        ],
        max_tokens=300,
        temperature=0,
    )
    answer = response.choices[0].message.content.strip()
 
    if answer.startswith("ESCALATE") or answer == "":
        # Cheap model bailed. Escalate.
        response = client.chat.completions.create(
            model=HEAVY,
            messages=[{"role": "user", "content": question}],
        )
        return response.choices[0].message.content, HEAVY
 
    return answer, CHEAP

Pola 3 — Hybrid — Classifier + eskalasi

Gunakan classifier sebagai gerbang cepat untuk mengarahkan permintaan sulit yang jelas langsung ke premium (tanpa overhead panggilan ganda). Untuk selebihnya, jalur murah-dengan-eskalasi berlaku. Gabungan terbaik keduanya.

Hybrid — klasifikasi lalu eskalasi

# Combine both: the classifier picks a candidate model, the candidate
# can still escalate on low confidence. Catches mis-classifications.
 
def smart_ask(question: str) -> dict:
    difficulty = classify(question)
 
    if difficulty == "hard":
        # Skip cheap layer entirely.
        return {"answer": ask_heavy(question), "model": HEAVY, "path": "direct"}
 
    answer, model_used = ask_with_escalation(question)
    return {
        "answer": answer,
        "model": model_used,
        "path": "escalated" if model_used == HEAVY else "cheap",
    }

Ekonomi — Perhitungan kasar

Ekonomi — perhitungan kasar per 10K permintaan

Assume 10,000 requests/day:
  - 60% easy (factual)
  - 30% medium (summarization, simple code)
  - 10% hard (multi-step reasoning)

Naive routing — everything to claude-sonnet-4-6:
  - Avg cost: ~$0.012 per request (~500 in + ~300 out tokens)
  - Daily:    $120
  - Monthly:  ~$3,600

Classifier-first routing:
  - Classifier:  10K × $0.00005 = $0.50
  - Easy → cheap (6K × $0.0005)  = $3
  - Med  → cheap (3K × $0.0008)  = $2.40
  - Hard → heavy (1K × $0.012)   = $12
  - Daily:    $17.90
  - Monthly:  ~$540
  - Savings:  85% vs naive

Confidence escalation — assume 5% escalation rate from cheap:
  - Cheap call:   10K × $0.0008 = $8
  - Heavy retry:  500 × $0.012  = $6
  - Daily:    $14
  - Monthly:  ~$420
  - Savings:  88% vs naive

Tips produksi

  • Lacak metadata — kirim metadata: {difficulty, path} pada setiap panggilan agar halaman Usage di dashboard menampilkan distribusi perutean. Membantu Anda menyetel prompt classifier.
  • Pantau tingkat eskalasi — jika >15%, classifier Anda terlalu sering salah mengarahkan. Setel prompt atau pindah ke pola hybrid.
  • Jalur sadar latensi — classifier menambah ~200 ms. Untuk UX yang sensitif latensi, pilih eskalasi confidence (jalur murah sekali panggil, eskalasi hanya saat diperlukan).
  • Cache classifier — pertanyaan yang sama menghasilkan klasifikasi yang sama. Tambahkan x-anoman-cache: semantic pada panggilan classifier agar pertanyaan berulang melewati bahkan hop classifier murah.
  • A/B test ambang batas — pisahkan 5% trafik ke "selalu pakai premium" sebagai kontrol kualitas. Bandingkan tingkat thumbs-up pengguna akhir vs kelompok yang dirutekan.

Lacak distribusi perutean Anda di dashboard.

Rincian per-model dengan biaya per rute.