Este producto no es compatible con el sitio Datadog seleccionado. ().

Descripción general

Al utilizar las convenciones semánticas estandarizadas de OpenTelemetry para operaciones de inteligencia artificial generativa, puedes instrumentar tus aplicaciones LLM con cualquier biblioteca o marco compatible con OpenTelemetry y visualizar las trazas en LLM Observability.

LLM Observability admite la ingestión de trazas de OpenTelemetry que siguen las convenciones semánticas de OpenTelemetry 1.37+ para inteligencia artificial generativa. Esto te permite enviar trazas LLM directamente desde aplicaciones instrumentadas con OpenTelemetry a Datadog sin requerir el SDK de Datadog LLM Observability o un Agente de Datadog.

Requisitos previos

Para enviar evaluaciones externas directamente a la API para spans de OpenTelemetry, debes incluir el source:otel etiqueta en la evaluación. Al referenciar spans, proporciona span_id y trace_id como cadenas decimales. OpenTelemetry utiliza IDs hexadecimales de forma nativa, así que conviértelos a decimal antes de enviar evaluaciones. Por ejemplo, utiliza el int(hex_span_id, 16) de Python para convertir un ID de span hexadecimal a su equivalente decimal.

Para información sobre el uso de Seguimiento de Prompts con spans de OpenTelemetry, consulta Seguimiento de Prompts - Instrumentación de OpenTelemetry.

También puedes usar spans de OpenTelemetry dentro de Experimentos de LLM Observability. Al establecer DD_TRACE_OTEL_ENABLED=1, OTel spans creados dentro de una tarea de experimento aparecen automáticamente como hijos del span del experimento.

Configuración

Para enviar trazas de OpenTelemetry a LLM Observability, configura tu exportador de OpenTelemetry con los siguientes ajustes:

Configuración

Establece las siguientes variables de entorno en tu aplicación:

OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=
OTEL_EXPORTER_OTLP_TRACES_HEADERS=dd-api-key=<YOUR_API_KEY>,dd-otlp-source=llmobs

Reemplaza <YOUR_API_KEY> con tu clave API de Datadog.

Si tu marco de trabajo anteriormente soportaba una versión de especificación de OpenTelemetry anterior a la 1.37, también necesitas establecer:

OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental

Esta variable de entorno habilita trazas de OpenTelemetry compatibles con la versión 1.37+ para marcos que ahora soportan las convenciones semánticas de la versión 1.37+, pero que anteriormente soportaban versiones más antiguas (como strands-agents).

Nota:

  • Si estás utilizando una biblioteca de OpenTelemetry diferente al SDK de OpenTelemetry por defecto, es posible que necesites configurar el endpoint, el protocolo y los encabezados de manera diferente dependiendo de la API de la biblioteca. Consulta la documentación de tu biblioteca para el método de configuración apropiado.
  • Al utilizar instrumentación de OpenTelemetry, algunos datos enviados a LLM Observability también pueden ser escritos en las trazas APM correspondientes. Si estás protegiendo datos sensibles, considera también configurar un Conjunto de Datos Restringido en APM para que coincida con tus controles de acceso de LLM Observability. Consulta Control de Acceso a Datos para más información.

Usando strands-agents

Si estás utilizando la strands-agents biblioteca, necesitas establecer una variable de entorno adicional para habilitar trazas que sean compatibles con OpenTelemetry v1.37+:

OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental

Esta variable de entorno asegura que strands-agents emita trazas siguiendo las convenciones semánticas de OpenTelemetry v1.37+ para IA generativa, que son requeridas por LLM Observability.

Instrumentación

Para generar trazas compatibles con LLM Observability, haz una de las siguientes opciones:

Después de que tu aplicación comience a enviar datos, las trazas aparecerán automáticamente en la página Trazas de Observabilidad LLM. Para buscar tus trazas en la interfaz de usuario, utiliza el atributo ml_app, que se establece automáticamente en el valor del atributo service de tu span raíz de OpenTelemetry.

  • OpenLLMetry versión 0.47+ es compatible. Vea el ejemplo de OpenLLMetry.
  • OpenInference no es compatible.
  • Puede haber un retraso de 3 a 5 minutos entre el envío de trazas y su aparición en la página de Trazas de Observabilidad LLM. Si tienes APM habilitado, las trazas aparecen inmediatamente en la página de Trazas APM.

Frameworks y bibliotecas probados

Estos frameworks y bibliotecas han sido probados con la Observabilidad LLM de Datadog. Cualquier framework que emita spans compatibles con la convención semántica GenAI de OpenTelemetry 1.37+ es compatible.

Ejemplos

Usando Agentes Strands

El siguiente ejemplo demuestra una aplicación completa utilizando Strands Agents con la integración de OpenTelemetry. Este mismo enfoque funciona con cualquier marco que soporte las convenciones semánticas de OpenTelemetry versión 1.37+ para inteligencia artificial generativa.

from strands import Agent
from strands_tools import calculator, current_time
from strands.telemetry.config import StrandsTelemetry
import os

# Configure AWS credentials for Bedrock access
os.environ["AWS_PROFILE"] = "<YOUR_AWS_PROFILE>"
os.environ["AWS_DEFAULT_REGION"] = "<YOUR_AWS_REGION>"

# Enable latest GenAI semantic conventions (1.37)
os.environ["OTEL_SEMCONV_STABILITY_OPT_IN"] = "gen_ai_latest_experimental"

# Configure OTLP endpoint to send traces to Datadog LLM Observability
os.environ["OTEL_EXPORTER_OTLP_TRACES_PROTOCOL"] = "http/protobuf"
os.environ["OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"] = ""
os.environ["OTEL_EXPORTER_OTLP_TRACES_HEADERS"] = f"dd-api-key={os.getenv('DD_API_KEY')},dd-otlp-source=llmobs"

# Initialize telemetry with OTLP exporter
telemetry = StrandsTelemetry()
telemetry.setup_otlp_exporter()

# Create agent with tools
agent = Agent(tools=[calculator, current_time])

# Run the agent
if __name__ == "__main__":
    result = agent("I was born in 1993, what is my age?")
    print(f"Agent: {result}")

Instrumentación personalizada de OpenTelemetry

El siguiente ejemplo demuestra cómo instrumentar tu aplicación LLM utilizando código personalizado de OpenTelemetry. Este enfoque te da control completo sobre las trazas y tramos emitidos por tu aplicación.

import os
import json
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource, SERVICE_NAME
from openai import OpenAI

# Configure OpenTelemetry to send traces to Datadog
os.environ["OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"] = ""
os.environ["OTEL_EXPORTER_OTLP_TRACES_HEADERS"] = "dd-api-key=<YOUR_DATADOG_API_KEY>,dd-otlp-source=llmobs"
os.environ["OTEL_SEMCONV_STABILITY_OPT_IN"] = "gen_ai_latest_experimental"

# Initialize OpenTelemetry SDK
resource = Resource(attributes={SERVICE_NAME: "simple-llm-example"})
provider = TracerProvider(resource=resource)
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(provider)

tracer = trace.get_tracer(__name__)

# Make LLM call with OpenTelemetry tracing
with tracer.start_as_current_span(
    "chat gpt-4o",
    kind=trace.SpanKind.CLIENT,
) as span:
    model = "gpt-4o"
    max_tokens = 1024
    temperature = 0.7
    messages = [{"role": "user", "content": "Explain OpenTelemetry in one sentence."}]

    # Set request attributes
    span.set_attribute("gen_ai.provider.name", "openai")
    span.set_attribute("gen_ai.request.model", model)
    span.set_attribute("gen_ai.operation.name", "chat")
    span.set_attribute("gen_ai.request.max_tokens", max_tokens)
    span.set_attribute("gen_ai.request.temperature", temperature)

    # Add input messages as event
    input_messages_parts = []
    for msg in messages:
        input_messages_parts.append({
            "role": msg["role"],
            "parts": [{"type": "text", "content": msg["content"]}]
        })

    span.add_event(
        "gen_ai.client.inference.operation.details",
        {
            "gen_ai.input.messages": json.dumps(input_messages_parts)
        }
    )

    # Make actual LLM call
    client = OpenAI(api_key="<YOUR_OPENAI_API_KEY>")
    response = client.chat.completions.create(
        model=model,
        max_tokens=max_tokens,
        temperature=temperature,
        messages=messages
    )

    # Set response attributes from actual data
    span.set_attribute("gen_ai.response.id", response.id)
    span.set_attribute("gen_ai.response.model", response.model)
    span.set_attribute("gen_ai.response.finish_reasons", [response.choices[0].finish_reason])
    span.set_attribute("gen_ai.usage.input_tokens", response.usage.prompt_tokens)
    span.set_attribute("gen_ai.usage.output_tokens", response.usage.completion_tokens)

    # Add output messages as event
    output_text = response.choices[0].message.content
    span.add_event(
        "gen_ai.client.inference.operation.details",
        {
            "gen_ai.output.messages": json.dumps([{
                "role": "assistant",
                "parts": [{"type": "text", "content": output_text}],
                "finish_reason": response.choices[0].finish_reason
            }])
        }
    )

    print(f"Response: {output_text}")

# Flush spans before exit
provider.force_flush()

Después de ejecutar este ejemplo, busca ml_app:simple-llm-example en la interfaz de usuario de Observabilidad LLM para encontrar la traza generada.

Usando OpenLLMetry

El siguiente ejemplo demuestra el uso de OpenLLMetry para instrumentar automáticamente las llamadas a OpenAI con OpenTelemetry.

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
import openai
from opentelemetry.sdk.resources import Resource

resource = Resource.create({
    "service.name": "simple-openllmetry-test",
})

provider = TracerProvider(resource=resource)
trace.set_tracer_provider(provider)

exporter = OTLPSpanExporter(
    endpoint="",
    headers={
        "dd-api-key": "<YOUR_DATADOG_API_KEY>",
        "dd-ml-app": "simple-openllmetry-test",
        "dd-otlp-source": "llmobs",
    },
)

provider.add_span_processor(BatchSpanProcessor(exporter))

OpenAIInstrumentor().instrument()

# Make OpenAI call (automatically traced)
client = openai.OpenAI(api_key="<YOUR_OPENAI_API_KEY>")
client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "What is 15 multiplied by 7?"}]
)

provider.force_flush(timeout_millis=5000)

Después de ejecutar este ejemplo, busca ml_app:simple-openllmetry-test en la interfaz de usuario de Observabilidad LLM para encontrar la traza generada.

Referencia de mapeo de atributos

Esta sección proporciona el mapeo entre las convenciones semánticas de OpenTelemetry GenAI (v1.37+) así como OpenLLMetry al esquema de span de Observabilidad LLM de Datadog.

Los mapeos específicos de OpenLLMetry están documentados por separado en la sección mapeos de atributos de OpenLLMetry.

Mapeos de atributos de OpenTelemetry 1.37+

Atributos base de span

Campo OTLPCampo de Observabilidad LLMNotas
resource.attributes.service.nameml_app, tags.service
namenameAnulado por gen_ai.tool.name si está presente
parent_span_idparent_id
start_time_unix_nanostart_ns
end_time_unix_nanodurationCalculado: fin - inicio
status.codestatuserror si > 0, de lo contrario ok
status.messagemeta.error.message
attributes.error.typemeta.error.type

Resolución del tipo de Span

gen_ai.operation.nameObservabilidad de LLM span.kind
generate_content, chat, text_completion, completionllm
embeddings, embeddingembedding
execute_tooltool
invoke_agent, create_agentagent
rerank, unknown, (predeterminado)workflow

Información del modelo

Atributo de OTELCampo de observabilidad de LLMNotas
gen_ai.operation.namemeta.span.kindVer tabla de resolución arriba
gen_ai.provider.namemeta.model_providerRecurre a gen_ai.system, luego a custom
gen_ai.response.modelmeta.model_name
gen_ai.request.modelmeta.model_nameRecurso si response.model está ausente

Métricas de uso de tokens

Atributo de OTELCampo de observabilidad de LLM
gen_ai.usage.input_tokensmetrics.input_tokens
gen_ai.usage.output_tokensmetrics.output_tokens
gen_ai.usage.prompt_tokensmetrics.prompt_tokens
gen_ai.usage.completion_tokensmetrics.completion_tokens
gen_ai.usage.total_tokensmetrics.total_tokens

Parámetros de solicitud

Todos los gen_ai.request.* parámetros se mapean a meta.metadata.* con el prefijo eliminado.

Atributo de OTELCampo de observabilidad de LLM
gen_ai.request.seedmetadata.seed
gen_ai.request.frequency_penaltymetadata.frequency_penalty
gen_ai.request.max_tokensmetadata.max_tokens
gen_ai.request.stop_sequencesmetadata.stop_sequences
gen_ai.request.temperaturemetadata.temperature
gen_ai.request.top_kmetadata.top_k
gen_ai.request.top_pmetadata.top_p
gen_ai.request.choice.countmetadata.choice.count

Atributos de la herramienta

Atributo de OTelCampo de LLM ObservabilityNotas
gen_ai.tool.namenameSobrescribe el nombre del span
gen_ai.tool.call.idmetadata.tool_id
gen_ai.tool.descriptionmetadata.tool_description
gen_ai.tool.typemetadata.tool_type
gen_ai.tool.definitionsmeta.tool_definitionsArray JSON analizado
gen_ai.tool.call.argumentsinput.value
gen_ai.tool.call.resultoutput.value

Sesión y conversación

Atributo de OTelCampo de LLM ObservabilityNotas
gen_ai.conversation.idsession_idTambién agregado a metadata.conversation_id y etiquetas

Atributos de respuesta

Atributo de OTelCampo de LLM Observability
gen_ai.response.modelmeta.model_name
gen_ai.response.finish_reasonsmetadata.finish_reasons

Mensajes de entrada y salida

Los mensajes de entrada y salida se extraen de las siguientes fuentes, en orden de prioridad:

  1. Atributos directos: gen_ai.input.messages, gen_ai.output.messages, gen_ai.system_instructions
  2. Eventos de tramo (meta["events"]) con nombre gen_ai.client.inference.operation.details
Fuente de OTelCampo de LLM ObservabilityNotas
gen_ai.input.messagesmeta.input.messages (llm) / meta.input.value (otros)
gen_ai.output.messagesmeta.output.messages (llm) / meta.output.value (otros)
gen_ai.system_instructionsPrecedido por entradaAgregado como mensajes de rol del sistema
Tramos de incrustación
Fuente OTELCampo de Observabilidad LLM
gen_ai.input.messagesmeta.input.documents
N/Ameta.output.value = [N embedding(s) returned]

Etiquetas

Las etiquetas se colocan directamente en el span:

  • Atributos no-gen_ai.* se convierten en etiquetas key:value
  • Claves desconocidas gen_ai.* se añaden con el prefijo eliminado Filtrado: - , _dd.*, llm.*, ddtags, events, y claves gen_ai.* ya mapeadas específicamente
Cualquiera gen_ai.* los atributos que no están explícitamente mapeados a los campos de span de LLM Observability se colocan en las etiquetas del span de LLM, con un límite de 256 caracteres por valor. Los valores que exceden este límite son truncados. Todos los demás no-gen_ai atributos son eliminados.

Mapeo de atributos de OpenLLMetry

Esta sección documenta los mapeos de atributos específicos de OpenLLMetry que difieren o extienden las convenciones semánticas estándar de OpenTelemetry GenAI.

Resolución del tipo de span

llm.request.type se utiliza como respaldo cuando gen_ai.operation.name está ausente.

llm.request.typeLLM Observability span.kind
chatllm
completionllm
embeddingembedding
rerankworkflow
unknown, (predeterminado)workflow

Información del modelo

Atributo de OpenLLMetryCampo de Observabilidad de LLMNotas
gen_ai.systemmeta.model_providerReemplazo cuando gen_ai.provider.name está ausente

Métricas de uso de tokens

Atributo de OpenLLMetryCampo de Observabilidad de LLMNotas
llm.usage.total_tokensmetrics.total_tokensReemplazo cuando gen_ai.usage.total_tokens está ausente

Mensajes de entrada y salida

OpenLLMetry utiliza atributos indexados en lugar de arreglos JSON. Estas son las fuentes de menor prioridad y solo se utilizan cuando no existen fuentes estándar de OTel.

Atributos de prompt (entrada)
Atributo de OpenLLMetryDescripción
gen_ai.prompt.<index>.roleRol del mensaje (usuario, sistema, asistente, herramienta)
gen_ai.prompt.<index>.contentContenido del mensaje
gen_ai.prompt.<index>.tool_call_idID de llamada de herramienta para mensajes de respuesta de herramienta
Atributos de finalización (salida)
Atributo de OpenLLMetryDescripción
gen_ai.completion.<index>.roleRol del mensaje
gen_ai.completion.<index>.contentContenido del mensaje
gen_ai.completion.<index>.finish_reasonRazón de finalización de la tarea
Mapeo

Los mensajes se convierten al formato compatible con OTel y se procesan normalmente:

Fuente de OpenLLMetryCampo de LLMObs
gen_ai.prompt.*meta.input.messages (llm) / meta.input.value (otros)
gen_ai.completion.*meta.output.messages (llm) / meta.output.value (otros)

Llamadas a herramientas

Las llamadas a herramientas están anidadas dentro de los atributos de finalización.

Atributo de OpenLLMetrySe mapea a
gen_ai.completion.<index>.tool_calls.<idx>.nametool_calls[].name
gen_ai.completion.<index>.tool_calls.<idx>.idtool_calls[].tool_id
gen_ai.completion.<index>.tool_calls.<idx>.argumentstool_calls[].arguments
Mensajes de respuesta de herramientas

Cuando role = "tool" y tool_call_id están presentes, el mensaje se convierte en un resultado de herramienta:

Atributo de OpenLLMetrySe mapea a
gen_ai.prompt.<index>.tool_call_idtool_results[].tool_id
gen_ai.prompt.<index>.contenttool_results[].result

Tramos de embedding

Para los tramos de embedding, los documentos se extraen de los atributos de contenido del prompt.

Fuente de OpenLLMetryCampo de Observabilidad de LLM
gen_ai.prompt.<index>.contentmeta.input.documents[].text

Filtrado de etiquetas

Los siguientes atributos específicos de OpenLLMetry se filtran de las etiquetas:

  • gen_ai.prompt.*
  • gen_ai.completion.*
  • llm.*

Convenciones semánticas soportadas

LLM Observability soporta tramos que siguen las convenciones semánticas de OpenTelemetry 1.37+ para IA generativa, incluyendo:

  • Operaciones de LLM con gen_ai.provider.name, "gen_ai.operation.name", gen_ai.request.model y otros atributos de gen_ai
  • Entradas/salidas de operación en atributos directos de tramo o mediante eventos de tramo
  • Métricas de uso de tokens (gen_ai.usage.input_tokens, gen_ai.usage.output_tokens)
  • Parámetros y metadatos del modelo

Para la lista completa de atributos soportados y sus especificaciones, consulte la documentación de convenciones semánticas de OpenTelemetry para IA generativa.

Deshabilitando la conversión de LLM Observability

Si solo desea que sus tramos de IA generativa permanezcan en APM y no aparezcan en LLM Observability, puede deshabilitar la conversión automática configurando el atributo dd_llmobs_enabled a false. Configurar este atributo en cualquier tramo de una traza impide que toda la traza se convierta en LLM Observability.

Usando variables de entorno

Agregue el atributo dd_llmobs_enabled=false a su variable de entorno OTEL_RESOURCE_ATTRIBUTES:

OTEL_RESOURCE_ATTRIBUTES=dd_llmobs_enabled=false

Usando código

También puede establecer el atributo programáticamente en cualquier tramo de su traza:

from opentelemetry import trace

tracer = trace.get_tracer(__name__)

with tracer.start_as_current_span("my-span") as span:
    # Disable LLM Observability conversion for this entire trace
    span.set_attribute("dd_llmobs_enabled", False)