Partilhar via


Inspeção de dados de telemetria com o console

Embora o console não seja uma maneira recomendada de inspecionar dados de telemetria, é uma maneira simples e rápida de começar. Este artigo mostra como enviar dados de telemetria para o console para inspeção com uma configuração mínima do kernel.

Exportador

Os exportadores são responsáveis pelo envio de dados de telemetria para um destino. Leia mais sobre exportadores aqui. Neste exemplo, usamos o exportador de console para enviar dados de telemetria para o console.

Pré-requisitos

  • Uma implantação de conclusão de chat do Azure OpenAI.
  • O SDK .Net mais recente para o seu sistema operacional.

Nota

A Observabilidade do Kernel Semântico ainda não está disponível para Java.

Configurar

Criar um novo aplicativo de console

Em um terminal, execute o seguinte comando para criar um novo aplicativo de console em C#:

dotnet new console -n TelemetryConsoleQuickstart

Navegue até o diretório do projeto recém-criado após a conclusão do comando.

Instalar pacotes necessários

  • Kernel Semântico

    dotnet add package Microsoft.SemanticKernel
    
  • Exportador de console OpenTelemetry

    dotnet add package OpenTelemetry.Exporter.Console
    

Crie uma aplicação simples com o Kernel Semântico

No diretório do projeto, abra o Program.cs arquivo com seu editor favorito. Vamos criar um aplicativo simples que usa o Kernel Semântico para enviar um prompt para um modelo de conclusão de chat. Substitua o conteúdo existente pelo código a seguir e preencha os valores necessários para deploymentName, endpointe 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);
        }
    }
}

Adicionar telemetria

Se você executar o aplicativo de console agora, você deve esperar ver uma frase explicando por que o céu é azul. Para observar o kernel via telemetria, substitua o // Telemetry setup code goes here comentário pelo seguinte código:

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);
});

Finalmente, Descomente a linha // builder.Services.AddSingleton(loggerFactory); para adicionar a fábrica de madeireiras ao construtor.

No trecho de código acima, primeiro criamos um construtor de recursos para criar instâncias de recursos. Um recurso representa a entidade que produz dados de telemetria. Você pode ler mais sobre recursos aqui. O construtor de recursos para os provedores é opcional. Se não for fornecido, o recurso padrão com atributos padrão será usado.

Em seguida, ativamos o diagnóstico com dados confidenciais. Este é um recurso experimental que permite habilitar diagnósticos para os serviços de IA no Kernel Semântico. Com isso ativado, você verá dados de telemetria adicionais, como os prompts enviados e as respostas recebidas dos modelos de IA, que são considerados dados confidenciais. Se você não quiser incluir dados confidenciais em sua telemetria, poderá usar outro switch Microsoft.SemanticKernel.Experimental.GenAI.EnableOTelDiagnostics para habilitar diagnósticos com dados não confidenciais, como o nome do modelo, o nome da operação e o uso do token, etc.

Em seguida, criamos um construtor de provedor de rastreador e um construtor de provedor de medidor. Um provedor é responsável por processar dados de telemetria e canalizá-los para os exportadores. Assinamos a Microsoft.SemanticKernel* fonte para receber dados de telemetria dos namespaces do Kernel Semântico. Adicionamos um exportador de console ao provedor de rastreador e ao provedor de medidor. O exportador de console envia dados de telemetria para o console.

Finalmente, criamos uma fábrica de logger e adicionamos OpenTelemetry como um provedor de log que envia dados de log para o console. Definimos o nível mínimo de log e Information incluímos mensagens formatadas e escopos na saída do log. A fábrica de madeireiros é então adicionada ao construtor.

Importante

Um provedor deve ser um singleton e deve estar vivo durante toda a vida útil do aplicativo. O provedor deve ser descartado quando o aplicativo for desligado.

Criar um novo ambiente virtual Python

python -m venv telemetry-console-quickstart

Ative o ambiente virtual.

telemetry-console-quickstart\Scripts\activate

Instalar pacotes necessários

pip install semantic-kernel

Crie um script Python simples com o Kernel Semântico

Crie um novo script Python e abra-o com o seu editor favorito.

New-Item -Path telemetry_console_quickstart.py -ItemType file

Vamos criar um script Python simples que usa o Kernel Semântico para enviar um prompt para um modelo de conclusão de chat. Substitua o conteúdo existente pelo código a seguir e preencha os valores necessários para deployment_name, endpointe 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())

Adicionar telemetria

Variáveis de ambiente

Por padrão, o kernel não emite vãos para os conectores de IA, porque esses vãos carregam gen_ai atributos que são considerados experimentais. Para habilitar o recurso, defina a variável SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS de ambiente ou SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE como true.

Importante

Prompts e preenchimentos são considerados dados confidenciais. O Kernel Semântico não emitirá esses dados dos conectores de IA, a menos que a SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE variável de ambiente esteja definida como true. A configuração SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS como true emitirá apenas dados não confidenciais, como o nome do modelo, o nome da operação e o uso do token.

Crie um novo arquivo nomeado .env no mesmo diretório do script e adicione o seguinte conteúdo:

SEMANTICKERNEL_EXPERIMENTAL_GENAI_ENABLE_OTEL_DIAGNOSTICS_SENSITIVE=true

Código

Se você executar o script agora, você deve esperar ver uma frase explicando por que o céu é azul. Para observar o kernel via telemetria, substitua o # Telemetry setup code goes here comentário pelo seguinte código:

# 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()

No trecho de código acima, primeiro criamos um recurso para representar o serviço. Um recurso representa a entidade que produz dados de telemetria. Você pode ler mais sobre recursos aqui. Em seguida, criamos três funções para configurar o registro, o rastreamento e as métricas. Cada função cria um provedor para os respetivos dados de telemetria e adiciona um exportador de console ao provedor.

Finalmente, chamamos as três funções para configurar o registro, o rastreamento e as métricas. Isso deve ser feito antes de qualquer outra chamada de telemetria.

Nota

A Observabilidade do Kernel Semântico ainda não está disponível para Java.

Executar

Execute o aplicativo de console com o seguinte comando:

dotnet run

Execute o script Python com o seguinte comando:

python telemetry_console_quickstart.py

Nota

A Observabilidade do Kernel Semântico ainda não está disponível para Java.

Inspecionar dados de telemetria

Registos de registo

Você deve ver vários registros de log na saída do console. Eles são semelhantes aos seguintes:

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

Há duas partes em cada registro de log:

  • O registro de log em si: contém o carimbo de data/hora e o namespace no qual o registro de log foi gerado, a gravidade e o corpo do registro de log e quaisquer atributos associados ao registro de log.
  • O recurso associado ao registro de log: contém informações sobre o serviço, a instância e o SDK usados para gerar o registro de log.

Atividades

Nota

As atividades no .Net são semelhantes aos vãos no OpenTelemetry. Eles são usados para representar uma unidade de trabalho no aplicativo.

Você deve ver várias atividades na saída do console. Eles são semelhantes aos seguintes:

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

Cada atividade tem duas partes:

  • A atividade em si: contém o ID de span e o ID de span pai que as ferramentas APM usam para criar os rastreamentos, a duração da atividade e quaisquer tags e eventos associados à atividade.
  • O recurso associado à atividade: contém informações sobre o serviço, a instância e o SDK usados para gerar a atividade.

Importante

Os atributos aos quais prestar atenção extra são os que começam com gen_ai. Estes são os atributos especificados nas Convenções Semânticas do GenAI.

Métricas

Você deve ver vários registros métricos na saída do console. Eles são semelhantes aos seguintes:

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

Aqui você pode ver o nome, a descrição, a unidade, o intervalo de tempo, o tipo, o valor da métrica e o medidor ao qual a métrica pertence.

Nota

A métrica acima é uma métrica Contador. Para obter uma lista completa dos tipos de métricas, consulte aqui. Dependendo do tipo de métrica, a saída pode variar.

Registos

Você deve ver vários registros de log na saída do console. Eles são semelhantes aos seguintes:

{
    "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": ""
    }
}

Espaças

Você deve ver várias extensões na saída do console. Eles são semelhantes aos seguintes:

{
    "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": ""
    }
}

Preste atenção aos atributos que começam com gen_ai. Estes são os atributos especificados nas Convenções Semânticas do GenAI. Eles fornecem informações úteis sobre as solicitações enviadas e as respostas recebidas dos modelos de IA.

Métricas

Você deve ver vários registros métricos na saída do console. Eles são semelhantes aos seguintes:

{
    "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": ""
        }
    ]
}

A medida mostrada acima é uma métrica de histograma. Para obter uma lista completa dos tipos de métricas, consulte aqui.

Nota

A Observabilidade do Kernel Semântico ainda não está disponível para Java.

Próximos passos

Agora que você enviou com êxito dados de telemetria para o console, pode aprender mais sobre como usar as ferramentas APM para visualizar e analisar dados de telemetria.