دانيلا (⁦Dayfing⁩)
العودة إلى المقالات
1,916 كلمة8 د

قابلية ملاحظة وكيل الذكاء الاصطناعي: التتبعات، زمن الاستجابة، الرموز، التكلفة والأخطاء

لماذا يحتاج الوكيل إلى نموذج مختلف لقابلية الملاحظة

يملك طلب API العادي بداية ومعالجاً واستجابة واضحة. يضيف وكيل الذكاء الاصطناعي حلقة متكررة. فهو يختار نموذجاً، ويقرر استدعاء أداة، وينتظر نظاماً بعيداً، ويقرأ النتيجة، وقد يعود إلى النموذج مرة أخرى. لذلك قد يضم طلب مستخدم واحد عدة استدعاءات للنموذج، وعمليات بحث، وتنفيذ أدوات، ومحاولات إعادة، وفحوص سياسات. لا تخبرنا سطرية سجل تقول «فشل الطلب» أي فرع استهلك الوقت أو الميزانية.

تجعل قابلية الملاحظة هذا المسار مرئياً من خلال التتبعات والمقاييس والسجلات المترابطة. تصف OpenTelemetry التتبّع بأنه مسار الطلب، وspan بأنه عملية داخل ذلك المسار. استخدم span جذرياً واحداً لتشغيل الوكيل الذي يراه المستخدم، ثم spans فرعية للاستدلال، والاسترجاع، والأدوات، وحواجز الأمان، والتسلسل. اجعل أسماء النماذج والأدوات منخفضة التعدد. ضع معرّفات الطلب في سياق التتبّع أو في السجلات المهيكلة، وليس في تسميات المقاييس. عندها يستطيع المشغّل معرفة ما حدث في تشغيل واحد، ومدى تكراره، وسير العمل المتأثر.

يستخدم هذا المقال مخططاً محايداً تجاه المزوّد. تظل وثائق المزوّد المرجع للحقول الدقيقة وقواعد الفوترة. توفر اتفاقيات OpenTelemetry الخاصة بـ GenAI للـ spans واتفاقيات المقاييس مفردات مشتركة للتكاملات التي تتطور.

مخطط تتبّع يصمد أمام حلقة الوكيل

أنشئ الـ span الجذري عند قبول التطبيق للطلب، وليس عند أول وصول إلى النموذج. استخدم عملية مثل invoke_agent، وأضف سمات للخدمة، والنشر، والبيئة، وإصدار سير العمل، وفئة مستأجر غير حساسة. لا تسجل معرّف المحادثة إلا إذا كان متاحاً ويسمح به نظام الاحتفاظ. لا تضع رسالة المستخدم أو المطالبة كاملة أو حمولة الأداة في تسمية مقياس.

يجب أن يجيب كل span فرعي عن سؤال تشغيلي واحد. الحد الأدنى المفيد هو:

Span ما يجب تسجيله
agent.run اسم وإصدار سير العمل، النتيجة، عدد المحاولات، المدة
gen_ai.inference المزوّد، النموذج المطلوب والفعلي، العملية، البث، سبب النهاية، الرموز
gen_ai.retrieval فئة الفهرس أو مصدر البيانات، نمط الاستعلام، عدد النتائج، حالة الذاكرة
gen_ai.tool اسم الأداة ونوعها، قرار التفويض، المهلة، النتيجة
guardrail.check إصدار السياسة، القرار، رمز السبب، المدة

عيّن حالة للـ span وقيمة error.type للعملية الفاشلة. سجّل حدثاً زمنياً عند إعادة المحاولة، يضم رقمها ومدة التراجع ورمز السبب. إعادة المحاولة ليست تشغيلًا جذرياً ثانياً، بل محاولة أخرى للعملية المنطقية نفسها مع span عميل مستقل عندما يرسل طلب عبر الشبكة. يمنع ذلك عدّ طلبات المستخدم مرتين، مع إبقاء محاولات المزوّد ظاهرة.

يمثل JSON التالي شكلاً لسجل مُصدّر، وليس صيغة يفرضها مزوّد محدد. يحتوي على عدادات وأكواد ولا يحتوي على محتوى.

{
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "span_id": "00f067aa0ba902b7",
  "parent_span_id": "b7ad6b7169203331",
  "name": "chat model",
  "kind": "CLIENT",
  "status": "OK",
  "attributes": {
    "gen_ai.operation.name": "chat",
    "gen_ai.provider.name": "provider.example",
    "gen_ai.request.model": "model.example",
    "gen_ai.response.model": "model.example-2026-01",
    "gen_ai.usage.input_tokens": 820,
    "gen_ai.usage.output_tokens": 146,
    "gen_ai.response.finish_reasons": ["stop"],
    "app.agent.attempt": 1
  }
}

يجب أن يصف اسم span فئة العملية، لا معرّفاً أو نص المستخدم. احتفظ بإصدار الاتفاقية الدلالية في بيانات أداة القياس. إذا أبلغ المزوّد عن الرموز القابلة للفوترة منفصلة عن الرموز المعالَجة، فاحتفظ بالقيمتين في حساب خاص واستخدم القابلة للفوترة في عرض التكلفة. لا تجمع قياس العميل والخادم للطلب نفسه دون تمييز الطبقة، وإلا عُدّت الرموز مرتين.

معرّفات الارتباط ونشر السياق

يربط trace ID الخدمات. ويحدد span ID عملية واحدة. يظل request ID الخاص بالتطبيق مفيداً للدعم، لكنه لا يحل محل سياق التتبّع. انشر ترويسة W3C traceparent عبر بوابة API، وخدمة الوكيل، وخدمة الاسترجاع، ومحولات الأدوات. يشرح دليل OpenTelemetry لنشر السياق استخراج السياق البعيد وإنشاء span فرعي. ويمكن حقن السياق نفسه في السجلات المهيكلة للوصول من سجل إلى تتبّع.

أنشئ request ID عشوائياً منفصلاً عندما يحتاج الدعم إلى معرّف قصير. خزّن علاقته بـ trace ID في السجلات وليس في مقياس عالي التعدد. في الطوابير، احقن السياق في بيانات الرسالة الوصفية وأنشئ span للمستهلك عند المعالجة. وللمهام المتوازية التي لا تملك أباً واحداً استخدم span links. عند الحدود العامة تعامل مع ترويسات التتبّع الداخلة كمدخلات غير موثوقة، وتحقق من صيغتها، ولا ترسل baggage الداخلي إلى مزوّد أو أداة خارجية. قد تحمل baggage بيانات اعتماد أو معلومات شخصية.

تكشف spans الأدوات سلوك الوكيل الحقيقي

افصل قرار النموذج عن التنفيذ عندما يكون هذا الفرق مفيداً. يوضح span النموذج أن الأداة طُلبت، بينما يوضح span الأداة ما نفذه التطبيق فعلاً. يجب أن يضم اسماً ثابتاً مثل tool.name، ونوعاً مثل function أو extension أو datastore، وقرار السياسة، والعملية الخارجية. أضف طريقة الطلب أو فئة الاستعلام فقط إذا لم تكشف سراً. لا تخزّن رمز وصول أو معاملات SQL أو محتوى مستند أو عنوان URL كاملاً يحوي query.

لكل استدعاء أداة، سجّل أوقات البدء والانتهاء، وإعداد المهلة، وفئة النتيجة، وعدد الإعادات، وحجم النتيجة المحدود. يجب أن تملك المهلة، والرفض التجاري، ومنع السياسة، وخطأ upstream 5xx أكواد أسباب مختلفة. انشر السياق إذا استدعت الأداة خدمة أخرى. وإذا نفذت أمراً محلياً، فسجّل عائلة الأمر وفئة الخروج فقط، لا إدخال المستخدم.

أظهر أيضاً الانتظار الذي لا يمثل استدعاء أداة. أضف spans لتأخر الطابور، والنوم بسبب حد المعدل، وفتح قاطع الدارة، وبث الاستجابة. وإلا قد يخفي زمن span النموذج وقت انتظار فتحة في حد التزامن. في سير عمل متعدد الوكلاء، امنح كل وكيل مفوّض اسم سير عمل واربطه بالتتبّع الأب. لا تنشئ تتبّعاً جديداً لكل حالة داخلية.

حساب الرموز والتكلفة

احسب الاستخدام من استجابة المزوّد متى كان متاحاً. قد تختلف أسعار رموز الإدخال والإخراج والذاكرة المؤقتة والاستدلال، وكذلك الصور ووحدات الأدوات. تذكر وثيقة OpenAI عن الرموز أن التجزئة تختلف حسب النموذج واللغة، وأن كائن usage في الاستجابة هو الأساس للطلب المكتمل. يفيد محلل رموز محلي في تقدير الميزانية مسبقاً، لكنه لا يحل محل استخدام المزوّد عند مطابقة الفاتورة.

خزّن لكل محاولة المزوّد والنموذج المطلوب والفعلي وفئة الرمز والعدد والعملة وإصدار جدول الأسعار ومركز التكلفة. احسب بعد وصول الاستجابة:

cost = input_billable_tokens * input_price
     + cached_input_tokens * cached_input_price
     + output_billable_tokens * output_price
     + provider_units * unit_price

يجب أن تكون الأسعار إعداداً مؤرخاً، لا قيمة ثابتة في مُصدّر التتبّع. احتفظ بالعدد الخام والمبلغ المحسوب لتدقيق التصحيحات. اجمع كل المحاولات لأن الاستدعاء الفاشل قد يستهلك رموزاً. ضع علامة مؤقت على الرسم التقديري أو المؤجل وطابقه مع تقرير المزوّد.

اعرض أبعاداً يستطيع المالك تغييرها: سير العمل، عائلة النموذج، البيئة، فئة المستأجر والنتيجة. لا تستخدم معرّف المستخدم أو نص المطالبة أو معاملات الأداة كأبعاد. يجب أن يعرض لوحة التكلفة الإجمالي والتكلفة لكل تشغيل والرموز لكل تشغيل ونسبة الإعادات وحصة النماذج الغالية. قد تشير زيادة رموز الإخراج مع بقاء زمن الاستجابة طبيعياً إلى إجابة غير محدودة أو حلقة أو تغيّر في المطالبة.

توزيعات زمن الاستجابة: p50 وp95 وp99

يخفي المتوسط الذيل الذي يراه المستخدم عند انتظار الطابور أو أداة بطيئة. سجّل مدة التشغيل الجذري والـ spans المهمة في histogram بوحدة الثواني. قِس زمن أول رمز، والفاصل بين أجزاء البث عندما يؤثر في العرض، والزمن الكلي. افصل زمن الخادم والطابور والشبكة عندما يوفر المزوّد هذه الحقول.

يمثل p50 الحالة المعتادة، ويصف p95 المستخدمين البطيئين، ويكشف p99 الحالات النادرة الشديدة. هذه كميات مئينية لتوزيع، وليست ثلاثة متوسطات. اختر صناديق histogram حول هدف المنتج من أجزاء الثانية حتى الدقائق، وثبّت الوحدات. تقدر دالة Prometheus histogram_quantile المئين من الصناديق. في histogram الكلاسيكي اجمع حسب le قبل الحساب.

histogram_quantile(
  0.95,
  sum by (le, workflow) (
    rate(agent_run_duration_seconds_bucket[10m])
  )
)

لا تضع trace ID في تسميات المقاييس. قسّم زمن الاستجابة حسب عدد صغير من الأبعاد المضبوطة مثل سير العمل وعائلة النموذج والمنطقة والنتيجة. ستشرح عينة تتبّع سبب تحرك p95. لا تجمع مدد spans المتوازية، بل استخدم المسار الحرج.

الأخطاء والإعادات وحدود المعدل

عرّف تصنيف الأخطاء قبل إنشاء التنبيهات. ميّز بين التحقق، ومنع السياسة، والمصادقة، وحد المعدل، والمهلة، وخطأ upstream، واستجابة نموذج مشوهة، وفشل الأداة والإلغاء. حوّل أكواد المزوّد إلى هذه الفئات واحتفظ بكود أصلي محدود. ميّز إلغاء المستخدم المتوقع عن فشل الخادم.

تحتاج كل إعادة إلى سبب ورقم محاولة وbackoff ومآل نهائي. استخدم backoff أُسّياً محدوداً مع jitter فقط عندما يسمح العقد بذلك. لا تعد محاولة التحقق أو التفويض أو السياسة أو أخطاء المخطط الحتمية. ضع deadline للتشغيل الكامل ولكل محاولة. يبلّغ span الجذري عن retry_count وattempt_count والنتيجة، وتحتفظ كل محاولة بحالتها. قد ترفع الإعادات التكلفة مع بقاء نسبة النجاح جيدة.

سجّل اختيار نموذج احتياطي كحدث أو span. يجب أن تميّز اللوحة بين حد المعدل وزمن الاستجابة وسياسة السلامة وفحص القدرة. راقب معاملات الأدوات المشوهة وحلقات إصلاح المخطط كلّاً على حدة. إذا سمحت بالإصلاح، حدّ عدد التكرارات وأصدر loop_limit عند بلوغ الحد.

الخصوصية والتنقيح وأخذ العينات

قد تحتوي المطالبات وبيانات الأدوات على معلومات شخصية أو سرية أو حساسة أمنياً. الإعداد الآمن الافتراضي هو جمع البيانات الوصفية، وعدادات الرموز، والبصمات وأكواد الأسباب، مع إبقاء المحتوى خارج القياس. إذا احتاج التصحيح إلى أمثلة، استخدم مخزناً منفصلاً مع موافقة واحتفاظ قصير وتشفير وسجل وصول وتنقيح على مستوى الحقل. نقّح قبل التصدير.

استخدم قائمة سماح للسمات. احذف ترويسات التفويض وملفات cookie ومفاتيح API وبيانات الاتصال وأرقام الحسابات وعناوين URL ذات query ونصوص الوثائق. لا يجعل التجزئة البيانات مجهولة تلقائياً. افصل بصمة المطالبة عن المطالبة ووثّق من يستطيع الربط بينهما. اختبر التنقيح بأسرار واقعية وبيانات شخصية متعددة اللغات.

يقلل أخذ العينات الحجم لكنه لا ينبغي أن يخفي الحوادث. استخدم parent-based sampling للحفاظ على اتساق التتبّع. ويمكن في Collector استخدام tail sampling للاحتفاظ بالأخطاء والمهل والتشغيلات المكلفة والتتبعات البطيئة، مع أخذ عينات من النجاحات العادية. تميز مواصفة OpenTelemetry لأخذ العينات بين التسجيل والتصدير، لذلك يستطيع sampler محلي تفادي إنشاء سمات مكلفة. أبقِ المقاييس بلا عينات واستخدم التتبعات للتحقيق.

OpenTelemetry وGrafana وSentry معاً

أضف قياس OpenTelemetry والاتفاقيات الدلالية إلى الوكيل، وأرسل OTLP إلى Collector، ودعه يطبق التجميع وحد الذاكرة والتنقيح وأخذ العينات والتوجيه. صدّر التتبعات والمقاييس والسجلات إلى backends المناسبة، مع سمات خدمة وإصدار وبيئة ومنطقة ونشر متسقة. تحقق من تتبّع كامل في staging قبل أخذ عينات الإنتاج.

توفر Grafana عرضاً تشغيلياً مشتركاً. أنشئ لوحات للحجم ونسبة النجاح وp50 وp95 وp99 وزمن أول رمز والرموز والتكلفة والإعادات ومدة الأداة وحالة المزوّد. اربط اللوحات ببحث التتبّع وrunbook. تصف وثائق Grafana لقواعد التنبيه الاستعلامات والشروط وفترات التقييم والإشعارات. تضيف Sentry تجميع المشكلات وسياق الخطأ وفحص التتبّع. تعرض Trace API في Sentry الـ spans والأخطاء التي تكوّن تتبّعاً واحداً. أرسل بيانات منقّحة فقط واضبط أخذ العينات صراحة.

أهداف SLO وتنبيهات يستطيع المشغّل استخدامها

يجب أن يعبر SLO عن وعد للمستخدم، لا عن صحة Collector. عرّف التوافر كنسبة التشغيلات المكتملة بلا خطأ مصنّف للخادم أو المزوّد أو الأداة. وعرّف زمن الاستجابة كنسبة التشغيلات الجذرية تحت عتبة مختارة. إذا كانت التكلفة قيداً للمنتج، فتتبّع SLI للميزانية منفصلاً.

اختر الأهداف من خط أساس مقاس ومتطلبات المنتج. افصل سير العمل ذي التوقعات المختلفة. اعرض error budget في نافذة طويلة ومنظور قصير للنشر. تصف وثائق Grafana لـ SLO استعلامات SLI واستهلاك الميزانية وتنبيهات fast-burn وslow-burn. لا ترسل صفحة إلا عندما يكون الإجراء ممكناً. يناسب الاتجاه البطيء تذكرة عمل.

من التنبيهات العملية ارتفاع أخطاء التشغيل الجذري المستمر، والاستهلاك السريع للميزانية، وتجاوز p95 للعقد، وارتفاع حد المعدل، وزيادة الإعادات، وغياب سجلات usage، ومعدل تكلفة غير متوقع، وطابور متوقف. أدرج سير العمل والمنطقة والنشر والقيمة والعتبة ورابط التتبّع والمالك وrunbook. تمنع فترة pending الإخطار بسبب نقطة واحدة. جمّع الإشعارات حسب الخدمة والشدة. عند غياب إجراء فوري استخدم لوحة، لا تنبيهاً.

طريق استكشاف العطل من العرض إلى السبب

ابدأ من SLO أو بلاغ المستخدم واختر تتبّعاً ممثلاً. افحص أبناء span الجذري وانتقال السياق عند البوابة والطابور وحدود الأدوات. عند غياب spans افحص صحة المُصدّر وأخذ العينات وحقن السياق قبل تعديل كود التطبيق.

في التشغيل البطيء قارن انتظار الطابور وزمن أول رمز وزمن الإخراج والاسترجاع والمسارات الحرجة للأدوات. يشير p99 المرتفع مع p50 العادي عادة إلى اعتماد ذي ذيل طويل أو حد تزامن أو إعادة. أما تحرك p50 فيشير إلى نشر أو نموذج أو مطالبة أو منطقة مختلفة. عند ارتفاع التكلفة جمّع حسب النموذج الفعلي وفئة الرمز وإصدار سير العمل والمحاولات، ثم طابق الاستخدام مع تقرير المزوّد.

في الخطأ ابدأ بأول span فاشل لا بالاستثناء المغلّف. افحص status وerror.type وكود المزوّد وميزانية المهلة وأحداث الإعادة. فرّق رفض الأداة عن انقطاع المزوّد وعن استجابة النموذج المشوهة وعن خطأ المحلل. تأكد أن التنقيح أبقى كود تشخيص آمناً. عُدّ حظر السياسة المتوقع نتيجة منتج، وأنشئ تنبيهاً فقط عند تغير معدله بشكل غير متوقع.

احتفظ بطلبات تركيبية ذات fixtures حتمية وغير حساسة. بعد تغيير القياس أو النموذج أو المطالبة أو التوجيه، تحقق من أن التتبعات والمقاييس وسجلات الرموز والأخطاء تشترك في correlation ID نفسه. لفهم البنية راجع production AI agent architecture، وAI agent evaluations، وprompt injection and MCP security، وhybrid RAG with pgvector. تحدد هذه الموضوعات الـ spans الموجودة وSLO المقبول، بينما تظل قابلية الملاحظة طبقة الأدلة المحايدة.

مقالات أخرى