View a markdown version of this page

Agents OpenAI - Amazon Bedrock AgentCore

Agents OpenAI

Cette page explique comment instrumenter un agent OpenAI Agents, comment les intervalles sont identifiés et comment les champs d'évaluation sont extraits.

Rubriques

Instrumez votre agent

Vous pouvez instrumenter un agent OpenAI Agents avec l'une des deux bibliothèques d'instrumentation suivantes : OpenTelemetry(opentelemetry-instrumentation-openai-agents) ou OpenInference(openinference-instrumentation-openai-agents). Amazon Bedrock AgentCore Evaluations prend en charge les deux bibliothèques. Les bibliothèques émettent des noms de portée différents et utilisent des attributs d'étendue différents. Le service d'évaluation extrait les mêmes valeurs de chacun d'entre eux.

Lorsque votre agent s'exécute avec le AWS Distro for OpenTelemetry (ADOT), par exemple sur Amazon Bedrock AgentCore Runtime, vous n'avez pas besoin d'ajouter de code d'instrumentation explicite. Il suffit d'ajouter la bibliothèque d'instrumentation aux dépendances de votre projet. ADOT le découvre au démarrage et l'active automatiquement.

Ajoutez la bibliothèque d'instrumentation correspondant au chemin que vous souhaitez accéder à vos dépendances. Utilisez la dernière version disponible, sauf si vous avez une raison de l'épingler.

Exemple
OpenTelemetry

REMARQUE : Utilisez la version 0.61.0 ou une version ultérieure. Il s'agit de la première version testée avec le service d'évaluation.

Ajoutez opentelemetry-instrumentation-openai-agents à vos dépendances. Le nom de la portée émis estopentelemetry.instrumentation.openai_agents.

requirements.txt:

opentelemetry-instrumentation-openai-agents>=0.61.0

pyproject.toml:

[project] dependencies = [ "opentelemetry-instrumentation-openai-agents>=0.61.0", ]
OpenInference

REMARQUE : Utilisez la version 1.5.0 ou une version ultérieure. Il s'agit de la première version testée avec le service d'évaluation.

Ajoutez openinference-instrumentation-openai-agents à vos dépendances. Le nom de la portée émis estopeninference.instrumentation.openai_agents.

requirements.txt:

openinference-instrumentation-openai-agents>=1.5.0

pyproject.toml:

[project] dependencies = [ "openinference-instrumentation-openai-agents>=1.5.0", ]
Note

L'instrumentation est l'une des étapes de la mise en place de l'observabilité. Pour exporter la télémétrie à des fins d'évaluation, effectuez la configuration complète dans Configurer l'observabilité.

Comment les travées sont identifiées

L'attribut utilisé pour classer les intervalles diffère entre les deux bibliothèques d'instrumentation.

Exemple
OpenTelemetry

La bibliothèque OpenTelemetry d'instrumentation classe les travées à l'aide de l'gen_ai.operation.nameattribut.

Type de travée Attribut d'identification

Invoquer l'agent

gen_ai.operation.name = invoke_agent

Exécuter l'outil

gen_ai.operation.name = execute_tool

Inférence

gen_ai.operation.name = chat

Note

Les agents OpenAI émettent également des intervalles de rotation internes avec =. gen_ai.operation.name unknown Le service d'évaluation les ignore.

OpenInference

La bibliothèque OpenInference d'instrumentation classe les travées à l'aide de l'openinference.span.kindattribut.

Type de travée Attribut d'identification

Invoquer l'agent

openinference.span.kind= AGENT ou CHAIN

Exécuter l'outil

openinference.span.kind = TOOL

Inférence

openinference.span.kind = LLM

Note

Dans le cas de la OpenInference bibliothèque, CHAIN les AGENT travées et sont des conteneurs structurels vides : elles ne contiennent aucun contenu de conversation. L'invite de l'utilisateur et la réponse de l'agent sont reconstruites à partir des intervalles d'inférence (LLM) dans la même trace.

Comment les champs d'évaluation sont extraits

Les agents OpenAI sérialisent les messages dans un format basé sur les parties, dans lequel chaque message contient un parts tableau de blocs de contenu dactylographiés (par exemple,). [{"role": "user", "parts": [{"type": "text", "content": "…​"}]}] Avec la OpenTelemetry bibliothèque, AgentCore Evaluations analyse le texte de ces parties. Avec la OpenInference bibliothèque, la sortie du modèle est l'objet OpenAI Response complet, et AgentCore Evaluations lit le texte de la réponse. output[].content[].text

L'emplacement de ce contenu dépend de la manière dont la télémétrie a été collectée. L'attribut d'identification (gen_ai.operation.nameouopeninference.span.kind) se trouve sur la plage dans les deux cas. Pour plus d'informations, voir Spans, enregistrements d'événements et signaux de télémétrie.

À partir des enregistrements d'événements

Lorsque la télémétrie est divisée, AgentCore Evaluations lit le contenu de la conversation à partir de l'enregistrement d'événements corrélé à chaque période. L'emplacement des entrées et sorties des outils diffère entre les deux bibliothèques :

  • OpenTelemetry:

    • Demande de l'utilisateur et réponse de l'agent : à partir de l'enregistrement des événements de l'intervalle d'appel de l'agent, dans body.input etbody.output.

    • Appel à l'outil : nom de l'outil depuisgen_ai.tool.name, arguments et résultats depuis gen_ai.tool.call.arguments et pendant gen_ai.tool.call.result l'intervalle d'exécution de l'outil. Avec la OpenTelemetry bibliothèque, les arguments et les résultats de l'outil restent sur les attributs span même lorsque la télémétrie est divisée.

  • OpenInference:

    • Demande de l'utilisateur et réponse de l'agent : reconstruites à partir de l'enregistrement des événements de la période d'inférence. AgentCore Evaluations lit les messages provenant de l'agent Invokebody.output, body.input puis remplit à nouveau le champ vide de l'agent Invoke avec l'invite de l'utilisateur et la réponse de l'agent.

    • Appel à l'outil : nom de l'outil à partir tool.name de la plage d'outils d'exécution. Les arguments et le résultat de l'outil proviennent de l'enregistrement des événements de cette plage, dans body.input etbody.output.

Pour des exemples, voir Exemples de périodes avec enregistrements d'événements.

À partir des attributs span

Lorsque la télémétrie n'est pas divisée, le même contenu reste sur la plage que les attributs. Les attributs dépendent de la bibliothèque d'instrumentation :

  • OpenTelemetry:

    • Demande de l'utilisateur et réponse de l'agent : depuis gen_ai.input.messages et gen_ai.output.messages pendant la durée d'appel de l'agent.

    • Appel à l'outil : nom de l'outil à partir degen_ai.tool.name, arguments et résultats de gen_ai.tool.call.arguments etgen_ai.tool.call.result, sur la durée d'exécution de l'outil.

  • OpenInference:

    • Demande de l'utilisateur et réponse de l'agent : à partir des attributs de message indexés sur la plage d'inférence (llm.input_messages. etllm.output_messages.), puis renseignés sur la plage d'appel vide de l'agent.

    • Appel à l'outil : nom de l'outil à partir detool.name, arguments et résultats de input.value etoutput.value, sur la durée d'exécution de l'outil.

Pour des exemples, voir Exemples de périodes sans enregistrement d'événements.

Exemples de périodes avec des enregistrements d'événements

Lorsque la télémétrie est divisée, la plage contient les attributs d'identification et le contenu est enregistré dans un enregistrement d'événements corrélé. Les exemples suivants proviennent d'un agent de planification de voyage OpenAI Agents déployé sur Amazon Bedrock Runtime. AgentCore Le même agent est affiché sous chaque bibliothèque d'instruments.

Note

Ces exemples ne sont pas des étendues complètes. Ils présentent des données représentatives d'une interaction réelle avec un agent, certains champs étant omis et les valeurs longues tronquées pour des raisons de lisibilité.

OpenTelemetry

Exemple
Invoke agent span

L'gen_ai.operation.nameattribut (invoke_agent) l'identifie comme un span d'agent d'appel.

{ "traceId": "6a01eef11066751d68f90def0da1f80a", "spanId": "3a300b0b3fe650e4", "name": "invoke_agent openaiOtelTravel", "kind": "INTERNAL", "scope": { "name": "opentelemetry.instrumentation.openai_agents", "version": "0.62.1" }, "attributes": { "gen_ai.operation.name": "invoke_agent", "gen_ai.agent.name": "openaiOtelTravel", "gen_ai.system": "openai", "gen_ai.provider.name": "openai", "gen_ai.request.model": "gpt-4o-mini-2024-07-18", "session.id": "sea-nyc-trip-2-turns-openai-otel" }, "status": { "code": "OK" } }

L'enregistrement d'événements corrélé contient la conversation. Chaque message content correspond au tableau de formats de pièces OpenAI ; l'invite utilisateur est le texte du message utilisateur et la réponse de l'agent est le texte du message de l'assistant.

{ "spanId": "3a300b0b3fe650e4", "traceId": "6a01eef11066751d68f90def0da1f80a", "scope": { "name": "opentelemetry.instrumentation.openai_agents" }, "body": { "input": { "messages": [ { "role": "user", "content": "[{\"role\": \"user\", \"parts\": [{\"type\": \"text\", \"content\": \"Hey, how can you help me\"}]}]" } ] }, "output": { "messages": [ { "role": "assistant", "content": "[{\"role\": \"assistant\", \"parts\": [{\"type\": \"text\", \"content\": \"I can assist you with planning your trips ...\"}]}]" } ] } } }
Execute tool span

L'gen_ai.operation.nameattribut (execute_tool) l'identifie comme une plage d'outils d'exécution ; gen_ai.tool.name contient le nom de l'outil. Avec la OpenTelemetry bibliothèque, les arguments et le résultat de l'outil restent dans les attributs span même lorsque la télémétrie est divisée.

{ "traceId": "6a01eefa5c52f3d86a35038f35f5ba30", "spanId": "3cbc4ea5f73fef81", "name": "execute_tool search_flights", "kind": "INTERNAL", "scope": { "name": "opentelemetry.instrumentation.openai_agents", "version": "0.62.1" }, "attributes": { "gen_ai.operation.name": "execute_tool", "gen_ai.tool.name": "search_flights", "gen_ai.tool.type": "function", "gen_ai.tool.call.arguments": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}", "gen_ai.tool.call.result": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"flights\": [ ... ]}", "session.id": "sea-nyc-trip-2-turns-openai-otel" }, "status": { "code": "OK" } }
Inference span

L'gen_ai.operation.nameattribut (chat) l'identifie comme une plage d'inférence. Cette plage contient les métadonnées du modèle et, dansgen_ai.tool.definitions, la liste des outils mis à la disposition de l'agent. Les messages de conversation relatifs à l'appel modèle se trouvent dans l'enregistrement d'événements corrélé, dans body.input etbody.output.

{ "traceId": "6a01eef11066751d68f90def0da1f80a", "spanId": "7c1f9a2b4d6e8a03", "name": "openai.response", "kind": "INTERNAL", "scope": { "name": "opentelemetry.instrumentation.openai_agents", "version": "0.62.1" }, "attributes": { "gen_ai.operation.name": "chat", "gen_ai.provider.name": "openai", "gen_ai.request.model": "gpt-4o-mini-2024-07-18", "gen_ai.response.model": "gpt-4o-mini-2024-07-18", "gen_ai.usage.input_tokens": 269, "gen_ai.usage.output_tokens": 78, "gen_ai.tool.definitions": "[{\"type\": \"function\", \"function\": {\"name\": \"search_flights\", \"description\": \"Search for available flights between cities.\", \"parameters\": { ... }}}]", "session.id": "sea-nyc-trip-2-turns-openai-otel" }, "status": { "code": "OK" } }
{ "spanId": "7c1f9a2b4d6e8a03", "traceId": "6a01eef11066751d68f90def0da1f80a", "scope": { "name": "opentelemetry.instrumentation.openai_agents" }, "body": { "input": { "messages": [ { "role": "user", "content": "[{\"role\": \"user\", \"parts\": [{\"type\": \"text\", \"content\": \"Hey, how can you help me\"}]}]" } ] }, "output": { "messages": [ { "role": "assistant", "content": "[{\"role\": \"assistant\", \"parts\": [{\"type\": \"text\", \"content\": \"I can assist you with planning your trips ...\"}]}]" } ] } } }

OpenInference

Avec la OpenInference bibliothèque, le span invoke agent (AGENT) est un conteneur vide. AgentCore Les évaluations reconstituent l'invite de l'utilisateur et la réponse de l'agent à partir de la plage d'inférence (LLM), dont le contenu figure dans un enregistrement d'événements corrélé.

Exemple
Invoke agent span

L'openinference.span.kindattribut (AGENT) l'identifie comme un span d'agent d'appel. Le span ne contient aucun contenu de conversation.

{ "traceId": "6a387ee61078243c1cc455ed45c6c313", "spanId": "9a1c7dce81b692cd", "name": "openaiOInfTravel", "kind": "INTERNAL", "scope": { "name": "openinference.instrumentation.openai_agents", "version": "1.5.0" }, "attributes": { "openinference.span.kind": "AGENT", "graph.node.id": "openaiOInfTravel", "llm.system": "openai", "session.id": "sea-nyc-trip-2-turns-openai-oi" }, "status": { "code": "OK" } }
Execute tool span

L'openinference.span.kindattribut (TOOL) l'identifie comme une plage d'outils d'exécution ; tool.name contient le nom de l'outil. Les arguments et le résultat de l'outil figurent dans l'enregistrement d'événements corrélé.

{ "traceId": "6a387ef07b8f4f3732fab45d3c0b51ff", "spanId": "b4e78cb0a06a6fe2", "name": "search_flights", "kind": "INTERNAL", "scope": { "name": "openinference.instrumentation.openai_agents", "version": "1.5.0" }, "attributes": { "openinference.span.kind": "TOOL", "tool.name": "search_flights", "input.mime_type": "application/json", "output.mime_type": "application/json", "session.id": "sea-nyc-trip-2-turns-openai-oi" }, "status": { "code": "OK" } }
{ "spanId": "b4e78cb0a06a6fe2", "traceId": "6a387ef07b8f4f3732fab45d3c0b51ff", "scope": { "name": "openinference.instrumentation.openai_agents" }, "body": { "input": { "messages": [ { "role": "user", "content": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}" } ] }, "output": { "messages": [ { "role": "assistant", "content": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"flights\": [ ... ]}" } ] } } }
Inference span

L'openinference.span.kindattribut (LLM) l'identifie comme une plage d'inférence. Les rôles des messages et les définitions des outils figurent sur les attributs span ; le contenu du message figure dans l'enregistrement d'événements corrélé. ADOT ajuste les rôles de saisie àuser, de sorte qu' AgentCore Evaluations utilise le dernier message de saisie en texte brut comme demande de l'utilisateur. Le message de sortie est l'objet OpenAI Response, à partir duquel AgentCore Evaluations lit le texte de réponse.

{ "traceId": "6a387ee61078243c1cc455ed45c6c313", "spanId": "1221a062c7f90a8e", "name": "response", "kind": "INTERNAL", "scope": { "name": "openinference.instrumentation.openai_agents", "version": "1.5.0" }, "attributes": { "openinference.span.kind": "LLM", "llm.model_name": "gpt-4o-mini-2024-07-18", "llm.input_messages.0.message.role": "system", "llm.input_messages.1.message.role": "user", "llm.output_messages.0.message.role": "assistant", "llm.tools.0.tool.json_schema": "{\"type\": \"function\", \"function\": {\"name\": \"search_flights\", ...}}", "session.id": "sea-nyc-trip-2-turns-openai-oi" }, "status": { "code": "OK" } }
{ "spanId": "1221a062c7f90a8e", "traceId": "6a387ee61078243c1cc455ed45c6c313", "scope": { "name": "openinference.instrumentation.openai_agents" }, "body": { "input": { "messages": [ { "role": "user", "content": "[{\"content\": \"Hey, how can you help me\", \"role\": \"user\"}]" }, { "role": "user", "content": "You are a travel planning assistant. Help users plan trips ..." }, { "role": "user", "content": "Hey, how can you help me" } ] }, "output": { "messages": [ { "role": "assistant", "content": "{\"id\": \"resp_abc123...\", \"output\": [{\"type\": \"message\", \"content\": [{\"type\": \"output_text\", \"text\": \"I can assist you with planning your trips ...\"}]}]}" } ] } } }

Exemples de périodes sans enregistrement d'événements

Lorsque la télémétrie n'est pas divisée, le même contenu reste dans les attributs span et aucun enregistrement d'événement distinct n'est produit. Les exemples suivants proviennent d'un agent de planification de voyage d'OpenAI Agents. Le même agent est affiché sous chaque bibliothèque d'instruments.

Note

Ces exemples ne sont pas des étendues complètes. Ils présentent des données représentatives d'une interaction réelle avec un agent, certains champs étant omis et les valeurs longues tronquées pour des raisons de lisibilité.

OpenTelemetry

Exemple
Invoke agent span

L'gen_ai.input.messagesattribut contient l'invite de l'utilisateur et l'gen_ai.output.messagesattribut contient la réponse de l'agent. Les deux sont des tableaux au format de pièces OpenAI.

{ "traceId": "6a4de7b85e61747e6b568a1f4768e89d", "spanId": "50656fd77904d125", "name": "invoke_agent openaiOtelTravel", "kind": "INTERNAL", "scope": { "name": "opentelemetry.instrumentation.openai_agents", "version": "0.62.1" }, "attributes": { "gen_ai.operation.name": "invoke_agent", "gen_ai.agent.name": "openaiOtelTravel", "gen_ai.system": "openai", "gen_ai.input.messages": "[{\"role\": \"user\", \"parts\": [{\"type\": \"text\", \"content\": \"Hey, how can you help me\"}]}]", "gen_ai.output.messages": "[{\"role\": \"assistant\", \"parts\": [{\"type\": \"text\", \"content\": \"I can assist you with planning your trips ...\"}]}]", "session.id": "sea-nyc-trip-2-turns-unified" }, "status": { "code": "OK" } }
Execute tool span

L'gen_ai.tool.call.argumentsattribut contient les arguments de l'outil et l'gen_ai.tool.call.resultattribut contient le résultat de l'outil.

{ "traceId": "6a4de7c376913db82e6f0f336a16731d", "spanId": "8840e8e23724ebd7", "name": "execute_tool search_flights", "kind": "INTERNAL", "scope": { "name": "opentelemetry.instrumentation.openai_agents", "version": "0.62.1" }, "attributes": { "gen_ai.operation.name": "execute_tool", "gen_ai.tool.name": "search_flights", "gen_ai.tool.call.arguments": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}", "gen_ai.tool.call.result": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"flights\": [ ... ]}", "session.id": "sea-nyc-trip-2-turns-unified" }, "status": { "code": "OK" } }
Inference span

L'gen_ai.operation.nameattribut (chat) l'identifie comme une plage d'inférence. Les métadonnées du modèle et l'gen_ai.tool.definitionsattribut (la liste des outils mis à la disposition de l'agent) restent en ligne tout au long de la période.

{ "traceId": "6a4de7b85e61747e6b568a1f4768e89d", "spanId": "9b2c1e5f7a3d0846", "name": "openai.response", "kind": "INTERNAL", "scope": { "name": "opentelemetry.instrumentation.openai_agents", "version": "0.62.1" }, "attributes": { "gen_ai.operation.name": "chat", "gen_ai.provider.name": "openai", "gen_ai.request.model": "gpt-4o-mini-2024-07-18", "gen_ai.response.model": "gpt-4o-mini-2024-07-18", "gen_ai.usage.input_tokens": 269, "gen_ai.usage.output_tokens": 78, "gen_ai.tool.definitions": "[{\"type\": \"function\", \"function\": {\"name\": \"search_flights\", \"description\": \"Search for available flights between cities.\", \"parameters\": { ... }}}]", "session.id": "sea-nyc-trip-2-turns-unified" }, "status": { "code": "OK" } }

OpenInference

Exemple
Execute tool span

L'input.valueattribut contient les arguments de l'outil et l'output.valueattribut contient le résultat de l'outil.

{ "traceId": "6a387ef07b8f4f3732fab45d3c0b51ff", "spanId": "d5a1c9e70b46f312", "name": "search_flights", "kind": "INTERNAL", "scope": { "name": "openinference.instrumentation.openai_agents", "version": "1.5.1" }, "attributes": { "openinference.span.kind": "TOOL", "tool.name": "search_flights", "input.value": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}", "output.value": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"flights\": [ ... ]}", "session.id": "sea-nyc-trip-2-turns-oi" }, "status": { "code": "OK" } }
Inference span

Le contenu du message est intégré aux attributs indexés. Les llm.input_messages. attributs contiennent l'invite du système et l'invite de l'utilisateur, et les llm.output_messages. attributs contiennent la réponse de l'agent. AgentCore Evaluations reconstruit l'invite de l'utilisateur et la réponse de l'agent à partir de cette période et remplit la plage vide invoke agent ()AGENT.

{ "traceId": "6a387ee61078243c1cc455ed45c6c313", "spanId": "c9f0a2b41d773e88", "name": "response", "kind": "INTERNAL", "scope": { "name": "openinference.instrumentation.openai_agents", "version": "1.5.1" }, "attributes": { "openinference.span.kind": "LLM", "llm.model_name": "gpt-4o-mini-2024-07-18", "llm.input_messages.0.message.role": "system", "llm.input_messages.0.message.content": "You are a travel planning assistant ...", "llm.input_messages.1.message.role": "user", "llm.input_messages.1.message.content": "Hey, how can you help me", "llm.output_messages.0.message.role": "assistant", "llm.output_messages.0.message.contents.0.message_content.text": "I can assist you with planning your trips ...", "session.id": "sea-nyc-trip-2-turns-oi" }, "status": { "code": "OK" } }