التنبيه بشأن تدهور زمن الاستجابة والتكلفة والجودة
حدّدوا عتبات تنبيه لزمن الاستجابة عند p99، وتكلفة كل طلب، ودرجات الجودة الآلية، ووجّهوا التنبيهات إلى Slack أو PagerDuty عند تدهور مسار LLM.
التنبيه بشأن تدهور زمن الاستجابة والتكلفة والجودة درس مجاني في AI Engineering Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Engineering Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
لماذا تُعدّ التنبيهات مهمة لأنظمة LLM
تفشل تطبيقات LLM بطرق دقيقة وتدريجية. فقد تؤدي تغييرات المطالبة إلى زيادة متوسط زمن الاستجابة بنسبة 30%، وقد يؤدي تحسين الاسترجاع إلى خفض طفيف في جودة الإجابة، أو قد يؤدي ارتفاع الاستخدام إلى تجاوز التكاليف اليومية للميزانية بمقدار خمسة أضعاف. ومن دون تنبيهات استباقية، لن تكتشفوا هذه المشكلات إلا عندما يشتكي المستخدمون أو تصل الفاتورة الشهرية. تحوّل التنبيهات معالجة المشكلات بعد وقوعها إلى تشغيل استباقي.
فئات التنبيهات الثلاث
تنقسم تنبيهات تطبيقات LLM إلى ثلاث فئات. تُفعّل تنبيهات زمن الاستجابة عندما يتجاوز زمن الاستجابة حدًا يؤثر في تجربة المستخدم (مثل p99 > 10 ثوانٍ). وتُفعّل تنبيهات التكلفة عندما تتجاوز تكلفة الطلب أو الإنفاق اليومي حدود الميزانية، مما يمنع صدمة الفاتورة. أما تنبيهات الجودة فتُفعّل عندما تنخفض مقاييس الجودة التلقائية، مثل تقييمات LLM كمحكّم ومعدلات رضا المستخدمين وتقييمات الوفاء للمصدر، عن الحد الأدنى المقبول. وتتطلب كل فئة أدوات رصد وقنوات تنبيه مختلفة.
from dataclasses import dataclass
@dataclass
class AlertThresholds:
# Latency (milliseconds)
p50_latency_ms: int = 2000 # median should be under 2s
p99_latency_ms: int = 10000 # 99th percentile under 10s
# Cost (USD)
max_cost_per_request: float = 0.05 # alert if one request costs > 5 cents
max_daily_spend: float = 50.00 # alert if daily spend exceeds $50
# Quality (0.0 to 1.0 scale)
min_quality_score: float = 0.75 # alert if rolling avg drops below 75%
min_faithfulness: float = 0.80 # alert if RAGAS faithfulness drops below 80%
DEFAULT_THRESHOLDS = AlertThresholds()جمع مقاييس زمن الاستجابة
لإطلاق تنبيهات بشأن زمن الاستجابة، تحتاجون أولًا إلى جمعه باستمرار. قيسوا ثلاثة مكونات لزمن الاستجابة بشكل منفصل: زمن الوصول إلى الرمز المميّز الأول (TTFT، وهو مهم لتجربة المستخدم أثناء البث)، وزمن الاستجابة الإجمالي، وأزمنة كل خطوة من خطوات الاسترجاع والتوليد. خزّنوا هذه البيانات كسلاسل زمنية (نقطة بيانات واحدة لكل طلب) حتى تتمكنوا من حساب المئينات والمتوسطات المتحركة خلال آخر N دقيقة أو ساعة.
import time
from collections import deque
from statistics import quantiles
class LatencyTracker:
def __init__(self, window_size=100):
self.window = deque(maxlen=window_size) # rolling window of latencies
def record(self, latency_ms: float):
self.window.append(latency_ms)
def p50(self) -> float:
if not self.window:
return 0
return quantiles(self.window, n=100)[49]
def p99(self) -> float:
if not self.window:
return 0
return quantiles(self.window, n=100)[98]
def check_alert(self, thresholds: AlertThresholds) -> list[str]:
alerts = []
if self.p99() > thresholds.p99_latency_ms:
alerts.append(f'p99 latency {self.p99():.0f}ms exceeds {thresholds.p99_latency_ms}ms')
if self.p50() > thresholds.p50_latency_ms:
alerts.append(f'p50 latency {self.p50():.0f}ms exceeds {thresholds.p50_latency_ms}ms')
return alerts
latency_tracker = LatencyTracker()تتبّع التكلفة وإطلاق التنبيهات بشأنها
تتطلب مراقبة التكلفة تتبّع الإنفاق على مستويات متعددة من الدقة: تكلفة كل طلب (لاكتشاف الاستعلامات الشاذة مرتفعة التكلفة)، والإجماليات الساعية واليومية (لاكتشاف ارتفاعات الاستخدام)، وتكلفة كل ميزة (لتحديد الجزء الأعلى تكلفة في التطبيق). أطلقوا تنبيهًا فورًا عند اكتشاف حالات شاذة في تكلفة الطلب، واستخدموا عمليات فحص مجدولة لحدود الميزانية اليومية.
from datetime import datetime, date
import threading
class CostTracker:
def __init__(self):
self._lock = threading.Lock()
self._daily_spend = {} # date -> total USD
self._per_request = [] # list of (timestamp, cost)
def record(self, cost_usd: float) -> list[str]:
today = date.today().isoformat()
alerts = []
with self._lock:
# Track daily spend
self._daily_spend[today] = self._daily_spend.get(today, 0) + cost_usd
self._per_request.append((datetime.now(), cost_usd))
# Alert on expensive single requests
if cost_usd > DEFAULT_THRESHOLDS.max_cost_per_request:
alerts.append(f'Expensive request: ${cost_usd:.4f} (threshold: ${DEFAULT_THRESHOLDS.max_cost_per_request})')
# Alert on daily budget exceeded
daily_total = self._daily_spend[today]
if daily_total > DEFAULT_THRESHOLDS.max_daily_spend:
alerts.append(f'Daily budget exceeded: ${daily_total:.2f} > ${DEFAULT_THRESHOLDS.max_daily_spend}')
return alerts
cost_tracker = CostTracker()التنبيه بشأن تقييمات الجودة
يُعدّ التنبيه بشأن الجودة الفئة الأكثر تعقيدًا، لأن الجودة لا يمكن قياسها من مقاييس البنية التحتية وحدها، بل تتطلب تقييمًا دلاليًا. ويتمثل النهج الأكثر قابلية للتوسع في التقييم التلقائي لعينات مختارة: اختاروا عينة عشوائية من طلبات الإنتاج (بنسبة 5-10%)، وشغّلوا مقيّمًا يعتمد على LLM كمحكّم بشكل غير متزامن، وخزّنوا التقييمات واحسبوا متوسطًا متحركًا. أطلقوا تنبيهًا عندما ينخفض المتوسط المتحرك عن الحد الأدنى للجودة.
import random
from openai import OpenAI
client = OpenAI()
def evaluate_response_quality(question: str, answer: str) -> float:
judge_prompt = f'''Rate the quality of this AI assistant response on a scale from 0 to 1.
Question: {question}
Answer: {answer}
Return only a JSON object: {{"score": 0.85, "reason": "brief reason"}}
Scoring guide:
1.0 = Perfect, accurate, helpful
0.75 = Good, minor issues
0.5 = Acceptable but incomplete
0.25 = Poor, major gaps
0.0 = Completely wrong or harmful'''
response = client.chat.completions.create(
model='gpt-4o-mini', # cheaper model for evaluation
messages=[{'role': 'user', 'content': judge_prompt}],
response_format={'type': 'json_object'}
)
import json
result = json.loads(response.choices[0].message.content)
return float(result['score'])
def maybe_evaluate(question: str, answer: str, sample_rate=0.1):
if random.random() < sample_rate:
score = evaluate_response_quality(question, answer)
quality_tracker.record(score)
return score
return Noneالمتوسطات المتحركة لاكتشاف الاتجاهات
لا تشير استجابة سيئة واحدة إلى وجود مشكلة عامة. استخدموا المتوسطات المتحركة على مدى زمني (مثل الساعة الأخيرة أو آخر 100 طلب) لاكتشاف الاتجاهات. يشير المتوسط المتحرك الذي يتجاوز حدًا معينًا ويظل فوقه لأكثر من 10 دقائق إلى مشكلة حقيقية، بينما قد تكون الزيادة القصيرة مجرد ضوضاء. تستجيب المتوسطات المتحركة الموزونة أُسّيًا (EWMA) للتغييرات الحديثة أسرع من المتوسطات المتحركة البسيطة.
class RollingQualityMonitor:
def __init__(self, window=50, alert_threshold=0.75, ewma_alpha=0.1):
self.scores = []
self.window = window
self.alert_threshold = alert_threshold
self.alpha = ewma_alpha # EWMA decay factor
self.ewma_score = None
def record(self, score: float):
self.scores.append(score)
if len(self.scores) > self.window:
self.scores.pop(0)
# Update exponentially weighted moving average
if self.ewma_score is None:
self.ewma_score = score
else:
self.ewma_score = self.alpha * score + (1 - self.alpha) * self.ewma_score
def should_alert(self) -> bool:
if len(self.scores) < 10: # not enough data yet
return False
return self.ewma_score < self.alert_threshold
def summary(self) -> dict:
if not self.scores:
return {}
return {
'rolling_avg': sum(self.scores) / len(self.scores),
'ewma': self.ewma_score,
'sample_count': len(self.scores),
'alert': self.should_alert()
}
quality_tracker = RollingQualityMonitor()توجيه التنبيهات: Slack وPagerDuty
لا تكون التنبيهات مفيدة إلا إذا وصلت إلى الشخص المناسب عبر القناة المناسبة. وجّهوا التنبيهات حسب مستوى الخطورة: أرسلوا تنبيهات تدهور الجودة وتنبيهات تجاوز ميزانية التكلفة إلى قناة Slack التي يراقبها فريقكم خلال ساعات العمل. أما تنبيهات زمن الاستجابة التي تتجاوز الحدود الحرجة (مثل p99 > 30 ثانية) والارتفاعات المفاجئة في التكلفة (مثل تجاوز المعدل المعتاد بعشرة أضعاف خلال 5 دقائق)، فأرسلوها إلى PagerDuty لتصعيدها فورًا إلى المناوب.
import requests
def send_slack_alert(message: str, severity: str, webhook_url: str):
color = {'critical': '#ff0000', 'warning': '#ff9900', 'info': '#36a64f'}[severity]
payload = {
'attachments': [{
'color': color,
'title': f'LLM Alert [{severity.upper()}]',
'text': message,
'footer': 'AI Pipeline Monitor'
}]
}
requests.post(webhook_url, json=payload)
def send_pagerduty_alert(title: str, details: str, routing_key: str):
payload = {
'routing_key': routing_key,
'event_action': 'trigger',
'payload': {
'summary': title,
'severity': 'critical',
'source': 'ai-pipeline-monitor',
'custom_details': {'details': details}
}
}
requests.post('https://events.pagerduty.com/v2/enqueue', json=payload)
def route_alert(alert_text: str, severity: str):
send_slack_alert(alert_text, severity, SLACK_WEBHOOK_URL)
if severity == 'critical':
send_pagerduty_alert(alert_text, alert_text, PAGERDUTY_ROUTING_KEY)حلقة تقييم التنبيهات
ينبغي أن يعمل منطق التنبيهات ضمن حلقة مجدولة، لا بشكل مباشر مع معالجة الطلبات. فإجراء عمليات فحص التنبيهات بشكل غير متزامن يمنعها من إضافة زمن استجابة إلى طلبات الإنتاج. ويكفي لمعظم احتياجات التنبيه تشغيل خيط في الخلفية أو مهمة مجدولة كل 60 ثانية. اجمعوا المقاييس أثناء مسار الطلب، وقيّموا الحدود في حلقة الخلفية.
import threading
import time
def alert_evaluation_loop(interval_seconds=60):
while True:
try:
# Check latency
latency_alerts = latency_tracker.check_alert(DEFAULT_THRESHOLDS)
for alert in latency_alerts:
route_alert(f'LATENCY: {alert}', 'warning')
# Check quality
quality_summary = quality_tracker.summary()
if quality_summary.get('alert'):
msg = f'QUALITY DEGRADATION: Rolling avg {quality_summary["ewma"]:.2f} below threshold {DEFAULT_THRESHOLDS.min_quality_score}'
route_alert(msg, 'warning')
print(f'Alert check complete. Quality: {quality_summary.get("ewma", "N/A")}')
except Exception as e:
print(f'Alert evaluation error: {e}')
time.sleep(interval_seconds)
# Start in background thread
alert_thread = threading.Thread(target=alert_evaluation_loop, daemon=True)
alert_thread.start()إرهاق التنبيهات وضبط الحدود
يحدث إرهاق التنبيهات عندما تُطلق التنبيهات بوتيرة متكررة إلى حد يجعل الفريق يتجاهلها. امنعوا ذلك من خلال: البدء بحدود محافظة (مرتفعة) وتشديدها بعد فهم خط الأساس لديكم، واشتراط استمرار الحالة لعدة دورات تقييم قبل إطلاق التنبيه، وتجميع التنبيهات المرتبطة في إشعارات واحدة، ومراجعة التنبيهات التي لا تؤدي أبدًا إلى إجراء مفيد وإيقافها بانتظام.
class AlertDebouncer:
def __init__(self, required_consecutive_fires=3):
self.required = required_consecutive_fires
self.fire_counts = {} # alert_name -> consecutive fires
self.already_firing = set() # alert_names currently active
def should_fire(self, alert_name: str, condition: bool) -> bool:
if condition:
self.fire_counts[alert_name] = self.fire_counts.get(alert_name, 0) + 1
if self.fire_counts[alert_name] >= self.required and alert_name not in self.already_firing:
self.already_firing.add(alert_name)
return True # fire the alert (first time condition sustained)
else:
if self.fire_counts.get(alert_name, 0) > 0:
self.fire_counts[alert_name] = 0
self.already_firing.discard(alert_name) # condition cleared
return False # either not sustained or already firing (no duplicate alert)
debouncer = AlertDebouncer(required_consecutive_fires=3)مراقبة حالات شذوذ التكلفة باستخدام الأساليب الإحصائية
تفشل التنبيهات ذات الحدود البسيطة في اكتشاف حالات شذوذ دقيقة في التكلفة، مثل زيادة تدريجية بنسبة 50% خلال يومين. استخدموا اكتشاف الحالات الشاذة إحصائيًا: احسبوا المتوسط المتحرك والانحراف المعياري للتكاليف الساعية، وأطلقوا تنبيهًا عندما تتجاوز تكلفة الساعة الحالية المتوسط بأكثر من N من الانحرافات المعيارية (التنبيه باستخدام درجة Z). ويتكيف ذلك تلقائيًا مع أنماط الاستخدام الطبيعية، مثل اختلاف حركة المرور بين أيام الأسبوع وعطلة نهاية الأسبوع.
import statistics
def compute_z_score(recent_value: float, historical_values: list[float]) -> float:
if len(historical_values) < 5:
return 0 # not enough data
mean = statistics.mean(historical_values)
stdev = statistics.stdev(historical_values)
if stdev == 0:
return 0
return (recent_value - mean) / stdev
def check_cost_anomaly(current_hour_cost: float, historical_hourly_costs: list[float]) -> str | None:
z = compute_z_score(current_hour_cost, historical_hourly_costs)
if z > 3.0: # more than 3 standard deviations above mean
mean = statistics.mean(historical_hourly_costs)
return f'Cost anomaly: ${current_hour_cost:.2f} this hour (normal: ${mean:.2f}, z={z:.1f})'
return Noneإنشاء لوحة معلومات للعمليات
التنبيهات هي الطبقة التفاعلية، أما لوحة معلومات العمليات المباشرة فهي الطبقة الاستباقية. أنشئوا لوحة معلومات بسيطة تعرض المقاييس الآنية: زمن الاستجابة الحالي p50/p99، وعدد الطلبات في الدقيقة، وتقييم الجودة الحالي (EWMA متحرك)، والتكلفة اليومية حتى الآن مقارنةً بالميزانية، وأغلى 5 طلبات خلال الساعة الأخيرة. يمنح ذلك فريقكم رؤية سريعة عن حالة النظام دون انتظار إطلاق تنبيه.
فحص سريع
اختبروا مدى فهمكم للتنبيه بشأن مقاييس تطبيقات LLM من خلال هذا الدرس.
مراجعة الدرس
تعلمت في هذا الدرس أن ثلاث فئات من التنبيهات تغطي أنظمة LLM، وهي زمن الاستجابة والتكلفة والجودة، وتتطلب كل فئة منها أدوات قياس مختلفة، وأن المتوسطات المتحركة وEWMA تكشفان تدهور الجودة التدريجي بصورة أفضل من فحوصات العتبة المطبقة على الطلبات الفردية، وأن إزالة تكرار التنبيهات تمنع إرهاق التنبيهات من خلال اشتراط استمرار الظروف عبر دورات تقييم متعددة قبل إطلاق التنبيه. في الخطوة التالية، سنتعمق في هجمات حقن المطالبات وأمن الذكاء الاصطناعي.
تعلم Python مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 30
- الدروس
- 120
الأسئلة الشائعة
هل درس «التنبيه بشأن تدهور زمن الاستجابة والتكلفة والجودة» مجاني؟
نعم — نص درس «التنبيه بشأن تدهور زمن الاستجابة والتكلفة والجودة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Engineering Academy، انتقل إلى CoddyKit PRO. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
ماذا ستتعلم في «التنبيه بشأن تدهور زمن الاستجابة والتكلفة والجودة»؟
حدّدوا عتبات تنبيه لزمن الاستجابة عند p99، وتكلفة كل طلب، ودرجات الجودة الآلية، ووجّهوا التنبيهات إلى Slack أو PagerDuty عند تدهور مسار LLM. تتمرن على AI Engineering Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Engineering Academy؟
لا تُشترط خبرة سابقة. AI Engineering Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «التنبيه بشأن تدهور زمن الاستجابة والتكلفة والجودة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Engineering Academy هذا؟
نعم. كل درس في AI Engineering Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- لماذا يصعب تصحيح تطبيقات LLM
- التتبع باستخدام LangSmith
- Langfuse للرصد المستقل عن النموذج
- التنبيه بشأن تدهور زمن الاستجابة والتكلفة والجودة