إطار عمل Guardrails AI

تكامل LiteLLM

3 دقيقة للقراءة

يوفر LiteLLM واجهة موحدة لأكثر من 100 مزود LLM. بالجمع مع Guardrails AI، تحصل على مخرجات متحققة عبر أي نموذج مع احتياطي تلقائي وموازنة الحمل.

إعداد LiteLLM

pip install litellm
import litellm

# تكوين مفاتيح API
import os
os.environ["OPENAI_API_KEY"] = "sk-..."
os.environ["ANTHROPIC_API_KEY"] = "sk-ant-..."
os.environ["AZURE_API_KEY"] = "..."
os.environ["AZURE_API_BASE"] = "https://your-resource.openai.azure.com"

LiteLLM الأساسي مع Guardrails

from guardrails import Guard
from pydantic import BaseModel, Field
import litellm

class AnalysisResult(BaseModel):
    summary: str = Field(description="ملخص التحليل")
    key_findings: list[str] = Field(description="النتائج الرئيسية")
    confidence: float = Field(ge=0, le=1, description="درجة الثقة")

guard = Guard.for_pydantic(AnalysisResult)

# استخدم أي نموذج مدعوم من LiteLLM
result = guard(
    model="gpt-4o",  # OpenAI
    messages=[{"role": "user", "content": "حلل تقرير أرباح Q3"}]
)

# تبديل المزودين بسهولة
result = guard(
    model="claude-3-5-sonnet-20241022",  # Anthropic
    messages=[{"role": "user", "content": "حلل تقرير أرباح Q3"}]
)

result = guard(
    model="azure/gpt-4o",  # Azure OpenAI
    messages=[{"role": "user", "content": "حلل تقرير أرباح Q3"}]
)

تكوين الاحتياطي

from guardrails import Guard
import litellm
from litellm import Router

# تكوين سلسلة الاحتياطي
router = Router(
    model_list=[
        {
            "model_name": "gpt-4",
            "litellm_params": {
                "model": "gpt-4o",
                "api_key": os.environ["OPENAI_API_KEY"]
            }
        },
        {
            "model_name": "gpt-4",
            "litellm_params": {
                "model": "azure/gpt-4o",
                "api_key": os.environ["AZURE_API_KEY"],
                "api_base": os.environ["AZURE_API_BASE"]
            }
        },
        {
            "model_name": "gpt-4",
            "litellm_params": {
                "model": "claude-3-5-sonnet-20241022",
                "api_key": os.environ["ANTHROPIC_API_KEY"]
            }
        }
    ],
    fallbacks=[
        {"gpt-4": ["azure/gpt-4o", "claude-3-5-sonnet-20241022"]}
    ],
    retry_after=5  # إعادة المحاولة بعد 5 ثواني
)

guard = Guard.for_pydantic(AnalysisResult)

# استخدم الموجه للاحتياطي التلقائي
async def analyze_with_fallback(content: str):
    try:
        response = await router.acompletion(
            model="gpt-4",
            messages=[{"role": "user", "content": content}]
        )
        return guard.parse(response.choices[0].message.content)
    except Exception as e:
        # الموجه يحاول الاحتياطيات تلقائياً
        raise

التوجيه المحسن للتكلفة

from litellm import Router
from guardrails import Guard

# التوجيه بناءً على التعقيد
router = Router(
    model_list=[
        # نماذج رخيصة للمهام البسيطة
        {
            "model_name": "simple",
            "litellm_params": {
                "model": "gpt-4o-mini",
                "api_key": os.environ["OPENAI_API_KEY"]
            }
        },
        # نماذج مكلفة للمهام المعقدة
        {
            "model_name": "complex",
            "litellm_params": {
                "model": "gpt-4o",
                "api_key": os.environ["OPENAI_API_KEY"]
            }
        }
    ]
)

class TaskRouter:
    def __init__(self, guard: Guard):
        self.guard = guard
        self.router = router

    async def route(self, task: str, complexity: str = "auto") -> dict:
        """توجيه المهمة للنموذج المناسب بناءً على التعقيد."""
        if complexity == "auto":
            complexity = self._estimate_complexity(task)

        model = "simple" if complexity == "low" else "complex"

        result = self.guard(
            model=self.router.model_list[0 if model == "simple" else 1]["litellm_params"]["model"],
            messages=[{"role": "user", "content": task}]
        )

        return {
            "result": result.validated_output,
            "model_used": model,
            "estimated_cost": self._estimate_cost(model, task)
        }

    def _estimate_complexity(self, task: str) -> str:
        """تقدير التعقيد البسيط."""
        complex_keywords = ["analyze", "compare", "synthesize", "evaluate"]
        return "high" if any(kw in task.lower() for kw in complex_keywords) else "low"

    def _estimate_cost(self, model: str, task: str) -> float:
        """تقدير التكلفة بناءً على النموذج وطول المدخل."""
        costs = {"simple": 0.00015, "complex": 0.005}  # لكل 1K رمز
        tokens = len(task.split()) * 1.3  # تقدير تقريبي للرموز
        return costs[model] * tokens / 1000

تحديد المعدل والحصص

from litellm import Router
import asyncio
from datetime import datetime, timedelta

class RateLimitedRouter:
    """موجه مع تحديد المعدل لكل نموذج."""

    def __init__(self, guard: Guard):
        self.guard = guard
        self.request_counts = {}
        self.rate_limits = {
            "gpt-4o": 60,        # 60 طلب في الدقيقة
            "gpt-4o-mini": 200,  # 200 طلب في الدقيقة
            "claude-3-5-sonnet-20241022": 40   # 40 طلب في الدقيقة
        }
        self.router = Router(
            model_list=[
                {"model_name": "primary", "litellm_params": {"model": "gpt-4o"}},
                {"model_name": "fallback", "litellm_params": {"model": "gpt-4o-mini"}},
            ]
        )

    async def completion(self, model: str, messages: list) -> dict:
        """إكمال مع الوعي بحد المعدل."""
        await self._wait_for_rate_limit(model)

        result = self.guard(
            model=model,
            messages=messages
        )

        self._record_request(model)
        return result

    async def _wait_for_rate_limit(self, model: str):
        """انتظار إذا كان سيتم تجاوز حد المعدل."""
        limit = self.rate_limits.get(model, 60)
        current = self._get_request_count(model)

        if current >= limit:
            wait_time = 60 - (datetime.now().second)
            await asyncio.sleep(wait_time)

    def _record_request(self, model: str):
        """تسجيل طلب لتحديد المعدل."""
        now = datetime.now()
        minute_key = now.strftime("%Y%m%d%H%M")

        if model not in self.request_counts:
            self.request_counts[model] = {}

        self.request_counts[model][minute_key] = \
            self.request_counts[model].get(minute_key, 0) + 1

    def _get_request_count(self, model: str) -> int:
        """الحصول على عدد الطلبات للدقيقة الحالية."""
        minute_key = datetime.now().strftime("%Y%m%d%H%M")
        return self.request_counts.get(model, {}).get(minute_key, 0)

البث مع Guardrails

from guardrails import Guard
import litellm

guard = Guard.for_pydantic(AnalysisResult)

async def stream_with_validation(prompt: str):
    """بث الاستجابة والتحقق في النهاية."""
    full_response = ""

    async for chunk in await litellm.acompletion(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}],
        stream=True
    ):
        if chunk.choices[0].delta.content:
            content = chunk.choices[0].delta.content
            full_response += content
            yield {"type": "chunk", "content": content}

    # التحقق من الاستجابة الكاملة
    try:
        validated = guard.parse(full_response)
        yield {"type": "validated", "result": validated}
    except Exception as e:
        yield {"type": "error", "error": str(e)}

مغلف الإنتاج

from guardrails import Guard
from pydantic import BaseModel
import litellm
from typing import TypeVar, Type
import logging

T = TypeVar("T", bound=BaseModel)

class GuardedLLM:
    """مغلف LLM جاهز للإنتاج مع Guardrails."""

    def __init__(
        self,
        primary_model: str = "gpt-4o",
        fallback_model: str = "gpt-4o-mini",
        max_retries: int = 3
    ):
        self.primary_model = primary_model
        self.fallback_model = fallback_model
        self.max_retries = max_retries
        self.logger = logging.getLogger(__name__)

    async def generate(
        self,
        schema: Type[T],
        prompt: str,
        system_prompt: str = None,
        num_reasks: int = 2
    ) -> T:
        """توليد استجابة متحققة."""
        guard = Guard.for_pydantic(schema)

        messages = []
        if system_prompt:
            messages.append({"role": "system", "content": system_prompt})
        messages.append({"role": "user", "content": prompt})

        # جرب النموذج الأساسي
        try:
            result = guard(
                model=self.primary_model,
                messages=messages,
                num_reasks=num_reasks
            )

            if result.validated_output:
                return result.validated_output

        except Exception as e:
            self.logger.warning(f"فشل النموذج الأساسي: {e}")

        # الاحتياطي
        try:
            result = guard(
                model=self.fallback_model,
                messages=messages,
                num_reasks=num_reasks + 1  # إعادة محاولة إضافية للاحتياطي
            )

            if result.validated_output:
                return result.validated_output

        except Exception as e:
            self.logger.error(f"فشل النموذج الاحتياطي: {e}")
            raise

        raise ValueError("فشل في توليد استجابة صالحة")

# الاستخدام
llm = GuardedLLM()

result = await llm.generate(
    schema=AnalysisResult,
    prompt="حلل اتجاهات السوق للربع الرابع",
    system_prompt="أنت محلل مالي."
)

نصيحة LiteLLM: استخدم بادئات متغيرات البيئة للتكوينات الخاصة بالمزود: OPENAI_API_KEY، ANTHROPIC_API_KEY، AZURE_API_KEY، إلخ. يلتقطها LiteLLM تلقائياً.

التالي: أنماط نشر الإنتاج والمراقبة. :::

اختبار

الوحدة 5: إطار عمل Guardrails AI

خذ الاختبار
نشرة أسبوعية مجانية

ابقَ على مسار النيرد

بريد واحد أسبوعياً — دورات، مقالات معمّقة، أدوات، وتجارب ذكاء اصطناعي.

بدون إزعاج. إلغاء الاشتراك في أي وقت.