Agentes OpenAI
Esta página explica como instrumentar um agente do OpenAI Agents, como os intervalos são identificados e como os campos de avaliação são extraídos.
Tópicos
Instrumente seu agente
Você pode instrumentar um agente do OpenAI Agents com qualquer uma das duas bibliotecas de instrumentação: OpenTelemetry(opentelemetry-instrumentation-openai-agents) ou (). OpenInferenceopeninference-instrumentation-openai-agents O Amazon Bedrock AgentCore Evaluations oferece suporte a ambas as bibliotecas. As bibliotecas emitem nomes de escopo diferentes e usam atributos de extensão diferentes. O serviço de avaliação extrai os mesmos valores de cada um.
Quando seu agente é executado com a AWS Distro for OpenTelemetry (ADOT), como no Amazon Bedrock AgentCore Runtime, você não precisa adicionar código de instrumentação explícito. Adicionar a biblioteca de instrumentação às dependências do seu projeto é suficiente. O ADOT o descobre na inicialização e o ativa automaticamente.
Adicione a biblioteca de instrumentação para o caminho que você deseja para suas dependências. Use a versão mais recente disponível, a menos que você tenha um motivo para fixar.
exemplo
- OpenTelemetry
-
NOTA: Use a versão 0.61.0 ou posterior. Essa é a versão mais antiga testada com o serviço de avaliação.
Adicione opentelemetry-instrumentation-openai-agents às suas dependências. O nome do escopo emitido éopentelemetry.instrumentation.openai_agents.
requirements.txt:
opentelemetry-instrumentation-openai-agents>=0.61.0
pyproject.toml:
[project]
dependencies = [
"opentelemetry-instrumentation-openai-agents>=0.61.0",
]
- OpenInference
-
NOTA: Use a versão 1.5.0 ou posterior. Essa é a versão mais antiga testada com o serviço de avaliação.
Adicione openinference-instrumentation-openai-agents às suas dependências. O nome do escopo emitido éopeninference.instrumentation.openai_agents.
requirements.txt:
openinference-instrumentation-openai-agents>=1.5.0
pyproject.toml:
[project]
dependencies = [
"openinference-instrumentation-openai-agents>=1.5.0",
]
A instrumentação é uma etapa na configuração da observabilidade. Para exportar a telemetria para avaliação, conclua a configuração completa em Configurar observabilidade.
Como os vãos são identificados
O atributo usado para classificar extensões difere entre as duas bibliotecas de instrumentação.
exemplo
- OpenTelemetry
-
A biblioteca de OpenTelemetry instrumentação classifica as extensões usando o atributo. gen_ai.operation.name
| Tipo de extensão |
Atributo de identificação |
|
Invocar agente
|
gen_ai.operation.name = invoke_agent
|
|
Ferramenta de execução
|
gen_ai.operation.name = execute_tool
|
|
Inferência
|
gen_ai.operation.name = chat
|
Os agentes OpenAI também emitem intervalos internos de limite de turnos com =. gen_ai.operation.name unknown O serviço de avaliação os ignora.
- OpenInference
-
A biblioteca de OpenInference instrumentação classifica as extensões usando o atributo. openinference.span.kind
| Tipo de extensão |
Atributo de identificação |
|
Invocar agente
|
openinference.span.kind= AGENT ou CHAIN
|
|
Ferramenta de execução
|
openinference.span.kind = TOOL
|
|
Inferência
|
openinference.span.kind = LLM
|
Com a OpenInference biblioteca, os CHAIN vãos AGENT e são recipientes estruturais vazios: eles não carregam conteúdo de conversação. O prompt do usuário e a resposta do agente são reconstruídos a partir dos intervalos de inferência (LLM) no mesmo rastreamento.
O OpenAI Agents serializa as mensagens em um formato baseado em partes, no qual cada mensagem carrega uma parts matriz de blocos de conteúdo digitados (por exemplo,). [{"role": "user", "parts": [{"type": "text", "content": "…"}]}] Com a OpenTelemetry biblioteca, AgentCore as avaliações analisam o texto dessas partes. Com a OpenInference biblioteca, a saída do modelo é o objeto OpenAI Response completo, e o AgentCore Evaluations lê o texto da resposta. output[].content[].text
A localização desse conteúdo depende de como a telemetria foi coletada. O atributo de identificação (gen_ai.operation.nameouopeninference.span.kind) está no intervalo em ambos os casos. Para obter mais informações, consulte Espaços, registros de eventos e sinais de telemetria.
Quando a telemetria é dividida, o AgentCore Evaluations lê o conteúdo da conversa do registro do evento correlacionado a cada período. A localização das entradas e saídas da ferramenta difere entre as duas bibliotecas:
-
OpenTelemetry:
-
Solicitação do usuário e resposta do agente: do registro de eventos do invoke agent span, em body.input e. body.output
-
Chamada de ferramenta: o nome da gen_ai.tool.name ferramenta e os argumentos e resultados de gen_ai.tool.call.arguments e gen_ai.tool.call.result na extensão da ferramenta de execução. Com a OpenTelemetry biblioteca, os argumentos e os resultados da ferramenta permanecem nos atributos de amplitude mesmo quando a telemetria é dividida.
-
OpenInference:
-
Solicitação do usuário e resposta do agente: reconstruída a partir do registro de eventos do intervalo de inferência. AgentCore As avaliações lêem as mensagens de body.input ebody.output, em seguida, preenchem a extensão vazia do agente de invocação com o prompt do usuário e a resposta do agente.
-
Chamada de ferramenta: o nome da ferramenta tool.name na extensão da ferramenta de execução. Os argumentos e o resultado da ferramenta vêm do registro de eventos desse intervalo, em body.input body.output e.
Para ver exemplos, consulte Exemplos de períodos com registros de eventos.
Quando a telemetria não é dividida, o mesmo conteúdo permanece na extensão como atributos. Os atributos dependem da biblioteca de instrumentação:
-
OpenTelemetry:
-
Solicitação do usuário e resposta do agente: de gen_ai.input.messages e gen_ai.output.messages sobre o período de invocação do agente.
-
Chamada de ferramenta: o nome da ferramenta degen_ai.tool.name, os argumentos e o resultado de gen_ai.tool.call.arguments egen_ai.tool.call.result, na extensão da ferramenta de execução.
-
OpenInference:
-
Solicitação do usuário e resposta do agente: a partir dos atributos da mensagem indexada na extensão de inferência (llm.input_messages.
ellm.output_messages.) e, em seguida, preenchida na extensão vazia do agente de invocação.
-
Chamada de ferramenta: o nome da ferramenta detool.name, os argumentos e o resultado de input.value eoutput.value, na extensão da ferramenta de execução.
Por exemplo, consulte Exemplos de períodos sem registros de eventos.
Exemplos de períodos com registros de eventos
Quando a telemetria é dividida, o intervalo carrega os atributos de identificação e o conteúdo fica em um registro de evento correlacionado. Os exemplos a seguir são de um agente de planejamento de viagens do OpenAI Agents implantado no Amazon Bedrock Runtime. AgentCore O mesmo agente é mostrado em cada biblioteca de instrumentação.
Esses exemplos não são extensões completas. Eles mostram dados representativos de uma interação real do agente, com alguns campos omitidos e valores longos truncados para facilitar a leitura.
OpenTelemetry
exemplo
- Invoke agent span
-
O gen_ai.operation.name atributo (invoke_agent) identifica isso como uma extensão do agente de invocação.
{
"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"
}
}
O registro do evento correlacionado carrega a conversa. Cada mensagem content é a matriz de formato de peças do OpenAI; o prompt do usuário é o texto da mensagem do usuário e a resposta do agente é o texto da mensagem do assistente.
{
"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
-
O gen_ai.operation.name atributo (execute_tool) identifica isso como uma extensão da ferramenta de execução; gen_ai.tool.name contém o nome da ferramenta. Com a OpenTelemetry biblioteca, os argumentos e o resultado da ferramenta permanecem nos atributos de amplitude mesmo quando a telemetria é dividida.
{
"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
-
O gen_ai.operation.name atributo (chat) identifica isso como um intervalo de inferência. Esse intervalo carrega os metadados do modelo egen_ai.tool.definitions, na lista de ferramentas disponíveis para o agente. As mensagens de conversação para a chamada do modelo estão no registro do evento correlacionado, em body.input e. body.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
Com a OpenInference biblioteca, o intervalo invoke agent (AGENT) é um contêiner vazio. AgentCore As avaliações reconstroem o prompt do usuário e a resposta do agente a partir do intervalo inference (LLM), cujo conteúdo reside em um registro de evento correlacionado.
exemplo
- Invoke agent span
-
O openinference.span.kind atributo (AGENT) identifica isso como uma extensão do agente de invocação. O período não contém conteúdo de conversa.
{
"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
-
O openinference.span.kind atributo (TOOL) identifica isso como uma extensão da ferramenta de execução; tool.name contém o nome da ferramenta. Os argumentos e o resultado da ferramenta estão no registro do evento correlacionado.
{
"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
-
O openinference.span.kind atributo (LLM) identifica isso como um intervalo de inferência. As funções da mensagem e as definições da ferramenta estão nos atributos span; o conteúdo da mensagem reside no registro do evento correlacionado. O ADOT nivela as funções de entrada parauser, portanto, o AgentCore Evaluations usa a última mensagem de entrada de texto sem formatação como solicitação do usuário. A mensagem de saída é o objeto OpenAI Response, a partir do qual o AgentCore Evaluations lê o texto da resposta.
{
"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 ...\"}]}]}"
}
]
}
}
}
Exemplos de períodos sem registros de eventos
Quando a telemetria não é dividida, o mesmo conteúdo permanece nos atributos de span e nenhum registro de evento separado é produzido. Os exemplos a seguir são de um agente de planejamento de viagens da OpenAI Agents. O mesmo agente é mostrado em cada biblioteca de instrumentação.
Esses exemplos não são extensões completas. Eles mostram dados representativos de uma interação real do agente, com alguns campos omitidos e valores longos truncados para facilitar a leitura.
OpenTelemetry
exemplo
- Invoke agent span
-
O gen_ai.input.messages atributo contém o prompt do usuário e o gen_ai.output.messages atributo contém a resposta do agente. Ambos são matrizes em formato de peças 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
-
O gen_ai.tool.call.arguments atributo contém os argumentos da ferramenta e o gen_ai.tool.call.result atributo contém o resultado da ferramenta.
{
"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
-
O gen_ai.operation.name atributo (chat) identifica isso como um intervalo de inferência. Os metadados do modelo e o gen_ai.tool.definitions atributo (a lista de ferramentas disponíveis para o agente) permanecem alinhados durante o período.
{
"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
exemplo
- Execute tool span
-
O input.value atributo contém os argumentos da ferramenta e o output.value atributo contém o resultado da ferramenta.
{
"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
-
O conteúdo da mensagem está embutido nos atributos indexados. Os llm.input_messages.
atributos contêm o prompt do sistema e o prompt do usuário, e os llm.output_messages. atributos contêm a resposta do agente. AgentCore As avaliações reconstroem o prompt do usuário e a resposta do agente a partir desse período e preenchem o intervalo vazio de 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"
}
}