หมายเหตุ
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลอง ลงชื่อเข้าใช้หรือเปลี่ยนไดเรกทอรีได้
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลองเปลี่ยนไดเรกทอรีได้
คู่มือนี้จะแนะนำให้คุณรู้จักกระบวนการตั้งแต่ต้นจนจบในการส่งข้อมูลการวัดและส่งข้อมูลทางไกลของเอเจนต์ไปยัง Agent 365 โดยตรงผ่าน OpenTelemetry (OTLP/HTTP+JSON) ก่อนเริ่มต้น โปรดอ่าน แนวคิดเกี่ยวกับการเฝ้าสังเกตของ Agent 365 เพื่อทำความเข้าใจโมเดล โฟลว์การรับรองความถูกต้อง และจุดที่ข้อมูลของคุณไปถึง
สำคัญ
พาธ OTel โดยตรงเป็นข้อยกเว้น ไม่ใช่ค่าเริ่มต้น ใช้เฉพาะเมื่อคุณมีไปป์ไลน์ OpenTelemetry อยู่แล้ว เฟรมเวิร์กของคุณไม่สามารถใช้ Agent 365 SDK ได้ หรือเอเจนต์ของคุณอยู่ในภาษาที่ SDK ยังไม่รองรับ (เช่น Java) สำหรับผู้ใช้งานอื่น ๆ พาธที่แนะนำคือ Microsoft OpenTelemetry Distro ซึ่งให้บริการ SDK การเฝ้าสังเกตแบบรวมที่ครอบคลุม Agent 365, Microsoft Foundry, Azure Monitor และอื่น ๆ SDK การเฝ้าสังเกตรุ่นก่อนหน้ายังคงใช้งานได้โดยไม่มีการเปลี่ยนแปลงที่ส่งผลกระทบ แต่ไม่แนะนำให้ใช้สำหรับการผสานรวมใหม่อีกต่อไป โดยคำแนะนำการย้ายข้อมูลสำหรับผู้ใช้ SDK เดิมจะออกมาเร็ว ๆ นี้
ข้อกำหนดเบื้องต้น
ตรวจสอบให้แน่ใจว่าการกำหนดค่าต่อไปนี้พร้อมใช้งานก่อนที่ข้อมูลการวัดและส่งข้อมูลทางไกลจะเริ่มต้นส่งเข้าสู่ระบบ
| ใคร | สิ่งที่ต้องการ |
|---|---|
| ผู้ดูแลผู้เช่า | ลงทะเบียน Agent 365 และให้ความยินยอมสำหรับแอปเอเจนต์ของคุณ ดู เริ่มต้นใช้งาน Agent 365 หากไม่มีผู้เช่าที่ได้รับสิทธิการใช้งาน ข้อมูลจะถูกละทิ้งโดยไม่มีแจ้งเตือน - คำขอจะส่งคืน 200 OK พร้อมกับ partialSuccess: null แต่ข้อมูลจะไม่ปรากฏในระบบขั้นปลายอีกต่อไป |
| ผู้ดูแลผู้เช่า |
กำหนดสิทธิการใช้งาน Microsoft 365 E7 หรือ Microsoft Agent 365 ให้กับผู้ใช้อย่างน้อยหนึ่งรายในผู้เช่า การมี SKU อย่างเดียวไม่เพียงพอ การกำหนดสิทธิการใช้งานให้ผู้ใช้จะเริ่มกระบวนการเบื้องหลังของ Defender ซึ่งเปิดใช้งานการนำเข้าข้อมูล หากไม่มีสิทธิการใช้งานที่ถูกกำหน คำขอจะส่งคืน 200 OK พร้อมกับ partialSuccess: null และข้อมูลจะถูกทิ้งโดยไม่มีการแจ้งเตือน |
| ผู้ดูแลผู้เช่า | ให้ความยินยอมของผู้เช่า ดู การอนุญาตให้เอเจนต์เข้าถึงทรัพยากร Microsoft 365 หากไม่ได้รับการให้ความยินยอม โทเค็นจะถูกออกโดยไม่มีบทบาท/ขอบเขต และคำขอจะส่งคืน 403 |
| ทีมพัฒนาของคุณ | ลงทะเบียนแอปของคุณ (แอป Microsoft Entra มาตรฐานหรือแบบพิมพ์เขียว) ดู เริ่มต้นพัฒนา Agent 365 |
| ทีมพัฒนาของคุณ | เพิ่ม Agent365.Observability.OtelWrite ภายใต้ สิทธิ์ API (บทบาทแอปสำหรับ S2S, ขอบเขตสำหรับผู้รับมอบสิทธิ์) สำหรับแบบพิมพ์เขียว โปรดดู กำหนดค่าสิทธิ์ที่สืบทอดได้ ประสานงานกับทีมเริ่มต้นใช้งาน 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, ข้อมูลประจําตัวของเอเจนต์ที่ได้มาจากแบบพิมพ์เขียว |
| ข้อมูลประจําตัวของเอเจนต์ที่ได้มาจากแบบพิมพ์เขียว | OBO / เพื่อนร่วมทีม AI | OBO, ข้อมูลประจําตัวของเอเจนต์ที่ได้มาจากแบบพิมพ์เขียว |
S2S, แอป Microsoft Entra มาตรฐาน
ส่งคำขอ POST หนึ่งครั้งไปยังจุดเชื่อมต่อโทเค็นของผู้เช่าพร้อมกับ grant_type=client_credentials รับรองความถูกต้องของแอปโดยใช้รหัสลับไคลเอ็นต์, ใบรับรอง (การยืนยัน 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 ของแอปอิสระ
แบบพิมพ์เขียวรับรองความถูกต้องและรับโทเค็นการแลกเปลี่ยนข้อมูลประจําตัวี่ติดต่อกับภายนอก
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-
ข้อมูลประจำตัวของเอเจนต์ทำการแลกเปลี่ยน
T1เพื่อรับโทเค็นทรัพยากรการเฝ้าสังเกตของ Agent 365: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 มาตรฐาน
รับโทเค็นขาเข้าของผู้ใช้ Tc จากผู้เรียกใช้ขั้นต้น (แบบแบเรอร์หรือ PFAT) แล้วแลกเปลี่ยน:
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} ด้วยคู่ client_assertion_type + client_assertion เดียวกัน เช่นเดียวกับใน S2S
โทเค็นที่ส่งคืนมาจะมี appid/azp = {your-app-id}, scp ที่มี Agent365.Observability.OtelWrite และ aud = 9b975845-... ใช้กับเส้นทาง /observability/.../traces โทเค็นการรีเฟรชจะถูกส่งคืนมาพร้อมกับโทเค็นหลัก; ให้เก็บไว้ในแคชและนำมาใช้ซ้ำแทนการดำเนินการแลกเปลี่ยนใหม่ในการเรียกใช้ทุกครั้ง
OBO, ข้อมูลประจำตัวของเอเจนต์ที่ได้มาจากแบบพิมพ์เขียว (รวมถึงเพื่อนร่วมทีม AI)
มีสามขั้นตอนหลักในโฟลว์ในนามของผู้ใช้ สำหรับข้อมูลเพิ่มเติม โปรดดู โฟลว์ OAuth ของเอเจนต์: โฟลว์ในนามของผู้ใช้
รับโทเค็นผู้ใช้
Tcสำหรับเพื่อนร่วมทีม AI โทเค็นนี้หมายถึงบัญชีผู้ใช้ของเอเจนต์เอง มิฉะนั้นจะหมายถึงผู้เรียกใช้ที่เป็นมนุษย์แบบพิมพ์เขียวรับรองความถูกต้องและได้รับ
T1เช่นเดียวกับโฟลว์ข้อมูลประจำตัวของเอเจนต์ที่ได้มาจากแบบพิมพ์เขียว S2Sข้อมูลประจำตัวของเอเจนต์แลกเปลี่ยน
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 ของแอปพลิเคชันผู้เรียกใช้ (รวมถึง OAuthclient_id) สำหรับข้อมูลประจำตัวที่ได้มาจากแบบพิมพ์เขียว นี่คือ appId ข้อมูลประจำตัวของเอเจนต์ ไม่ใช่ appId แบบพิมพ์เขียว ต้องเท่ากับค่าการอ้างสิทธิ์appid/azpในโทเค็นของคุณ -
api-version=1- จำเป็น
การเข้ารหัสลับเนื้อความคำขอ
เนื้อความจะอยู่ในรูปแบบ OTLP/HTTP+JSON มาตรฐาน: ExportTraceServiceRequest ที่มี resourceSpans → scopeSpans → spans ควรคำนึงถึงรายละเอียดต่อไปนี้:
-
traceId(16 ไบต์) และspanId(8 ไบต์) จะถูกส่งเป็นสตริงฐานสิบหกตัวพิมพ์เล็ก -
startTimeUnixNano/endTimeUnixNanoเป็นสตริง ที่เก็บ Unix epoch ในหน่วยนาโนวินาที -
kindคือค่าการแจงนับ OTLP แบบจำนวนเต็ม (เช่น1สำหรับINTERNAL);status.codeเป็นการแจงนับแบบจำนวนเต็ม (เช่น1สำหรับOK,2สำหรับERROR) - ค่าแอตทริบิวต์ทั้งหมดจะถูกส่งเป็น
stringValue
รูปแบบการตอบ
เมื่อเรียกใช้สำเร็จจะคืนค่า 200 OK:
{ "partialSuccess": null }
หากสแปนบางรายการถูกปฏิเสธโดยตัวกรองแบบรายสแปน:
{
"partialSuccess": {
"rejectedSpans": 2,
"errorMessage": "Dropped 2 non-A365 span(s) ..."
}
}
ชื่อฟิลด์จะใช้รูปแบบ camelCase ในข้อมูลที่ส่งผ่านระบบ
ตรวจสอบ partialSuccess เสมอ: การได้รับ 200 โดยที่สแปนทั้งหมดของคุณถูกปฏิเสธเป็นผลลัพธ์ที่แท้จริงที่คุณต้องแสดง
ขีดจํากัดและเงื่อนไขการทิ้ง จะแสดงรายการกรณีที่มีการทิ้งโดยไม่มีการแจ้งเตือนที่ 200 ส่งคืนแม้ว่า partialSuccess: null จะไม่มีข้อมูลที่ปรากฏในขั้นปลายก็ตาม
คําขอที่เล็กที่สุด
การทดสอบแบบครบวงจรที่ง่ายที่สุดจะส่งสแปน invoke_agent รายการเดียว สแปน นี้เป็นเนื้อหาที่เล็กที่สุดที่อยู่ใน Microsoft Defender
ขั้นตอนที่ 1 รับโทเค็นแบบแบเรอร์ สำหรับ S2S ให้ใช้ข้อมูลรับรองไคลเอ็นต์ที่มีขอบเขต 9b975845-388f-4429-889e-eab1ef63949c/.default (ดู สูตรการรับรองความถูกต้องสำหรับสูตรแบบเต็ม)
ขั้นตอนที่ 2 POST สแปนเดียว:
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 OK ไม่ใช่หลักฐานการนำเข้า; การตรวจสอบการนำเข้าจะดําเนินการตามโฟลว์การยืนยัน หากต้องการ POST ไฟล์เนื้อความที่บันทึกไว้แทน ให้แทนที่ --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 */
]
}
สแปน B: 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
คู่ค้าส่วนใหญ่ส่งข้อมูลการติดตามผ่าน OTel SDK แทนที่จะใช้ HTTP ที่เขียนเอง 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 คำขอนั้น รูปแบบของเนื้อความถูกกำหนดไว้ใน ข้อมูลจำเพาะ OTLP/HTTP+JSON ของ OpenTelemetry:
{
"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 ดังนั้นแต่ละสแปนจึงมีเพียงพอที่จะสัมพันธ์กันไม่ว่าจะด้วยวิธีใดก็ตาม
สัญญาข้อความ
ส่วนนี้กำหนดว่าคุณสามารถส่งสแปนใดได้บ้าง และแอตทริบิวต์ใดที่กำหนดให้แต่ละสแปนมี สำหรับข้อมูลจำเพาะของแอตทริบิวต์ทั้งหมด ดูที่ ข้อมูลอ้างอิงแอตทริบิวต์
ชนิดการดำเนินงาน
ทุกสแปนที่คุณส่งจะต้องตั้งค่า gen_ai.operation.name เป็นหนึ่งในค่าสี่ค่าด้านล่างนี้ (ไม่สนใจตัวพิมพ์เล็ก-ใหญ่) สแปนใด ๆ ที่มีค่าขาดหายไปหรือไม่รู้จักจะถูกทิ้งโดยไม่มีการแจ้งเตือน และนับรวมใน partialSuccess.rejectedSpans
gen_ai.operation.name |
ความหมาย | gotcha ที่ค้นหาใน Google มากที่สุด |
|---|---|---|
invoke_agent |
การเรียกใช้เอเจนต์ "ราก" ของเอเจนต์ทํางาน | จำเป็นสำหรับการทำงานที่จะปรากฏในมุมมองกิจกรรมเอเจนต์ของ Microsoft Defender หรือศูนย์การจัดการ Microsoft 365 หากไม่มี ข้อมูลการวัดและส่งข้อมูลทางไกลจะมีเฉพาะในการค้นหาภัยคุกคามขั้นสูงของ Microsoft Defender (CloudAppEvents) เท่านั้น |
execute_tool |
การเรียกใช้เครื่องมือ/ฟังก์ชันโดยเอเจนต์ | -- |
chat |
การเรียกใช้การอนุมานของ LLM |
ใช้ chat แบบตรงตัว ไม่ใช่ inference |
output_messages |
ข้อความเอาต์พุตสุดท้ายที่ปล่อยออกมา | -- |
การจัดลำดับชั้นของสแปนและการจัดกลุ่มการทำงาน
Agent 365 สร้างการทำงานใหม่จากกราฟสแปน OTLP มาตรฐาน (traceId, spanId, parentSpanId) พร้อมกับแอตทริบิวต์ในการทำงานจาก ข้อมูลอ้างอิงแอตทริบิวต์
กฎหกข้อ:
-
ตั้งค่า
parentSpanIdเสมอในทุกสแปนที่ไม่ใช่ราก หากไม่มี โครงสร้างทรีของการทำงานจะไม่สามารถสร้างขึ้นใหม่ได้ -
นำของเดิมกลับมาใช้ซ้ำ
traceIdในทุกสแปนของการทำงาน -
ตั้งค่า
gen_ai.conversation.idในทุกสแปน โดยใช้ค่าเดียวกัน นี่คือคีย์หลักสำหรับการเชื่อมโยง "ทุกสแปนของการทำงานนี้" ซึ่งไม่ได้ถูกเผยแพร่โดยอัตโนมัติ -
ตั้งค่า
microsoft.channel.nameในทุกสแปน โดยใช้ค่าเดียวกัน สแปนของเครื่องมือที่ไม่มีช่องทาง/การสนทนาสามารถสืบทอดจากinvoke_agentหลักได้ก็ต่อเมื่อ รายการหลักอยู่ในคำขอ OTLP เดียวกัน ดังนั้นควรตั้งค่าในทุกสแปนด้วยตนเอง -
ตั้งค่า
microsoft.session.idในทุกสแปน เมื่อคุณมีเซสชันเชิงตรรกะ - สำหรับการเรียกใช้เอเจนต์ต่อเอเจนต์ที่เอเจนต์ย่อยอยู่ในคำขอแยกต่างหาก ให้ใช้
gen_ai.conversation.idเดียวกันซ้ำ และใช้แอตทริบิวต์microsoft.a365.caller.agent.*(ดู ข้อมูลอ้างอิงแอตทริบิวต์) เพื่อบันทึกบริบทของผู้เรียกใช้-เอเจนต์
แผนผังสี่สแปนใน ตัวอย่างการทำงานของเอเจนต์ คือรูปแบบมาตรฐาน
รูปแบบการทำงานทั่วไป
| รูปทรง | สแปนที่ต้องส่งออก | หมายเหตุ |
|---|---|---|
| แชทบอทแบบเอเจนต์เดียว (ไม่ใช้เครื่องมือและไม่มีสแปนของ LLM) |
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 ในผู้เช่า) หากไม่มีสิทธิการใช้งานที่กําหนด ระบบจะทิ้งการนําเข้าโดยไม่มีการแจ้งเตือน ดู ข้อกำหนดเบื้องต้น |
| Span | ทุกสแปนจะกําหนดสิ่งจําเป็นในการทำงาน (ลําดับชั้นสแปนและการจัดกลุ่มการทำงาน) |
| Span | สแปน invoke_agent ตั้งค่า gen_ai.input.messages และ gen_ai.output.messages |
| Span | สแปน 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 |
| Span | สแปน chat ตั้งค่า gen_ai.request.model และ gen_ai.provider.name (และตามหลักการแล้ว gen_ai.usage.input_tokens / gen_ai.usage.output_tokens - การเข้ารหัสลับสตริง) |
| Span | ชุดparentSpanId ชุดสแปนที่ไม่มีรากทั้งหมด; สแปนทั้งหมดในการทำงานใช้ traceId เดียวกันร่วมกัน |
| ส่วนข้อมูล | เนื้อความคำขอ ≤ 1 MB |
| การตรวจสอบ | คุณแยกวิเคราะห์ partialSuccess ในทุกการตอบกลับและบันทึกการปฏิเสธ |
| การตรวจสอบ | คุณเรียกใช้โฟลว์การยืนยันใน การยืนยันการนําเข้า กับการเรียกใช้ครั้งแรก |
ขั้นตอนถัดไป
- ข้อมูลอ้างอิงแอตทริบิวต์ - รายละเอียดแต่ละแอตทริบิวต์และคำแนะนำการเลือกค่า
- การแก้ไขปัญหา - การยืนยันการนําเข้า ข้อผิดพลาดทั่วไป และการตอบสนองต่อข้อผิดพลาด