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 IA generativa, puede instrumentar sus aplicaciones de LLM con cualquier biblioteca o framework compatible con OpenTelemetry y visualizar las trazas en Agent Observability.

Agent Observability admite la ingesta de trazas de OpenTelemetry que sigan las convenciones semánticas de OpenTelemetry 1.37+ para IA generativa o las convenciones semánticas de OpenInference compatibles. Esto le permite enviar trazas de LLM directamente desde aplicaciones instrumentadas con OpenTelemetry a Datadog sin necesidad del SDK de Agent Observability ni de un Datadog Agent.

Requisitos previos

Funciones compatibles

Evaluaciones

Para enviar evaluaciones externas directamente a la API para tramos de OpenTelemetry, incluya la etiqueta source:otel en la evaluación. Al hacer referencia a tramos, proporcione span_id y trace_id como cadenas decimales. OpenTelemetry utiliza IDs hexadecimales de forma nativa, por lo que debe convertirlos a decimal antes de enviar las evaluaciones. Por ejemplo, utilice int(hex_span_id, 16) de Python para convertir un ID de tramo hexadecimal a su equivalente decimal.

Prompt Tracking

Para obtener información sobre el uso de Prompt Tracking con tramos de OpenTelemetry, consulte Prompt Tracking - OpenTelemetry Instrumentation.

Experimentos

Puede utilizar tramos de OpenTelemetry dentro de Experimentos de Agent Observability. Al configurar DD_TRACE_OTEL_ENABLED=1, los tramos de OTel creados dentro de una tarea de experimento aparecen automáticamente como hijos del tramo del experimento.

Soporte multimodal

El audio y las imágenes en los mensajes de OpenTelemetry se renderizan en la vista de trazas. Datadog extrae contenido multimedia de las partes de mensajes que siguen las convenciones semánticas de GenAI de OpenTelemetry, como se describe en Media in messages.

Solo se renderiza el contenido multimedia transportado en línea como bytes base64. Una URL remota se registra como una referencia de texto y nunca se recupera. Para conocer los campos, formatos y límites de tamaño que se aplican una vez que el contenido multimedia llega a un tramo, consulte Multimodal Support.

Utilice OpenTelemetry span links en sus tramos de GenAI para expresar relaciones que no sean de padre-hijo, como cuando la salida de un tramo alimenta la entrada de otro tramo. Cuando dos tramos vinculados se encuentran en la misma traza, el enlace aparece como un borde en el Execution Graph de esa traza, para que pueda ver cómo fluyen los datos entre tramos hermanos (por ejemplo, la salida de una herramienta alimentando una llamada a un LLM posterior).

Execution Graph para una traza de canalización de contenido de múltiples agentes. El orquestador contiene research-agent, writer-agent y editor-agent, conectados por bordes de enlaces de tramo que muestran datos fluyendo desde una herramienta search_web hacia el LLM de investigación, luego de la investigación al escritor y al editor.

Utilice los atributos from y to para indicar la dirección del flujo de datos:

from opentelemetry import trace
from opentelemetry.trace import Link

tracer = trace.get_tracer(__name__)

# A tool span whose output feeds a downstream LLM call.
with tracer.start_as_current_span("lookup_order") as tool_span:
    tool_span.set_attribute("gen_ai.operation.name", "execute_tool")
    tool_ctx = tool_span.get_span_context()

# The LLM span links back to the tool span: its output became this span's input.
link = Link(context=tool_ctx, attributes={"from": "output", "to": "input"})
with tracer.start_as_current_span("chat gpt-4o", links=[link]) as llm_span:
    llm_span.set_attribute("gen_ai.operation.name", "chat")
Un enlace de tramo que apunta a un tramo en una traza diferente se almacena, pero no se dibuja en el Execution Graph, que visualiza una única traza.

Configuración

Cualquier método que Datadog admita para la ingesta de trazas de OpenTelemetry funciona con Agent Observability. Para obtener la lista completa de rutas de ingesta admitidas, consulte OpenTelemetry feature compatibility. La siguiente es una forma de configurarlo.

Para enviar trazas de OpenTelemetry a Agent Observability, configure su exportador de OpenTelemetry con los siguientes ajustes:

Configuración

Establezca las siguientes variables de entorno en su 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

Reemplace <YOUR_API_KEY> con su clave de Datadog API.

Si su framework admitía anteriormente una versión de la especificación de OpenTelemetry anterior a la 1.37, también debe 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 frameworks que ahora admiten las convenciones semánticas de la versión 1.37+, pero que anteriormente admitían versiones anteriores (como strands-agents).

Nota:

  • Si está utilizando una biblioteca de OpenTelemetry distinta al SDK de OpenTelemetry predeterminado, es posible que deba configurar el punto de conexión, el protocolo y los encabezados de manera diferente según la API de la biblioteca. Consulte la documentación de su biblioteca para conocer el método de configuración adecuado.
  • Al utilizar la instrumentación de OpenTelemetry, algunos datos enviados a Agent Observability también pueden escribirse en los tramos de APM correspondientes. Si está protegiendo datos confidenciales, considere también configurar un conjunto de datos restringido (Restricted Dataset) en APM para que coincida con su Access Control de Agent Observability. Consulte Data Access Control para obtener más información.

Uso de strands-agents

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

OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental

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

Instrumentación

Para generar tramos compatibles con Agent Observability, realice una de las siguientes acciones:

Después de que su aplicación comience a enviar datos, los tramos aparecerán automáticamente en la Agent Observability Traces página. Para buscar sus tramos en la interfaz de usuario, utilice el atributo ml_app, que se establece automáticamente en el valor del atributo service del tramo raíz de su OpenTelemetry.

  • OpenLLMetry versión 0.47+ es compatible. Consulte el ejemplo de OpenLLMetry.
  • Los tramos de OpenInference son compatibles. Consulte el ejemplo de OpenInference.
  • La instrumentación nativa de OpenTelemetry de Langfuse es compatible. Consulte los mapeos de atributos de Langfuse.
  • Puede haber un retraso de 3 a 5 minutos entre el envío de tramos y su aparición en la página de Agent Observability Traces. Si tiene habilitado APM, los tramos aparecen inmediatamente en la página de APM Traces.

Frameworks y bibliotecas probados

Estos frameworks y bibliotecas han sido probados con Agent Observability. Los frameworks que emiten los atributos compatibles de las convenciones semánticas de GenAI de OpenTelemetry 1.37+ o las convenciones semánticas de OpenInference pueden enviar tramos a Agent Observability.

Ejemplos

Uso de Strands Agents

El siguiente ejemplo demuestra una aplicación completa que utiliza Strands Agents con la integración de OpenTelemetry. Este mismo enfoque funciona con cualquier marco de trabajo que admita las convenciones semánticas de OpenTelemetry versión 1.37+ para IA 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 Agent 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 su aplicación de LLM utilizando código personalizado de OpenTelemetry. Este enfoque le brinda control total sobre las trazas y los tramos emitidos por su 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, busque ml_app:simple-llm-example en la interfaz de usuario de Agent Observability para encontrar la traza generada.

Uso de OpenLLMetry

El siguiente ejemplo demuestra el uso de OpenLLMetry para instrumentar automáticamente llamadas de 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, busque ml_app:simple-openllmetry-test en la interfaz de usuario de Agent Observability para encontrar la traza generada.

Uso de OpenInference

El siguiente ejemplo utiliza la instrumentación de OpenAI de OpenInference para instrumentar automáticamente llamadas de OpenAI con OpenTelemetry.

Configure el exportador de OpenTelemetry e instrumente el cliente de OpenAI:

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

resource = Resource.create({
    "service.name": "simple-openinference-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-openinference-test",
        "dd-otlp-source": "llmobs",
    },
)

provider.add_span_processor(BatchSpanProcessor(exporter))

OpenAIInstrumentor().instrument(tracer_provider=provider)

# 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, busque ml_app:simple-openinference-test en la interfaz de usuario de Agent Observability para encontrar la traza generada.

Referencia de asignación de atributos

Esta sección proporciona las asignaciones de las convenciones semánticas de GenAI de OpenTelemetry (v1.37+), OpenLLMetry, OpenInference y Langfuse al esquema de tramo de Agent Observability de Datadog.

Si a un tramo le falta un atributo esperado, o un atributo no se puede analizar, Agent Observability marca el tramo con un indicador de Advertencias de asignación. Consulte Solución de problemas de advertencias de asignación para obtener descripciones y soluciones.

Las asignaciones específicas del proveedor se documentan por separado en las secciones de asignaciones de atributos de OpenLLMetry, asignaciones de atributos de OpenInference y asignaciones de atributos de Langfuse.

Asignaciones de atributos de OpenTelemetry 1.37+

Atributos de tramo base

Campo OTLPCampo de Agent ObservabilityNotas
resource.attributes.service.nameml_app, tags.service
namenameReemplazado 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 de tipo de tramo

gen_ai.operation.nameAgent Observability 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 Agent ObservabilityNotas
gen_ai.operation.namemeta.span.kindConsulte la tabla de resolución anterior
gen_ai.provider.namemeta.model_providerRecurre a gen_ai.system, luego a custom
gen_ai.response.modelmeta.model_name
gen_ai.request.modelmeta.model_nameRespaldo si response.model está ausente

Métricas de uso de tokens

Atributo de OTelCampo de Agent Observability
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 parámetros gen_ai.request.* se asignan a meta.metadata.* con el prefijo eliminado.

Atributo de OTelCampo de Agent Observability
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 Agent ObservabilityNotas
gen_ai.tool.namenameAnula el nombre del tramo
gen_ai.tool.call.idmetadata.tool_id
gen_ai.tool.descriptionmetadata.tool_description
gen_ai.tool.typemetadata.tool_type
gen_ai.tool.definitionsmeta.tool_definitionsMatriz JSON analizada
gen_ai.tool.call.argumentsinput.value
gen_ai.tool.call.resultoutput.value

Sesión y conversación

Atributo de OTelCampo de Agent ObservabilityNotas
gen_ai.conversation.idsession_idTambién se agregó a metadata.conversation_id y etiquetas

Cuando el tramo superior de una traza de APM no es un tramo de gen_ai (por ejemplo, un controlador HTTP que invoca varios LLM en paralelo), Agent Observability genera una traza de Agent Observability independiente para cada tramo de gen_ai de nivel superior en esa traza de APM. Para mantener estas trazas divididas agrupadas en la interfaz de usuario, establezca gen_ai.conversation.id en el mismo valor en cada tramo de gen_ai dentro de la traza de APM: Agent Observability agrupa por session_id, por lo que las trazas resultantes aparecen juntas aunque tengan ID de traza de Agent Observability distintos. Este es el mismo atributo utilizado para la agrupación de conversaciones entre solicitudes.

Los enlaces de tramo que usted establece en un tramo de GenAI aparecen como span_links en el tramo de Agent Observability correspondiente.

Campo de enlace de tramo OTelCampo de Agent ObservabilityNotas
trace_idspan_links[].trace_idLos ID de traza de 128 bits se emiten como hexadecimales. Un enlace a un tramo en la misma traza se resuelve en el ID de traza de Agent Observability de ese tramo.
span_idspan_links[].span_idDecimal
attributesspan_links[].attributesLos puntos en las claves de atributo se reemplazan con guiones bajos (por ejemplo, messaging.operation se convierte en messaging_operation).

Los enlaces entre tramos en la misma traza se dibujan como bordes en el Gráfico de ejecución de esa traza.

Atributos de respuesta

Atributo de OTelCampo de Agent 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 OTelCampo de Agent 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_instructionsAntepuesto a la entradaAñadido como mensajes de rol del sistema
Contenido multimedia en los mensajes

Las partes del mensaje que transportan contenido multimedia se extraen a los campos tipados audio_parts y image_parts en el mensaje:

Tipo de parteComportamiento
blob con mime_type y bytes en líneaExtraído a image_parts o audio_parts. Cuando la parte omite modality, se infiere a partir del tipo MIME.
uri que transporta un URI de datos de imagen en base64, como data:image/png;base64,...Extraído a image_parts.
uri que transporta una URL remotaRegistrado como la referencia de texto [<modality>: <uri>]. La URL no se recupera.
file con un file_idRegistrado como la referencia de texto [<modality> file: <file_id>].

También se añade un marcador posicional como [image blob: image/png] al texto del mensaje para que el contenido multimedia mantenga su lugar entre las otras partes.

El audio llega a audio_parts solo a través de partes blob. Un URI de datos de audio en una parte uri se registra como texto, y las convenciones especifican blob como el tipo de parte para datos en base64 en línea, así que prefiera blob tanto para audio como para imágenes.

Para conocer los formatos que la vista de traza renderiza y los límites de tamaño que se aplican, consulte Soporte multimodal.

Tramos de incrustación
Fuente OTelCampo de Agent Observability
gen_ai.input.messagesmeta.input.documents
N/Ameta.output.value = [N embedding(s) returned]

Etiquetas

Las etiquetas se colocan directamente en el tramo:

  • Los atributos no-gen_ai.* se convierten en etiquetas key:value
  • Las claves desconocidas gen_ai.* se agregan con el prefijo eliminado
  • Filtrado: _dd.*, llm.*, ddtags, events y claves gen_ai.* ya asignadas específicamente
Cualquiera gen_ai.* los atributos que no están asignados explícitamente a los campos de tramo de Agent Observability se colocan en las etiquetas del tramo de LLM, con un límite de 256 caracteres por valor. Los valores que exceden este límite se truncan. Todos los demás atributos no-gen_ai se descartan.

Metadatos personalizados

Para agregar metadatos estructurados al campo meta.metadata de un tramo en lugar de a sus etiquetas, establezca el atributo _dd.ml_obs.metadata en una cadena de objeto JSON. Sus claves y valores (incluidos objetos y matrices anidados) se combinan en meta.metadata y se representan como JSON en la interfaz de usuario.

import json

span.set_attribute("_dd.ml_obs.metadata", json.dumps({
    "experiment": "a/b",
    "config": {
        "retry": {"max": 3, "backoff": "exp"},
        "feature_flags": ["new_ranker", "fast_path"],
    },
}))

Notas:

  • Los valores pueden estar anidados arbitrariamente; a diferencia de las etiquetas, los metadatos no están sujetos al límite de 256 caracteres por valor.
  • Las claves que entran en conflicto con los metadatos derivados de los atributos gen_ai.* (por ejemplo, temperature) son sobrescritas por sus valores, con la excepción de model_name y model_provider, que están reservados.
  • El valor debe ser un objeto JSON. Un valor que no sea un JSON válido, o que sea una matriz o escalar de nivel superior, se descarta.

Asignaciones de atributos de OpenLLMetry

Esta sección documenta las asignaciones de atributos específicas de OpenLLMetry que difieren o amplían las convenciones semánticas estándar de GenAI de OpenTelemetry.

Resolución de tipo de tramo

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

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

Información del modelo

Atributo de OpenLLMetryCampo de Agent ObservabilityNotas
gen_ai.systemmeta.model_providerRespaldo cuando gen_ai.provider.name está ausente

Métricas de uso de tokens

Atributo de OpenLLMetryCampo de Agent ObservabilityNotas
llm.usage.total_tokensmetrics.total_tokensRespaldo cuando gen_ai.usage.total_tokens está ausente

Mensajes de entrada y salida

OpenLLMetry utiliza atributos indexados en lugar de matrices 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 a 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
Asignación

Los mensajes se convierten a un 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 asigna 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 herramienta

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

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

Tramos de incrustación

Para los tramos de incrustación, los documentos se extraen de los atributos de contenido del prompt.

Fuente de OpenLLMetryCampo de Agent Observability
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.*

Asignaciones de atributos de OpenInference

Agent Observability reconoce un tramo de OpenInference cuando el atributo openinference.span.kind está presente y no está vacío. Las siguientes secciones documentan los atributos de OpenInference que se asignan a campos dedicados de Agent Observability.

Resolución de tipo de tramo

Si gen_ai.operation.name y openinference.span.kind están presentes, gen_ai.operation.name tiene prioridad.

openinference.span.kindAgent Observability span.kind
LLMllm
EMBEDDINGembedding
TOOLtool
AGENTagent
RETRIEVERretrieval
CHAIN, RERANKER, GUARDRAIL, EVALUATOR, PROMPT, otros valoresworkflow

Información del modelo

OpenInference AttributeCampo de Agent ObservabilityNotas
llm.providermeta.model_providerFuente de proveedor de OpenInference preferida
llm.systemmeta.model_providerRespaldo cuando llm.provider no está presente
llm.model_namemeta.model_name
embedding.model_namemeta.model_nameRespaldo para tramos de incrustación

Para los tramos llm y embedding, los valores de proveedor o modelo faltantes se establecen en unknown.

Métricas de uso de tokens

OpenInference AttributeCampo de Agent Observability
llm.token_count.promptmetrics.prompt_tokens
llm.token_count.completionmetrics.completion_tokens
llm.token_count.totalmetrics.total_tokens
llm.token_count.prompt_details.cache_readmetrics.cache_read_input_tokens
llm.token_count.prompt_details.cache_writemetrics.cache_write_input_tokens
llm.token_count.completion_details.reasoningmetrics.reasoning_output_tokens

Sesión, usuario y metadatos

OpenInference AttributeCampo de Agent ObservabilityNotas
session.idsession_idTambién añade las etiquetas session_id y conversation_id y propaga la sesión a la raíz de la traza
user.idtagsAñadido como user_id:<value>
tag.tagstagsCada elemento de la lista se convierte en una etiqueta de tramo
llm.invocation_parametersmeta.metadataAnalizado como un objeto JSON
metadatameta.metadataAnalizado como un objeto JSON

Los campos reservados de Agent Observability en llm.invocation_parameters y metadata no anulan los campos de tramo dedicados.

Atributos de herramienta

OpenInference AttributeCampo de Agent ObservabilityNotas
tool.namenameAnula el nombre del tramo
tool.idmeta.metadata.tool_id
tool.descriptionmeta.metadata.tool_description
tool.parametersmeta.metadata.tool_parameters
input.valuemeta.input.valueSe utiliza directamente para los tramos tool, agent y workflow
output.valuemeta.output.valueSe utiliza directamente para los tramos tool, agent y workflow

Mensajes de entrada y salida

En estos atributos, <direction> es input o output. La entrada y la salida se extraen de las siguientes fuentes, en orden de prioridad:

  1. OpenTelemetry gen_ai.* atributos directos y eventos de tramo
  2. Atributos indexados de OpenLLMetry
  3. Atributos indexados de OpenInference
  4. OpenInference input.value y output.value
OpenInference SourceCampo de Agent Observability
llm.input_messages.<index>.*meta.input.messages (llm) / meta.input.value (otros tipos de tramo)
llm.output_messages.<index>.*meta.output.messages (llm) / meta.output.value (otros tipos de tramo)
input.valueRespaldo de entrada
output.valueRespaldo de salida

Se admiten los siguientes atributos de mensaje indexados:

Atributo de OpenInferenceAsignación
llm.<direction>_messages.<message-index>.message.roleRol del mensaje
llm.<direction>_messages.<message-index>.message.contentContenido de texto
llm.<direction>_messages.<message-index>.message.contents.<content-index>.message_content.textContenido de texto ordenado
llm.<direction>_messages.<message-index>.message.contents.<content-index>.message_content.image.image.urlContenido de imagen ordenado
llm.<direction>_messages.<message-index>.message.tool_calls.<tool-index>.tool_call.*ID, nombre y argumentos de la llamada a la herramienta
llm.<direction>_messages.<message-index>.message.contents.<content-index>.tool_call.*Llamada a la herramienta dentro del contenido ordenado
llm.<direction>_messages.<message-index>.message.tool_call_idID del resultado de la herramienta cuando el rol del mensaje es tool

El contenido de la imagen se asigna a un URI de imagen mientras conserva su posición entre otro contenido del mensaje.

Tramos de incrustación

OpenInference SourceCampo de Agent Observability
embedding.embeddings.<index>.embedding.textmeta.input.documents[].text
N/Ameta.output.value = [N embedding(s) returned]

Tramos de recuperación

OpenInference SourceCampo de Agent Observability
input.valuemeta.input.value
retrieval.documents.<index>.document.contentmeta.output.documents[].text
retrieval.documents.<index>.document.idmeta.output.documents[].id
retrieval.documents.<index>.document.scoremeta.output.documents[].score
retrieval.documents.<index>.document.metadatameta.output.documents[].metadata (objeto JSON analizado)

Filtrado de etiquetas

Los atributos de OpenInference con los prefijos llm.*, retrieval.*, embedding.* y reranker.* se excluyen de las etiquetas. Los valores asignados específicamente, tales como input.value, output.value, metadata, tag.tags y tool.parameters, también se excluyen de las etiquetas duplicadas.

Otros atributos de OpenInference que no estén vacíos y tengan valores de 256 caracteres o menos se agregan como etiquetas key:value. La lista tag.tags se promueve directamente a etiquetas de tramo.

Asignaciones de atributos de Langfuse

Esta sección documenta las asignaciones de atributos específicas de Langfuse para aplicaciones que utilizan la instrumentación nativa de OpenTelemetry de Langfuse.

Detección

Un tramo se trata como un tramo de Langfuse cuando contiene un atributo langfuse.observation.type que no está vacío. Este atributo también se utiliza como alternativa para la resolución del tipo de tramo cuando gen_ai.operation.name no está presente.

Resolución del tipo de tramo

langfuse.observation.typeAgent Observability span.kind
generationllm
embeddingembedding
tooltool
agentagent
retrieverretrieval
span, event, chain, evaluator, guardrail, (predeterminado)workflow

Información del modelo

Atributo de LangfuseCampo de Agent ObservabilityNotas
langfuse.observation.metadata.ls_providermeta.model_provider
langfuse.observation.model.namemeta.model_nameAlternativa cuando gen_ai.response.model y gen_ai.request.model están ausentes

Métricas de uso de tokens

langfuse.observation.usage_details es un objeto JSON. Cada clave se asigna a una métrica de Agent Observability, utilizada como alternativa para cualquier métrica que no esté ya establecida a partir de los atributos gen_ai.usage.*:

Clave de uso de LangfuseCampo de Agent Observability
input, input_tokensmetrics.input_tokens
output, output_tokensmetrics.output_tokens
total, total_tokensmetrics.total_tokens
prompt_tokensmetrics.prompt_tokens
completion_tokensmetrics.completion_tokens
cache_creation_input_tokensmetrics.cache_write_input_tokens
cache_read_input_tokens, cached_tokensmetrics.cache_read_input_tokens
reasoning_tokensmetrics.reasoning_output_tokens

Mensajes de entrada y salida

langfuse.observation.input y langfuse.observation.output contienen un valor codificado en JSON que puede ser una matriz de mensajes de chat, un objeto de mensaje único o contenido JSON/cadena arbitrario. Estas son las fuentes de menor prioridad y solo se utilizan cuando no existen atributos de mensaje gen_ai.*.

Cada mensaje se convierte a la forma de mensaje basada en partes:

  • Una cadena content se convierte en una parte text.
  • Una matriz content de bloques convierte los bloques image_url en partes uri y los bloques text en partes text; cualquier otro bloque se mantiene como texto serializado.
  • Una matriz tool_calls en un mensaje se convierte en tool_call partes.
  • Un mensaje con role: tool y un tool_call_id se convierte en una tool_result parte.
Tramos de herramienta

Para los tramos de tool, agent y workflow, langfuse.observation.input/langfuse.observation.output se utilizan directamente como input.value/output.value, después de la reserva estándar de gen_ai.tool.call.*.

Tramos de recuperación

Para los tramos de retrieval, langfuse.observation.input se utiliza como el valor de consulta en meta.input.value. langfuse.observation.output se analiza como una colección de documentos (una matriz de objetos de documento, una matriz de cadenas o un solo objeto de documento) en meta.output.documents. La clave text, content o page_content de cada objeto de documento (verificada en ese orden) se asigna a text, junto con cualquier clave id, score y metadata.

Tramos de incrustación

Para embedding tramos, langfuse.observation.input se analiza de la misma manera que los documentos de recuperación en meta.input.documents[].text, conservando solo los documentos que contienen texto no vacío.

Sesión, usuario, metadatos y etiquetas

Atributo de LangfuseCampo de Agent ObservabilityNotas
langfuse.session.idsession_idReserva cuando gen_ai.conversation.id está ausente
langfuse.user.iduser_id: etiquetaReserva cuando el atributo de ID de usuario estándar está ausente
langfuse.observation.model.parametersmeta.metadata.*Objeto JSON, fusionado en los metadatos, omitiendo las claves reservadas (model_name, model_provider)
langfuse.trace.metadata.*, langfuse.observation.metadata.*meta.metadata.*Prefijo eliminado, fusionado en los metadatos, omitiendo las claves reservadas
langfuse.trace.tagsAnexado a las etiquetasMatriz JSON de cadenas

Filtrado de etiquetas

Los siguientes atributos específicos de Langfuse se filtran de las etiquetas porque se consumen en otra parte:

  • langfuse.internal.*, langfuse.observation.metadata.*, langfuse.trace.metadata.* (prefijos)
  • langfuse.observation.input, langfuse.observation.output, langfuse.observation.model.name, langfuse.observation.model.parameters, langfuse.observation.usage_details, langfuse.observation.cost_details, langfuse.observation.completion_start_time
  • langfuse.trace.input, langfuse.trace.output, langfuse.trace.metadata, langfuse.trace.tags
  • langfuse.experiment.item.expected_output, langfuse.experiment.item.metadata, langfuse.experiment.metadata

Solución de problemas de advertencias de mapeo

Durante la ingesta, Agent Observability detecta problemas de mapeo de tramos, como mensajes de entrada faltantes o un conteo de tokens que no se puede analizar. Marca los tramos afectados en lugar de fallar silenciosamente.

Los tramos marcados muestran un indicador de Advertencias de mapeo en el panel de detalles del tramo. Seleccione el indicador para abrir las advertencias de mapeo del tramo. Cada entrada enumera el atributo afectado, una solución sugerida y un enlace a la referencia de mapeo de atributos.

Cada advertencia también incluye una breve descripción de su efecto posterior, como evaluaciones omitidas o estimación de costos no disponible.

Las advertencias de mapeo se detectan durante la ingesta. No afectan la facturación ni la retención de tramos.

Referencia de advertencias de mapeo

Un tramo puede mostrar advertencias que no aparecen en la siguiente tabla si Datadog añade verificaciones. Estos se renderizan con un título generado basado en la verificación que activó la advertencia.

Valor de búsqueda muestra el valor almacenado en el tramo. Úselo con el atributo @collection_errors para encontrar tramos marcados, por ejemplo @collection_errors:otel_warning_missing_model_name.

AdvertenciaValor de búsqueda (@collection_errors:)AtributoSolución
Falta el nombre del modelootel_warning_missing_model_nameEsperado gen_ai.response.modelEmita gen_ai.response.model directamente, por lo que el nombre del modelo no necesita ser extraído de gen_ai.request.model.
Falta el proveedor del modelootel_warning_missing_model_providerEsperado gen_ai.provider.nameEmita gen_ai.provider.name directamente, por lo que el proveedor no necesita ser inferido desde gen_ai.system.
Identificador de modelo mal formadootel_warning_strands_model_malformedEn gen_ai.request.modelEmita gen_ai.response.model directamente, por lo que el nombre del modelo no necesita ser extraído de gen_ai.request.model.
Entrada mal formadaotel_warning_input_malformedEn gen_ai.input.messagesEmita gen_ai.input.messages como una matriz JSON válida de mensajes.
Salida mal formadaotel_warning_output_malformedEn gen_ai.output.messagesEmita gen_ai.output.messages como una matriz JSON válida de mensajes.
Mensaje mal formadootel_warning_message_malformedEn gen_ai.input.messagesEmita cada mensaje con un campo role y content.
Contenido de mensaje vacíootel_warning_invalid_partsEn gen_ai.output.messagesEmita una cadena content, o entradas parts con un type reconocido, por ejemplo text, tool_call, tool_call_response.
Falta la entrada de incrustaciónotel_warning_embedding_input_missingEsperado gen_ai.input.messagesEstablezca gen_ai.input.messages en el texto incrustado.
Entrada de incrustación mal formadaotel_warning_embedding_input_malformedEn gen_ai.input.messagesEmita gen_ai.input.messages como una matriz JSON válida de mensajes.
Recuentos de tokens ilegiblesotel_warning_token_usage_unparseableEn gen_ai.usage.input_tokensEmita los recuentos de tokens como números enteros, no como cadenas u objetos.
Recuentos de tokens no válidosotel_warning_token_usage_invalidEn gen_ai.usage.input_tokensEmita recuentos de tokens que sean números enteros no negativos.
Métricas de costo ilegiblesotel_warning_cost_metrics_unparseableEn gen_ai.cost.estimated_totalEmita las métricas de costo como números enteros o de punto flotante, no como cadenas u objetos.
Métricas de costo no válidasotel_warning_cost_metrics_invalidEn gen_ai.cost.estimated_totalEmita valores de costo no negativos.
Parámetros de invocación mal formadosotel_warning_params_malformedEn los parámetros de invocaciónEmita los parámetros de invocación como un objeto JSON válido, o establézcalos individualmente como atributos gen_ai.request.* (tales como temperature, top_p y max_tokens).
Definiciones de herramienta mal formadasotel_warning_tool_definitions_malformedEn gen_ai.tool.definitionsEmita gen_ai.tool.definitions como un arreglo JSON válido de definiciones de herramienta.
Definición de herramienta mal formadaotel_warning_tool_definition_entry_malformedEn gen_ai.tool.definitionsProporcione a cada definición de herramienta un name, y haga que su parameters sea un objeto JSON.
Nombre de herramienta faltanteotel_warning_tool_span_name_missingEsperado gen_ai.tool.nameEstablezca gen_ai.tool.name en los tramos de herramienta.
Nombre de llamada de herramienta faltanteotel_warning_tool_call_name_missingEn gen_ai.output.messagesProporcione a cada llamada de herramienta un name.
Nombre de operación faltanteotel_warning_operation_missingEsperado gen_ai.operation.nameEstablezca gen_ai.operation.name en uno de chat, text_completion, embeddings, execute_tool, invoke_agent o retriever.
Eventos de tramo mal formadosotel_warning_failed_to_parse_span_eventsEn eventsEmita JSON válido en los eventos de tramo, o establezca gen_ai.input.messages y gen_ai.output.messages directamente.
Puntaje de documento ilegibleotel_warning_failed_to_parse_document_scoreEn output.documentsEmita cada puntaje de documento como un número.
Metadatos de documento mal formadosotel_warning_document_metadata_malformedEn output.documentsEmita los metadatos de cada documento como un objeto JSON.
Instrumentación no reconocidaotel_warning_spec_version_unknownEsperado gen_ai.operation.nameEstablezca gen_ai.operation.name y gen_ai.system para que Datadog pueda identificar la instrumentación.

Encuentre los atributos de tramo sin procesar para un tramo marcado

Para encontrar los atributos sin procesar que Datadog recibió para un tramo marcado:

  • Si APM está habilitado, los mismos datos también se escriben en la traza de APM correspondiente. Abra la traza de APM vinculada para inspeccionar los atributos de tramo sin procesar.
  • Compare los atributos sin procesar con el atributo esperado de la referencia de advertencia de mapeo o la referencia de mapeo de atributos completa. Consulte Correlación de Agent Observability y APM para ver cómo se relacionan las dos vistas.
  • Para una advertencia de formato incorrecto, verifique si el valor del atributo es un JSON válido. Las causas comunes incluyen doble codificación, truncamiento y la emisión de una cadena u otro valor que no sea un objeto donde se espera un objeto.
  • Para una advertencia de atributo faltante, verifique la versión de su biblioteca de instrumentación con la tabla de marcos y bibliotecas probados, y confirme que OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental esté configurado si su biblioteca lo requiere.

Convenciones semánticas admitidas

Agent Observability admite 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 de tramo directos 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 obtener la lista completa de atributos admitidos y sus especificaciones, consulte la documentación de convenciones semánticas de OpenTelemetry para IA generativa.

Deshabilitación de la conversión de Agent Observability

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

Uso de 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

Uso de código

También puede establecer el atributo mediante programación 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 Agent Observability conversion for this entire trace
    span.set_attribute("dd_llmobs_enabled", False)