Einrichtung der Observability-Authentifizierung

Der Agent 365-Exporter benötigt einen Token-Resolver, um sich beim Export von Telemetriedaten zu authentifizieren. In diesem Leitfaden werden die Einrichtung für Agents behandelt, die mit dem Microsoft 365 Agents SDK erstellt wurden und sowohl Agent 365-fähige Agents als auch benutzerdefinierte Modul-Agents in .NET, Python und Node.jsabdecken.

Informationen zur Einführungsinstallation, allgemeinen Konfiguration und Nicht-Agent SDK-Szenarien finden Sie unter Microsoft OpenTelemetry Distro.

Overview

Es gibt vier Authentifizierungsszenarien, abhängig von Ihrem Agenttyp und davon, wie Ihr Agent Token bezieht. Für den Tokenabruf kann On-Behalf-Of flow (OBO) oder Service-to-Service (S2S) verwendet werden. Wählen Sie das Szenario aus, das Ihrem Setup entspricht:

Scenario Description
Agent 365-fähig mithilfe von OBO Die integrierte Distro verwaltet den Abruf von Tokens automatisch auf der delegierten Route. Kein benutzerdefinierter Resolver erforderlich. Diese Route benötigt die delegierte Agent365.Observability.OtelWrite Berechtigung und die Administratorzustimmung, die a365 setup all für Blueprint-Agenten nicht konfiguriert.
Agent 365-aktiviert mit S2S Der Agent erhält ein reines App-Token durch die Nutzung der agentischen Identitätskette (getAgenticApplicationToken + Microsoft Authentication Libraries (MSAL)). Erfordert eine benutzerdefinierte TokenResolver und die S2S-Endpunkt-Option. Eine Registered Agent-Instanz benötigt keine Observability-Berechtigung oder Administrator-Einwilligung, daher ist dies der empfohlene Ansatz für Blueprint-Agenten, die mit a365 setup all eingerichtet sind.
Benutzerdefinierte Engine mit OBO Der Agent erhält über Azure Bot OAuth ein Benutzertoken mit Geltungsbereich für die Observability-API. Erfordert eine benutzerdefinierte TokenResolver, eine Azure Bot OAuth-Verbindung und die delegierte Agent365.Observability.OtelWrite Berechtigung mit Zustimmung des Administrators.
Benutzerdefinierte Engine mit S2S Der Agent erwirbt ein Nur-App-Token mit Clientanmeldeinformationen. Erfordert eine benutzerdefinierte TokenResolver. Die App-Registrierung muss eine standardmäßige (nicht agentische) App sein. Standard-App-Registrierungen sind keine registrierten Agent-Instanzen, daher benötigen sie die Agent365.Observability.OtelWrite Anwendungsberechtigung mit Zustimmung des Administrators.

Agent 365-aktiviert mit OBO

Agent 365-fähige Agents empfangen Anforderungen mit agentischer Identität (agenticAppId, agenticUserId) von der Agent 365-Plattform. Durch die Nutzung von OBO übernimmt die in die Distribution integrierte Komponente AgenticTokenCache automatisch die Tokenbeschaffung auf der delegierten Route, sodass Sie keinen benutzerdefinierten Token-Resolver benötigen.

Voraussetzungen

  • Microsoft Entra-App-Registrierung: Ein Service Principal (App-Registrierung) mit Client-ID, Client Secret und Tenant-ID.

  • Delegierte API-Berechtigungen: Fügen Sie Agent365.Observability.OtelWrite (Delegiert) hinzu und erteilen Sie die Administratorzustimmung. Der Befehl a365 setup all fügt diese Berechtigung für Blueprint-Agenten nicht hinzu. Ein globaler Administrator kann es hinzufügen und die Administratorzustimmung erteilen, indem er folgenden Befehl ausführt:

    a365 setup permissions custom --resource-app-id 9b975845-388f-4429-889e-eab1ef63949c --scopes Agent365.Observability.OtelWrite
    

    Für weitere Optionen, einschließlich des Microsoft Entra Admin Center, siehe Die Berechtigung erteilen.

Tip

Um die delegierte Observability-Berechtigung und die Admin-Erlaubnis zu vermeiden, verwenden Sie Agent 365-enabled mit S2S für Blueprint-Agenten, die mit a365 setup all eingerichtet sind.

Konfiguration

Bei jeder Interaktion ruft Ihr Agent die RegisterObservability-Funktion mit dem Kontext der Interaktion auf. Der integrierte Cache verwendet das delegierte Token des Benutzers aus dem AgenticUserAuthorization-Handler, um einen OBO-Austausch auszuführen und ein Token abzurufen, das für Agent365.Observability.OtelWrite gültig ist.

Vollständige Einrichtungsanweisungen, einschließlich Paketen, Konfigurationen und Codebeispielen, finden Sie unter Agentic Token Cache mit Agent Framework-Apps.

Agent 365-aktiviert mit S2S

Agent 365-fähige Agents können auch die S2S-Authentifizierung (Service-to-Service) anstelle von OBO verwenden. Dieser Weg wird für Blueprint-Agenten empfohlen, die mit a365 setup all eingerichtet sind. Der Agent erwirbt ein Token mithilfe einer eigenen Dienstprinzipalidentität über eine zweistufige agentische Identitätskette:

  1. Rufen Sie getAgenticApplicationToken(tenantId, agentId) an, um ein Client-Zugangs-Token mit dem Pfad für Federated Managed Identity (FMI) zu erhalten.
  2. Ruf MSAL acquireTokenForClient mit dem App-Token als clientAssertion und dem Scope api://9b975845-388f-4429-889e-eab1ef63949c/.default auf.

Note

Federated Managed Identity (FMI) ist eine Architektur, bei der eine verwaltete Identität mittels Verbundidentitätsanmeldeinformationen an der Verbundauthentifizierung für Workloadidentitäten teilnimmt und so den Tokenaustausch sowie eine geheimnislose Authentifizierung auf der Grundlage von Vertrauensbeziehungen zwischen Identitäten ermöglicht.

Die Microsoft OpenTelemetry-Distribution verwendet standardmäßig die delegierte Route, daher musst du eine benutzerdefinierte TokenResolver angeben und die S2S-Endpunktoption für deine Sprache festlegen, wie zum Beispiel UseS2SEndpoint = true, useS2SEndpoint: true oder a365_use_s2s_endpoint=True.

Voraussetzungen

  • Agent 365-Registrierung: Die Agent-Instanz muss bei Agent 365 registriert sein. Der a365 setup all Befehl registriert Blueprint-Agenten-Instanzen. Das Erstellen einer Microsoft Entra-Identität allein registriert keine Agenteninstanz.
  • Blueprint-Zugangsdaten für den FMI-Austausch: Verwenden Sie ein Blueprint-Client-Geheimnis oder eine verwaltete Identität, um das Federated Managed Identity (FMI)-Token für api://AzureADTokenExchange/.default abzurufen, und tauschen Sie es dann gegen das Agent-Instanz-Observability-Token aus.
  • Übereinstimmung von Identitätswerten: Die Agenten-ID und die Mandanten-ID im Gepäck sowie die Export-URL müssen mit der Client-ID und dem Mandanten der Agent-Instanz im App-only-Token übereinstimmen.

Note

Eine bei Agent 365 registrierte Agent-Instanz kann auf der S2S-Route mit einem App-only-Token exportieren, das keine Agent365.Observability.OtelWrite Rolle hat. Es braucht keine Observability-Berechtigung oder Admin-Einwilligung. Nicht registrierte Identitäten, einschließlich der Standard-App-Registrierungen, benötigen weiterhin die Agent365.Observability.OtelWrite App-Rolle und die Administratorzustimmung.

Schritt 1: Umgebungskonfiguration

Die folgenden Codebeispiele zeigen, wie Sie die erforderlichen Verbindungs-, Mandanten-, Clientanmeldeinformationen- und Observability-Exporterumgebungseinstellungen festlegen, bevor Sie den benutzerdefinierten S2S-Tokenfluss aktivieren.

Kein AgenticUserAuthorization-Behandler erforderlich. S2S verwendet die manuelle Agent-Identitätskette (get_agentic_application_token + MSAL acquire_token_for_client), um ein Token abzurufen, das für die Observability-Ressource vorgesehen ist.

CONNECTIONSMAP__0__SERVICEURL=*
CONNECTIONSMAP__0__CONNECTION=SERVICE_CONNECTION

CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID=<your-client-id>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET=<your-client-secret>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID=<your-tenant-id>

ENABLE_A365_OBSERVABILITY=true
ENABLE_A365_OBSERVABILITY_EXPORTER=true

Schritt 2: Konfigurieren Sie die Distribution mit benutzerdefiniertem Token-Resolver

Die folgenden Beispiele zeigen, wie Sie das Exportieren von Agent 365 aktivieren und eine benutzerdefinierte TokenResolver Registrierung durchführen, damit der Exporter S2S-Token für jeden Agent und Mandanten abrufen kann.

from microsoft.opentelemetry import use_microsoft_opentelemetry

_token_cache: dict[str, str] = {}

def token_resolver(agent_id: str, tenant_id: str) -> str | None:
    return _token_cache.get(f"{agent_id}:{tenant_id}")

use_microsoft_opentelemetry(
    enable_a365=True,
    a365_token_resolver=token_resolver,
    a365_use_s2s_endpoint=True,
    a365_enable_observability_exporter=True,
)

Schritt 3: Abrufen und Zwischenspeichern des S2S-Tokens

Rufen Sie für jede eingehende Nachricht das S2S-Token über die Agenten-Identitätskette ab und zwischenspeichern Sie es für den Resolver.

import asyncio
from msal import ConfidentialClientApplication
from microsoft.opentelemetry.a365.core import BaggageBuilder, InvokeAgentScope, InvokeAgentScopeDetails, Request

OBSERVABILITY_S2S_SCOPE = "api://9b975845-388f-4429-889e-eab1ef63949c/.default"

async def get_agentic_s2s_token(connection, tenant_id: str, agent_id: str) -> str:
    # Step 1: Get agentic application token (client_credentials + fmi_path)
    app_token = await connection.get_agentic_application_token(tenant_id, agent_id)
    if not app_token:
        raise ValueError(f"Failed to get agentic app token for agent {agent_id}")

    # Step 2: Exchange for observability-scoped token
    cca = ConfidentialClientApplication(
        client_id=agent_id,
        authority=f"https://login.microsoftonline.com/{tenant_id}",
        client_credential={"client_assertion": app_token},
    )
    result = await asyncio.to_thread(
        lambda: cca.acquire_token_for_client(scopes=[OBSERVABILITY_S2S_SCOPE])
    )
    if not result or "access_token" not in result:
        raise ValueError(f"Token acquisition failed: {result}")
    return result["access_token"]

# In your message handler : use SDK helpers to get agent/tenant from the activity:
@AGENT_APP.activity("message")
async def on_message(context: TurnContext, _state: TurnState):
    # get_agentic_instance_id reads from recipient (SDK convention)
    agent_id = context.activity.get_agentic_instance_id()
    tenant_id = context.activity.get_agentic_tenant_id()

    # Acquire S2S token and cache BEFORE creating spans
    connection = CONNECTION_MANAGER.get_connection("SERVICE_CONNECTION")
    token = await get_agentic_s2s_token(connection, tenant_id, agent_id)
    _token_cache[f"{agent_id}:{tenant_id}"] = token

    # Wrap spans in BaggageBuilder so the exporter can resolve the token
    request = Request(content=user_message, session_id=None)
    with BaggageBuilder().tenant_id(tenant_id).agent_id(agent_id).build():
        invoke_scope = InvokeAgentScope.start(request, InvokeAgentScopeDetails(), agent_details)
        with invoke_scope:
            invoke_scope.record_input_messages([user_message])
            invoke_scope.record_output_messages([response])

Important

Der manuelle zweistufige Fluss (get_agentic_application_token + MSAL acquire_token_for_client) ist für S2S erforderlich. AgenticUserAuthorization.get_token() gibt ein Token mit Bereich 5a807f24-.../.default (Bot Framework) und nicht die Observability-Ressource api://9b975845-.../.default zurück: Der S2S-Endpunkt lehnt es mit 401 InvalidAudienceab.

  • Verwenden Sie context.activity.get_agentic_instance_id() und get_agentic_tenant_id(), um den Agenten und den Mandanten aus der Aktivität zu lesen (gemäß SDK-Konvention aus recipient).
  • Abrufen und Zwischenspeichern des S2S-Tokens vor dem Erstellen von Spans. Der Exporter BatchSpanProcessor wird möglicherweise geleert, bevor der Handler fertig ist: Wenn das Token noch nicht zwischengespeichert ist, schlägt der Export fehl.
  • Umschließen Sie alle A365-Scopes mit BaggageBuilder, damit der Exporter weiß, für welchen Agent und Mandanten Tokens aufgelöst werden sollen. Ohne Baggage werden Spans stillschweigend mit „Keine Spans mit Mandanten-/Agenten-Identität gefunden.“ verworfen.

Important

Bevor dein Resolver das finale Observability-Token zurückgibt und zwischenspeichert:

  • Überprüfen Sie, dass das Token nur für Apps gilt. Akzeptieren idtyp=app. Wenn idtyp fehlt, akzeptieren Sie nur ein Token mit einem nichtleeren roles-Anspruch oder einem nichtleeren oid-Anspruch, der sub entspricht. Lehne Token ab, die einen scp Claim oder einen anderen idtyp Wert haben.
  • Überprüfe, ob aud9b975845-388f-4429-889e-eab1ef63949c oder api://9b975845-388f-4429-889e-eab1ef63949c ist und ob der Token nicht abgelaufen ist.
  • Senden Sie niemals die Zwischen-Blueprint-Assertion, ein Blueprint-Token oder ein Benutzer- oder OBO-Token an Observability.
  • Cache den letzten Token und erneuere ihn, bevor er abläuft. Der Exporter ruft den Resolver für jeden Tenant und jede Agentenidentität in jedem Exportbatch einmal auf.

Für vollständige Implementierungen, die die Distro verwenden, siehe die Agent-365-Beispiele für Node.js, Python und .NET.

Benutzerdefinierte Engine unter Verwendung von OBO

Benutzerdefinierte Engine-Agents verwenden Standard-App-Registrierungen mit Azure Bot OAuth-Verbindungen, nicht die agentenbasierte Identitätskette. Mithilfe von OBO ruft der Agent ein Benutzertoken über Azure Bot OAuth ab, das bereits auf die A365-Observability-API vom Bot Framework-Tokendienst begrenzt ist. Ein einzelner getToken- oder GetTurnTokenAsync-Aufruf gibt das korrekt abgegrenzte Token zurück, sodass Sie exchangeToken nicht benötigen.

Voraussetzungen

Microsoft Entra-App-Registrierung mit delegierten API-Berechtigungen. Fügen Sie Agent365.Observability.OtelWrite (Delegiert) hinzu und erteilen Sie die Administratorzustimmung.

Important

Das agentId im Token-Cache muss mit der Client-ID der App-Registrierung übereinstimmen, nicht mit dem agenticAppId der Aktivität, das es für benutzerdefinierte Engine-Agents nicht gibt. Die Export-URL enthält das agentIdUnd ein Konflikt führt zu HTTP 403.

Schritt 1: Umgebungs- und App-Konfiguration

Die folgenden Beispiele zeigen, wie Sie Ihre App und Laufzeitumgebung konfigurieren, einschließlich Dienstverbindungswerte, Mandanten- und Clienteinstellungen sowie erforderliche Autorisierungszuordnungen.

# .env
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID=<your-client-id>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET=<your-client-secret>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID=<your-tenant-id>

CONNECTIONSMAP__0__CONNECTION=SERVICE_CONNECTION
CONNECTIONSMAP__0__SERVICEURL=*

# Auth handler config : TYPE is required, name is uppercased by load_configuration_from_env
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__OBOCONNECTIONPROFILE__TYPE=UserAuthorization
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__OBOCONNECTIONPROFILE__SETTINGS__AZUREBOTOAUTHCONNECTIONNAME=oboConnectionProfile
AGENTAPPLICATION__USERAUTHORIZATION__HANDLERS__OBOCONNECTIONPROFILE__SETTINGS__SCOPES=api://9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite

ENABLE_A365_OBSERVABILITY=true
ENABLE_A365_OBSERVABILITY_EXPORTER=true

Important

load_configuration_from_env schreibt alle Schlüssel von Umgebungsvariablen in Großbuchstaben. Der Handlername lautet dann OBOCONNECTIONPROFILE, und Sie müssen in Aufrufen von auth_handlers und get_token() mit genau dieser Groß- und Kleinschreibung darauf verweisen. Das Fehlen von TYPE verursacht Auth handler ... not recognized or not configured zur Laufzeit.

Schritt 2: Die Distribution für OBO konfigurieren

Die folgenden Beispiele zeigen, wie Sie den Agent 365-Export aktivieren, den Exporter auf dem OBO-Endpunkt beibehalten und einen benutzerdefinierten Code TokenResolver registrieren, der während des Exports delegierte Token zurückgibt.

from microsoft.opentelemetry import use_microsoft_opentelemetry

_token_cache: dict[str, str] = {}

def token_resolver(agent_id: str, tenant_id: str) -> str | None:
    return _token_cache.get(f"{agent_id}:{tenant_id}")

environ["ENABLE_A365_OBSERVABILITY_EXPORTER"] = "true"

use_microsoft_opentelemetry(
    enable_a365=True,
    a365_token_resolver=token_resolver,
    a365_use_s2s_endpoint=False,  # OBO uses /observability endpoint
    a365_enable_observability_exporter=True,
)

Note

Der OBO-Modus erfordert jwt_authorization_middleware für das aiohttpApplication (validiert das eingehende JWT (JSON Web Token) von Bot Framework). Der S2S-/Emulatorpfad sollte diese Middleware nicht enthalten.

from microsoft_agents.hosting.aiohttp import jwt_authorization_middleware
app = Application(middlewares=[jwt_authorization_middleware])

Schritt 3: OBO-Token abrufen

Die folgenden Beispiele zeigen, wie Sie ein delegiertes OBO-Token aus der konfigurierten Azure Bot OAuth-Verbindung anfordern und dann nach App-Client und Mandant für den Exporter zwischenspeichern.

from microsoft_agents.hosting.core import (
    AgentApplication, Authorization, MemoryStorage, TurnContext, TurnState,
)
from microsoft_agents.activity import load_configuration_from_env
from microsoft_agents.authentication.msal import MsalConnectionManager
from microsoft_agents.hosting.aiohttp import CloudAdapter

# Auth handlers are loaded from .env via load_configuration_from_env (see Environment config above)
agents_sdk_config = load_configuration_from_env(environ)

STORAGE = MemoryStorage()
CONNECTION_MANAGER = MsalConnectionManager(**agents_sdk_config)
ADAPTER = CloudAdapter(connection_manager=CONNECTION_MANAGER)
AUTHORIZATION = Authorization(STORAGE, CONNECTION_MANAGER, **agents_sdk_config)

AGENT_APP = AgentApplication[TurnState](
    storage=STORAGE, adapter=ADAPTER, authorization=AUTHORIZATION, **agents_sdk_config,
)

CLIENT_ID = environ.get("CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID", "")
TENANT_ID = environ.get("CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID", "")

# Message handler : get_token returns a token already scoped to the observability API.
# The Azure Bot Token Service performs the OBO exchange internally based on the
# OAuth connection's configured scope. No manual MSAL exchange_token call is needed.
@AGENT_APP.activity("message", auth_handlers=["OBOCONNECTIONPROFILE"])
async def on_message(context: TurnContext, _state: TurnState):
    token_response = await AGENT_APP.auth.get_token(context, "OBOCONNECTIONPROFILE")
    # token_response.token has aud=<a365-observability-app-id>,
    # scp=Agent365.Observability.OtelWrite
    _token_cache[f"{CLIENT_ID}:{TENANT_ID}"] = token_response.token

Important

Voraussetzung im Azure-Portal: Setzen Sie die Scopes für die Azure Bot OAuth-Verbindung oboConnectionProfile auf api://9b975845-388f-4429-889e-eab1ef63949c/Agent365.Observability.OtelWrite. Ohne diese Einstellung ist das Token auf die eigene Zielgruppe (api://botid-...) des Bots beschränkt und der Export schlägt mit HTTP 401 InvalidAudiencefehl.

Note

AGENT_APP.auth.get_token() gibt das korrekt bereichsbezogene Token direkt zurück – es ist kein exchange_token() Aufruf erforderlich. Der Bot Framework-Tokendienst verarbeitet den OBO-Austausch, wenn der OAuth-Verbindungsumfang auf die A365-Observability-Ressource ausgerichtet ist.

Benutzerdefinierte Engine mit S2S

Benutzerdefinierte Engine-Agenten können S2S (Client-Zugangsdaten) verwenden, um ein App-only-Token zu erhalten, indem sie die Service-Connection-Zugangsdaten verwenden. Diese Methode verwendet Standard-MSAL-Client-Zugangsdaten – sie benötigt keine agentische Identitätskette.

Voraussetzungen

  • Microsoft Entra-App-Registrierung: Die App-Registrierung muss eine App des Typs Custom Engine (Standard) sein. Für Agent 365 aktivierte App-Registrierungen können kein einfaches client_credentials für die Observability-Ressource (AADSTS82001) verwenden.
  • Anwendungsberechtigungen: Fügen Sie Agent365.Observability.OtelWrite hinzu (Anwendung, nicht delegiert), und erteilen Sie Administratorzustimmung. Standard-App-Registrierungen sind keine Agent-365-registrierten Agenten-Instanzen, daher benötigen sie diese App-Rolle auf der S2S-Route.

Important

Das agentId, das du für das Caching verwendest, muss das ClientId von ServiceConnection sein. Die Export-URL lautet /observabilityService/tenants/{tenantId}/otlp/agents/{agentId}/traces : Ein Konflikt verursacht HTTP 403.

Schritt 1: Umgebungs- und App-Konfiguration

Die folgenden Beispiele zeigen, wie Sie Ihre App und Laufzeitumgebung konfigurieren, einschließlich Dienstverbindungswerte, Mandanten- und Clienteinstellungen sowie erforderliche Autorisierungszuordnungen.

# .env
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID=<your-client-id>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTSECRET=<your-client-secret>
CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID=<your-tenant-id>

CONNECTIONSMAP__0__CONNECTION=SERVICE_CONNECTION
CONNECTIONSMAP__0__SERVICEURL=*

ENABLE_A365_OBSERVABILITY=true
ENABLE_A365_OBSERVABILITY_EXPORTER=true

Schritt 2: Konfigurieren der Distro für S2S

Die folgenden Beispiele zeigen, wie Sie den Export von Agent 365 aktivieren, den Exporter auf den S2S-Endpunkt festlegen und eine benutzerdefinierte TokenResolver für die Token-Suche während des Exports registrieren.

from microsoft.opentelemetry import use_microsoft_opentelemetry

_token_cache: dict[str, str] = {}

def token_resolver(agent_id: str, tenant_id: str) -> str | None:
    return _token_cache.get(f"{agent_id}:{tenant_id}")

use_microsoft_opentelemetry(
    enable_a365=True,
    a365_token_resolver=token_resolver,
    a365_use_s2s_endpoint=True,  # S2S uses /observabilityService endpoint
    a365_enable_observability_exporter=True,
)

Schritt 3: Abrufen des S2S-Tokens

Die folgenden Beispiele zeigen, wie Sie ein Nur-App-Zugriffstoken für die Observability-Ressource mithilfe der Dienstverbindungsanmeldeinformationen anfordern und dann nach Agent und Mandant für den Exporter zwischenspeichern.

# Force agentId to ServiceConnection ClientId (custom engine agents have no agenticAppId)
agent_id = os.environ.get("CONNECTIONS__SERVICE_CONNECTION__SETTINGS__CLIENTID")
tenant_id = os.environ.get("CONNECTIONS__SERVICE_CONNECTION__SETTINGS__TENANTID")

connection = CONNECTION_MANAGER.get_connection("SERVICE_CONNECTION")
token = await connection.get_access_token(
    resource_url="https://login.microsoftonline.com",
    scopes=["api://9b975845-388f-4429-889e-eab1ef63949c/.default"],
)
_token_cache[f"{agent_id}:{tenant_id}"] = token

Schritt 4: Festlegen des Gepäcks für den Spanexport

Der Agent365-Exporteur benötigt Baggage (Mieter-ID und Agenten-ID) im Span-Kontext. Ohne diese Komponente verwirft der Exporteur Spans und protokolliert die Nachricht No spans with tenant/agent identity found..

from microsoft.opentelemetry.a365.core import BaggageBuilder, InvokeAgentScope

# Baggage must wrap the span as a context manager
with BaggageBuilder().tenant_id(tenant_id).agent_id(agent_id).build():
    invoke_scope = InvokeAgentScope.start(request, InvokeAgentScopeDetails(), agent_details)
    with invoke_scope:
        invoke_scope.record_input_messages([user_message])
        invoke_scope.record_output_messages([response])