Поделиться через


Трассировка приложений ИИ с помощью пакета SDK OpenAI

Трассировка обеспечивает детальное представление о выполнении вашего приложения, записывая подробные данные телеметрии на каждом этапе выполнения. Это помогает диагностировать проблемы и повысить производительность путем выявления таких проблем, как неточные вызовы инструментов, вводящие в заблуждение запросы, высокая задержка, оценка низкого качества и многое другое.

В этой статье объясняется, как реализовать трассировку приложений ИИ с помощью пакета SDK OpenAI с openTelemetry в Azure AI Foundry.

Предпосылки

Для выполнения этого руководства вам потребуется следующее:

  • Проект Azure AI Foundry создан.

  • Приложение ИИ, использующее пакет SDK OpenAI для вызова моделей, размещенных в Azure AI Foundry.

Включите трассировку в вашем проекте

Azure AI Foundry хранит трассировки в ресурсах Azure Application Insight с помощью OpenTelemetry. По умолчанию новые ресурсы Azure AI Foundry не подготавливают эти ресурсы. Вы можете подключить проекты к существующему ресурсу Azure Application Insights или создать новый из проекта. Такая конфигурация выполняется один раз для каждого ресурса Azure AI Foundry.

Ниже показано, как настроить ресурс.

  1. Перейдите на портал Azure AI Foundry и перейдите к проекту.

  2. На боковой панели навигации выберите "Трассировка".

  3. Если ресурс Azure Application Insights не связан с ресурсом Azure AI Foundry, свяжите его.

    Снимок экрана: настройка Azure Application Insights в ресурсе Azure AI Foundry.

  4. Чтобы повторно использовать существующую службу Azure Application Insights, используйте раскрывающееся имя ресурса Application Insights, чтобы найти ресурс и выбрать "Подключить".

    Подсказка

    Чтобы подключиться к существующему Azure Application Insights, вам потребуется, по крайней мере, доступ уровня участника к ресурсу Azure AI Foundry (или узлу).

  5. Чтобы подключиться к новому ресурсу Azure Application Insights, выберите параметр "Создать".

    1. Используйте мастер конфигурации, чтобы настроить имя нового ресурса.

    2. По умолчанию новый ресурс создается в той же группе ресурсов, где был создан ресурс Azure AI Foundry. Используйте параметр "Заранее" , чтобы настроить другую группу ресурсов или подписку.

      Подсказка

      Чтобы создать ресурс Azure Application Insights, вам также нужна роль участника в выбранной группе ресурсов (или по умолчанию).

    3. Выберите "Создать", чтобы создать ресурс и подключить его к ресурсу Azure AI Foundry.

  6. После настройки подключения вы будете готовы использовать трассировку в любом проекте в ресурсе.

  7. Перейдите на целевую страницу проекта и скопируйте URI конечной точки проекта. Вам потребуется позже в этом руководстве.

    Снимок экрана: копирование URI конечной точки проекта.

    Это важно

    Для использования конечной точки проекта требуется настройка идентификатора Microsoft Entra в приложении. Если у вас не настроен Entra ID, используйте строку подключения Azure Application Insights, как указано на шаге 3 руководства.

Настройка пакета SDK OpenAI

При разработке с помощью пакета SDK OpenAI можно инструментировать код, чтобы трассировки отправлялись в Azure AI Foundry. Выполните следующие действия, чтобы инструментировать код:

  1. Установите azure-ai-projects, azure-monitor-opentelemetryа также opentelemetry-instrumentation-openai-v2 в вашей среде. В следующем примере используется pip.

    pip install azure-ai-projects azure-monitor-opentelemetry opentelemetry-instrumentation-openai-v2
    
  2. Инструментирование пакета SDK OpenAI с помощью OpenAIInstrumentor():

    from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor
    
    OpenAIInstrumentor().instrument()
    
  3. Получите строку подключения к ресурсу Azure Application Insights, связанному с проектом. В следующей строке используется клиент Azure AI Project, который требует использования идентификатора Microsoft Entra для проверки подлинности:

    from azure.ai.projects import AIProjectClient
    from azure.identity import DefaultAzureCredential
    
    project_client = AIProjectClient(
        credential=DefaultAzureCredential(),
        endpoint="https://<your-resource>.services.ai.azure.com/api/projects/<your-project>",
    )
    
    connection_string = project_client.telemetry.get_connection_string()
    

    Подсказка

    Строки подключения к Azure Application Insights выглядят следующим образом InstrumentationKey=aaaa0a0a-bb1b-cc2c-dd3d-eeeee4e4e4e;.... Вы также можете получить доступ к строке подключения, используемой в проекте, из раздела Трассировки на портале Azure AI Foundry. На верхней панели навигации выберите "Управление источником данных " и скопируйте строку подключения. Настройте строку подключения в переменной среды.

    Снимок экрана: копирование строки подключения в базовый ресурс Azure Application Insights из проекта.

  4. Настройте OpenTelemetry для отправки трассировок в Azure Application Insights:

    from azure.monitor.opentelemetry import configure_azure_monitor
    
    configure_azure_monitor(connection_string=connection_string)
    
  5. По умолчанию OpenTelemetry не записывает входные и выходные данные. Используйте переменную OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true среды для их записи. Убедитесь, что эта переменная среды настроена на уровне среды, где выполняется код.

  6. Используйте пакет SDK OpenAI как обычно:

    client = project_client.get_azure_openai_client()
    
    response = client.chat.completions.create(
        model="deepseek-v3-0324",
        messages=[
            {"role": "user", "content": "Write a short poem on open telemetry."},
        ],
    )
    
  7. Если вернуться на портал Azure AI Foundry, отобразится трассировка:

    Снимок экрана, показывающий, как в трассировке отображается простой запрос на завершение чата.

  8. Это может быть полезно для записи разделов кода, которые смешивают бизнес-логику с моделями при разработке сложных приложений. OpenTelemetry использует концепцию диапазонов для отслеживания интересующих вас разделов. Чтобы начать генерацию собственных интервалов, получите экземпляр текущего объекта трейсера.

    from opentelemetry import trace
    
    tracer = trace.get_tracer(__name__)
    
  9. Затем используйте декораторы в вашем методе, чтобы фиксировать конкретные сценарии в коде, который вас интересует. Такие декораторы создают диапазоны автоматически. В следующем примере кода метод assess_claims_with_context производит итерацию по списку заявлений и проверяет, поддерживается ли каждое заявление контекстом с помощью LLM. Все вызовы, выполненные в этом методе, фиксируются в одном диапазоне:

    def build_prompt_with_context(claim: str, context: str) -> str:
        return [{'role': 'system', 'content': "I will ask you to assess whether a particular scientific claim, based on evidence provided. Output only the text 'True' if the claim is true, 'False' if the claim is false, or 'NEE' if there's not enough evidence."},
                {'role': 'user', 'content': f"""
                    The evidence is the following: {context}
    
                    Assess the following claim on the basis of the evidence. Output only the text 'True' if the claim is true, 'False' if the claim is false, or 'NEE' if there's not enough evidence. Do not output any other text.
    
                    Claim:
                    {claim}
    
                    Assessment:
                """}]
    
    @tracer.start_as_current_span("assess_claims_with_context")
    def assess_claims_with_context(claims, contexts):
        responses = []
        for claim, context in zip(claims, contexts):
            response = client.chat.completions.create(
                model="gpt-4.5-preview",
                messages=build_prompt_with_context(claim=claim, context=context),
            )
            responses.append(response.choices[0].message.content.strip('., '))
    
        return responses
    
  10. Трассировки выглядят следующим образом:

    Снимок экрана, показывающий, как метод с помощью декоратора отображается в трассировке.

  11. Вы также можете добавить дополнительные сведения в текущий диапазон. OpenTelemetry использует концепцию атрибутов для этого. trace Используйте объект для доступа к ним и включения дополнительных сведений. Узнайте, как assess_claims_with_context метод был изменен для включения атрибута:

    @tracer.start_as_current_span("assess_claims_with_context")
    def assess_claims_with_context(claims, contexts):
        responses = []
        current_span = trace.get_current_span()
    
        current_span.set_attribute("operation.claims_count", len(claims))
    
        for claim, context in zip(claims, contexts):
            response = client.chat.completions.create(
                model="gpt-4.5-preview",
                messages=build_prompt_with_context(claim=claim, context=context),
            )
            responses.append(response.choices[0].message.content.strip('., '))
    
        return responses
    

Трассировка в консоль

Это может быть полезно также для трассировки приложения и отправки трассировок в локальную консоль выполнения. Такой подход может оказаться полезным при выполнении модульных тестов или тестов интеграции в приложении с помощью автоматизированного конвейера CI/CD. Трассировки можно отправлять в консоль и захватывать с помощью средств CI/CD для дальнейшего анализа.

Настройте трассировку следующим образом:

  1. Настройте пакет SDK OpenAI как обычно.

    from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor
    
    OpenAIInstrumentor().instrument()
    
  2. Настройте OpenTelemetry для отправки трассировок в консоль:

    from opentelemetry import trace
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter
    
    span_exporter = ConsoleSpanExporter()
    tracer_provider = TracerProvider()
    tracer_provider.add_span_processor(SimpleSpanProcessor(span_exporter))
    trace.set_tracer_provider(tracer_provider)
    
  3. Используйте пакет SDK OpenAI как обычно:

    response = client.chat.completions.create(
        model="deepseek-v3-0324",
        messages=[
            {"role": "user", "content": "Write a short poem on open telemetry."},
        ],
    )
    
    {
        "name": "chat deepseek-v3-0324",
        "context": {
            "trace_id": "0xaaaa0a0abb1bcc2cdd3d",
            "span_id": "0xaaaa0a0abb1bcc2cdd3d",
            "trace_state": "[]"
        },
        "kind": "SpanKind.CLIENT",
        "parent_id": null,
        "start_time": "2025-06-13T00:02:04.271337Z",
        "end_time": "2025-06-13T00:02:06.537220Z",
        "status": {
            "status_code": "UNSET"
        },
        "attributes": {
            "gen_ai.operation.name": "chat",
            "gen_ai.system": "openai",
            "gen_ai.request.model": "deepseek-v3-0324",
            "server.address": "my-project.services.ai.azure.com",
            "gen_ai.response.model": "DeepSeek-V3-0324",
            "gen_ai.response.finish_reasons": [
                "stop"
            ],
            "gen_ai.response.id": "aaaa0a0abb1bcc2cdd3d",
            "gen_ai.usage.input_tokens": 14,
            "gen_ai.usage.output_tokens": 91
        },
        "events": [],
        "links": [],
        "resource": {
            "attributes": {
                "telemetry.sdk.language": "python",
                "telemetry.sdk.name": "opentelemetry",
                "telemetry.sdk.version": "1.31.1",
                "service.name": "unknown_service"
            },
            "schema_url": ""
        }
    }
    

Дальнейшие шаги