تخطَّ إلى المحتوى
kazma.
EN نجمة 6 ابدأ الآن

OpenTelemetry — كاظمه في لوحة المعلومات التي لديك أصلًا

OpenTelemetry — كاظمه في لوحة المعلومات التي لديك أصلًا

Section titled “OpenTelemetry — كاظمه في لوحة المعلومات التي لديك أصلًا”

تُصدر كاظمه فترات OpenTelemetry GenAI لكل استدعاء LLM ولكل تنفيذ أداة. إذا كانت مؤسستك تشغّل أصلًا مجمّع OTel، تظهر آثار وكيل كاظمه فيه دون أي عمل تكامل ودون مُصدِّر خاص بكاظمه، لأن أسماء الخصائص هي الأسماء القياسية الصناعية لا أسماء اخترعناها.

خطوتان. ثبّت الحزم — فهي ليست تبعيات لكاظمه:

Terminal window
uv pip install opentelemetry-sdk opentelemetry-exporter-otlp

ثم وجّهها إلى مجمّعك عبر متغيرات OTLP القياسية:

Terminal window
export OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.internal:4317
export OTEL_SERVICE_NAME=kazma

هذا كل شيء. تثبّت كاظمه المُصدِّر بنفسها عند أول فترة، فلا تحتاج إلى opentelemetry-instrument ولا إلى تغيير أمر البدء.

يختار OTEL_EXPORTER_OTLP_PROTOCOL بين grpc (افتراضي OTLP) و http/protobuf. أما OTEL_EXPORTER_OTLP_TRACES_ENDPOINT و OTEL_EXPORTER_OTLP_TRACES_PROTOCOL فلهما الأسبقية إن ضبطتهما.

قاعدتان تمنعان هذا من أن يكون فظًّا:

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

مع غياب الحزم ونقطة النهاية معًا، يصبح كل مساعد فترة مديرَ سياق لا يفعل شيئًا. والمتتبّع المعياري الخالي من التبعيات في swarm/tracing.py غير متأثر ويبقى المسار الافتراضي.

:::note لماذا تضبط كاظمه المُصدِّر بنفسها تثبيت SDK وضبط OTEL_EXPORTER_OTLP_ENDPOINT لا يُنتج، من تلقاء نفسه، فتراتٍ في أي مكتبة — فحتى يثبّت شيءٌ ما TracerProvider، يبقى المزوّد العالمي ProxyTracerProvider وتبقى كل فترة NonRecordingSpan لا تذهب إلى أي مكان. الإجابة المعتادة هي إعادة الإطلاق تحت opentelemetry-instrument، ويعني ذلك حزمة إضافية وأمر بدء مختلفًا. مسودة سابقة من هذه الصفحة أخبرتك بضبط المتغيرين والاكتفاء بذلك؛ واختبار ذلك أمام مجمّع حقيقي أظهر أنه كان سيأخذك إلى لوحة فارغة، لذلك تتولى كاظمه التوصيل بدلًا من ذلك. :::

نوعان من الفترات، مسمّيان وفق الاتفاقيات حتى يتجمّعا بشكل صحيح في واجهة لم تسمع بكاظمه قط:

الفترةالنوعالاسمالخصائص المفتاحية
استدعاء LLMCLIENTchat {model}gen_ai.system, gen_ai.request.model, gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, gen_ai.response.finish_reasons
تنفيذ أداةINTERNALexecute_tool {name}gen_ai.operation.name, gen_ai.tool.name, gen_ai.tool.call.id

أثر حقيقي من دورة حيّة:

span: 'chat deepseek-flash' kind=CLIENT
gen_ai.system = 'deepseek'
gen_ai.operation.name = 'chat'
gen_ai.usage.input_tokens = 41370
gen_ai.usage.output_tokens = 512
span: 'execute_tool shell_exec' kind=INTERNAL
span: 'chat compound-mini' kind=CLIENT status=ERROR error.type='ValueError'

الخاصية gen_ai.system هي المزوّد، لا اسم المضيف — deepseek وgroq وanthropic وopenrouter وollama. البوابة غير المتعرَّف عليها تُبلغ عن openai، لأن ذلك هو بروتوكول السلك الذي تتحدثه وهو ما تصفه الخاصية.

فترة الدردشة تغطي الاستدعاء بالكامل بما فيه إعادة المحاولات من جهة المزوّد. من انتظر أربعين ثانية عبر ثلاث محاولات فقد انتظر أربعين ثانية؛ وفترةٌ لكل محاولة كانت ستبلغ عن ثلاثة استدعاءات سريعة وتخفي الكمون الذي خُبِر فعلًا.

أي شيء خارج المواصفة يوضع تحت نطاق kazma. حتى لا يتصادم أبدًا مع خاصية اتفاقية مستقبلية: kazma.llm.duration_ms وkazma.llm.tool_calls.

ما الذي لا تحصل عليه عمدًا

Section titled “ما الذي لا تحصل عليه عمدًا”

لا موجِّهات. لا إكمالات. لا وسطاء أدوات. لا نتائج أدوات.

تجعل الاتفاقيات التقاطَ الرسائل اختياريًا تحديدًا لأنه سطح لتسرّب البيانات. المنتج الذي شعاره وكيلك، جهازك لا ينبغي أن يبث محادثاتك إلى مجمّع افتراضيًا، لذا فـgen_ai.input.messages وgen_ai.output.messages غائبتان — ولا يوجد علم يشغّلهما. إضافة مثل هذا العلم قرارٌ مرفق بحجة خصوصية، لا افتراضُ ضبط، ويفشل اختبارٌ إن عادت السلاسل إلى الوحدة.

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

التتبّع القادر على إفشال طلب أسوأ من عدم التتبّع. إعداد الفترة محمي، والتعليق محمي، والمُصدِّر المعطوب يكلّفك فترةً لا إجابة.

الشيء الوحيد الذي يجب ألا يبتلعه الحارس أبدًا هو استثناءك أنت. مسودة مبكرة غلّفت جسم الفترة بـexcept Exception واسع بقصد امتصاص إخفاقات آلة الفترات، فالتقطت خطأ المستدعي المعاد رفعه بدلًا منه — وكانت ستبلّغ عن كل استدعاء LLM فاشل وكل أداة فاشلة بوصفه نجاحًا. اختباران اكتشفا ذلك قبل الشحن، وأربعة أخرى الآن تثبّت السلوك على مسار المُجهَّز ومسار بلا OpenTelemetry معًا، بما فيه KeyboardInterrupt، فلا يمكن أن يعود بصمت.

نقطتا الاختناق كلتاهما، حتى لا تتوقف التغطية على تذكّر مواضع الاستدعاء:

  • يغلّف LLMProvider.chat()‏ _chat_inner()
  • يغلّف LocalToolRegistry.execute()‏ _execute_inner()

كل استدعاء LLM وكل تنفيذ أداة في كاظمه يمر عبر إحدى هاتين النقطتين، وهي الخاصية نفسها التي تعتمد عليها بوابة الموافقة (انظر نموذج التهديد).