प्रत्यक्ष OTel का उपयोग करके एजेंट अवलोकन को एकीकृत करें

यह मार्गदर्शिका आपको एजेंट टेलीमेट्री को सीधे OpenTelemetry (OTLP/HTTP+JSON) पर एजेंट टेलीमेट्री भेजने के माध्यम से शुरू से अंत तक ले जाती है। शुरू करने से पहले, मॉडल, प्रमाणीकरण प्रवाह और उन सतहों को समझने के लिए Agent 365 अवलोकन अवधारणाएँ पढ़ें, जिनमें आपका डेटा पहुँचता है।

महत्त्वपूर्ण

प्रत्यक्ष OTel पथ डिफ़ॉल्ट नहीं, बल्कि अपवाद है। इसका उपयोग केवल तभी करें जब आपके पास पहले से OpenTelemetry पाइपलाइन हो, आपका फ़्रेमवर्क Agent 365 SDK का उपयोग नहीं कर सकता हो, या आपका एजेंट ऐसी भाषा में हो जिसे SDK अभी तक समर्थन नहीं करता (जैसे Java)। अन्य सभी के लिए, अनुशंसित मार्ग Microsoft OpenTelemetry Distro है, जो Agent 365, Microsoft Foundry, Azure Monitor और अन्य के लिए एकीकृत observability SDK प्रदान करता है। पूर्व Observability SDK बिना किसी बदलाव के काम करता है, लेकिन अब नई इंटीग्रेशन के लिए अनुशंसित नहीं है; मौजूदा SDK उपयोगकर्ताओं के लिए माइग्रेशन मार्गदर्शन जल्द आ रहा है।

आवश्यकताएँ

किसी भी टेलीमेट्री प्रवाह से पहले सुनिश्चित करें कि निम्नलिखित कॉन्फ़िगरेशन लागू हैं।

कौन क्या
टैनेंट व्यवस्थापक Agent 365 के लिए साइन अप करें और अपने एजेंट ऐप के लिए सहमति प्रदान करें। देखें Agent 365 में ऑनबोर्डिंग। लाइसेंस प्राप्त टैनेंट के बिना, इंगेशन चुपचाप ड्रॉप कर दिया जाता है - अनुरोध 200 OK के साथ partialSuccess: null लौटाता है, लेकिन डेटा कभी भी डाउनस्ट्रीम दिखाई नहीं देता।
टैनेंट व्यवस्थापक टैनेंट में कम से कम एक उपयोगकर्ता को Microsoft 365 E7 या Microsoft Agent 365 लाइसेंस असाइन करें। SKU का केवल उपलब्ध होना पर्याप्त नहीं है। किसी उपयोगकर्ता को लाइसेंस असाइन करने से डिफेंडर बैकएंड वर्कफ़्लो प्रारंभ होता है, जो अंतर्ग्रहण को सक्षम करता है। असाइन किए गए लाइसेंस के बिना, अनुरोध 200 OK और partialSuccess: null के साथ लौटते हैं और डेटा बिना किसी सूचना के चुपचाप छोड़ दिया जाता है।
टैनेंट व्यवस्थापक टेनेंट की सहमति प्रदान करें। Microsoft 365 संसाधनों तक एजेंटों को पहुँच प्रदान करें देखें. इसके बिना, टोकन भूमिका/स्कोप के बिना जारी किए जाते हैं और अनुरोध 403 लौटाते हैं।
आपकी डेव टीम अपने ऐप को पंजीकृत करें (मानक Microsoft Entra ऐप या ब्लूप्रिंट)। देखें Agent 365 विकास की शुरुआत करें।
आपकी डेव टीम एपीआई अनुमतियाँ के तहत Agent365.Observability.OtelWrite जोड़ें (S2S के लिए ऐप भूमिका, delegated के लिए स्कोप)। ब्लूप्रिंट्स के लिए, इनहेरिटेबल अनुमतियाँ कॉन्फ़िगर करें देखें। अनुमति को सक्षम करने के लिए Agent 365 ऑनबोर्डिंग टीम के साथ समन्वय करें।

प्रमाणीकरण विधियाँ

सभी चार विधियाँ मानक Microsoft Entra टोकन समापन बिंदु का उपयोग करती हैं:

क्षेत्र मान
टोकन एंडपॉइंट https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
संसाधन (aud लौटाए गए टोकन में) 9b975845-388f-4429-889e-eab1ef63949c (साथ ही api://9b975845-388f-4429-889e-eab1ef63949c को भी स्वीकार करता है)
S2S कार्यक्षेत्र 9b975845-388f-4429-889e-eab1ef63949c/.default
OBO कार्यक्षेत्र 9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite

नीचे दिए गए उदाहरण स्पष्टता के लिए कच्चा HTTP दिखाते हैं। उत्पादन में, Microsoft.Identity.Web या कोई अन्य MSAL लाइब्रेरी, जो टोकन रीफ्रेश और कैशिंग को संभालती है, को प्राथमिकता दें।

मुझे किस नुस्खे की आवश्यकता है?

मेरा ऐप मॉडल मेरा OAuth प्रवाह यहाँ जाएँ
मानक Microsoft Entra ऐप पंजीकरण S2S (क्लाइंट क्रेडेंशियल्स) S2S, मानक Microsoft Entra ऐप
मानक Microsoft Entra ऐप पंजीकरण OBO (प्रदत्त) OBO, मानक Microsoft Entra ऐप
ब्लूप्रिंट-आधारित एजेंट पहचान S2S (क्लाइंट क्रेडेंशियल्स) S2S, ब्लूप्रिंट-व्युत्पन्न एजेंट पहचान
ब्लूप्रिंट-आधारित एजेंट पहचान ओबीओ/एआई टीममेट ओबीओ, ब्लूप्रिंट-व्युत्पन्न एजेंट पहचान

S2S, मानक Microsoft Entra ऐप

किरायेदार के टोकन एंडपॉइंट पर grant_type=client_credentials के साथ एक POST करें। क्लाइंट सीक्रेट, सर्टिफिकेट (साइन किया गया JWT असर्शन), या प्रबंधित पहचान या फेडरेटेड क्रेडेंशियल का उपयोग करके ऐप को प्रमाणित करें।

POST https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

client_id={your-app-id}
&scope=9b975845-388f-4429-889e-eab1ef63949c%2F.default
&client_secret={secret}
&grant_type=client_credentials

लौटाए गए टोकन में appid/azp = {your-app-id} हैं, roles जिसमें Agent365.Observability.OtelWrite शामिल है, और aud = 9b975845-... हैं। /observabilityService/.../traces मार्ग पर इसका उपयोग करें।

प्रमाणपत्र-आधारित प्रमाणीकरण के लिए, client_secret={secret} को client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion={signed-jwt} से बदलें।

S2S, ब्लूप्रिंट-आधारित एजेंट पहचान

एजेंट पहचान के पास अपनी क्रेडेंशियल्स नहीं होती हैं। एजेंट पहचान ब्लूप्रिंट क्रेडेंशियल्स (प्रबंधित पहचान FIC, प्रमाणपत्र, या क्लाइंट सीक्रेट) रखता है और दो-चरणीय एक्सचेंज के माध्यम से अपनी चाइल्ड एजेंट पहचानों की ओर से टोकन जारी करता है। अधिक जानकारी के लिए, ऑटोनॉमस एप OAuth फ्लो देखें।

  1. ब्लूप्रिंट प्रमाणित करता है और एक फ़ेडरेटेड आइडेंटिटी एक्सचेंज टोकन T1 प्राप्त करता है:

    • {blueprint-credential} ब्लूप्रिंट का MSI टोकन, प्रमाणपत्र-हस्ताक्षरित JWT, या गुप्त एक्सचेंज-टोकन दावा - जैसा कि ब्लूप्रिंट विन्यास में तय किया गया है।
    POST https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
    Content-Type: application/x-www-form-urlencoded
    
    client_id={blueprint-app-id}
    &scope=api%3A%2F%2FAzureADTokenExchange%2F.default
    &fmi_path={agent-identity-app-id}
    &client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
    &client_assertion={blueprint-credential}
    &grant_type=client_credentials
    
  2. एजेंट पहचान Agent 365 अवलोकन संसाधन टोकन के लिए आदान-प्रदान करता T1 है:

    POST https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
    Content-Type: application/x-www-form-urlencoded
    
    client_id={agent-identity-app-id}
    &scope=9b975845-388f-4429-889e-eab1ef63949c%2F.default
    &client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
    &client_assertion={T1}
    &grant_type=client_credentials
    
    • लौटाए गए टोकन में appid/azp = {agent-identity-app-id} हैं, roles जिसमें Agent365.Observability.OtelWrite शामिल है, और aud = 9b975845-... हैं।
    • इस टोकन का उपयोग /observabilityService/.../traces मार्ग पर करें।
    • URL {agentId} एजेंट पहचान appId है, ब्लूप्रिंट appId नहीं।

OBO, मानक Microsoft Entra ऐप

अपने अपस्ट्रीम कॉलर (Bearer या PFAT) से उपयोगकर्ता का इनकमिंग टोकन Tc प्राप्त करें, फिर उसका आदान-प्रदान करें:

POST https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded

client_id={your-app-id}
&scope=9b975845-388f-4429-889e-eab1ef63949c%2FAgent365.Observability.OtelWrite
&client_secret={secret}
&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion={Tc}
&requested_token_use=on_behalf_of

प्रमाणपत्र प्रमाणीकरण के लिए, client_secret={secret} को S2S के समान client_assertion_type + client_assertion युग्म से बदलें।

लौटाए गए टोकन में appid/azp = {your-app-id} हैं, scp जिसमें Agent365.Observability.OtelWrite शामिल है, और aud = 9b975845-... हैं। /observability/.../traces मार्ग पर इसका उपयोग करें। रिफ्रेश टोकन साथ में लौटाया जाता है; इसे कैश करें और प्रत्येक कॉल पर एक्सचेंज प्रक्रिया को दोहराने के बजाय इसका पुनः उपयोग करें।

ओबीओ, ब्लूप्रिंट-व्युत्पन्न एजेंट पहचान (एआई टीममेट सहित)

ओबीओ प्रवाह के तीन मुख्य चरण हैं। अधिक जानकारी के लिए देखें एजेंट OAuth फ्लोज़: ओबीओ प्रवाह।

  1. उपयोगकर्ता टोकन Tcप्राप्त करें। एआई टीम के साथी के लिए, यह टोकन एजेंट के अपने उपयोगकर्ता खाते का प्रतिनिधित्व करता है; अन्यथा, यह मानव कॉलर का प्रतिनिधित्व करता है।

  2. ब्लूप्रिंट प्रमाणित करता है और T1 प्राप्त करता है, जो S2S ब्लूप्रिंट-व्युत्पन्न एजेंट पहचान प्रवाह के समान है।

  3. एजेंट पहचान T1 और Tc का आदान-प्रदान एक प्रत्यायोजित संसाधन टोकन के लिए करता है:

    POST https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
    Content-Type: application/x-www-form-urlencoded
    
    client_id={agent-identity-app-id}
    &scope=9b975845-388f-4429-889e-eab1ef63949c%2FAgent365.Observability.OtelWrite
    &client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
    &client_assertion={T1}
    &grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
    &assertion={Tc}
    &requested_token_use=on_behalf_of
    

लौटाए गए टोकन appid/azp = {agent-identity-app-id}, scp हैं जिसमे Agent365.Observability.OtelWrite शामिल है, और एजेंट के उपयोगकर्ता का प्रतिनिधित्व करता है। /observability/.../traces मार्ग पर इसका उपयोग करें। URL {agentId} एजेंट पहचान appId है, ब्लूप्रिंट appId नहीं। एक ताज़ा टोकन साथ में लौटाया जाता है; कैश करें और इसका पुन: उपयोग करें।

लौटाए गए टोकन में आवश्यक क्लेम्स

S2S रूट (/observabilityService/...) - ऐप-ओनली टोकन:

दावा आवश्यक मान
aud 9b975845-388f-4429-889e-eab1ef63949c (या api://9b975845-...)
roles इसमें Agent365.Observability.OtelWrite होना चाहिए
appid (v1) या azp (v2) URL के बराबर होना चाहिए {agentId}
scp अनुपस्थित होना चाहिए

प्रत्यायोजित मार्ग (/observability/...) - उपयोगकर्ता-प्रत्यायोजित टोकन (बेयरर या PFAT):

दावा आवश्यक मान
aud 9b975845-388f-4429-889e-eab1ef63949c (या api://9b975845-...)
scp इसमें Agent365.Observability.OtelWrite होना चाहिए
appid / azp URL के बराबर होना चाहिए {agentId}

प्रत्यायोजित मार्ग दोनों Bearer और MSAuth1.0 PFAT टोकन स्वीकार करता है। सीधे कॉल करने वालों को Bearer का उपयोग करना चाहिए। यदि आपको नहीं पता कि आपके पास कौन सा है, Bearer का उपयोग करें।

समाप्ति बिंदु

दो मार्ग; इस आधार पर चुनें कि आपकी सेवा कैसे प्रमाणित करती है, न कि उपयोगकर्ता क्या कर रहा है:

POST https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1   # S2S
POST https://agent365.svc.cloud.microsoft/observability/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1          # OBO

शीर्षलेख:

Authorization: Bearer <token>      # or MSAuth1.0 ... for delegated PFAT
Content-Type: application/json

URL पैरामीटर

  • {tenantId} - ग्राहक टैनेंट GUID। सर्वर इसे आधिकारिक मानता है; यदि आपके स्पैन microsoft.tenant.id सेट करते हैं और यह असहमत होता है, तो अनुरोध अस्वीकार कर दिया जाता है।
  • {agentId} - कॉलिंग एप्लिकेशन का appId (यह client_idOAuth भी है)। ब्लूप्रिंट-व्युत्पन्न पहचान के लिए, यह एजेंट पहचान appId है, न कि ब्लूप्रिंट appId। यह मान आपके टोकन के appid / azp क्लेम के बराबर होना चाहिए।
  • api-version=1 - आवश्यक है।

अनुरोध के मुख्य भाग का एन्कोड हो रहा है

शरीर मानक OTLP/HTTP+JSON आकार है: ExportTraceServiceRequest के साथ resourceSpans → scopeSpans → spans हैं। इन बातों का ध्यान रखें:

  • traceId (16 बाइट्स) और spanId (8 बाइट्स) को लोअरकेस हेक्स स्ट्रिंग्स के रूप में भेजा जाता है।
  • startTimeUnixNano / endTimeUnixNanoयूनिक्स युग नैनोसेकंड धारण करने वाले तार हैं।
  • kind पूर्णांक OTLP एनम मान है (उदाहरण के लिए 1INTERNAL); status.code पूर्णांक एनम है (उदाहरण के लिए 1OK, 2ERROR)।
  • सभी विशेषता मान stringValue के रूप में भेजे जाते हैं।

प्रतिक्रिया संरचना

एक सफल कॉल 200 OK लौटाता है:

{ "partialSuccess": null }

यदि कुछ स्पैन प्रति-स्पैन फ़िल्टर द्वारा अस्वीकार किए गए हों:

{
  "partialSuccess": {
    "rejectedSpans": 2,
    "errorMessage": "Dropped 2 non-A365 span(s) ..."
  }
}

फ़ील्ड नाम वायर पर camelCase में होते हैं। हमेशा partialSuccess की जाँच करें: यदि आपको 200 प्रतिक्रिया मिले और आपके सभी स्पैन अस्वीकृत हो जाएँ, तो यह एक वास्तविक परिणाम है जिसे आपको रिपोर्ट करना चाहिए। सीमाएं और ड्रॉप की शर्तें उन साइलेंट ड्रॉप मामलों को सूचीबद्ध करती हैं, जहाँ partialSuccess: null के साथ 200 रिटर्न होता है, बावजूद इसके कि डाउनस्ट्रीम में कोई डेटा दिखाई नहीं देता।

सबसे छोटा संभव अनुरोध

सबसे सरल एंड-टू-एंड परीक्षण एक स्पैन invoke_agent भेजता है। यह स्पैन Microsoft Defender में पहुँचने वाली सबसे छोटी इकाई है।

चरण 1. बियरर टोकन प्राप्त करें। S2S के लिए, स्कोप 9b975845-388f-4429-889e-eab1ef63949c/.default के साथ क्लाइंट क्रेडेंशियल्स का उपयोग करें (पूर्ण नुस्खा के लिए प्रमाणीकरण व्यंजन देखें)।

चरण 2. एक स्पैन पोस्ट करें:

TOKEN="$(./get-token.sh)"
TENANT_ID="<customer-tenant-guid>"
AGENT_ID="<your-agent-app-id>"

curl -i -X POST \
  "https://agent365.svc.cloud.microsoft/observabilityService/tenants/${TENANT_ID}/otlp/agents/${AGENT_ID}/traces?api-version=1" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  --data @- <<EOF
{
  "resourceSpans": [{
    "scopeSpans": [{
      "scope": { "name": "my-instrumentation", "version": "1.0.0" },
      "spans": [{
        "traceId": "0102030405060708090a0b0c0d0e0f10",
        "spanId":  "1111111111111111",
        "parentSpanId": "",
        "name": "invoke_agent",
        "kind": 1,
        "startTimeUnixNano": "1736175600000000000",
        "endTimeUnixNano":   "1736175601500000000",
        "status": { "code": 1 },
        "attributes": [
          { "key": "gen_ai.operation.name", "value": { "stringValue": "invoke_agent" } },
          { "key": "gen_ai.agent.id",       "value": { "stringValue": "${AGENT_ID}" } },
          { "key": "gen_ai.agent.name",     "value": { "stringValue": "MyAgent" } },
          { "key": "microsoft.a365.agent.blueprint.id", "value": { "stringValue": "${AGENT_ID}" } },
          { "key": "gen_ai.conversation.id","value": { "stringValue": "conv-001" } },
          { "key": "microsoft.channel.name","value": { "stringValue": "web" } },
          { "key": "user.id",               "value": { "stringValue": "<entra-user-objectid>" } },
          { "key": "client.address",        "value": { "stringValue": "10.1.2.80" } },
          { "key": "server.address",        "value": { "stringValue": "myagent.example.com" } },
          { "key": "server.port",           "value": { "stringValue": "443" } },
          { "key": "gen_ai.input.messages", "value": { "stringValue": "[{\"role\":\"user\",\"content\":\"hi\"}]" } },
          { "key": "gen_ai.output.messages","value": { "stringValue": "[{\"role\":\"assistant\",\"content\":\"hello\"}]" } }
        ]
      }]
    }]
  }]
}
EOF

चरण 3. इस बॉडी के साथ 200 OK अपेक्षा करें:

{ "partialSuccess": null }

चरण 4. पुष्टि करें कि डेटा वास्तव में उतरा है। 200 ओके अंतर्ग्रहण का प्रमाण नहीं है; अंतर्ग्रहण की पुष्टि सत्यापन प्रवाह के माध्यम से चलता है। इसके बजाय सहेजी गई बॉडी फ़ाइल पोस्ट करने के लिए, --data @- <<EOF ... EOF को --data @./otlp-request.json से बदलें।

एजेंट रन उदाहरण

Microsoft Teams पर एक उपयोगकर्ता पूछता है "सिएटल में मौसम कैसा है?"। आपका एजेंट GetWeather फ़ंक्शन को कॉल करता है, LLM से उत्तर को प्रारूपित करने के लिए कहता है, और उत्तर देता है। वह एकल रन चार स्पैन है:

graph TD
    A["<b>invoke_agent</b> · spanId=A · parentSpanId=∅<br/><i>root - the run itself</i>"]
    B["<b>chat</b> · spanId=B · parentSpanId=A<br/><i>LLM picks the tool / formats reply</i>"]
    C["<b>execute_tool</b> · spanId=C · parentSpanId=A<br/><i>the GetWeather call</i>"]
    D["<b>output_messages</b> · spanId=D · parentSpanId=A<br/><i>final reply emitted to the user</i>"]
    A --> B
    A --> C
    A --> D

हर स्पैन पर सेट की गई रन-वाइड विशेषताएँ:

विशेषता उदाहरण मान
traceId 0102030405060708090a0b0c0d0e0f10
gen_ai.conversation.id 19:abc@thread.tacv2
microsoft.session.id session-1234
microsoft.channel.name msteams
gen_ai.agent.id <AGENT_APP_ID>
gen_ai.agent.name WeatherBot
microsoft.a365.agent.blueprint.id <BLUEPRINT_APP_ID>
user.id <entra-user-objectid>
client.address 10.1.2.80
server.address weatherbot.example.com
server.port 443

महत्त्वपूर्ण

ये रन-वाइड विशेषताएँ स्वचालित रूप से प्रचारित नहीं होती हैं। प्रत्येक स्पैन पर आपको gen_ai.conversation.id, microsoft.channel.name, और microsoft.session.id स्वयं सेट करना होगा।

स्पैन A: invoke_agent (रूट)

{
  "traceId": "0102030405060708090a0b0c0d0e0f10",
  "spanId": "1111111111111111",
  "parentSpanId": "",
  "name": "invoke_agent",
  "kind": 1,
  "startTimeUnixNano": "1736175600000000000",
  "endTimeUnixNano":   "1736175601500000000",
  "status": { "code": 1 },
  "attributes": [
    { "key": "gen_ai.operation.name",   "value": { "stringValue": "invoke_agent" } },
    { "key": "gen_ai.execution.type",   "value": { "stringValue": "HumanToAgent" } },
    { "key": "gen_ai.input.messages",   "value": { "stringValue": "[{\"role\":\"user\",\"content\":\"What's the weather in Seattle?\"}]" } },
    { "key": "gen_ai.output.messages",  "value": { "stringValue": "[{\"role\":\"assistant\",\"content\":\"It's 65F and partly cloudy in Seattle.\"}]" } },
    { "key": "user.email",              "value": { "stringValue": "alice@contoso.com" } }
    /* plus all the run-wide attributes listed above */
  ]
}

स्पैन बी: chat (LLM कॉल)

{
  "traceId": "0102030405060708090a0b0c0d0e0f10",
  "spanId": "2222222222222222",
  "parentSpanId": "1111111111111111",
  "name": "chat",
  "kind": 1,
  "startTimeUnixNano": "1736175600200000000",
  "endTimeUnixNano":   "1736175600900000000",
  "status": { "code": 1 },
  "attributes": [
    { "key": "gen_ai.operation.name",      "value": { "stringValue": "chat" } },
    { "key": "gen_ai.request.model",       "value": { "stringValue": "gpt-4o" } },
    { "key": "gen_ai.provider.name",       "value": { "stringValue": "openai" } },
    { "key": "gen_ai.usage.input_tokens",  "value": { "stringValue": "42" } },
    { "key": "gen_ai.usage.output_tokens", "value": { "stringValue": "23" } }
    /* plus all the run-wide attributes */
  ]
}

स्पैन C: execute_tool

{
  "traceId": "0102030405060708090a0b0c0d0e0f10",
  "spanId": "3333333333333333",
  "parentSpanId": "1111111111111111",
  "name": "execute_tool",
  "kind": 1,
  "startTimeUnixNano": "1736175600950000000",
  "endTimeUnixNano":   "1736175601200000000",
  "status": { "code": 1 },
  "attributes": [
    { "key": "gen_ai.operation.name",      "value": { "stringValue": "execute_tool" } },
    { "key": "gen_ai.tool.name",           "value": { "stringValue": "GetWeather" } },
    { "key": "gen_ai.tool.type",           "value": { "stringValue": "function" } },
    { "key": "gen_ai.tool.call.id",        "value": { "stringValue": "call-001" } },
    { "key": "gen_ai.tool.call.arguments", "value": { "stringValue": "{\"location\":\"Seattle\"}" } },
    { "key": "gen_ai.tool.call.result",    "value": { "stringValue": "{\"tempF\":65,\"condition\":\"partly cloudy\"}" } }
    /* plus all the run-wide attributes */
  ]
}

स्पैन D: output_messages

{
  "traceId": "0102030405060708090a0b0c0d0e0f10",
  "spanId": "4444444444444444",
  "parentSpanId": "1111111111111111",
  "name": "output_messages",
  "kind": 1,
  "startTimeUnixNano": "1736175601400000000",
  "endTimeUnixNano":   "1736175601500000000",
  "status": { "code": 1 },
  "attributes": [
    { "key": "gen_ai.operation.name",  "value": { "stringValue": "output_messages" } },
    { "key": "gen_ai.output.messages", "value": { "stringValue": "[{\"role\":\"assistant\",\"content\":\"It's 65F and partly cloudy in Seattle.\"}]" } }
    /* plus all the run-wide attributes */
  ]
}

टेलीमेट्री भेजना

OTel SDK का उपयोग करना

अधिकांश भागीदार स्वनिर्मित HTTP के बजाय OTel SDK के माध्यम से ट्रेस भेजते हैं। SDK आपके लिए बैचिंग, पुनः प्रयास और OTLP/HTTP+JSON एन्कोडिंग का प्रबंधन करता है। निर्यातक समापन बिंदु सेट करें और Authorization हेडर इंजेक्ट करें।

निर्यातक समापन बिंदु स्वयं मार्ग URL है, जिसमें क्वेरी स्ट्रिंग भी शामिल है:

https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1

(प्रत्यायोजित मार्ग के लिए /observability/... का इस्तेमाल करें, /observabilityService/... के स्थान पर।)

Python

from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter

exporter = OTLPSpanExporter(
    endpoint="https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1",
    headers={"Authorization": f"Bearer {token}"},
)

पैकेज: opentelemetry-exporter-otlp-proto-http।

Node.js / TypeScript

import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";

const exporter = new OTLPTraceExporter({
  url: "https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1",
  headers: { Authorization: `Bearer ${token}` },
});

पैकेज: @opentelemetry/exporter-trace-otlp-http।

.NET

using OpenTelemetry.Exporter;

services.AddOpenTelemetry().WithTracing(b => b
    .AddOtlpExporter(o =>
    {
        o.Endpoint = new Uri("https://agent365.svc.cloud.microsoft/observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces?api-version=1");
        o.Headers = $"Authorization=Bearer {token}";
        o.Protocol = OtlpExportProtocol.HttpJson;
    }));

पैकेज: OpenTelemetry.Exporter.OpenTelemetryProtocol।

मैन्युअल HTTP

यदि आप OTel SDK का उपयोग नहीं कर सकते या नहीं करना चाहते, तो OTLP/HTTP+JSON अनुरोध स्वयं बनाएं और इसे POST करें। शरीर का आकार OpenTelemetry OTLP/HTTP+JSON युक्ति द्वारा परिभाषित किया गया है:

{
  "resourceSpans": [{
    "resource":  { "attributes": [ ... ] },          // optional
    "scopeSpans": [{
      "scope":  { "name": "<your-instrumentation>", "version": "1.0.0" },
      "spans":  [ <span>, <span>, ... ]
    }]
  }]
}

प्रत्येक <span> एक वस्तु है जिसकी आवश्यक फील्ड्स traceId, spanId, name, kind, startTimeUnixNano, endTimeUnixNano, attributes हैं, और (गैर-रूट स्पैन के लिए) parentSpanId। एन्कोडिंग नियमों के लिए एंडपॉइंट्स और रिक्वेस्ट बॉडी एन्कोडिंग देखें (जैसे: स्ट्रिंग-एन्कोडेड समय, हेक्स traceId / spanId, पूर्णांक kind / status.code, सभी एट्रिब्यूट मान stringValue के रूप में)।

प्रत्येक स्पैन पर सेट की जाने वाली विशेषताओं का समूह संदेश अनुबंधों में परिभाषित है। पूर्ण एट्रिब्यूट सूची के लिए, एट्रिब्यूट संदर्भ देखें। एजेंट रन उदाहरण देखें, जिसमें हेडर में बियरर टोकन और बॉडी इनलाइन के साथ एक एंड-टू-एंड कार्यशील उदाहरण है।

आप एक रन के सभी स्पैन को एक ही POST बॉडी में भेज सकते हैं (पसंदीदा - एक अनुरोध, एक ट्रेस) या कई POST के माध्यम से भेज सकते हैं। सर्वर रन traceId + parentSpanId + gen_ai.conversation.id को फिर से बनाता है, इसलिए प्रत्येक स्पैन किसी भी तरह से सहसंबद्ध होने के लिए पर्याप्त है।

Message सम्पर्क

इस अनुभाग में बताया गया है कि आप कौन-कौन से स्पैन प्रेषित कर सकते हैं और प्रत्येक में कौन-कौन सी विशेषताएँ शामिल करनी हैं। पूरा विशेषता-बाय-विशेषता स्पेसिफिकेशन देखने के लिए एट्रिब्यूट विशेषता देखें।

ऑपरेशन के प्रकार

हर स्पैन में gen_ai.operation.name इन चार मानों में से किसी एक पर (केस-असंवेदनशील) सेट होना चाहिए। कोई भी स्पान जिसमें मान गायब या अपरिचित हो, उसे चुपचाप छोड़ दिया जाता है और partialSuccess.rejectedSpans में गणना की जाती है।

gen_ai.operation.name अर्थ सबसे अधिक गूदा गया
invoke_agent एक एजेंट का आह्वान। एजेंट रन की "रूट"। यह आवश्यक है ताकि रन Microsoft Defender एजेंट-गतिविधि दृश्य या Microsoft 365 व्यवस्थापन केंद्र में दिखाई दे सके। इसके बिना, टेलीमेट्री केवल Microsoft Defender एडवांस्ड हंटिंग (CloudAppEvents) में ही सीमित रहती है।
execute_tool एजेंट द्वारा किया गया टूल/फंक्शन कॉल। --
chat एक LLM इनफेरेंस कॉल। chat लिटरल का उपयोग करें, ना कि inference।
output_messages एक अंतिम उत्सर्जित आउटपुट संदेश। --

स्पैन पदानुक्रम और रन समूहीकरण

Agent 365 मानक OTLP स्पैन ग्राफ़ (traceId, spanId, parentSpanId) और विशेषता संदर्भ से रन-वाइड विशेषताओं को जोड़कर एक रन का पुनर्निर्माण करता है।

छह नियम:

  1. हमेशा हर नॉन-रूट स्पैन पर सेट करें parentSpanId । इसके बिना, रन के पेड़ की संरचना का पुनर्निर्माण नहीं किया जा सकता है।
  2. हर रन में प्रत्येक स्पैन में उसी traceId का पुनः उपयोग करें।
  3. समान मूल्य के साथ gen_ai.conversation.idप्रत्येक स्पैन पर सेट करें। यह "इस रन में सभी स्पैन" के लिए प्राथमिक जॉइन कुंजी है। यह स्वचालित रूप से नहीं प्रसारित होता है।
  4. समान मूल्य के साथ प्रत्येक स्पैन पर microsoft.channel.name सेट करें। चैनल / संवाद अनुपस्थित होने वाले टूल स्पैन अपने पैरेंट से विरासत में ले सकते हैं invoke_agentकेवल तब जब पैरेंट उसी OTLP अनुरोध में हो, इसलिए इन्हें हर स्पैन पर स्वयं सेट करें।
  5. हर अवधि पर microsoft.session.id सेट करें जब आपके पास एक तार्किक सत्र हो।
  6. ऐजेंट-से-ऐजेंट कॉल्स के लिए, जहाँ चाइल्ड एजेंट अलग अनुरोध में है, उसी gen_ai.conversation.id का पुन: उपयोग करें और कॉलर-एजेंट संदर्भ को कैप्चर करने के लिए microsoft.a365.caller.agent.* एट्रिब्यूट्स का उपयोग करें (देखें: एट्रिब्यूट रेफरेंस)।

एजेंट रन उदाहरण में चार-स्पैन ट्री आदर्श संरचना है।

सामान्य रन आकार

आकार उत्सर्जित करने के लिए स्पैन नोट
एकल-एजेंट चैटबॉट (कोई उपकरण नहीं, कोई एलएलएम स्पैन नहीं) केवल एक invoke_agent रन-वाइड विशेषताओं के साथ gen_ai.input.messages और gen_ai.output.messages भी सेट करें। सबसे छोटे संभव अनुरोध के समान।
टूल्स के साथ एजेंट (सबसे आम) invoke_agentजड़ + chat, execute_toolबच्चे output_messages सभी चाइल्ड रूट का traceId साझा करते हैं और parentSpanId = root.spanId सेट करते हैं। सभी में समान रन-वाइड विशेषताएँ होती हैं। पूर्ण उदाहरण के लिए एजेंट रन उदाहरण देखें।
एजेंट-टू-एजेंट प्रत्येक एजेंट अपना स्वयं का उत्सर्जन करता है invoke_agent दोनों एजेंटों में एक ही gen_ai.conversation.id का पुनः उपयोग करें। लक्ष्य के invoke_agent पर, सेट gen_ai.execution.type = "Agent2Agent" और microsoft.a365.caller.agent.* विशेषताएँ (कॉलिंग एजेंट का appId, नाम, खाका appId, उपयोगकर्ता आईडी और ईमेल)। यदि कॉलिंग एजेंट के पास कोई Entra पंजीकरण नहीं है, तो microsoft.a365.caller.agent.platform.id और gen_ai.caller.agent.type का उपयोग करें।

ऑनबोर्डिंग चेकलिस्ट

उत्पादन पर जाने से पहले इस चेकलिस्ट को पूरा करें।

श्रेणी जाँचें
प्रमाणीकरण आपका Entra ऐप (या ब्लूप्रिंट) पंजीकृत है और आप इसके लिए टोकन जारी कर सकते हैं।
प्रमाणीकरण आपके ऐप को Agent365.Observability.OtelWrite (S2S के लिए ऐप भूमिका, प्रत्यायोजित के लिए गुंजाइश) प्रदान किया गया है।
प्रमाणीकरण प्रत्येक एजेंट का अपना Entra appId होता है जैसा कि {agentId} URL में होता है। ब्लूप्रिंट-व्युत्पन्न पहचान के लिए, वह appId एजेंट पहचान appId है, न कि ब्लूप्रिंट appId। यदि एजेंट के पास कोई Entra पंजीकरण नहीं है, तो मान चुनना देखें।
प्रमाणीकरण एक टैनेंट व्यवस्थापक ने सहमतिAgent365.Observability.OtelWrite के लिए दी है। सहमति के बिना, टोकन भूमिका/दायरे के बिना जारी किए जाते हैं और अनुरोधों को अस्वीकार कर दिया जाता है 403।
लाइसेंसिंग ग्राहक टैनेंट में कम से कम एक उपयोगकर्ता को Microsoft 365 E7 या Microsoft Agent 365 लाइसेंस आवंटित किया गया है (आवंटन, टैनेंट में केवल SKU की उपस्थिति नहीं)। एक निर्दिष्ट लाइसेंस के बिना, अंतर्ग्रहण चुपचाप छोड़ दिया जाता है। पूर्वावश्यकताएँ देखें।
स्पैन्स प्रत्येक स्पैन रन-वाइड अनिवार्यता (स्पैन पदानुक्रम और रन ग्रुपिंग) सेट करता है।
स्पैन्स invoke_agentस्पैन सेट gen_ai.input.messages और gen_ai.output.messages।
स्पैन्स execute_tool स्पैन सेट gen_ai.tool.name, gen_ai.tool.type, gen_ai.tool.call.id, gen_ai.tool.call.arguments, gen_ai.tool.call.result.
स्पैन्स chat स्पैन सेट में gen_ai.request.model और gen_ai.provider.name (और आदर्श रूप से gen_ai.usage.input_tokens / gen_ai.usage.output_tokens - स्ट्रिंग-एन्कोडेड) शामिल हैं।
स्पैन्स सभी गैर-रूट स्पैन सेट हैं parentSpanId; एक रन में सभी स्पैन समान साझा करते हैं traceId।
पेलोड रिक्वेस्ट बॉडी 1 एमबी या उससे कम होनी चाहिए।
सत्यापन आप हर प्रतिक्रिया में partialSuccess को पार्स करते हैं और अस्वीकृतियों को लॉग करते हैं।
सत्यापन आपने अपने पहले रन के खिलाफ अंतर्ग्रहण की पुष्टि करने में सत्यापन प्रवाह चलाया।

अगले चरण

  • विशेषता संदर्भ - प्रत्येक विशेषता के विनिर्देश और मूल्य चयन मार्गदर्शन।
  • समस्या निवारण - अंतर्ग्रहण, सामान्य नुकसान और त्रुटि प्रतिक्रियाओं की पुष्टि करना।