Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Наблюдаемость является ключевым аспектом создания надежных и обслуживаемых систем. Agent Framework обеспечивает встроенную поддержку наблюдаемости, позволяя отслеживать поведение агентов.
В этом руководстве вы узнаете, как обеспечить наблюдаемость с помощью Agent Framework, чтобы понять, как выполняются агенты и диагностировать любые проблемы, которые могут возникнуть.
Интеграция OpenTelemetry
Agent Framework интегрируется с OpenTelemetry, а в частности агентная платформа выдает трассировки, журналы и метрики в соответствии с семантические соглашения OpenTelemetry GenAI.
Включение наблюдаемости (C#)
Чтобы включить наблюдаемость для клиента чата, необходимо создать клиент чата следующим образом:
// Using the AIProjectClient as an example
var instrumentedChatClient = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
.GetProjectOpenAIClient()
.GetProjectResponsesClient()
.AsIChatClient(deploymentName) // Converts into a Microsoft.Extensions.AI.IChatClient
.AsBuilder()
.UseOpenTelemetry(sourceName: SourceName, configure: (cfg) => cfg.EnableSensitiveData = true) // Enable OpenTelemetry instrumentation with sensitive data
.Build();
Предупреждение
DefaultAzureCredential удобно для разработки, но требует тщательного рассмотрения в рабочей среде. В рабочей среде рекомендуется использовать определенные учетные данные (например, ManagedIdentityCredential), чтобы избежать проблем с задержкой, непреднамеренного проверки учетных данных и потенциальных рисков безопасности из резервных механизмов.
Чтобы включить наблюдаемость для агента, необходимо создать агент следующим образом:
var agent = new ChatClientAgent(
instrumentedChatClient,
name: "OpenTelemetryDemoAgent",
instructions: "You are a helpful assistant that provides concise and informative responses.",
tools: [AIFunctionFactory.Create(GetWeatherAsync)]
).WithOpenTelemetry(sourceName: SourceName, configure: (cfg) => cfg.EnableSensitiveData = true); // Enable OpenTelemetry instrumentation with sensitive data
Это важно
При включении наблюдаемости для клиентов и агентов чата может отображаться повторяющаяся информация, особенно при включении конфиденциальных данных. Контекст чата (включая запросы и ответы), захваченный клиентом чата и агентом, будет включен в оба диапазона. В зависимости от ваших потребностей вы можете включить наблюдаемость только в клиенте чата или только на агенте, чтобы избежать дублирования. Дополнительные сведения об атрибутах, захваченных для LLM и агентов, см. в семантических соглашениях GenAI .
Предупреждение
Включить конфиденциальные данные только в средах разработки или тестирования, так как они могут предоставлять сведения о пользователях в рабочих журналах и трассировках. Конфиденциальные данные включают запросы, ответы, аргументы вызова функции и результаты.
Конфигурация
Теперь, когда клиент чата и агент инструментируются, вы можете настроить экспортеров OpenTelemetry для отправки данных телеметрии в нужную серверную часть.
Следы
Чтобы экспортировать трассировки в нужную серверную часть, можно настроить пакет SDK OpenTelemetry в коде запуска приложения. Например, чтобы экспортировать трассировки в ресурс Azure Monitor:
using Azure.Monitor.OpenTelemetry.Exporter;
using OpenTelemetry;
using OpenTelemetry.Trace;
using OpenTelemetry.Resources;
using System;
// The source name under which all activities, metrics, and logs will be emitted.
const string SourceName = "MyApplication";
const string ServiceName = "AgentOpenTelemetry";
var applicationInsightsConnectionString = Environment.GetEnvironmentVariable("APPLICATION_INSIGHTS_CONNECTION_STRING")
?? throw new InvalidOperationException("APPLICATION_INSIGHTS_CONNECTION_STRING is not set.");
var resourceBuilder = ResourceBuilder
.CreateDefault()
.AddService(ServiceName);
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(resourceBuilder)
.AddSource(SourceName)
.AddAzureMonitorTraceExporter(options => options.ConnectionString = applicationInsightsConnectionString)
.Build();
Подсказка
Метод AddSource используется для указания исходного имени, к которому будет прослушивать поставщик. Убедитесь, что оно соответствует исходному имени, используемому в коде инструментирования (например, UseOpenTelemetry(sourceName: SourceName)). Если исходное имя не указано в коде инструментирования, оно по умолчанию будет Experimental.Майкрософт.Agents.AI, в этом случае следует использовать AddSource("Experimental.Майкрософт.Agents.AI") в конфигурации поставщика трассировки и поставщика счетчиков.
Подсказка
В зависимости от серверной части можно использовать различные экспортеры. Дополнительные сведения см. в документации .NET OpenTelemetry. Для локальной разработки рекомендуется использовать панель мониторинга Aspire.
Metrics
Аналогичным образом, чтобы экспортировать метрики в нужную серверную часть, можно настроить пакет SDK OpenTelemetry в коде запуска приложения. Например, чтобы экспортировать метрики в ресурс Azure Monitor:
using Azure.Monitor.OpenTelemetry.Exporter;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using System;
var applicationInsightsConnectionString = Environment.GetEnvironmentVariable("APPLICATION_INSIGHTS_CONNECTION_STRING")
?? throw new InvalidOperationException("APPLICATION_INSIGHTS_CONNECTION_STRING is not set.");
var resourceBuilder = ResourceBuilder
.CreateDefault()
.AddService(ServiceName);
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.SetResourceBuilder(resourceBuilder)
.AddSource(SourceName)
.AddAzureMonitorMetricExporter(options => options.ConnectionString = applicationInsightsConnectionString)
.Build();
Logs
Журналы записываются с помощью используемой платформы ведения журнала, например Майкрософт.Extensions.Logging. Чтобы экспортировать журналы в ресурс Azure Monitor, можно настроить поставщика ведения журнала в коде запуска приложения:
using Azure.Monitor.OpenTelemetry.Exporter;
using Microsoft.Extensions.Logging;
var applicationInsightsConnectionString = Environment.GetEnvironmentVariable("APPLICATION_INSIGHTS_CONNECTION_STRING")
?? throw new InvalidOperationException("APPLICATION_INSIGHTS_CONNECTION_STRING is not set.");
using var loggerFactory = LoggerFactory.Create(builder =>
{
// Add OpenTelemetry as a logging provider
builder.AddOpenTelemetry(options =>
{
options.SetResourceBuilder(resourceBuilder);
options.AddAzureMonitorLogExporter(options => options.ConnectionString = applicationInsightsConnectionString);
// Format log messages. This is default to false.
options.IncludeFormattedMessage = true;
options.IncludeScopes = true;
})
.SetMinimumLevel(LogLevel.Debug);
});
// Create a logger instance for your application
var logger = loggerFactory.CreateLogger<Program>();
Панель мониторинга Aspire
Используйте панель мониторинга Aspire в качестве быстрого способа визуализации трассировок и метрик во время разработки. Дополнительные сведения см. в документации по панели мониторинга Aspire. Панель мониторинга Aspire получает данные через сборщик OpenTelemetry, который можно добавить в поставщик трассировки следующим образом:
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(resourceBuilder)
.AddSource(SourceName)
.AddOtlpExporter(options => options.Endpoint = new Uri("http://localhost:4317"))
.Build();
Начало работы
Полный пример агента с поддержкой OpenTelemetry в репозитории Agent Framework.
Подсказка
Полные примеры запуска см. в примерах .NET.
Зависимости
Включенные пакеты
Чтобы включить наблюдаемость в приложении Python, по умолчанию устанавливаются следующие пакеты OpenTelemetry:
Экспортеров
По умолчанию не устанавливаем экспортеров, чтобы предотвратить ненужные зависимости и потенциальные проблемы с автоматической инструментацией. Существует множество экспортеров, доступных для разных серверных служб, поэтому вы можете выбрать те, которые лучше всего соответствуют вашим потребностям.
Некоторые распространенные экспортеры, которые могут потребоваться установить в зависимости от ваших потребностей:
- Для поддержки протокола gRPC: установка
opentelemetry-exporter-otlp-proto-grpc - Для поддержки протокола HTTP: установка
opentelemetry-exporter-otlp-proto-http - Для приложение Azure Insights: установите
azure-monitor-opentelemetry
Используйте реестр OpenTelemetry , чтобы найти больше экспортеров и пакетов инструментирования.
Включение наблюдаемости (Python)
Пять шаблонов для настройки наблюдаемости
Мы определили несколько способов настройки наблюдаемости в приложении в зависимости от ваших потребностей:
1. Стандартные переменные среды OpenTelemetry (рекомендуется)
Самый простой подход — настройка всего с помощью переменных среды:
from agent_framework.observability import configure_otel_providers
# Reads OTEL_EXPORTER_OTLP_* environment variables automatically
configure_otel_providers()
Или если требуется только экспортеры консоли, задайте ENABLE_CONSOLE_EXPORTERS переменную среды:
ENABLE_CONSOLE_EXPORTERS=true
from agent_framework.observability import configure_otel_providers
# Console exporters are enabled via the ENABLE_CONSOLE_EXPORTERS env var
configure_otel_providers()
2. Настраиваемые экспортеры
Чтобы больше контролировать экспортеров, создайте их самостоятельно и передайте их configure_otel_providers()в:
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
from agent_framework.observability import configure_otel_providers
# Create custom exporters with specific configuration
exporters = [
OTLPSpanExporter(endpoint="http://localhost:4317", compression=Compression.Gzip),
OTLPLogExporter(endpoint="http://localhost:4317"),
OTLPMetricExporter(endpoint="http://localhost:4317"),
]
# These will be added alongside any exporters from environment variables
configure_otel_providers(exporters=exporters, enable_sensitive_data=True)
3. Сторонняя настройка
Многие сторонние пакеты OpenTelemetry имеют собственные методы установки. Эти методы можно использовать сначала, а затем вызвать enable_instrumentation() путь к коду инструментирования Agent Framework:
from azure.monitor.opentelemetry import configure_azure_monitor
from agent_framework.observability import create_resource, enable_instrumentation
# Configure Azure Monitor first
configure_azure_monitor(
connection_string="InstrumentationKey=...",
resource=create_resource(), # Uses OTEL_SERVICE_NAME, etc.
enable_live_metrics=True,
)
# Then activate Agent Framework's telemetry code paths
# This is optional if ENABLE_INSTRUMENTATION and/or ENABLE_SENSITIVE_DATA are set in env vars
enable_instrumentation(enable_sensitive_data=False)
Для Langfuse:
from agent_framework.observability import enable_instrumentation
from langfuse import get_client
langfuse = get_client()
# Verify connection
if langfuse.auth_check():
print("Langfuse client is authenticated and ready!")
# Then activate Agent Framework's telemetry code paths
enable_instrumentation(enable_sensitive_data=False)
4. Настройка вручную
Для полного управления можно вручную настроить экспортеров, поставщиков и инструментирование. Используйте вспомогательную функцию create_resource() , чтобы создать ресурс с соответствующим именем и версией службы. Подробные инструкции по инструментированию вручную см. в документации Python OpenTelemetry.
5. Автоматическое инструментирование (нулевой код)
Используйте средство КОМАНДНОй строки OpenTelemetry для автоматического инструментирования приложения без изменений кода:
opentelemetry-instrument \
--traces_exporter console,otlp \
--metrics_exporter console \
--service_name your-service-name \
--exporter_otlp_endpoint 0.0.0.0:4317 \
python agent_framework_app.py
Дополнительные сведения см. в документации OpenTelemetry Zero-Python code.
Использование трассировок и счетчиков
После настройки наблюдаемости можно создать настраиваемые диапазоны или метрики:
from agent_framework.observability import get_tracer, get_meter
tracer = get_tracer()
meter = get_meter()
with tracer.start_as_current_span("my_custom_span"):
# do something
pass
counter = meter.create_counter("my_custom_counter")
counter.add(1, {"key": "value"})
Это оболочки API OpenTelemetry, возвращающие трассировку или метрика от глобального поставщика, с agent_framework заданным именем библиотеки инструментирования по умолчанию.
Переменные среды
Следующие переменные среды управляют наблюдаемостью Agent Framework:
-
ENABLE_INSTRUMENTATION— Значение по умолчанию — дляfalsetrueвключения инструментирования OpenTelemetry. -
ENABLE_SENSITIVE_DATA— Значение по умолчанию —falsetrueдля включения ведения журнала конфиденциальных данных (запросы, ответы, аргументы вызова функции и результаты). Будьте осторожны с этим параметром, так как он может предоставлять конфиденциальные данные. -
ENABLE_CONSOLE_EXPORTERS— Значение по умолчанию — дляfalsetrueвключения выходных данных консоли для телеметрии. -
VS_CODE_EXTENSION_PORT— порт для набора средств ИИ Майкрософт или интеграция расширения Vs Code для Foundry VS Code.
Предупреждение
Конфиденциальная информация включает запросы, ответы и многое другое и должна быть включена только в средах разработки или тестирования. Не рекомендуется включить эту функцию в рабочей среде, так как она может предоставлять конфиденциальные данные.
Стандартные переменные среды OpenTelemetry
Функция configure_otel_providers() автоматически считывает стандартные переменные среды OpenTelemetry:
Конфигурация OTLP (для панели мониторинга Aspire, Jaeger и т. д.):
-
OTEL_EXPORTER_OTLP_ENDPOINT— базовая конечная точка для всех сигналов (например,http://localhost:4317) -
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT— конечная точка трассировки (переопределяет базовую) -
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT— конечная точка для конкретных метрик (переопределяет базовую) -
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT— конечная точка для определенных журналов (переопределяет базовую) -
OTEL_EXPORTER_OTLP_PROTOCOL— протокол для использования (grpcилиhttp, по умолчанию:grpc) -
OTEL_EXPORTER_OTLP_HEADERS— заголовки для всех сигналов (например,key1=value1,key2=value2)
Идентификация службы:
-
OTEL_SERVICE_NAME— имя службы (по умолчанию:agent_framework) -
OTEL_SERVICE_VERSION— версия службы (по умолчанию: версия пакета) -
OTEL_RESOURCE_ATTRIBUTES- Дополнительные атрибуты ресурсов
Дополнительные сведения см. в спецификации OpenTelemetry .
настройка Майкрософт Foundry
Майкрософт Foundry поддерживает встроенную поддержку трассировки с визуализацией для диапазонов.
Убедитесь, что у вас настроен экземпляр Foundry с Azure Monitor, см. раздел details
Установите пакет azure-monitor-opentelemetry.
pip install azure-monitor-opentelemetry
Настройка наблюдаемости непосредственно из FoundryChatClient
Для проектов Foundry можно настроить наблюдаемость непосредственно из FoundryChatClientследующих объектов:
import os
from agent_framework.foundry import FoundryChatClient
from azure.identity.aio import AzureCliCredential
async def main():
async with AzureCliCredential() as credential:
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
credential=credential,
)
# Automatically configures Azure Monitor with the connection string from the Foundry project
await client.configure_azure_monitor(enable_live_metrics=True)
Подсказка
Аргументы для client.configure_azure_monitor() передаются в базовую функцию configure_azure_monitor() из пакета azure-monitor-opentelemetry см. в разделе документации подробные сведения о настройке строка подключения и ресурса.
Настройка Azure Monitor и включение инструментирования
Сведения о проектах, отличных от Foundry, с помощью Application Insights, см. в разделе сведений о настройке пользовательского агента в Foundry.
Затем запустите агент с тем же идентификатором агента OpenTelemetry , что зарегистрировано в Foundry, и настройте azure monitor следующим образом:
from azure.monitor.opentelemetry import configure_azure_monitor
from agent_framework.observability import create_resource, enable_instrumentation
configure_azure_monitor(
connection_string="InstrumentationKey=...",
resource=create_resource(),
enable_live_metrics=True,
)
# optional if you do not have ENABLE_INSTRUMENTATION in env vars
enable_instrumentation()
# Create your agent with the same OpenTelemetry agent ID as registered in Foundry
agent = Agent(
client=...,
name="My Agent",
instructions="You are a helpful assistant.",
id="<OpenTelemetry agent ID>"
)
# use the agent as normal
Панель мониторинга Aspire
Для локальной разработки без настройки Azure можно использовать панель мониторинга Aspire Dashboard, которая выполняется локально через Docker и обеспечивает отличный интерфейс просмотра телеметрии.
Настройка панели мониторинга Aspire с помощью Docker
# Pull and run the Aspire Dashboard container
docker run --rm -it -d \
-p 18888:18888 \
-p 4317:18889 \
--name aspire-dashboard \
mcr.microsoft.com/dotnet/aspire-dashboard:latest
Эта команда запустит панель мониторинга с помощью следующих команд:
- Веб-интерфейс: доступно в http://localhost:18888
-
Конечная точка OTLP: доступна
http://localhost:4317для приложений для отправки данных телеметрии
Настройка приложения
Задайте следующие переменные среды:
ENABLE_INSTRUMENTATION=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
Или включите их в .env файл и убедитесь, что вы вызываете load_dotenv() в начале приложения (Agent Framework не загружает .env файлы автоматически).
После завершения работы примера перейдите http://localhost:18888 в веб-браузер, чтобы просмотреть данные телеметрии. Следуйте руководству по просмотру панели мониторинга Aspire , чтобы пройти проверку подлинности на панели мониторинга и начать изучение трассировок, журналов и метрик.
Диапазоны и метрики
Когда все будет настроено, вы начнете видеть диапазоны и метрики, создаваемые автоматически для вас, диапазоны:
-
invoke_agent <agent_name>: это диапазон верхнего уровня для каждого вызова агента, он будет содержать все остальные диапазоны как дочерние. -
chat <model_name>: этот диапазон создается при вызове базовой модели чата, он будет содержать запрос и ответ в качестве атрибутов, еслиenable_sensitive_dataзадано значениеTrue. -
execute_tool <function_name>: этот диапазон создается при вызове средства функции, он будет содержать аргументы функции и результат в виде атрибутов, еслиenable_sensitive_dataзадано значениеTrue.
Созданные метрики:
Для клиента чата и
chatопераций:-
gen_ai.client.operation.duration(гистограмма): эта метрика измеряет длительность каждой операции в секундах. -
gen_ai.client.token.usage(гистограмма): эта метрика измеряет использование маркеров в количестве маркеров.
-
Для вызова функции во время операций
execute_tool:-
agent_framework.function.invocation.duration(гистограмма): эта метрика измеряет длительность каждого выполнения функции в секундах.
-
Пример выходных данных трассировки
При запуске агента с включенной наблюдаемостью вы увидите данные трассировки, аналогичные следующим выходным данным консоли:
{
"name": "invoke_agent Joker",
"context": {
"trace_id": "0xf2258b51421fe9cf4c0bd428c87b1ae4",
"span_id": "0x2cad6fc139dcf01d",
"trace_state": "[]"
},
"kind": "SpanKind.CLIENT",
"parent_id": null,
"start_time": "2025-09-25T11:00:48.663688Z",
"end_time": "2025-09-25T11:00:57.271389Z",
"status": {
"status_code": "UNSET"
},
"attributes": {
"gen_ai.operation.name": "invoke_agent",
"gen_ai.system": "openai",
"gen_ai.agent.id": "Joker",
"gen_ai.agent.name": "Joker",
"gen_ai.request.instructions": "You are good at telling jokes.",
"gen_ai.response.id": "chatcmpl-CH6fgKwMRGDtGNO3H88gA3AG2o7c5",
"gen_ai.usage.input_tokens": 26,
"gen_ai.usage.output_tokens": 29
}
}
Эта трассировка показывает:
- Идентификаторы трассировки и диапазона: для сопоставления связанных операций
- Сведения о времени: при запуске и завершении операции
- Метаданные агента: идентификатор агента, имя и инструкции
- Сведения о модели: используемая система ИИ (OpenAI) и идентификатор ответа
- Использование маркеров: количество входных и выходных маркеров для отслеживания затрат
Samples
В репозитории есть несколько примеров microsoft/agent-framework , демонстрирующих эти возможности. Дополнительные сведения см. в папке примеров наблюдаемости. Эта папка содержит примеры для использования телеметрии нулевого кода, а также.
Полный пример
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from random import randint
from typing import Annotated
from agent_framework import Agent, tool
from agent_framework.observability import configure_otel_providers, get_tracer
from agent_framework.openai import OpenAIChatClient
from opentelemetry.trace import SpanKind
from opentelemetry.trace.span import format_trace_id
from pydantic import Field
"""
This sample shows how you can observe an agent in Agent Framework by using the
same observability setup function.
"""
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/tools/function_tool_with_approval_and_sessions.py.
@tool(approval_mode="never_require")
async def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
await asyncio.sleep(randint(0, 10) / 10.0) # Simulate a network call
conditions = ["sunny", "cloudy", "rainy", "stormy"]
return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."
async def main():
# calling `configure_otel_providers` will *enable* tracing and create the necessary tracing, logging
# and metrics providers based on environment variables.
# See the .env.example file for the available configuration options.
configure_otel_providers()
questions = ["What's the weather in Amsterdam?", "and in Paris, and which is better?", "Why is the sky blue?"]
with get_tracer().start_as_current_span("Scenario: Agent Chat", kind=SpanKind.CLIENT) as current_span:
print(f"Trace ID: {format_trace_id(current_span.get_span_context().trace_id)}")
agent = Agent(
client=OpenAIChatClient(),
tools=get_weather,
name="WeatherAgent",
instructions="You are a weather assistant.",
id="weather-agent",
)
thread = agent.create_session()
for question in questions:
print(f"\nUser: {question}")
print(f"{agent.name}: ", end="")
async for update in agent.run(
question,
session=thread,
stream=True,
):
if update.text:
print(update.text, end="")
if __name__ == "__main__":
asyncio.run(main())