Inspection des données de télémétrie avec la console
Bien que la console ne soit pas un moyen recommandé d’inspecter les données de télémétrie, il s’agit d’un moyen simple et rapide de commencer. Cet article vous montre comment générer des données de télémétrie dans la console pour l’inspection avec une configuration minimale du noyau.
Exportateur
Les exportateurs sont responsables de l’envoi de données de télémétrie à une destination. En savoir plus sur les exportateurs ici. Dans cet exemple, nous utilisons l’exportateur de console pour générer des données de télémétrie dans la console.
Prérequis
- Déploiement d’une conversation Azure OpenAI terminée.
- Dernier SDK .Net pour votre système d’exploitation.
- Déploiement d’une conversation Azure OpenAI terminée.
- Python 3.10, 3.11 ou 3.12 installé sur votre ordinateur.
Remarque
L’observabilité du noyau sémantique n’est pas encore disponible pour Java.
Programme d’installation
Créer une application console
Dans un terminal, exécutez la commande suivante pour créer une application console en C# :
dotnet new console -n TelemetryConsoleQuickstart
Accédez au répertoire du projet nouvellement créé une fois la commande terminée.
Installer les packages nécessaires
Noyau sémantique
dotnet add package Microsoft.SemanticKernel
OpenTelemetry Console Exporter
dotnet add package OpenTelemetry.Exporter.Console
Créer une application simple avec le noyau sémantique
Dans le répertoire du projet, ouvrez le Program.cs
fichier avec votre éditeur favori. Nous allons créer une application simple qui utilise le noyau sémantique pour envoyer une invite à un modèle d’achèvement de conversation. Remplacez le contenu existant par le code suivant et renseignez les valeurs requises pour deploymentName
, endpoint
et apiKey
:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.SemanticKernel;
using OpenTelemetry;
using OpenTelemetry.Logs;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
namespace TelemetryConsoleQuickstart
{
class Program
{
static async Task Main(string[] args)
{
// Telemetry setup code goes here
IKernelBuilder builder = Kernel.CreateBuilder();
// builder.Services.AddSingleton(loggerFactory);
builder.AddAzureOpenAIChatCompletion(
deploymentName: "your-deployment-name",
endpoint: "your-azure-openai-endpoint",
apiKey: "your-azure-openai-api-key"
);
Kernel kernel = builder.Build();
var answer = await kernel.InvokePromptAsync(
"Why is the sky blue in one sentence?"
);
Console.WriteLine(answer);
}
}
}
Ajouter des données de télémétrie
Si vous exécutez l’application console maintenant, vous devez vous attendre à voir une phrase expliquant pourquoi le ciel est bleu. Pour observer le noyau via la télémétrie, remplacez le // Telemetry setup code goes here
commentaire par le code suivant :
var resourceBuilder = ResourceBuilder
.CreateDefault()
.AddService("TelemetryConsoleQuickstart");
// Enable model diagnostics with sensitive data.
AppContext.SetSwitch("Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnosticsSensitive", true);
using var traceProvider = Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(resourceBuilder)
.AddSource("Microsoft.SemanticKernel*")
.AddConsoleExporter()
.Build();
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.SetResourceBuilder(resourceBuilder)
.AddMeter("Microsoft.SemanticKernel*")
.AddConsoleExporter()
.Build();
using var loggerFactory = LoggerFactory.Create(builder =>
{
// Add OpenTelemetry as a logging provider
builder.AddOpenTelemetry(options =>
{
options.SetResourceBuilder(resourceBuilder);
options.AddConsoleExporter();
// Format log messages. This is default to false.
options.IncludeFormattedMessage = true;
options.IncludeScopes = true;
});
builder.SetMinimumLevel(LogLevel.Information);
});
Enfin, supprimez les marques de commentaire de la ligne // builder.Services.AddSingleton(loggerFactory);
pour ajouter la fabrique d’enregistreurs d’événements au générateur.
Dans l’extrait de code ci-dessus, nous créons d’abord un générateur de ressources pour créer des instances de ressources. Une ressource représente l’entité qui produit des données de télémétrie. Vous pouvez en savoir plus sur les ressources ici. Le générateur de ressources aux fournisseurs est facultatif. S’il n’est pas fourni, la ressource par défaut avec des attributs par défaut est utilisée.
Ensuite, nous allons activer les diagnostics avec des données sensibles. Il s’agit d’une fonctionnalité expérimentale qui vous permet d’activer les diagnostics pour les services IA dans le noyau sémantique. Avec cette option activée, vous verrez des données de télémétrie supplémentaires telles que les invites envoyées et les réponses reçues des modèles IA, qui sont considérées comme des données sensibles. Si vous ne souhaitez pas inclure de données sensibles dans vos données de télémétrie, vous pouvez utiliser un autre commutateur Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnostics
pour activer les diagnostics avec des données non sensibles, telles que le nom du modèle, le nom de l’opération et l’utilisation des jetons, etc.
Ensuite, nous créons un générateur de fournisseurs de suivi et un générateur de fournisseurs de compteurs. Un fournisseur est chargé de traiter les données de télémétrie et de les acheminer vers les exportateurs. Nous nous abonneons à la Microsoft.SemanticKernel*
source pour recevoir des données de télémétrie à partir des espaces de noms du noyau sémantique. Nous ajoutons un exportateur de console au fournisseur de suivi et au fournisseur de compteurs. L’exportateur de console envoie des données de télémétrie à la console.
Enfin, nous créons une fabrique d’enregistreurs d’événements et ajoutons OpenTelemetry en tant que fournisseur de journalisation qui envoie des données de journalisation à la console. Nous définissons le niveau Information
minimal du journal et incluons des messages et des étendues mis en forme dans la sortie du journal. La fabrique d’enregistreurs d’événements est ensuite ajoutée au générateur.
Important
Un fournisseur doit être un singleton et doit être actif pour toute la durée de vie de l’application. Le fournisseur doit être supprimé lorsque l’application est arrêtée.
Créer un environnement virtuel Python
python -m venv telemetry-console-quickstart
Activez l’environnement virtuel.
telemetry-console-quickstart\Scripts\activate
Installer les packages nécessaires
pip install semantic-kernel
Créer un script Python simple avec le noyau sémantique
Créez un script Python et ouvrez-le avec votre éditeur favori.
New-Item -Path telemetry_console_quickstart.py -ItemType file
Nous allons créer un script Python simple qui utilise le noyau sémantique pour envoyer une invite à un modèle d’achèvement de conversation. Remplacez le contenu existant par le code suivant et renseignez les valeurs requises pour deployment_name
, endpoint
et api_key
:
import asyncio
import logging
from opentelemetry._logs import set_logger_provider
from opentelemetry.metrics import set_meter_provider
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor, ConsoleLogExporter
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import ConsoleMetricExporter, PeriodicExportingMetricReader
from opentelemetry.sdk.metrics.view import DropAggregation, View
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter
from opentelemetry.semconv.resource import ResourceAttributes
from opentelemetry.trace import set_tracer_provider
from semantic_kernel import Kernel
from semantic_kernel.connectors.ai.open_ai import AzureChatCompletion
# Telemetry setup code goes here
async def main():
# Create a kernel and add a service
kernel = Kernel()
kernel.add_service(AzureChatCompletion(
api_key="your-azure-openai-api-key",
endpoint="your-azure-openai-endpoint",
deployment_name="your-deployment-name"
))
answer = await kernel.invoke_prompt("Why is the sky blue in one sentence?")
print(answer)
if __name__ == "__main__":
asyncio.run(main())
Ajouter des données de télémétrie
Variables d'environnement
Par défaut, le noyau n’émet pas d’étendues pour les connecteurs IA, car ces étendues portent gen_ai
des attributs considérés comme expérimentaux. Pour activer la fonctionnalité, définissez la variable SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS
d’environnement ou SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE
sur true
.
Important
Les invites et les achèvements sont considérés comme des données sensibles. Le noyau sémantique n’émet pas ces données à partir des connecteurs IA, sauf si la SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE
variable d’environnement est définie true
sur . Le paramètre SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS
pour true
émettre uniquement des données non sensibles telles que le nom du modèle, le nom de l’opération et l’utilisation des jetons.
Créez un fichier nommé .env
dans le même répertoire que votre script et ajoutez le contenu suivant :
SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE=true
Code
Si vous exécutez le script maintenant, vous devez vous attendre à voir une phrase expliquant pourquoi le ciel est bleu. Pour observer le noyau via la télémétrie, remplacez le # Telemetry setup code goes here
commentaire par le code suivant :
# Create a resource to represent the service/sample
resource = Resource.create({ResourceAttributes.SERVICE_NAME: "telemetry-console-quickstart"})
def set_up_logging():
exporter = ConsoleLogExporter()
# Create and set a global logger provider for the application.
logger_provider = LoggerProvider(resource=resource)
# Log processors are initialized with an exporter which is responsible
# for sending the telemetry data to a particular backend.
logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter))
# Sets the global default logger provider
set_logger_provider(logger_provider)
# Create a logging handler to write logging records, in OTLP format, to the exporter.
handler = LoggingHandler()
# Add filters to the handler to only process records from semantic_kernel.
handler.addFilter(logging.Filter("semantic_kernel"))
# Attach the handler to the root logger. `getLogger()` with no arguments returns the root logger.
# Events from all child loggers will be processed by this handler.
logger = logging.getLogger()
logger.addHandler(handler)
logger.setLevel(logging.INFO)
def set_up_tracing():
exporter = ConsoleSpanExporter()
# Initialize a trace provider for the application. This is a factory for creating tracers.
tracer_provider = TracerProvider(resource=resource)
# Span processors are initialized with an exporter which is responsible
# for sending the telemetry data to a particular backend.
tracer_provider.add_span_processor(BatchSpanProcessor(exporter))
# Sets the global default tracer provider
set_tracer_provider(tracer_provider)
def set_up_metrics():
exporter = ConsoleMetricExporter()
# Initialize a metric provider for the application. This is a factory for creating meters.
meter_provider = MeterProvider(
metric_readers=[PeriodicExportingMetricReader(exporter, export_interval_millis=5000)],
resource=resource,
views=[
# Dropping all instrument names except for those starting with "semantic_kernel"
View(instrument_name="*", aggregation=DropAggregation()),
View(instrument_name="semantic_kernel*"),
],
)
# Sets the global default meter provider
set_meter_provider(meter_provider)
# This must be done before any other telemetry calls
set_up_logging()
set_up_tracing()
set_up_metrics()
Dans l’extrait de code ci-dessus, nous créons d’abord une ressource pour représenter le service. Une ressource représente l’entité qui produit des données de télémétrie. Vous pouvez en savoir plus sur les ressources ici. Nous créons ensuite trois fonctions pour configurer la journalisation, le suivi et les métriques. Chaque fonction crée un fournisseur pour les données de télémétrie respectives et ajoute un exportateur de console au fournisseur.
Enfin, nous appelons les trois fonctions pour configurer la journalisation, le suivi et les métriques. Cette opération doit être effectuée avant tout autre appel de télémétrie.
Remarque
L’observabilité du noyau sémantique n’est pas encore disponible pour Java.
Exécuter
Exécutez l’application console avec la commande suivante :
dotnet run
Exécutez le script Python avec la commande suivante :
python telemetry_console_quickstart.py
Remarque
L’observabilité du noyau sémantique n’est pas encore disponible pour Java.
Inspecter les données de télémétrie
Enregistrement de journaux
Vous devez voir plusieurs enregistrements de journal dans la sortie de la console. Ils ressemblent à ce qui suit :
LogRecord.Timestamp: 2024-09-12T21:48:35.2295938Z
LogRecord.TraceId: 159d3f07664838f6abdad7af6a892cfa
LogRecord.SpanId: ac79a006da8a6215
LogRecord.TraceFlags: Recorded
LogRecord.CategoryName: Microsoft.SemanticKernel.KernelFunction
LogRecord.Severity: Info
LogRecord.SeverityText: Information
LogRecord.FormattedMessage: Function InvokePromptAsync_290eb9bece084b00aea46b569174feae invoking.
LogRecord.Body: Function {FunctionName} invoking.
LogRecord.Attributes (Key:Value):
FunctionName: InvokePromptAsync_290eb9bece084b00aea46b569174feae
OriginalFormat (a.k.a Body): Function {FunctionName} invoking.
Resource associated with LogRecord:
service.name: TelemetryConsoleQuickstart
service.instance.id: a637dfc9-0e83-4435-9534-fb89902e64f8
telemetry.sdk.name: opentelemetry
telemetry.sdk.language: dotnet
telemetry.sdk.version: 1.9.0
Il existe deux parties pour chaque enregistrement de journal :
- Enregistrement de journal lui-même : contient l’horodatage et l’espace de noms à partir desquels l’enregistrement du journal a été généré, la gravité et le corps de l’enregistrement du journal, ainsi que tous les attributs associés à l’enregistrement du journal.
- Ressource associée à l’enregistrement de journal : contient des informations sur le service, l’instance et le Kit de développement logiciel (SDK) utilisés pour générer l’enregistrement du journal.
Activités
Remarque
Les activités dans .Net sont similaires aux étendues dans OpenTelemetry. Ils sont utilisés pour représenter une unité de travail dans l’application.
Vous devez voir plusieurs activités dans la sortie de la console. Ils ressemblent à ce qui suit :
Activity.TraceId: 159d3f07664838f6abdad7af6a892cfa
Activity.SpanId: 8c7c79bc1036eab3
Activity.TraceFlags: Recorded
Activity.ParentSpanId: ac79a006da8a6215
Activity.ActivitySourceName: Microsoft.SemanticKernel.Diagnostics
Activity.DisplayName: chat.completions gpt-4o
Activity.Kind: Client
Activity.StartTime: 2024-09-12T21:48:35.5717463Z
Activity.Duration: 00:00:02.3992014
Activity.Tags:
gen_ai.operation.name: chat.completions
gen_ai.system: openai
gen_ai.request.model: gpt-4o
gen_ai.response.prompt_tokens: 16
gen_ai.response.completion_tokens: 29
gen_ai.response.finish_reason: Stop
gen_ai.response.id: chatcmpl-A6lxz14rKuQpQibmiCpzmye6z9rxC
Activity.Events:
gen_ai.content.prompt [9/12/2024 9:48:35 PM +00:00]
gen_ai.prompt: [{"role": "user", "content": "Why is the sky blue in one sentence?"}]
gen_ai.content.completion [9/12/2024 9:48:37 PM +00:00]
gen_ai.completion: [{"role": "Assistant", "content": "The sky appears blue because shorter blue wavelengths of sunlight are scattered in all directions by the gases and particles in the Earth\u0027s atmosphere more than other colors."}]
Resource associated with Activity:
service.name: TelemetryConsoleQuickstart
service.instance.id: a637dfc9-0e83-4435-9534-fb89902e64f8
telemetry.sdk.name: opentelemetry
telemetry.sdk.language: dotnet
telemetry.sdk.version: 1.9.0
Il existe deux parties pour chaque activité :
- L’activité elle-même : contient l’ID d’étendue et l’ID d’étendue parent que les outils APM utilisent pour générer les traces, la durée de l’activité et toutes les balises et événements associés à l’activité.
- Ressource associée à l’activité : contient des informations sur le service, l’instance et le SDK utilisés pour générer l’activité.
Important
Les attributs auxquels prêter une attention supplémentaire sont ceux qui commencent par gen_ai
. Il s’agit des attributs spécifiés dans les conventions sémantiques GenAI.
Métriques
Vous devez voir plusieurs enregistrements de métriques dans la sortie de la console. Ils ressemblent à ce qui suit :
Metric Name: semantic_kernel.connectors.openai.tokens.prompt, Number of prompt tokens used, Unit: {token}, Meter: Microsoft.SemanticKernel.Connectors.OpenAI
(2024-09-12T21:48:37.9531072Z, 2024-09-12T21:48:38.0966737Z] LongSum
Value: 16
Ici, vous pouvez voir le nom, la description, l’unité, l’intervalle de temps, le type, la valeur de la métrique et le compteur auquel appartient la métrique.
Remarque
La métrique ci-dessus est une métrique compteur. Pour obtenir la liste complète des types de métriques, voir ici. Selon le type de métrique, la sortie peut varier.
Journaux d’activité
Vous devez voir plusieurs enregistrements de journal dans la sortie de la console. Ils ressemblent à ce qui suit :
{
"body": "Function SyVCcBjaULqEhItH invoking.",
"severity_number": "<SeverityNumber.INFO: 9>",
"severity_text": "INFO",
"attributes": {
"code.filepath": "C:\\tmp\\telemetry-console-quickstart\\Lib\\site-packages\\semantic_kernel\\functions\\kernel_function_log_messages.py",
"code.function": "log_function_invoking",
"code.lineno": 19
},
"dropped_attributes": 0,
"timestamp": "2024-09-13T17:55:45.504983Z",
"observed_timestamp": "2024-09-13T17:55:45.504983Z",
"trace_id": "0xe23e2c10785ea61ffc9f28be19482a80",
"span_id": "0x686bd592e27661d7",
"trace_flags": 1,
"resource": {
"attributes": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.27.0",
"service.name": "telemetry-console-quickstart"
},
"schema_url": ""
}
}
Étendues
Vous devez voir plusieurs étendues dans la sortie de la console. Ils ressemblent à ce qui suit :
{
"name": "chat.completions gpt-4o",
"context": {
"trace_id": "0xe23e2c10785ea61ffc9f28be19482a80",
"span_id": "0x8b20e9655610c3c9",
"trace_state": "[]"
},
"kind": "SpanKind.INTERNAL",
"parent_id": "0x686bd592e27661d7",
"start_time": "2024-09-13T17:55:45.515198Z",
"end_time": "2024-09-13T17:55:46.469471Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"gen_ai.operation.name": "chat.completions",
"gen_ai.system": "openai",
"gen_ai.request.model": "gpt-4o",
"gen_ai.response.id": "chatcmpl-A74oD7WGDjawnZ44SJZrj9fKrEv1B",
"gen_ai.response.finish_reason": "FinishReason.STOP",
"gen_ai.response.prompt_tokens": 16,
"gen_ai.response.completion_tokens": 29
},
"events": [
{
"name": "gen_ai.content.prompt",
"timestamp": "2024-09-13T17:55:45.515198Z",
"attributes": {
"gen_ai.prompt": "[{\"role\": \"user\", \"content\": \"Why is the sky blue in one sentence?\"}]"
}
},
{
"name": "gen_ai.content.completion",
"timestamp": "2024-09-13T17:55:46.469471Z",
"attributes": {
"gen_ai.completion": "[{\"role\": \"assistant\", \"content\": \"The sky appears blue because shorter blue wavelengths of sunlight are scattered in all directions by the molecules and particles in the atmosphere more effectively than other colors.\"}]"
}
}
],
"links": [],
"resource": {
"attributes": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.27.0",
"service.name": "telemetry-console-quickstart"
},
"schema_url": ""
}
}
Attention aux attributs qui commencent par gen_ai
. Il s’agit des attributs spécifiés dans les conventions sémantiques GenAI. Ils fournissent des informations utiles sur les demandes envoyées et les réponses reçues des modèles IA.
Métriques
Vous devez voir plusieurs enregistrements de métriques dans la sortie de la console. Ils ressemblent à ce qui suit :
{
"resource_metrics": [
{
"resource": {
"attributes": {
"telemetry.sdk.language": "python",
"telemetry.sdk.name": "opentelemetry",
"telemetry.sdk.version": "1.27.0",
"service.name": "telemetry-console-quickstart"
},
"schema_url": ""
},
"scope_metrics": [
{
"scope": {
"name": "semantic_kernel.functions.kernel_function",
"version": null,
"schema_url": "",
"attributes": null
},
"metrics": [
{
"name": "semantic_kernel.function.invocation.duration",
"description": "Measures the duration of a function's execution",
"unit": "s",
"data": {
"data_points": [
{
"attributes": {
"semantic_kernel.function.name": "SyVCcBjaULqEhItH"
},
"start_time_unix_nano": 1726250146470468300,
"time_unix_nano": 1726250146478526600,
"count": 1,
"sum": 0.9650602999900002,
"bucket_counts": [
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"explicit_bounds": [
0.0,
5.0,
10.0,
25.0,
50.0,
75.0,
100.0,
250.0,
500.0,
750.0,
1000.0,
2500.0,
5000.0,
7500.0,
10000.0
],
"min": 0.9650602999900002,
"max": 0.9650602999900002
}
],
"aggregation_temporality": 2
}
}
],
"schema_url": ""
}
],
"schema_url": ""
}
]
}
La mesure indiquée ci-dessus est une métrique d’histogramme. Pour obtenir la liste complète des types de métriques, voir ici.
Remarque
L’observabilité du noyau sémantique n’est pas encore disponible pour Java.
Étapes suivantes
Maintenant que vous avez correctement généré des données de télémétrie dans la console, vous pouvez en savoir plus sur l’utilisation des outils APM pour visualiser et analyser les données de télémétrie.