Skip to main content
لوكيل كتبته بنفسك، أو إطار عمل لا يوجد له محول في Failproof AI. لا شيء يجب إدراجه: أنت تصدر الأحداث. هذا هو نفس API الذي يستدعيه محولات الأطر الأربعة. وهي جداول ترجمة فوقه.

التثبيت

بدون إضافات، وبدون تبعيات.

الإدراج

اقرأه من الأعلى إلى الأسفل وسيخبرك بما يعنيه: وما يصدره كل واحد فعلياً: كل شيء بالداخل يمكن أن يحذف session_id و agent_id. تربط النطاقات الهوية على متغيرات السياق وكل نداء حدث يقرأها مرة أخرى، لذلك لا تمرر أبداً المعرفات من خلال وظائفك. تعمل الثلاثة جميعاً مع async with وكذلك مع with. يبني التداخل للوكلاء الشجرة. يتم حساب parent_id والعمق من المكدس:

كيف يغلق النطاق

agent() يتعامل مع الاستثناءات لك: يتم إصدار الخطأ قبل agent_end، لأن لوحة التحكم تغلق الامتداد في agent_end وأي شيء بعده يُنسب إلى لا شيء. الإلغاء ليس فشلاً، لذلك لا تلوث التشغيلات الملغاة سطح الأخطاء. يتم إعادة رفع الاستثناء دائماً: النطاق لا يبتلعه أبداً.

طرق الحدث

خمسة عشر طريقة في ست عائلات. معظمها يأتي في أزواج — تصدر الفاتحة، ثم الأغلق، و SDK يقيس الامتداد بينهما.
فضّل النطاقات — agent() و tool_call() — أينما كانت مناسبة. إنها تضمن حدث الإغلاق حتى عندما يرفع الجسم. تصل إلى هذه الطرق مباشرة عندما لا يتداخل تدفق التحكم، مثل نداء نموذج داخل مساعد.
العائلتان البشريتان تشير في اتجاهين متعاكسين.لا يشير أي إطار عمل إلى الزوج الثاني، لذا فهو دائماً لك لإصداره.
مرر request_id عندما تعمل نداءات النموذج بالتزامن. بدونه، تتزاوج طلبات الاستجابات بترتيب الوصول لكل وكيل — والنداءات المتزامنة تتزاوج بشكل خاطئ، مرفقة كل استجابة بالطلب الخاطئ.

مثال

حلقة استدعاء الأداة مقابل OpenAI API، بدون إطار عمل وكيل:
ينتج عن هذا نفس أنواع الأحداث الستة التي سيعطيك المحول. الإصدار الكامل القابل للتشغيل، مع تعريفات الأداة، يأتي في مستودع SDK تحت docs/manual/examples/.

الخيوط و async

تنتشر متغيرات السياق في مهام asyncio تلقائياً. لا تنتشر في خيوط جديدة، لأن الخيط يبدأ بسياق فارغ.
بدون propagate()، تثير أحداث العامل TypeError تسمي الإصلاح بدلاً من الهبوط على جلسة لا شيء. هذا متعمد: حدث بدون جلسة يتم تخطيه بواسطة ingest والإجابة 200، وهو الفشل الصامت الذي توجد طبقة الهوية لمنعه.

أدرج إطار عمل بدون محول

كل إطار عمل وكيل يعطيك نفس الفتحات الثلاثة. اربطها وسيكون لديك تتبع كامل — المحولات الأربعة المشحونة لا تفعل أكثر من هذا.
1

احيط التشغيل

2

احيط كل أداة

في أي مكان يستدعيه الإطار غلاف أداة أو برنامج وسيط.
3

زاوج كل نداء نموذج

لديك عقدة أو خطوة أو حدود برنامج وسيط تستحق الرؤية؟ غلفها في زوج خطاف — hook_triggered / hook_completed — وليس agent() متداخل. agent_id هو جانب cardinality منخفض، وإدخال واحد لكل عقدة يغرقه. تُعرض امتدادات الخطاف بنفس الطريقة وتمنحك زمن الكمون لكل عقدة.
اليدوي والتلقائي يتكونان. يدخل محول يعمل داخل نطاق مكتوب يدوياً تلك الجلسة والآباء إلى ذلك الوكيل، حتى تحصل على شجرة واحدة بدلاً من شجرتين — مفيد عندما تدرج إطار عمل بنفسك إلى جانب واحد مدعوم.
سببان، والفتحات الثلاثة أعلاه هي الإجابة على كليهما:
  • autogen-core لم يتم صيانته منذ سبتمبر 2025.
  • AG2 لا يعرض نقطة تسجيل على مستوى العملية تعادل خطافات أطر العمل الأخرى، لذا فإن إدراجها يعني تغليف كل وكيل في كل موقع البناء.
يسجل رسم الفتحات يدوياً نفس الأحداث، بنفس الدقة، كما سيفعل محول مشحون.

الذهاب أعمق

كيف يعمل التسجيل فعلياً. لا شيء من هذا مطلوب للبدء.
كل تسجيل له نفس الشكل: يفتح امتداد، يتداخل العمل بداخله، وكل حدث افتتاحي يحصل على حدث إغلاق.الزوج هو الوحدة. كل حدث إغلاق يحمل مدة يقيسها SDK من الحدث الافتتاحي الخاص به.فيما يلي تشغيل واحد حقيقي لكل إطار عمل — مأخوذ من الأمثلة المشحونة مع SDK، اسم النموذج معياري. لاحظ كم يعود من نداء واحد.
14 events
تصبح العقد أزواج خطاف، لذا تحصل على زمن الكمون لكل عقدة بدون أن تزحمها قائمة الوكيل.
لا توجد حدث نهاية الجلسة. الجلسة ليست شيء تغلقه — إنها مجموعة من الأحداث تشترك في session_id.يتم استخلاص الحالة من شكل التتبع:لذلك تنتهي الجلسة عندما يتم إغلاق كل زوج. يصدر المحولات agent_end لك، وعند الهدم يغلقون أي شيء لا يزال مفتوحاً ويوقعونه كغير كامل — يستقر التشغيل المتعطل كـ done بفجوة مرئية بدلاً من التعليق.
هذا هو السبب في أن الجلسة يمكن أن تمتد على نداءين. يوقف interrupt() في LangGraph التشغيل، يبقى الامتداد الجذري مفتوحاً عن قصد، والنداء المستأنف يغلقه. كلا النداءين جلسة واحدة.
session_id و agent_id اختياريان في كل طريقة حدث. محذوفاً، يحلان من النطاق المرفق:
تمريرهما بشكل صريح يعمل بعد ذلك ويأخذ الأسبقية. بدون شيء مرتبط وبدون شيء تم تمريره، يرفع الاستدعاء TypeError تسمية الإصلاح بدلاً من إصدار حدث بدون جلسة، والتي ستقفزها ingest مع الإجابة 200.تربط النطاقات الهوية على متغيرات السياق. تلك تنتشر في مهام asyncio تلقائياً لكن ليس في خيوط جديدة — غلف عامل في failproofai_sdk.propagate().

من يضرب أي معرف

كيف تحل المحولات session_id

أول تطابق يفوز:
  1. session_id خيار صريح
  2. البيانات الوصفية لكل نداء
  3. نطاق session() المرفق
  4. بيانات إطار العمل الوصفية
  5. معرف التشغيل الخاص بإطار العمل
لا يتم اختراعه أبداً مع وجود أحد تلك — معرف مركب سيقسم تشغيل واحد عبر عدة جلسات.

حافظ على agent_id على cardinality منخفضة

إنه الجانب الأساسي على كل سطح لوحة تحكم، وعمود LowCardinality(String). تقلل القيمة لكل تشغيل العمود وتملأ قائمة القائمة المنسدلة بإدخال واحد لكل تشغيل.تحافظ المحولات على هذا العمود لك:المعرف الحقيقي يبقى على fw_agent_id / fw_run_id، حيث يبقى قابلاً للاستعلام بدون أن يكون جانباً.
هذا الحراس يلمس فقط التسميات التي اختارها الإطار. agent_id تمرره بنفسك — إلى event.*، أو إلى failproofai_sdk.agent(...) — مسجل تماماً كما هو محدد. إعادة كتابة صريحة لحجة صريحة ستكون أسوأ من cardinality التي تمنعها، لذا سمِّ امتدادات خاصة بك وفقاً لذلك.
أي إطار عمل يسجل ماذا، مقاس من التشغيلات أعلاه:الشرطة تعني أن الإطار ليس لديه مثل هذا المفهوم. human_pause و human_interrupt تصف شخص يتصرف على الوكيل، الذي لا يشير إليه أي إطار — انبعث بنفسك.
حدث لا يصل وحده أبداً. يفتح أحدهما امتداد، يغلقه الآخر، والحدث الإغلاق يحمل مدة يقيسها SDK من الحدث الافتتاحي.
حدث افتتاحي بدون حدث إغلاق هو امتداد لا ينتهي أبداً. تُرسّم الجلسة كما لا تزال قيد التشغيل، إلى الأبد، ومدتها النشطة تستمر في النمو. هذا هو فشل العرض الذي يجب مراقبته عند الإدراج يدوياً.

قواعد الارتباط

  • أعد استخدام نفس tool_call_id أو hook_id أو pause_id أو input_id لحدث الإكمال المطابق.
  • حسابات SDK duration_ms لـ tool_result و hook_completed و agent_resume و human_input. تمريره إلى تلك الطرق يرفع ValueError.
  • duration_ms يُقبل على model_response، لأن فقط المتصل يعرف زمن المزود الحقيقي. يجب أن يكون عدداً صحيحاً — عدد عشري يرفع ValueError في موقع الاستدعاء، لأن الخادم يقرأ العمود كعدد صحيح بدون إشارة 32 بت ويخزن NULL لأي شيء آخر.
  • مفاتيح الارتباط مجالها حسب النوع والجلسة، لذا يمكن لاستدعاء أداة وخطاف مشاركة معرف بأمان، ويمكن لجلستين متزامنتين إعادة استخدام نفس المعرفات بدون تصادم. لا تكون مجالاً بواسطة وكيل: زوج مفتوح تحت وكيل واحد ومغلق تحت آخر لا يزال يرتبط، وهي الحالة العادية في الأطر متعددة الوكلاء.
  • request_id يزاوج model_request مع model_response. بدونه، أحداث النموذج تتزاوج بالترتيب لكل وكيل، لذا تتزاوج النداءات المتزامنة بشكل خاطئ.
  • زوج مقسم عبر العمليات لا يزال يرتبط في المصب، لكن SDK لا يمكنه حساب مدته في العملية.
  • تمسك الخريطة المعلقة بـ 10,000 ابدأ كحد أقصى وتطرد الإدخال الأقدم عندما تكون ممتلئة.
تثبيت failproofai-sdk يثبت كل شيء، كل المحولات الأربعة مضمونة. تسحب الإضافات الإطار، وليس المحول.
import failproofai_sdk هو بدون تبعيات بموجب العقد، مفروض بواسطة اختبار يثبت العجلة المدمجة بـ --no-deps وآخر يثبت عدم وصول أي إطار إلى sys.modules.
لا يوجد failproofai_sdk.crewai تصريح. المحولات مقصودة عن قصد ألا تُعرّض على حزمة المستوى الأعلى: لمس أحدها سيستورد الإطار كتأثير جانبي لوصول السمة، مما يكسر وعد عدم التبعيات. استخدم instrument().
قراءة الكشف التلقائي sys.modules، وليس قائمة الحزمة المثبتة، لذا فإن إطار عمل لديك مثبت لكن لم تستورده أبداً لا يتم إدراجه ولا يتم استيراده نيابة عنك. لرؤية ما هو موصول:
instrument("crewai") على جهاز بدون CrewAI لا يرفع. يسجل تحذيراً ويرجع ()، حتى أحد إطر العمل المفقودة لا تأخذ عملية تدرج أيضاً آخرين.التحذير يحمل ImportError الأساسي، وتلك الرسالة تسمي أمر التثبيت الدقيق — لذا الإصلاح يكون في سجلاتك، ليس مختبئاً.
اضبط FAILPROOFAI_SDK_STRICT=1 لإرفاعه بدلاً من ذلك. تُقرأ تلك العلم مرة واحدة وتُخزن مؤقتاً، لذا يصدرها قبل بدء العملية بدلاً من تعيينها في منتصف التشغيل.
instrument() يجب أن يأتي بعد استيراد إطار العمل الخاص بك. قراءة الكشف التلقائي sys.modules، لذا نداء عارٍ فوق الاستيراد يجد لا شيء، يثبت لا شيء، ويرجع ().
احصل على هذا خطأ والعملية تعمل مع SDK مستوردة، المحول يبدو مثبتاً، و حدث واحد لم يُصدر. يسجل تحذيراً يقول بالضبط ذلك — لذا تحقق من السجلات أولاً عندما لا يسجل التشغيل شيئاً.
الملف هو ما يجعل هذا آمناً: وكيلك لا يسد أبداً على الشبكة، وانقطاع السحابة يعني دليل ينمو بدلاً من فقدان الأحداث.كل تنظيف يكتب ملف دفعة واحدة، .tmp أولاً، ثم fsync، ثم إعادة تسمية ذرية:
يختار المراقب فقط .jsonl، لذا لا يمكن أبداً قراءة ملف نصف مكتوب. الجذع يحمل طابع زمني، معرف العملية ورقم التسلسل، لذا لا يمكن لعمليتين تنظيف في نفس الميلي ثانية أن تصطدما. تُغطى القائمة بـ 10,000 حدث؛ بعد ذلك تسقط الأقدم وتسجل.
collector.redact لا ينطبق على أحداث SDK الخاصة بك. لا يراها أبداً.
المراقب ينقل دفعاتك. إنه لا يفتحها أو يعيد كتابتها.التعديل يعمل حيث يكتب المراقب أحداثه الخاصة — وليس حيث تُنقل الدفعات. لذا طلب أو حجة أداة تحمل مفتاح API لا تزال تحمله عند الوصول.هذا مقصود. هذه هي نداءات الإدراج الخاصة بك، وإعادة الكتابة في الحركة ستعني أن الأحداث التي تستقبلها ليست الأحداث التي أصدرتها.
أنت تتحكم في الحمولات من المصدر، في مكانين:
  • أوقف التقاط المحتوى على المحول. اسم الخيار يختلف، ومحول واحد لا يملك أي — هذا ليس مفتاح عام واحد:
    • LangChain / LangGraph, Pydantic AI — capture_content=False
    • LlamaIndex — capture_messages=False
    • CrewAI — لا مفتاح محتوى على الإطلاق؛ session_id هو الخيار الوحيد الذي يقرأه، لذا يتم تسجيل الطلبات والإكمالات دائماً.
    instrument() يسقط الخيارات التي لا يقرأها محول، لذا تمرير الاسم الخاطئ لا يرفع شيء ولا يغير شيء.
  • لا تسلم السر إلى input= في المقام الأول.
collector.redact ليس بديلاً عن أي منهما.
دليل ملف فارغ هو الحالة الصحية. لا تستخدمه للتحقق من التسليم.
يحذف المراقب كل دفعة في غضون ميلي ثانية من نقلها، لذا فإن ls يتسابق المجمع ويظهر جزء من ما أصدرته — لا يمكن تمييزه عن SDK لم يسجل شيء.للتأكد من أن الأحداث هبطت فعلاً، تحقق من لوحة التحكم. لمراقبة امتلاء الملف، توقف المراقب أولاً.
كل رد اتصال يعمل داخل غلاف وظيفته الوحيدة هي إعادة الرفع، لذا استدعاؤك يجلس في try واحدة بالضبط وكل شيء SDK يحدث خارجها.الافتراضي صحيح في الإنتاج وخاطئ أثناء التصحيح، لأنه لا يمكن أبداً إثبات أنه لم يتعطل. اضبط FAILPROOFAI_SDK_STRICT=1 لإسكات الفشل المبتلع.

مشاكل شائعة

حدث افتتاحي بدون حدث إغلاق: model_request بدون model_response، أو tool_use بدون tool_result. استخدم النطاقات، التي تضمن الزوج حتى عندما يرفع الجسم. إذا استدعيت طرق الحدث مباشرة، استخدم try و finally.
يتم قياسه من حدث الافتتاح المطابق، لذا يتم رفضه على tool_result و hook_completed و agent_resume و human_input. يتم قبوله على model_response، لأن فقط أنت تعرف زمن المزود الحقيقي، ويجب أن يكون عدداً صحيحاً.
الخيط لم يرث السياق أبداً. غلف الدالة في failproofai_sdk.propagate(). انظر الخيوط و async.
الحقول الإضافية تدمج آخراً، لذا أحد باسم مثل حقل حقيقي مثل model أو outcome سيكتب فوقه ويغير عمود مخزن. مساحة أسماء لك؛ المحولات تستخدم بادئة fw_.
agent_id هو جانب cardinality منخفض وأنت وضعت معرف تشغيل فيه. استخدم دوراً أو اسم عقدة وضع المعرف الحقيقي في حقل الحمولة.

التالي

كيف يعمل

الأزواج والمعرفات ودورة حياة الجلسة والتسليم.

اقرأ تتبع

اتبع السببية عبر الجلسة التي التقطتها للتو.

محولات الإطار

LangGraph و CrewAI و LlamaIndex و Pydantic AI.