AI Router چیست؟ آموزش انتخاب خودکار مدل هوش مصنوعی براساس کیفیت، هزینه و سرعت

AI Router با بررسی نوع درخواست، قابلیت مدل، هزینه، سرعت و سلامت ارائه‌دهنده، بهترین مسیر را برای هر درخواست انتخاب می‌کند. در این راهنما، Routing، Fallback و Load Balancing را همراه با نمونه‌کد و API درواره می‌آموزید.

Share
AI Router چیست؟ آموزش انتخاب خودکار مدل هوش مصنوعی براساس کیفیت، هزینه و سرعت

در بسیاری از پروژه‌های هوش مصنوعی، توسعه‌دهنده در ابتدا یک مدل انتخاب می‌کند و تمام درخواست‌ها را به همان مدل می‌فرستد:

response = client.chat.completions.create(
    model="MODEL_ID",
    messages=[
        {
            "role": "user",
            "content": "درخواست کاربر"
        }
    ]
)

این روش برای نمونه اولیه ساده است، اما در محیط Production محدودیت‌های مهمی دارد.

همه درخواست‌ها یکسان نیستند. بعضی درخواست‌ها فقط به یک پاسخ کوتاه نیاز دارند، برخی شامل تصویر هستند، بعضی باید خروجی JSON معتبر تولید کنند و برخی دیگر نیازمند Context طولانی، Tool Calling یا Reasoning پیچیده‌اند.

همه مدل‌ها نیز یکسان نیستند. مدل‌ها از نظر قابلیت، قیمت، سرعت، Context Window، کیفیت زبان فارسی، پشتیبانی از ابزارها و پایداری ارائه‌دهنده تفاوت دارند.

اگر تمام درخواست‌ها به قوی‌ترین مدل ارسال شوند، هزینه افزایش پیدا می‌کند. اگر همه درخواست‌ها به ارزان‌ترین مدل بروند، کیفیت کاهش می‌یابد. اگر فقط به یک Provider وابسته باشیم، اختلال آن می‌تواند کل محصول را متوقف کند.

AI Router برای حل همین مسئله طراحی می‌شود: انتخاب بهترین مدل و مسیر برای هر درخواست براساس نیاز واقعی آن.

فهرست مطالب

  • AI Router چیست؟
  • تفاوت Model Routing و Provider Routing
  • چرا استفاده از یک مدل ثابت مناسب نیست؟
  • تفاوت AI Router، API Gateway و Load Balancer
  • مراحل تصمیم‌گیری Router
  • Static Routing و Dynamic Routing
  • Rule-based Routing
  • Capability-based Routing
  • Cost-aware Routing
  • Latency-aware Routing
  • Quality-aware Routing
  • Semantic Routing
  • Complexity Routing
  • Context-aware Routing
  • Routing برای Text، Image، Audio و Video
  • Routing برای Tool Calling و Structured Outputs
  • Routing براساس پلن کاربران
  • Routing میان Providerها
  • Load Balancing
  • Health Check و Circuit Breaker
  • Retry، Fallback و Routing
  • طراحی تابع امتیازدهی
  • معماری Production
  • نمونه‌کد Python
  • نمونه‌کد TypeScript
  • Observability و Evaluation
  • A/B Testing، Shadow و Canary
  • امنیت و حریم خصوصی
  • خطاهای رایج
  • چک‌لیست Production
  • پرسش‌های متداول
  • جمع‌بندی

AI Router چیست؟

AI Router یا Model Router یک لایه تصمیم‌گیری میان اپلیکیشن و مدل‌های هوش مصنوعی است. این لایه هر درخواست را بررسی می‌کند و مناسب‌ترین مدل، Provider یا Deployment را برای پردازش آن انتخاب می‌کند.

Router می‌تواند براساس معیارهای مختلف تصمیم بگیرد:

  • نوع ورودی
  • نوع خروجی
  • قابلیت‌های موردنیاز
  • پیچیدگی درخواست
  • Context Window
  • قیمت مدل
  • بودجه کاربر
  • Latency
  • Time to First Token
  • Throughput
  • کیفیت
  • سلامت Provider
  • Rate Limit
  • محل جغرافیایی
  • سیاست نگهداری داده
  • پلن کاربر
  • حجم ترافیک
  • نتایج ارزیابی‌های قبلی

فرایند ساده Routing می‌تواند چنین باشد:

درخواست کاربر
→ استخراج نیازها
→ حذف مدل‌های ناسازگار
→ بررسی سلامت مسیرها
→ امتیازدهی به مدل‌های باقی‌مانده
→ انتخاب بهترین مسیر
→ ارسال درخواست
→ Validation
→ Retry یا Fallback در صورت نیاز
→ ثبت نتیجه و به‌روزرسانی معیارها

Amazon Bedrock نیز Intelligent Prompt Routing را روشی برای پیش‌بینی کیفیت پاسخ مدل‌ها برای هر درخواست و انتخاب مسیر مناسب با هدف ایجاد تعادل میان کیفیت و هزینه تعریف می‌کند. مستندات Intelligent Prompt Routing در Amazon Bedrock

تفاوت Model Routing و Provider Routing

این دو مفهوم مرتبط‌اند، اما یکسان نیستند.

Model Routing

Router میان مدل‌های متفاوت انتخاب می‌کند:

مدل سریع و ارزان
مدل عمومی
مدل Reasoning
مدل Vision
مدل Coding

برای مثال:

دسته‌بندی متن → مدل کوچک
تحلیل قرارداد → مدل قوی
بررسی تصویر → مدل Vision
تولید کد پیچیده → مدل Coding

Provider Routing

ممکن است یک مدل مشخص از چند Provider یا Deployment قابل‌دسترسی باشد. Provider Router بهترین مسیر اجرای همان مدل را انتخاب می‌کند:

Model X
  ├── Provider A
  ├── Provider B
  └── Provider C

انتخاب Provider می‌تواند براساس معیارهای زیر باشد:

  • قیمت
  • Latency
  • Throughput
  • Uptime
  • Region
  • Rate Limit
  • سیاست داده
  • سلامت فعلی

OpenRouter در Provider Routing امکان اولویت‌دادن براساس قیمت، Throughput یا Latency را ارائه می‌کند. راهنمای Provider Routing در OpenRouter

Router چندسطحی

در یک معماری کامل، ابتدا مدل و سپس Provider انتخاب می‌شود:

درخواست
→ انتخاب خانواده مدل
→ انتخاب مدل
→ انتخاب Provider
→ انتخاب Deployment یا Region

چرا استفاده از یک مدل ثابت مناسب نیست؟

هزینه غیرضروری

برای تشخیص احساس یک جمله کوتاه نیازی به گران‌ترین مدل Reasoning نیست.

کیفیت ناکافی

مدل ارزان ممکن است برای استخراج اطلاعات ساده مناسب باشد، اما در تحلیل حقوقی پیچیده یا کدنویسی چندمرحله‌ای عملکرد کافی نداشته باشد.

تفاوت قابلیت‌ها

همه مدل‌ها از قابلیت‌های زیر پشتیبانی نمی‌کنند:

  • Vision
  • Audio
  • Video
  • Tool Calling
  • Structured Outputs
  • JSON Mode
  • Prompt Caching
  • Context طولانی
  • Streaming

وابستگی به یک Provider

اختلال، Rate Limit یا تغییر سیاست یک Provider می‌تواند کل سیستم را متوقف کند.

تفاوت Latency

برخی مدل‌ها برای پاسخ سریع مناسب‌اند و برخی برای Reasoning طولانی.

تفاوت زبان و حوزه

یک مدل ممکن است در فارسی بهتر باشد و مدل دیگری در کدنویسی، ریاضیات یا تحلیل تصویر.

تغییرات مستمر

قیمت، عملکرد، نسخه و دسترسی مدل‌ها تغییر می‌کنند. قراردادن نام مدل در تمام بخش‌های کد، تغییر و مهاجرت را دشوار می‌کند.

بهتر است اپلیکیشن از نام‌های منطقی استفاده کند:

fast-text
balanced-chat
deep-reasoning
vision-analysis
code-generation
structured-extraction

Router این نام منطقی را به مدل واقعی نگاشت می‌کند.

تفاوت AI Router، API Gateway و Load Balancer

API Gateway

وظایف عمومی API را انجام می‌دهد:

  • Authentication
  • Rate Limit
  • Quota
  • Logging
  • Billing
  • Validation
  • مدیریت Endpoint
  • امنیت

Load Balancer

ترافیک را میان چند نمونه مشابه توزیع می‌کند:

Deployment A
Deployment B
Deployment C

هدف اصلی آن توزیع بار و افزایش دسترسی‌پذیری است.

AI Router

براساس معنای درخواست، قابلیت، هزینه و کیفیت تصمیم می‌گیرد کدام مدل یا مسیر مناسب‌تر است.

قابلیتAPI GatewayLoad BalancerAI Router
احراز هویتبلهمعمولاً خیرممکن است
Rate Limitبلهمحدوددر تصمیم دخیل
توزیع بارمحدودبلهبله
درک نوع درخواستخیرخیربله
انتخاب مدلخیرخیربله
انتخاب براساس هزینهمعمولاً خیرخیربله
انتخاب براساس کیفیتخیرخیربله
بررسی قابلیت مدلخیرخیربله
Fallback هوشمندمحدودمحدودبله

در معماری Production این سه لایه می‌توانند کنار یکدیگر باشند.

مراحل تصمیم‌گیری AI Router

یک Router مناسب معمولاً چند مرحله دارد.

۱. تحلیل درخواست

اطلاعات لازم استخراج می‌شوند:

{
  "task_type": "document_extraction",
  "input_modalities": ["text", "image"],
  "required_capabilities": [
    "vision",
    "structured_output"
  ],
  "estimated_input_tokens": 18000,
  "max_latency_ms": 15000,
  "max_cost": 0.08,
  "quality_tier": "high"
}

۲. فیلتر دسترسی

فقط مدل‌هایی باقی می‌مانند که کاربر یا سازمان اجازه استفاده از آن‌ها را دارد.

۳. فیلتر قابلیت

مدل‌های فاقد Vision، Structured Outputs یا Context کافی حذف می‌شوند.

۴. فیلتر عملیاتی

مسیرهای ناسالم، Rate-limited یا دارای Circuit باز حذف می‌شوند.

۵. فیلتر بودجه

مدل‌هایی که هزینه تخمینی آن‌ها از سقف عبور می‌کند کنار گذاشته می‌شوند.

۶. امتیازدهی

مسیرهای باقی‌مانده براساس کیفیت، هزینه، Latency و سلامت امتیاز می‌گیرند.

۷. انتخاب و اجرا

بهترین مسیر انتخاب و درخواست ارسال می‌شود.

۸. ثبت نتیجه

Latency، هزینه، مصرف، کیفیت و خطا ثبت می‌شوند تا تصمیم‌های آینده بهتر شوند.

Static Routing چیست؟

در Static Routing قواعد از قبل مشخص‌اند:

if task_type == "classification":
    return "FAST_MODEL"

if task_type == "vision":
    return "VISION_MODEL"

if task_type == "reasoning":
    return "REASONING_MODEL"

مزایا

  • ساده
  • قابل‌پیش‌بینی
  • سریع
  • قابل‌توضیح
  • مناسب شروع پروژه

محدودیت‌ها

  • با تغییر وضعیت Provider سازگار نمی‌شود.
  • تفاوت پیچیدگی درخواست‌ها را کامل در نظر نمی‌گیرد.
  • به به‌روزرسانی دستی نیاز دارد.
  • از داده‌های کیفیت Production یاد نمی‌گیرد.

Dynamic Routing چیست؟

Dynamic Routing در لحظه و براساس داده‌های جاری تصمیم می‌گیرد:

  • Latency اخیر
  • نرخ موفقیت
  • هزینه فعلی
  • سلامت Provider
  • ظرفیت باقی‌مانده
  • کیفیت پیش‌بینی‌شده
  • نوع درخواست
  • بودجه

برای مثال:

اگر Model A سالم و p95 Latency کمتر از ۵ ثانیه است:
    Model A
در غیر این صورت:
    Model B

Dynamic Routing انعطاف بیشتری دارد، اما پیچیده‌تر است و به Observability، State مشترک و Guardrail نیاز دارد.

Rule-based Routing

در این روش تصمیم با قواعد صریح گرفته می‌شود.

def route(request):
    if request.has_image:
        return "vision"

    if request.requires_tools:
        return "tool-capable"

    if request.estimated_tokens > 100_000:
        return "long-context"

    if request.task_type == "classification":
        return "fast"

    return "balanced"

چه زمانی مناسب است؟

  • تعداد مدل‌ها محدود است.
  • قوانین کسب‌وکار روشن‌اند.
  • قابلیت توضیح تصمیم مهم است.
  • Dataset کافی برای Router یادگیری‌محور نداریم.

Rule-based Routing معمولاً بهترین نقطه شروع است.

Capability-based Routing

قبل از مقایسه قیمت و سرعت، باید مدل‌های ناسازگار حذف شوند.

Capability Matrix

مدلTextVisionToolsJSON SchemaStreamingContext
Model Aبلهخیربلهبلهبلهمتوسط
Model Bبلهبلهبلهمحدودبلهبزرگ
Model Cبلهخیرخیرخیربلهکوچک

قابلیت‌های قابل‌بررسی

  • Input Modalities
  • Output Modalities
  • Tool Calling
  • Parallel Tool Calls
  • Structured Outputs
  • JSON Mode
  • Streaming
  • Context Window
  • Maximum Output
  • Prompt Caching
  • Reasoning
  • Batch
  • زبان
  • Region
  • سیاست داده

اصل مهم

قابلیت یک شرط اجباری است، نه فقط یک امتیاز.

اگر درخواست به Vision نیاز دارد، مدل Text-only نباید حتی با قیمت کمتر انتخاب شود.

Cost-aware Routing

Cost-aware Router هزینه تخمینی هر مسیر را پیش از انتخاب محاسبه می‌کند.

هزینه متنی

Estimated Cost =
Estimated Input Tokens × Input Price
+ Maximum Output Tokens × Output Price

اگر قیمت به‌ازای یک میلیون Token باشد:

def estimate_cost(
    input_tokens,
    output_tokens,
    input_price_per_million,
    output_price_per_million,
):
    input_cost = (
        input_tokens / 1_000_000
        * input_price_per_million
    )

    output_cost = (
        output_tokens / 1_000_000
        * output_price_per_million
    )

    return input_cost + output_cost

هزینه کامل

در سیستم واقعی ممکن است هزینه‌های دیگری نیز وجود داشته باشند:

  • Cached Tokens
  • Image Input
  • Audio Duration
  • Video Duration
  • Tool Calls
  • Retrieval
  • Retry
  • Fallback
  • Storage
  • Provider Fee

Cheapest-first همیشه بهترین نیست

مدل ارزان ممکن است:

  • Retry بیشتری نیاز داشته باشد؛
  • JSON نامعتبر تولید کند؛
  • Tool Call اشتباه داشته باشد؛
  • پاسخ را طولانی‌تر کند؛
  • Task Completion پایین‌تری داشته باشد.

معیار بهتر:

Expected Cost per Successful Task =
Expected Request Cost / Expected Success Probability

مثال:

Model A:
هزینه درخواست = 0.01
احتمال موفقیت = 0.60
هزینه مورد انتظار هر موفقیت = 0.0167

Model B:
هزینه درخواست = 0.02
احتمال موفقیت = 0.95
هزینه مورد انتظار هر موفقیت = 0.021

انتخاب به اهمیت کیفیت، هزینه Retry و ارزش وظیفه بستگی دارد.

Latency-aware Routing

Latency-aware Router مسیر را براساس سرعت واقعی و اخیر انتخاب می‌کند.

معیارهای Latency

  • Time to First Token
  • Time to Last Token
  • p50 Latency
  • p95 Latency
  • Queue Time
  • Tokens per Second
  • Provider Processing Time

انتخاب براساس کاربرد

برای Chat تعاملی:

Time to First Token مهم‌تر است.

برای Batch:

Throughput و هزینه مهم‌ترند.

برای پاسخ کوتاه API:

Total Latency مهم است.

استفاده از میانگین متحرک

new_ewma = (
    alpha * current_latency
    + (1 - alpha) * previous_ewma
)

EWMA به داده‌های جدید وزن بیشتری می‌دهد و از واکنش افراطی به یک درخواست غیرعادی جلوگیری می‌کند.

Latency لحظه‌ای یا تاریخی؟

ترکیبی از این دو بهتر است:

  • داده تاریخی برای Baseline
  • داده کوتاه‌مدت برای اختلال جاری
  • Health Check برای حذف مسیر خراب

Quality-aware Routing

در Quality-aware Routing، مدل براساس کیفیت پیش‌بینی‌شده برای وظیفه انتخاب می‌شود.

منابع امتیاز کیفیت

  • Benchmark داخلی
  • Dataset ارزیابی
  • بازخورد کاربران
  • Human Review
  • JSON Validation Rate
  • Tool Success Rate
  • Groundedness
  • Task Completion
  • کیفیت به تفکیک زبان
  • کیفیت به تفکیک نوع وظیفه

کیفیت باید Task-specific باشد

یک امتیاز کلی برای مدل کافی نیست.

{
  "model": "MODEL_A",
  "quality": {
    "persian_chat": 0.91,
    "coding": 0.76,
    "vision_ocr": 0.62,
    "structured_extraction": 0.94,
    "tool_calling": 0.88
  }
}

مدلی که در Coding قوی است الزاماً برای OCR یا پاسخ فارسی بهترین گزینه نیست.

داده کیفیت Production

Router می‌تواند نتایج واقعی را به‌صورت دوره‌ای وارد امتیازها کند، اما نباید با هر پاسخ فوراً سیاست خود را تغییر دهد. تغییر بیش‌ازحد سریع باعث ناپایداری می‌شود.

Semantic Routing چیست؟

Semantic Routing براساس معنای درخواست، Intent یا شباهت معنایی مسیر را انتخاب می‌کند.

برای مثال:

«این فاکتور را تحلیل کن»
→ document-extraction

«این کد چرا خطا می‌دهد؟»
→ coding

«این تصویر را توضیح بده»
→ vision

«وضعیت سفارش من چیست؟»
→ support-agent

روش‌های Semantic Routing

Keyword

ساده اما محدود:

if "تصویر" in text:
    return "vision"

Classifier

مدل کوچک یا Classifier نوع درخواست را تشخیص می‌دهد.

Embedding

درخواست به Vector تبدیل و با نمونه‌های هر Route مقایسه می‌شود.

LLM Router

یک مدل درباره مسیر مناسب تصمیم می‌گیرد.

مزایا و محدودیت‌ها

روشسرعتهزینهدقتنگهداری
Keywordزیادبسیار کممحدوددشوار در مقیاس
Ruleزیادکمخوب برای موارد مشخصمتوسط
Embeddingزیادکمخوبنیازمند نمونه
Classifierزیادکمخوبنیازمند Dataset
LLM Routerکمتربیشترانعطاف‌پذیرPrompt و Eval لازم

Router نیز ممکن است اشتباه کند

تصمیم Router باید قابل‌ثبت و ارزیابی باشد:

{
  "route": "coding",
  "confidence": 0.82,
  "router_version": "intent-router-v4",
  "fallback_route": "balanced-chat"
}

اگر Confidence پایین است:

  • از مسیر عمومی استفاده کنید؛
  • سؤال تکمیلی بپرسید؛
  • یا مدل قوی‌تر انتخاب کنید.

Complexity Routing

در Complexity Routing درخواست‌های ساده به مدل سبک و درخواست‌های دشوار به مدل قوی هدایت می‌شوند.

ویژگی‌های پیچیدگی

  • طول ورودی
  • تعداد محدودیت‌ها
  • نیاز به استدلال چندمرحله‌ای
  • وجود کد
  • تعداد اسناد
  • نیاز به Tool Calling
  • نوع خروجی
  • حوزه تخصصی
  • ابهام
  • Context طولانی
  • درخواست مقایسه یا برنامه‌ریزی

امتیاز ساده

def complexity_score(request):
    score = 0

    if request.estimated_tokens > 10_000:
        score += 2

    if request.requires_tools:
        score += 2

    if request.requires_reasoning:
        score += 3

    if request.output_schema_depth > 3:
        score += 1

    if request.has_multiple_documents:
        score += 2

    return score

سپس:

۰ تا ۲ → مدل سریع
۳ تا ۵ → مدل متعادل
۶ به بالا → مدل قوی

خطر Under-routing

اگر درخواست پیچیده به مدل ضعیف ارسال شود:

  • کیفیت کاهش می‌یابد؛
  • Retry رخ می‌دهد؛
  • کاربر درخواست را تکرار می‌کند؛
  • هزینه نهایی افزایش می‌یابد.

خطر Over-routing

اگر درخواست ساده به مدل گران ارسال شود، هزینه و Latency بدون بهبود واقعی افزایش می‌یابد.

Context-aware Routing

Router باید Context Window موردنیاز را بررسی کند.

Required Context =
System Prompt
+ Tools
+ Messages
+ Retrieved Documents
+ Output Reserve

اگر مجموع Tokenها از ظرفیت مدل بیشتر باشد، چند انتخاب وجود دارد:

  • مدل دارای Context بزرگ‌تر
  • فشرده‌سازی تاریخچه
  • کاهش اسناد
  • Summarization
  • تقسیم وظیفه
  • رد درخواست با خطای واضح

انتخاب براساس Context واقعی

نباید فقط طول متن خام را اندازه گرفت. تعریف ابزارها، تصاویر، اسناد و ظرفیت خروجی نیز اهمیت دارند.

if required_context > model.context_window:
    exclude(model)

Routing برای Text، Image، Audio و Video

Text

معیارها:

  • زبان
  • Context
  • Reasoning
  • Tools
  • Structured Outputs
  • هزینه
  • سرعت

Image Understanding

مدل باید ورودی تصویر را پشتیبانی کند. Router باید موارد زیر را نیز بررسی کند:

  • تعداد تصویر
  • Resolution
  • فرمت
  • اندازه فایل
  • OCR
  • Context ترکیبی Text و Image

Image Generation

Routing می‌تواند براساس این موارد باشد:

  • کیفیت
  • سرعت
  • Resolution
  • Aspect Ratio
  • ویرایش تصویر
  • ورودی Reference
  • Transparent Background
  • قیمت هر تصویر

Audio

  • Speech-to-Text
  • Text-to-Speech
  • زبان فارسی
  • Speaker Diarization
  • Timestamp
  • Streaming
  • مدت فایل

Video

  • Text-to-Video
  • Image-to-Video
  • مدت ویدئو
  • Resolution
  • Audio
  • First/Last Frame
  • Job Async
  • قیمت تولید

Router چندرسانه‌ای باید از یک مدل قیمت‌گذاری عمومی فراتر برود، زیرا هزینه ممکن است براساس تصویر، ثانیه صوت، مدت ویدئو یا Resolution محاسبه شود.

Routing برای Tool Calling

اگر درخواست Tools دارد، مدل و Provider باید از Tool Calling پشتیبانی کنند.

موارد مهم:

  • Function Calling
  • Strict Schema
  • Parallel Tool Calls
  • تعداد Tool
  • کیفیت انتخاب Tool
  • صحت آرگومان‌ها
  • Tool Choice
  • Streaming Tool Calls

کیفیت Provider در Tool Calling

ممکن است چند Provider یک مدل مشابه ارائه دهند، اما در پردازش Tool Call، Schema یا Streaming رفتار یکسانی نداشته باشند.

در نتیجه Routing فقط براساس نام مدل کافی نیست؛ مسیر اجرایی نیز باید ارزیابی شود.

OpenRouter برای درخواست‌های دارای ابزار، Routeهای Provider را با توجه به قابلیت و قابلیت‌اعتماد Tool Calling بهینه می‌کند. راهنمای Auto Exacto در OpenRouter

Routing برای Structured Outputs

برای خروجی JSON باید بررسی شود:

  • مدل json_schema را پشتیبانی می‌کند؟
  • Provider پارامتر را منتقل می‌کند؟
  • حالت Strict قابل‌استفاده است؟
  • Schema در محدودیت‌های مدل قرار دارد؟
  • نرخ Validation موفق چقدر است؟

Fallback به مدلی که فقط Text تولید می‌کند می‌تواند قرارداد نرم‌افزار را بشکند.

Capability Requirement:

{
  "required": [
    "chat",
    "structured_outputs"
  ],
  "schema_complexity": "medium"
}

Routing براساس پلن کاربران

ممکن است کاربران براساس پلن به مدل‌ها یا سطح کیفیت متفاوت دسترسی داشته باشند.

رایگان:
  مدل‌های اقتصادی
  Concurrency محدود
  Context محدود

حرفه‌ای:
  مدل‌های متعادل
  Context بیشتر
  Fallback بهتر

سازمانی:
  مسیرهای اختصاصی
  SLA
  Region و سیاست داده
  مدل‌های پیشرفته

اما باید تجربه حداقلی قابل‌قبول برای همه پلن‌ها حفظ شود. ارسال کاربران پلن ارزان به مدل نامناسب می‌تواند محصول را بی‌استفاده کند.

Authorization پیش از Routing

Router نباید مدلی را انتخاب کند که کاربر اجازه استفاده از آن را ندارد.

Candidate Models
→ User Permission Filter
→ Capability Filter
→ Operational Filter
→ Scoring

Routing براساس سیاست داده

در سازمان‌ها ممکن است محدودیت‌هایی وجود داشته باشد:

  • عدم ذخیره داده
  • Region مشخص
  • منع استفاده از Provider خاص
  • عدم ارسال اطلاعات شخصی
  • استفاده فقط از مدل‌های تأییدشده
  • الزام پردازش اختصاصی

این قواعد باید Hard Constraint باشند:

{
  "allowed_regions": ["eu"],
  "allowed_providers": ["provider_a", "provider_c"],
  "requires_zero_data_retention": true
}

قیمت پایین‌تر نباید سیاست امنیتی را دور بزند.

Provider Routing و Load Balancing

پس از انتخاب مدل، ممکن است چند Deployment قابل‌استفاده باشند.

Round Robin

درخواست‌ها به‌ترتیب توزیع می‌شوند:

A → B → C → A

ساده است، اما تفاوت ظرفیت و Latency را در نظر نمی‌گیرد.

Weighted Round Robin

هر مسیر وزن دارد:

Provider A: 50%
Provider B: 30%
Provider C: 20%

Least Connections

مسیری انتخاب می‌شود که درخواست فعال کمتری دارد.

Least Latency

مسیر دارای Latency کمتر انتخاب می‌شود.

Throughput-based

مسیر دارای Tokens per Second بیشتر در اولویت قرار می‌گیرد.

Cost-based

ارزان‌ترین Provider سالم انتخاب می‌شود.

Random Weighted

انتخاب تصادفی براساس وزن انجام می‌شود و برای A/B Testing یا توزیع کنترل‌شده مناسب است.

LiteLLM Router نیز Load Balancing، Retry، Cooldown و Fallback را میان Deploymentها و Providerهای مختلف مدیریت می‌کند. مستندات Router در LiteLLM

Health Check

Router نباید منتظر بماند تا درخواست واقعی کاربر مسیر خراب را کشف کند.

Health Check فعال

در بازه‌های زمانی مشخص، مسیر بررسی می‌شود:

هر ۳۰ ثانیه:
  Ping یا درخواست سبک
  بررسی Status
  اندازه‌گیری Latency
  ثبت سلامت

Health Check غیرفعال

از نتایج ترافیک واقعی استفاده می‌شود:

  • نرخ خطا
  • Timeout
  • Latency
  • Rate Limit
  • پاسخ نامعتبر

وضعیت سلامت

healthy
degraded
rate_limited
unhealthy
cooldown
unknown

Health Check فعال می‌تواند مسیر خراب را پیش از رسیدن درخواست کاربر از Pool خارج کند. Health Check Driven Routing در LiteLLM

درخواست Health Check واقعی نباید پرهزینه باشد

Health Check نباید:

  • Context طولانی داشته باشد؛
  • خروجی زیاد تولید کند؛
  • Tool حساس اجرا کند؛
  • هزینه غیرضروری ایجاد کند.

Circuit Breaker

اگر مسیر در بازه کوتاه چند بار شکست بخورد، Circuit Breaker آن را موقتاً خارج می‌کند.

Closed

مسیر فعال است.

Open

درخواست جدید به مسیر ارسال نمی‌شود.

Half-open

تعداد محدودی درخواست آزمایشی برای بررسی بازیابی ارسال می‌شود.

{
  "failure_threshold": 5,
  "window_seconds": 60,
  "cooldown_seconds": 30,
  "half_open_requests": 2
}

خطاهای مؤثر

  • Timeout
  • Connection Error
  • 5xx
  • Rate Limit گسترده
  • پاسخ خراب

خطای 400 ناشی از ورودی کاربر نباید سلامت Provider را کاهش دهد.

تفاوت Retry، Fallback و Routing

Routing

پیش از درخواست، بهترین مسیر انتخاب می‌شود.

Retry

همان مسیر یا Deployment دوباره امتحان می‌شود.

Fallback

پس از شکست، مدل یا مسیر جایگزین استفاده می‌شود.

Load Balancing

ترافیک میان چند مسیر سالم و معادل توزیع می‌شود.

یک جریان مناسب:

Route
→ Primary Provider
→ Retry محدود
→ Provider Fallback
→ Model Fallback
→ Controlled Error

Retry Budget

اگر هر Provider چند Retry و هر مدل چند Fallback داشته باشد، تعداد درخواست‌ها و هزینه می‌تواند به‌شدت افزایش یابد.

{
  "max_total_attempts": 3,
  "max_provider_attempts": 2,
  "max_model_fallbacks": 1,
  "deadline_ms": 30000,
  "max_total_cost": 0.05
}

Fallback سازگار

Fallback باید از نظر قابلیت و قرارداد با مسیر اصلی سازگار باشد.

نیازشرط مدل جایگزین
Visionپشتیبانی از تصویر
Tool Callingپشتیبانی از Tools
JSON SchemaStructured Outputs
Context طولانیظرفیت کافی
StreamingStreaming سازگار
فارسیکیفیت ارزیابی‌شده
Data PolicyProvider مجاز

تغییر مدل پس از شروع Streaming

بعد از ارسال اولین Chunk به کاربر، ادامه پاسخ با مدل دیگر معمولاً مناسب نیست. در صورت شکست:

  • Stream را ناقص پایان دهید.
  • وضعیت incomplete ثبت کنید.
  • امکان Retry از ابتدا فراهم کنید.
  • دو پاسخ متفاوت را به هم متصل نکنید.

طراحی تابع امتیازدهی

پس از فیلترکردن مسیرهای ناسازگار، می‌توان به هر گزینه امتیاز داد.

Score =
Quality Weight × Quality Score
+ Reliability Weight × Reliability Score
+ Speed Weight × Speed Score
+ Cost Weight × Cost Score

مثال:

Score =
0.40 × Quality
+ 0.25 × Reliability
+ 0.20 × Speed
+ 0.15 × Cost

تمام مقادیر باید به بازه مشترک مانند صفر تا یک Normalized شوند.

امتیاز هزینه

هزینه کمتر باید امتیاز بیشتر بگیرد:

cost_score = 1 - normalized_cost

امتیاز Latency

latency_score = 1 - normalized_latency

امتیاز سلامت

health_score = (
    0.5 * success_rate
    + 0.3 * timeout_score
    + 0.2 * availability_score
)

وزن براساس کاربرد

برای Chat:

Speed: بالا
Quality: بالا
Cost: متوسط

برای Batch:

Cost: بالا
Throughput: بالا
TTFT: کم‌اهمیت

برای تحلیل حقوقی:

Quality: بسیار بالا
Groundedness: بالا
Cost: کم‌اهمیت‌تر

Hard Constraint پیش از Score

مدلی که قابلیت لازم ندارد نباید با امتیاز قیمت بالا برنده شود.

Filter first, score second.

جلوگیری از نوسان Route

اگر امتیاز دو مدل نزدیک باشد، Router ممکن است در هر درخواست بین آن‌ها جابه‌جا شود.

راهکارها:

  • حداقل اختلاف لازم برای تغییر
  • Sticky Routing در یک Conversation
  • وزن‌دهی به مسیر فعلی
  • EWMA
  • بازه به‌روزرسانی
  • Hysteresis
  • حداقل مدت فعال‌بودن Route

Sticky Routing

در یک مکالمه بهتر است مدل بی‌دلیل تغییر نکند، زیرا:

  • سبک پاسخ متفاوت می‌شود؛
  • رفتار Tool Calling تغییر می‌کند؛
  • Tokenization و Context متفاوت‌اند؛
  • کیفیت تجربه ناپایدار می‌شود.
conversation_id → selected_route

تغییر فقط در صورت خطا، عدم قابلیت یا سیاست مشخص انجام شود.

معماری Production برای AI Router

Client
→ API Gateway
→ Authentication
→ Rate Limit
→ Billing Guard
→ Request Analyzer
→ Capability Filter
→ Policy Filter
→ Health Filter
→ Router Scoring
→ Selected Model
→ Selected Provider
→ AI Request
→ Output Validation
→ Retry/Fallback
→ Usage Recording
→ Quality Evaluation

اجزای اصلی

Model Registry

اطلاعات مدل‌ها:

{
  "model_id": "MODEL_A",
  "capabilities": [
    "text",
    "tools",
    "json_schema"
  ],
  "context_window": 128000,
  "input_price": 1.2,
  "output_price": 4.8,
  "quality_tier": "balanced"
}

Provider Registry

{
  "provider_id": "provider_a",
  "regions": ["global"],
  "data_policy": "standard",
  "priority": 1,
  "enabled": true
}

Health Store

معیارهای کوتاه‌مدت:

{
  "route_id": "provider_a/model_a",
  "status": "healthy",
  "success_rate_5m": 0.992,
  "p95_latency_ms_5m": 4200,
  "rate_limit_rate_5m": 0.01,
  "circuit_state": "closed"
}

Quality Store

نتایج Eval:

{
  "model_id": "MODEL_A",
  "task_type": "persian_support",
  "quality_score": 0.91,
  "sample_size": 2500,
  "evaluated_at": "2026-07-01"
}

Routing Policy

{
  "policy_id": "support-balanced-v3",
  "quality_weight": 0.45,
  "cost_weight": 0.15,
  "latency_weight": 0.20,
  "reliability_weight": 0.20,
  "max_cost": 0.05,
  "max_latency_ms": 15000
}

نمونه پیاده‌سازی AI Router با Python

تعریف مدل‌ها

from dataclasses import dataclass, field
from typing import Literal


@dataclass
class ModelRoute:
    model_id: str
    provider_id: str
    capabilities: set[str]
    context_window: int
    input_price_per_million: float
    output_price_per_million: float
    quality_scores: dict[str, float]
    p95_latency_ms: float
    success_rate: float
    healthy: bool = True
    allowed_plans: set[str] = field(
        default_factory=lambda: {
            "free",
            "pro",
            "enterprise",
        }
    )


@dataclass
class RoutingRequest:
    task_type: str
    required_capabilities: set[str]
    estimated_input_tokens: int
    max_output_tokens: int
    plan: Literal["free", "pro", "enterprise"]
    max_cost: float
    max_latency_ms: float

تخمین هزینه

def estimate_cost(
    route: ModelRoute,
    request: RoutingRequest,
) -> float:
    input_cost = (
        request.estimated_input_tokens
        / 1_000_000
        * route.input_price_per_million
    )

    output_cost = (
        request.max_output_tokens
        / 1_000_000
        * route.output_price_per_million
    )

    return input_cost + output_cost

فیلتر مسیرها

def is_compatible(
    route: ModelRoute,
    request: RoutingRequest,
) -> bool:
    if not route.healthy:
        return False

    if request.plan not in route.allowed_plans:
        return False

    if not request.required_capabilities.issubset(
        route.capabilities
    ):
        return False

    required_context = (
        request.estimated_input_tokens
        + request.max_output_tokens
    )

    if required_context > route.context_window:
        return False

    estimated_cost = estimate_cost(route, request)

    if estimated_cost > request.max_cost:
        return False

    return True

Normalization

def clamp(value: float) -> float:
    return max(0.0, min(1.0, value))


def cost_score(
    estimated_cost: float,
    max_cost: float,
) -> float:
    if max_cost <= 0:
        return 0.0

    return clamp(1 - estimated_cost / max_cost)


def latency_score(
    latency_ms: float,
    max_latency_ms: float,
) -> float:
    if max_latency_ms <= 0:
        return 0.0

    return clamp(1 - latency_ms / max_latency_ms)

امتیاز نهایی

def score_route(
    route: ModelRoute,
    request: RoutingRequest,
) -> float:
    quality = route.quality_scores.get(
        request.task_type,
        route.quality_scores.get("default", 0.5),
    )

    estimated_cost = estimate_cost(route, request)

    return (
        0.45 * quality
        + 0.20 * route.success_rate
        + 0.20 * latency_score(
            route.p95_latency_ms,
            request.max_latency_ms,
        )
        + 0.15 * cost_score(
            estimated_cost,
            request.max_cost,
        )
    )

انتخاب مسیر

def select_route(
    routes: list[ModelRoute],
    request: RoutingRequest,
) -> tuple[ModelRoute, list[ModelRoute]]:
    compatible_routes = [
        route
        for route in routes
        if is_compatible(route, request)
    ]

    if not compatible_routes:
        raise ValueError("no_compatible_model_route")

    ranked = sorted(
        compatible_routes,
        key=lambda route: score_route(route, request),
        reverse=True,
    )

    return ranked[0], ranked[1:]

فراخوانی API درواره

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["DARVAREH_API_KEY"],
    base_url="https://api.darvareh.ir/v1",
)


def call_selected_route(
    route: ModelRoute,
    messages: list[dict],
    max_tokens: int,
):
    return client.chat.completions.create(
        model=route.model_id,
        messages=messages,
        max_tokens=max_tokens,
        temperature=0.2,
    )

در یک API یکپارچه، model_id شناسه مدلی است که از فهرست مدل‌های درواره انتخاب می‌کنید. نحوه انتخاب Provider بالادستی می‌تواند در لایه زیرساخت انجام شود و قابلیت‌های قابل‌کنترل برای هر مدل باید از مستندات و Metadata همان مدل بررسی شوند.

اجرای Fallback در Python

import time
from openai import (
    APIConnectionError,
    APITimeoutError,
    RateLimitError,
    APIStatusError,
)


RETRYABLE_STATUS_CODES = {
    408,
    429,
    500,
    502,
    503,
    504,
}


def should_fallback(error: Exception) -> bool:
    if isinstance(
        error,
        (
            APIConnectionError,
            APITimeoutError,
            RateLimitError,
        ),
    ):
        return True

    if isinstance(error, APIStatusError):
        return (
            error.status_code
            in RETRYABLE_STATUS_CODES
        )

    return False


def execute_with_fallback(
    primary: ModelRoute,
    alternatives: list[ModelRoute],
    messages: list[dict],
    max_tokens: int,
):
    routes = [primary, *alternatives[:2]]
    errors = []

    for attempt, route in enumerate(routes, start=1):
        started_at = time.monotonic()

        try:
            response = call_selected_route(
                route=route,
                messages=messages,
                max_tokens=max_tokens,
            )

            latency_ms = int(
                (time.monotonic() - started_at) * 1000
            )

            return {
                "response": response,
                "route": route,
                "attempt": attempt,
                "latency_ms": latency_ms,
                "fallback_used": attempt > 1,
            }

        except Exception as error:
            errors.append(
                {
                    "route": (
                        f"{route.provider_id}/"
                        f"{route.model_id}"
                    ),
                    "error": type(error).__name__,
                }
            )

            if not should_fallback(error):
                raise

    raise RuntimeError(
        {
            "code": "all_routes_failed",
            "attempts": errors,
        }
    )

در Production باید Deadline، Circuit Breaker، هزینه تجمعی، Idempotency و Retry داخلی SDK نیز مدیریت شوند.

نمونه پیاده‌سازی TypeScript

انواع داده

type Capability =
  | "text"
  | "vision"
  | "tools"
  | "json_schema"
  | "streaming"
  | "long_context";

type Plan = "free" | "pro" | "enterprise";

interface ModelRoute {
  modelId: string;
  providerId: string;
  capabilities: Set<Capability>;
  contextWindow: number;
  inputPricePerMillion: number;
  outputPricePerMillion: number;
  qualityScores: Record<string, number>;
  p95LatencyMs: number;
  successRate: number;
  healthy: boolean;
  allowedPlans: Set<Plan>;
}

interface RoutingRequest {
  taskType: string;
  requiredCapabilities: Set<Capability>;
  estimatedInputTokens: number;
  maxOutputTokens: number;
  plan: Plan;
  maxCost: number;
  maxLatencyMs: number;
}

محاسبه هزینه و سازگاری

function estimateCost(
  route: ModelRoute,
  request: RoutingRequest,
): number {
  const inputCost =
    (request.estimatedInputTokens / 1_000_000) *
    route.inputPricePerMillion;

  const outputCost =
    (request.maxOutputTokens / 1_000_000) *
    route.outputPricePerMillion;

  return inputCost + outputCost;
}

function isCompatible(
  route: ModelRoute,
  request: RoutingRequest,
): boolean {
  if (!route.healthy) return false;
  if (!route.allowedPlans.has(request.plan)) return false;

  for (const capability of request.requiredCapabilities) {
    if (!route.capabilities.has(capability)) {
      return false;
    }
  }

  const requiredContext =
    request.estimatedInputTokens +
    request.maxOutputTokens;

  if (requiredContext > route.contextWindow) {
    return false;
  }

  if (estimateCost(route, request) > request.maxCost) {
    return false;
  }

  return true;
}

امتیازدهی و انتخاب

function clamp(value: number): number {
  return Math.max(0, Math.min(1, value));
}

function scoreRoute(
  route: ModelRoute,
  request: RoutingRequest,
): number {
  const quality =
    route.qualityScores[request.taskType] ??
    route.qualityScores.default ??
    0.5;

  const estimatedCost = estimateCost(route, request);

  const costScore = clamp(
    1 - estimatedCost / request.maxCost,
  );

  const latencyScore = clamp(
    1 - route.p95LatencyMs / request.maxLatencyMs,
  );

  return (
    0.45 * quality +
    0.2 * route.successRate +
    0.2 * latencyScore +
    0.15 * costScore
  );
}

function rankRoutes(
  routes: ModelRoute[],
  request: RoutingRequest,
): ModelRoute[] {
  return routes
    .filter((route) => isCompatible(route, request))
    .sort(
      (a, b) =>
        scoreRoute(b, request) -
        scoreRoute(a, request),
    );
}

اتصال به درواره

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.DARVAREH_API_KEY,
  baseURL: "https://api.darvareh.ir/v1",
});

async function callRoute(
  route: ModelRoute,
  messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[],
  maxTokens: number,
) {
  return client.chat.completions.create({
    model: route.modelId,
    messages,
    max_tokens: maxTokens,
    temperature: 0.2,
  });
}

Semantic Router با یک مدل سبک

برای تشخیص نوع درخواست می‌توان از خروجی ساختاریافته استفاده کرد:

{
  "task_type": "coding",
  "complexity": "medium",
  "required_capabilities": [
    "text",
    "tools"
  ],
  "confidence": 0.91
}

System Prompt:

وظیفه شما فقط تحلیل نیاز فنی درخواست است.
به سؤال کاربر پاسخ ندهید.
نوع وظیفه، پیچیدگی، قابلیت‌های لازم و میزان اطمینان را مشخص کنید.

هزینه Router Call

اگر برای هر درخواست ابتدا یک مدل دیگر فراخوانی شود:

  • Latency افزایش پیدا می‌کند.
  • هزینه Router اضافه می‌شود.
  • یک نقطه شکست جدید ایجاد می‌شود.

برای درخواست‌های واضح بهتر است ابتدا Rules اجرا شوند و فقط درخواست‌های مبهم به Semantic Classifier ارسال شوند.

Rules
→ اگر تصمیم قطعی بود: Route
→ اگر مبهم بود: Semantic Classifier
→ اگر Confidence پایین بود: Default Safe Route

Cache تصمیم‌های Routing

اگر درخواست‌های مشابه زیادند، می‌توان تصمیم Intent یا Route را Cache کرد.

Cache Key باید موارد مؤثر را در نظر بگیرد:

normalized_request_hash
+ router_version
+ policy_version
+ user_plan
+ capability_requirements

اما Health و Provider State نباید برای مدت طولانی Cache شوند. بهتر است دو تصمیم جدا داشته باشیم:

  1. انتخاب Model Class
  2. انتخاب Provider لحظه‌ای

انتخاب Model Class می‌تواند Cache شود، اما Provider باید براساس سلامت تازه انتخاب شود.

Routing و Prompt Caching

اگر Prompt Prefix بزرگی Cache شده باشد، تغییر مدل یا Provider ممکن است Cache Hit را از بین ببرد.

Router باید هزینه Cache Miss را در نظر بگیرد:

Route A:
قیمت پایه کمتر
Cache Miss

Route B:
قیمت پایه کمی بیشتر
Cache Hit بالا

گاهی Route B در هزینه واقعی و Latency بهتر است.

Observability برای AI Router

بدون Observability نمی‌توان فهمید Router واقعاً تصمیم‌های خوبی می‌گیرد یا نه.

داده‌های هر تصمیم

{
  "request_id": "req_2048",
  "router_version": "router-v5",
  "policy_version": "balanced-v3",
  "task_type": "structured_extraction",
  "required_capabilities": [
    "vision",
    "json_schema"
  ],
  "candidate_count": 8,
  "compatible_count": 3,
  "selected_model": "MODEL_A",
  "selected_provider": "provider_b",
  "route_score": 0.87,
  "estimated_cost": 0.021,
  "fallback_used": false,
  "decision_latency_ms": 4
}

Metricهای Router

  • Route Selection Count
  • Router Decision Latency
  • No Compatible Route Rate
  • Fallback Rate
  • Retry Rate
  • Route Success Rate
  • Route Quality Score
  • Cost per Route
  • Latency per Route
  • Override Rate
  • Capability Mismatch
  • Budget Rejection Rate
  • Circuit Open Rate

Decision Explanation

برای Debug بهتر است دلایل انتخاب ثبت شوند:

{
  "selected_because": [
    "supports_vision",
    "supports_json_schema",
    "within_budget",
    "highest_quality_score"
  ],
  "excluded_routes": {
    "MODEL_B": "missing_json_schema",
    "MODEL_C": "context_window_too_small",
    "MODEL_D": "provider_unhealthy"
  }
}

این توضیح از نظر عملیاتی بسیار ارزشمند است.

ارزیابی AI Router

Router را نباید فقط براساس نرخ موفقیت API ارزیابی کرد.

Router Accuracy

آیا Route انتخاب‌شده با Route مطلوب Dataset برابر بوده است؟

Regret

اختلاف نتیجه انتخاب Router با بهترین انتخاب ممکن:

Routing Regret =
Best Possible Utility - Selected Route Utility

Over-routing Rate

درخواست‌های ساده‌ای که بی‌دلیل به مدل گران ارسال شده‌اند.

Under-routing Rate

درخواست‌های پیچیده‌ای که به مدل ناکافی ارسال شده‌اند.

Escalation Rate

چند درخواست پس از شکست مدل کوچک به مدل قوی‌تر منتقل شده‌اند؟

Cost Saving

Cost Saving =
Fixed Strong Model Cost - Routed Cost

Quality Delta

Quality Delta =
Routed Quality - Fixed Baseline Quality

صرفه‌جویی هزینه نباید با افت غیرقابل‌قبول کیفیت همراه باشد.

A/B Testing

برای مقایسه دو سیاست Router:

Policy A: ۵۰٪
Policy B: ۵۰٪

معیارها:

  • Task Success
  • هزینه
  • Latency
  • Feedback
  • Fallback
  • Retry
  • Quality Score

Sticky Assignment

یک کاربر یا Conversation باید تا حد امکان در یک گروه باقی بماند:

bucket = hash(user_id) % 100

بدون Sticky Assignment، کاربر ممکن است در هر پیام تجربه متفاوتی دریافت کند.

Shadow Routing

در Shadow Routing پاسخ مسیر جدید به کاربر نمایش داده نمی‌شود:

Request
  ├── Production Route → User
  └── Shadow Route → Evaluation only

مزایا:

  • مقایسه روی ترافیک واقعی
  • بدون تغییر تجربه کاربر
  • مناسب بررسی مدل و سیاست جدید

محدودیت‌ها:

  • هزینه اضافی
  • پردازش مضاعف داده
  • نیاز به رعایت سیاست‌های حریم خصوصی
  • Toolهای Write نباید در Shadow اجرا شوند

Canary Routing

در ابتدا درصد کمی از ترافیک به Router جدید داده می‌شود:

Router فعلی: ۹۵٪
Router جدید: ۵٪

اگر کیفیت، هزینه و خطا مناسب بودند، سهم افزایش می‌یابد.

Rollback

Router Policy، Model Registry و Weightها باید نسخه‌بندی و قابل Rollback باشند.

Human Override

در بعضی کاربردها باید امکان انتخاب مستقیم مدل وجود داشته باشد.

{
  "routing_mode": "manual",
  "model": "MODEL_ID"
}

یا:

{
  "routing_mode": "auto",
  "preference": "quality"
}

حالت‌های پیشنهادی:

Auto
Fast
Balanced
Quality
Lowest Cost
Manual

اما حتی در حالت Manual باید دسترسی، سلامت، بودجه و قابلیت بررسی شوند.

امنیت AI Router

Router نباید Authorization را دور بزند

مدل جایگزین باید در فهرست مجاز کاربر باشد.

Fallback نباید سیاست داده را تغییر دهد

اگر Provider اصلی Zero Data Retention دارد، Fallback به Provider فاقد این سیاست ممکن است مجاز نباشد.

Prompt Router با داده حساس

اگر برای Routing از یک مدل Classifier استفاده می‌کنید، خود درخواست کاربر به آن مدل نیز ارسال می‌شود. باید بررسی کنید:

  • آیا ارسال کل متن لازم است؟
  • می‌توان Metadata یا نسخه Redacted ارسال کرد؟
  • Provider مجاز است؟
  • داده ثبت می‌شود؟

Tool Routing

Router نباید ابزارهای حساس را فقط براساس Intent مدل فعال کند. مجوز Backend مستقل لازم است.

Tenant Isolation

State سلامت مشترک است، اما سیاست، Budget و Cache کاربران و سازمان‌ها باید جدا باشند.

خطاهای رایج

انتخاب همیشه ارزان‌ترین مدل

هزینه هر درخواست کاهش می‌یابد، اما Retry و شکست افزایش پیدا می‌کند.

ترکیب Capability و Score

مدل فاقد قابلیت نباید صرفاً به‌دلیل قیمت امتیاز بگیرد.

استفاده از Latency میانگین

p95، TTFT و داده کوتاه‌مدت معمولاً اطلاعات بهتری می‌دهند.

نبود Sticky Routing

رفتار مدل در یک مکالمه ناپایدار می‌شود.

Fallback بدون Validation

مدل جایگزین ممکن است قرارداد خروجی را رعایت نکند.

Retry در چند لایه

SDK، Router و اپلیکیشن ممکن است هم‌زمان Retry کنند و هزینه را چند برابر سازند.

Health Check فقط واکنشی

اولین درخواست کاربر خرابی مسیر را کشف می‌کند.

به‌روزرسانی فوری وزن‌ها

Router به نویز کوتاه‌مدت بیش‌ازحد واکنش نشان می‌دهد.

نبود Versioning

مشخص نیست هر پاسخ با کدام سیاست Routing تولید شده است.

نادیده‌گرفتن Cache

مسیر ارزان‌تر ممکن است به‌دلیل Cache Miss گران‌تر تمام شود.

تغییر مدل پس از شروع Stream

پاسخ ناهمگون یا خراب به کاربر می‌رسد.

Shadow روی ابزارهای تغییردهنده

ممکن است عملیات واقعی دو بار انجام شود.

ارزیابی فقط با Benchmark عمومی

عملکرد واقعی باید روی داده و وظایف محصول شما سنجیده شود.

چک‌لیست AI Router برای Production

Model Registry

  • قابلیت‌های هر مدل ثبت شده‌اند.
  • Context Window مشخص است.
  • قیمت ورودی و خروجی به‌روز است.
  • قابلیت Streaming ثبت شده است.
  • Tool Calling و Structured Outputs مشخص‌اند.
  • کیفیت به تفکیک وظیفه ثبت شده است.
  • مدل‌های منقضی غیرفعال می‌شوند.
  • Metadata نسخه‌بندی شده است.

درخواست

  • نوع ورودی تشخیص داده می‌شود.
  • قابلیت‌های ضروری استخراج می‌شوند.
  • Token ورودی تخمین زده می‌شود.
  • ظرفیت خروجی رزرو می‌شود.
  • بودجه کاربر بررسی می‌شود.
  • پلن و مجوز بررسی می‌شوند.
  • سیاست داده اعمال می‌شود.
  • Deadline مشخص است.

Routing

  • ابتدا Hard Constraintها اعمال می‌شوند.
  • سپس مسیرها امتیاز می‌گیرند.
  • کیفیت Task-specific است.
  • Latency با داده‌های جدید به‌روزرسانی می‌شود.
  • هزینه واقعی تخمین زده می‌شود.
  • مسیر پیش‌فرض امن وجود دارد.
  • تصمیم Router قابل‌توضیح است.
  • Sticky Routing در Conversation لحاظ شده است.
  • Router Version ثبت می‌شود.

Provider و سلامت

  • Health Check فعال وجود دارد.
  • سلامت از ترافیک واقعی نیز محاسبه می‌شود.
  • Circuit Breaker وجود دارد.
  • مسیرهای Rate-limited مدیریت می‌شوند.
  • Cooldown تعریف شده است.
  • Region و Data Policy بررسی می‌شوند.
  • ظرفیت RPM و TPM در تصمیم لحاظ می‌شود.

Retry و Fallback

  • Retry فقط برای خطاهای موقت است.
  • تعداد تلاش کل محدود است.
  • Deadline کل رعایت می‌شود.
  • هزینه تجمعی کنترل می‌شود.
  • Fallback از نظر قابلیت سازگار است.
  • Fallback مجوز کاربر را رعایت می‌کند.
  • Provider Fallback و Model Fallback جدا هستند.
  • Fallback Loop غیرممکن است.
  • بعد از شروع Stream مدل تغییر نمی‌کند.

Observability

  • تمام Candidateها و دلایل حذف ثبت می‌شوند.
  • Route انتخابی ثبت می‌شود.
  • امتیاز مسیر ثبت می‌شود.
  • هزینه تخمینی و واقعی مقایسه می‌شوند.
  • Router Decision Latency اندازه‌گیری می‌شود.
  • Retry و Fallback قابل‌مشاهده‌اند.
  • کیفیت به Route مرتبط است.
  • Provider Request ID ثبت می‌شود.
  • Dashboard مدل و Provider وجود دارد.

Evaluation و انتشار

  • Dataset واقعی Routing وجود دارد.
  • Baseline با مدل ثابت مقایسه می‌شود.
  • Over-routing اندازه‌گیری می‌شود.
  • Under-routing اندازه‌گیری می‌شود.
  • Cost Saving محاسبه می‌شود.
  • Quality Delta بررسی می‌شود.
  • سیاست جدید Shadow Test می‌شود.
  • Canary Release وجود دارد.
  • Rollback سریع امکان‌پذیر است.

امنیت

  • Authorization پیش از Routing انجام می‌شود.
  • Fallback سیاست داده را تغییر نمی‌دهد.
  • داده حساس برای Classifier محدود می‌شود.
  • Toolهای Write در Shadow اجرا نمی‌شوند.
  • Cache میان Tenantها جداست.
  • عملیات حساس Audit می‌شوند.
  • API Key در Client قرار نمی‌گیرد.

پرسش‌های متداول

AI Router چیست؟

AI Router لایه‌ای است که با بررسی نوع درخواست، قابلیت مدل‌ها، قیمت، سرعت، کیفیت، سلامت و سیاست‌های دسترسی، مناسب‌ترین مدل و Provider را برای هر درخواست انتخاب می‌کند.

تفاوت AI Router و API Gateway چیست؟

API Gateway وظایفی مانند احراز هویت، Rate Limit، Logging و Billing را انجام می‌دهد. AI Router درباره انتخاب مدل و مسیر پردازش تصمیم می‌گیرد. این دو می‌توانند در یک زیرساخت کنار هم قرار گیرند.

تفاوت AI Router و Load Balancer چیست؟

Load Balancer معمولاً ترافیک را میان Deploymentهای مشابه توزیع می‌کند. AI Router می‌تواند میان مدل‌های متفاوت و براساس معنا، قابلیت، کیفیت و هزینه انتخاب کند.

Semantic Routing چیست؟

Semantic Routing معنای درخواست را تحلیل و Intent یا نوع وظیفه را تشخیص می‌دهد تا آن را به مدل، Agent یا Workflow مناسب هدایت کند.

آیا AI Router همیشه ارزان‌ترین مدل را انتخاب می‌کند؟

خیر. Router مناسب میان هزینه، کیفیت، سرعت، قابلیت و پایداری تعادل ایجاد می‌کند. ارزان‌ترین مدل ممکن است به‌دلیل Retry یا کیفیت پایین درنهایت گران‌تر باشد.

چگونه Router پیچیدگی درخواست را تشخیص می‌دهد؟

با Ruleها، طول Context، تعداد اسناد، نیاز به Tools، نوع خروجی، Embedding، Classifier یا یک مدل سبک می‌توان Complexity را تخمین زد.

Fallback چه تفاوتی با Routing دارد؟

Routing پیش از ارسال درخواست مسیر اصلی را انتخاب می‌کند. Fallback پس از شکست مسیر اصلی، درخواست را به مسیر سازگار دیگری منتقل می‌کند.

آیا می‌توان پس از شروع Streaming مدل را تغییر داد؟

معمولاً نباید این کار را انجام داد. بخشی از پاسخ قبلاً به کاربر ارسال شده و ادامه آن با مدل دیگر می‌تواند ناسازگار باشد. بهتر است Stream ناقص پایان یابد و امکان تلاش مجدد فراهم شود.

آیا Router به مدل هوش مصنوعی نیاز دارد؟

الزاماً خیر. بسیاری از Routerهای موفق با Rules و Metadata شروع می‌شوند. برای درخواست‌های مبهم می‌توان از Classifier، Embedding یا LLM استفاده کرد.

چگونه کیفیت مدل‌ها را برای Routing اندازه‌گیری کنیم؟

با Dataset داخلی، Task Completion، Validation Rate، Groundedness، Tool Success، بازخورد کاربران و ارزیابی انسانی. کیفیت باید به تفکیک نوع وظیفه اندازه‌گیری شود.

چگونه از نوسان میان مدل‌ها جلوگیری کنیم؟

از Sticky Routing، EWMA، حداقل اختلاف امتیاز، Hysteresis و بازه‌های به‌روزرسانی استفاده کنید.

آیا AI Router هزینه را کاهش می‌دهد؟

اگر درست طراحی شود، درخواست‌های ساده را به مدل‌های اقتصادی و درخواست‌های دشوار را به مدل‌های مناسب می‌فرستد. صرفه‌جویی باید همراه با Quality Delta و هزینه هر وظیفه موفق سنجیده شود.

آیا می‌توان AI Router را با API درواره پیاده‌سازی کرد؟

بله. اپلیکیشن می‌تواند مدل مناسب را انتخاب و درخواست را با API سازگار با OpenAI درواره ارسال کند:

https://api.darvareh.ir/v1

Routing پیشرفته می‌تواند در Backend اپلیکیشن یا در لایه زیرساخت اجرا شود.

جمع‌بندی

AI Router یکی از مهم‌ترین اجزای زیرساخت اپلیکیشن‌های چندمدلی است. این لایه به نرم‌افزار اجازه می‌دهد برای هر درخواست، به‌جای استفاده از یک مدل ثابت، مسیر مناسب‌تری انتخاب کند.

یک Router حرفه‌ای باید:

  • نیازهای درخواست را استخراج کند؛
  • مدل‌های فاقد قابلیت را حذف کند؛
  • Context Window را بررسی کند؛
  • مجوز، پلن و سیاست داده را رعایت کند؛
  • سلامت Provider را در نظر بگیرد؛
  • میان کیفیت، هزینه، Latency و پایداری تعادل ایجاد کند؛
  • Fallback سازگار داشته باشد؛
  • تصمیم خود را ثبت و قابل‌توضیح کند؛
  • و با داده‌های Evaluation و Production بهبود یابد.

بهترین مسیر الزاماً ارزان‌ترین، سریع‌ترین یا قوی‌ترین مدل نیست. بهترین مسیر مدلی است که برای همان درخواست، با محدودیت‌های همان کاربر و در شرایط فعلی زیرساخت، بیشترین ارزش مورد انتظار را ایجاد کند.

دسترسی به مدل‌های هوش مصنوعی با API درواره

درواره زیرساخت دسترسی به مدل‌های مختلف هوش مصنوعی را از طریق یک API سازگار با OpenAI فراهم می‌کند. توسعه‌دهندگان می‌توانند در Backend خود، Routing را براساس نوع وظیفه، قابلیت، هزینه و کیفیت انجام دهند و مدل منتخب را از طریق یک اتصال فراخوانی کنند.

آدرس پایه API درواره:

https://api.darvareh.ir/v1

استفاده از یک رابط یکپارچه، تغییر مدل، اجرای Fallback و توسعه معماری‌های چندمدلی را ساده‌تر می‌کند؛ بااین‌حال، قابلیت‌ها، پارامترها و Context Window هر مدل باید پیش از قرارگرفتن در Routing Policy بررسی شوند.

مقالات مرتبط

Read more