وقتی یک ایجنت هوش مصنوعی زنجیرهای از ابزارها، سرورهای MCP و فراخوانیهای متعدد مدل زبانی را اجرا میکند، عیبیابی کندی یا خطاهای مقطعی آن به یک کابوس تبدیل میشود. بدون داشتن دید سرتاسری، لاگهای ساده فقط نشان میدهند که کل پردازش زمان زیادی برده است، اما مشخص نمیکنند گلوگاه کجاست؛ آیا مدل زبانی تأخیر داشته، یا یکی از ابزارهای جانبی و سرورهای بیرونی دچار اختلال شده است.
قراردادهای معنایی OpenTelemetry GenAI این چالش را با یک استاندارد واحد حل کردهاند. با مجهز کردن برنامهها به این ساختار، اسپنها و سنجهها با قالبی یکپارچه تولید میشوند و به ابزارهای محلی و متنبازی مثل Jaeger یا پلتفرمهای مانیتورینگ دیگر ارسال میگردند، بدون اینکه وابستگی به ابزار پایش خاصی در منطق برنامه ایجاد شود.
از آنجا که بسیاری از بکاندهای ابری خارجی مانیتورینگ به دلیل تحریمها یا هزینههای ارزی دردسترس نیستند، مزیت بزرگ استاندارد OTel قابلیت ارسال آسان دادهها به کلکتورهای محلی و متنباز (مانند Jaeger یا نسخههای محلی Langfuse) است که به سادگی روی سرورهای داخلی یا سیستم شخصی بدون نیاز به سرویسهای پرداختی خارجی راهاندازی میشوند.
فرض کنید ایجنتی پنج ابزار، سه سرور MCP و دو زیرایجنت (Sub-agent) را فراخوانی میکند؛ شما برای بررسی تمام این فرایندها فقط به یک ردگیری محاسبات (Trace) سرتاسری نیاز دارید. قراردادهای معنایی OpenTelemetry GenAI (ویژگیهای پایدار در نسخهی 1.37 به بالا) استاندارد سال 2026 هستند و Datadog، Langfuse، Arize Phoenix، OpenLLMetry و AgentOps بهطور پیشفرض از آنها پشتیبانی میکنند. در این درس با ویژگیهای الزامی آشنا میشوید، ساختار سلسلهمراتبی اسپنها (Span؛ ایجنت ← مدل زبانی ← ابزار) را بررسی میکنید و یک ارسالکنندهی اسپن مبتنی بر کتابخانهی استاندارد پایتون پیادهسازی میکنید که به هر صادرکنندهی OTel متصل میشود.
اهداف یادگیری
- نام بردن ویژگیهای الزامی OTel GenAI برای اسپن مدل زبانی و اسپن اجرای ابزار.
- ساخت سلسلهمراتب ردگیری محاسبات شامل حلقهی ایجنت، فراخوانی مدل زبانی، فراخوانی ابزار و ارسال درخواست به کلاینت MCP.
- تصمیمگیری دربارهی ثبت محتوا (انتخابی یا Opt-in) در برابر سانسور دادهها (پیشفرض).
- ارسال اسپنها به یک گردآورندهی محلی (Jaeger، Langfuse) بدون نیاز به بازنویسی کدهای ابزار.
صورت مسئله
یک سناریوی خطایابی از فوریهی 2026: کاربر گزارش میدهد «ایجنتم گاهی ظرف 3 ثانیه پاسخ میدهد و گاهی 30 ثانیه طول میکشد.» هیچ ردی در دست نیست. لاگها فراخوانی مدل زبانی را نشان میدهند، اما اثری از اجرای ابزار، رفتوبرگشت سرور MCP یا زیرایجنت نیست. ناچارید حدس بزنید. در نهایت متوجه میشوید: یکی از سرورهای MCP گهگاه هنگام راهاندازی اولیه (Cold-start) گیر میکند.
بدون ردگیری سرتاسری (End-to-end tracing)، پیدا کردن این مشکل غیرممکن است. OTel GenAI دقیقاً این چالش را حل میکند.
این قراردادها در سالهای 2025 و 2026 در کارگروه قراردادهای معنایی OpenTelemetry نهایی شدند. آنها نامهای ثابتی برای ویژگیها تعریف میکنند تا Datadog، Langfuse، Phoenix، OpenLLMetry و AgentOps همگی اسپنهای یکسانی را پردازش کنند؛ یعنی یک بار سیستم را مجهز میکنید و دادهها را به هر بکاندی میفرستید.
مفاهیم پایه
سلسلهمراتب اسپنها
agent.invoke_agent (top, INTERNAL span)
├── llm.chat (CLIENT span)
├── tool.execute (INTERNAL)
│ └── mcp.call (CLIENT span)
├── llm.chat (CLIENT span)
└── subagent.invoke (INTERNAL)
تمام این ساختار ذیل یک شناسهی ردگیری (Trace ID) قرار میگیرد. شناسههای اسپن روابط والد-فرزندی را پیوند میدهند.
ویژگیهای الزامی
بر اساس قراردادهای معنایی سالهای 2025-2026:
gen_ai.operation.name— مقادیر"chat"،"text_completion"،"embeddings"،"execute_tool"،"invoke_agent".gen_ai.provider.name— مقادیر"openai"،"anthropic"،"google"،"azure_openai".gen_ai.request.model— رشتهی نام مدل درخواستی (مثلاً"gpt-4o-2024-08-06").gen_ai.response.model— نام مدلی که در عمل پاسخ داده است.gen_ai.usage.input_tokens/gen_ai.usage.output_tokens.gen_ai.response.id— شناسهی پاسخ ارائهدهنده برای تطبیق و همبستگی.
برای اسپنهای مربوط به ابزار:
gen_ai.tool.name— شناسهی ابزار.gen_ai.tool.call.id— شناسهی اختصاصی فراخوانی.gen_ai.tool.description— توضیحات ابزار (اختیاری).
برای اسپنهای مربوط به ایجنت:
gen_ai.agent.name/gen_ai.agent.id/gen_ai.agent.description.
انواع اسپن (Span kinds)
SpanKind.CLIENTبرای فراخوانیهایی که از مرز پروسس عبور میکنند (ارائهدهندهی مدل زبانی، سرور MCP).SpanKind.INTERNALبرای مراحل داخلی حلقهی ایجنت (Agent loop) و اجرای ابزارها.
ثبت انتخابی محتوا
اسپنها بهطور پیشفرض فقط سنجهها و زمانبندی را نگه میدارند، نه پرامپتها یا خروجیهای مدل را. ثبت بارهای کاری حجیم و دادههای هویتی و حساس (PII) در حالت عادی غیرفعال است. برای درج محتوا، باید متغیر محیطی OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental و متغیرهای محیطی مشخص ثبت محتوا را تنظیم کنید. پیش از فعالسازی این مورد در محیط عملیاتی، جوانب امنیتی را بهدقت بسنجید.
رویدادها روی اسپنها
رویدادهای در سطح توکن را میتوان بهصورت رویداد اسپن ثبت کرد:
gen_ai.content.prompt— پیامهای ورودی.gen_ai.content.completion— پیامهای خروجی.gen_ai.content.tool_call— فراخوانی ابزار به همان شکلی که ثبت شده است.
این رویدادها بر اساس زمان مرتب میشوند تا بازپخش و بررسی دقیق مراحل میسر شود.
صادرکنندهها (Exporters)
اسپنهای OTel به مقصدهای زیر صادر میشوند:
- Jaeger / Tempo: متنباز، قابل نصب روی سرورهای محلی.
- Langfuse: اختصاصیِ پایشپذیری مدلهای زبانی؛ مصورسازی مصرف توکنها.
- Arize Phoenix: ترکیب ارزیابیها و ردگیری محاسبات.
- Datadog: تجاری؛ با پشتیبانی مستقیم از ویژگیهای
gen_ai.*. - Honeycomb: پایگاه دادهی ستونمحور با قابلیت کوئریزدن سریع.
همهی این ابزارها از پروتکل OTLP که فرمت انتقال داده روی شبکه است پشتیبانی میکنند؛ بنابراین نوع بکاند تفاوتی در منطق کد شما ایجاد نمیکند.
انتشار کانتکست در MCP
وقتی کلاینت MCP سروری را صدا میزند، هدر استاندارد W3C با نام traceparent را به درخواست تزریق کنید. پروتکل Streamable HTTP از هدرهای استاندارد پشتیبانی میکند. از آنجا که رابط stdio هدرهای HTTP را پشتیبانی نمیکند، نقشهی راه سال 2026 این مشخصه، افزودن فیلد _meta.traceparent را در فراخوانیهای JSON-RPC پیشنهاد کرده است.
تا زمان پیادهسازی رسمی این قابلیت، traceparent را بهصورت دستی در بخش _meta هر درخواست قرار دهید تا سرور بتواند شناسهی ردگیری را لاگ کند.
سنجهها (Metrics)
قراردادهای معنایی GenAI در کنار اسپنها، سنجههای زیر را هم تعریف میکنند:
gen_ai.client.token.usage— نمودار توزیع فراوانی (هیستوگرام).gen_ai.client.operation.duration— هیستوگرام.gen_ai.tool.execution.duration— هیستوگرام.
از این سنجهها برای ساخت داشبوردهایی استفاده کنید که نیازی به جزئیات تکتک فراخوانیها ندارند.
لایهی AgentOps
پلتفرم AgentOps (تأسیس 2024) بهطور تخصصی روی پایشپذیری سیستمهای GenAI تمرکز دارد. این ابزار فریمورکهای متداول (LangGraph، Pydantic AI و CrewAI) را در بر میگیرد تا اسپنهای OTel را بهصورت خودکار تولید کند. اگر از فریمورکهای پشتیبانیشده استفاده میکنید این ابزار به کارتان میآید؛ در غیر این صورت باید کدها را دستی تجهیز کنید.
استفاده از ابزارهای واقعی
فایل code/main.py اسپنهایی با استاندارد OTel را (در قالبی شبیه به OTLP-JSON) برای ایجنتی در stdout چاپ میکند که یک مدل زبانی را فراخوانی کرده، دو ابزار را به کار انداخته و یک رفتوبرگشت MCP داشته است. در اینجا صادرکنندهی واقعی در کار نیست؛ تمرکز این درس روی ساختار اسپنها و مجموعهی ویژگیهای آنهاست. خروجی را در یک ابزار مشاهدهی OTLP کپی کنید یا مستقیماً آن را بخوانید.
به این بخشها دقت کنید:
- شناسهی ردگیری میان همهی اسپنها یکسان است.
- ارتباط والد-فرزندی از طریق
parentSpanIdثبت شده است. - ویژگیهای الزامی
gen_ai.*مقداردهی شدهاند. - ثبت محتوا بهطور پیشفرض غیرفعال است؛ اما در یکی از سناریوها با متغیر محیطی فعال میشود.
خروجی این درس
این درس فایل outputs/skill-otel-genai-instrumentation.md را تولید میکند. با دادن کد یک ایجنت به این مهارت، برنامهی دقیق تجهیز آن مشخص میشود: محل افزودن اسپنها، ویژگیهای موردنیاز برای مقداردهی و صادرکنندههای مناسب برای ارسال داده.
تمرینها
-
اسکریپت
code/main.pyرا اجرا کنید. تعداد اسپنها را بشمارید و مشخص کنید کدام CLIENT و کدام INTERNAL است. -
ثبت محتوا را با تنظیم متغیر محیطی فعال کنید و مطمئن شوید رویدادهای
gen_ai.content.promptوgen_ai.content.completionتولید میشوند. پیامدهای افشای دادههای هویتی و حساس (PII) را بررسی کنید. -
سنجهی اجرای ابزار با نام
gen_ai.tool.execution.durationرا اضافه کنید و آن را برای هر فراخوانی در قالب یک نمونهی هیستوگرام بفرستید. -
مقدار traceparent را از اسپن والدِ ایجنت به فیلد
_meta.traceparentدرخواست MCP منتقل کنید. بررسی کنید که آیا سرور MCP همان شناسهی ردگیری را دریافت میکند یا خیر. -
مستندات OTel GenAI semconv را بخوانید. یکی از ویژگیهای موجود در استاندارد را که در کدهای این درس نیامده است پیدا کنید و به کد بیفزایید.
اصطلاحات کلیدی
| اصطلاح | اصطلاح رایج | مفهوم واقعی |
|---|---|---|
| OTel | «اوپنتلمتری» | استاندارد باز برای ردگیریها، سنجهها و لاگها |
| GenAI semconv | «قراردادهای معنایی GenAI» | نامهای ثابت ویژگیها برای اسپنهای مدل زبانی / ابزار / ایجنت |
gen_ai.* |
«فضای نام ویژگیها» | پیشوند مشترک تمام ویژگیهای GenAI |
| Span | «عملیات زماندار» | واحدی از کار با زمان شروع، پایان و مجموعهای از ویژگیها |
| Trace | «نسبنامه و مسیر فراخوانیها» | درختی از اسپنها با شناسهی ردگیری یکسان |
| SpanKind | «انواع اسپن: CLIENT / SERVER / INTERNAL» | راهنمایی دربارهی جهت و مرز ارتباطی اسپن |
| OTLP | «پروتکل اوپنتلمتری» | فرمت انتقال داده روی شبکه برای صادرکنندهها |
| Opt-in content | «ثبت انتخابی محتوا» | ثبت پرامپت و پاسخ؛ پیشفرض خاموش، فعالسازی با متغیر محیطی |
| traceparent | «هدر W3C» | کانتکست ردگیری را میان سرویسها منتقل میکند |
| Exporter | «ارسالکنندهی داده به بکاند» | مؤلفهای که اسپنها را به Jaeger، Datadog یا سایر مقاصد میفرستد |
برای مطالعهی بیشتر
- OpenTelemetry — GenAI semconv — مستندات مرجع برای اسپنها، سنجهها و رویدادهای GenAI
- OpenTelemetry — GenAI spans — فهرست ویژگیهای اسپن مربوط به مدل زبانی و اجرای ابزار
- OpenTelemetry — GenAI agent spans — اسپنهای سطح ایجنت از نوع
invoke_agent - open-telemetry/semantic-conventions — GenAI spans — مرجع اصلی استاندارد در گیتهاب
- Datadog — LLM OTel semantic convention — راهنمای جامع پیادهسازی عملیاتی در Datadog
