View a markdown version of this page

Configurar LangGraph telemetria para avaliações AgentCore - Base da Amazônia AgentCore

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Configurar LangGraph telemetria para avaliações AgentCore

Esta página explica como instrumentar um LangGraph agente, como os intervalos são identificados e como os campos de avaliação são extraídos. AgentCore As avaliações oferecem suporte a LangGraph agentes criados em Python e TypeScript; esta página aborda cada linguagem separadamente, em suporte a agentes e TypeScript suporte a agentes em Python. Ele termina com as melhores práticas para estruturar um LangGraph agente para que ele possa ser avaliado de forma confiável.

Tópicos

Suporte a agentes Python

Um LangGraph agente Python emite extensões sob o nome do escopo opentelemetry.instrumentation.langchain (OpenTelemetry) ou openinference.instrumentation.langchain (). OpenInference

Instrumente seu agente

Você pode instrumentar um LangGraph agente com uma das duas bibliotecas de instrumentação: OpenTelemetry (opentelemetry-instrumentation-langchain) ou OpenInference (openinference-instrumentation-langchain). O Amazon Bedrock AgentCore Evaluations oferece suporte às duas 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 executa com o 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. Os exemplos a seguir fixam uma versão mínima; 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.55.0 ou posterior. A versão 0.55.0 adicionou suporte às novas convenções de abrangência de agentes de OpenTelemetry IA generativa no GitHub site, nas quais o serviço de avaliação se baseia.

Adicione opentelemetry-instrumentation-langchain às suas dependências. O nome do escopo emitido éopentelemetry.instrumentation.langchain.

requirements.txt:

opentelemetry-instrumentation-langchain>=0.55.0

pyproject.toml:

[project] dependencies = [ "opentelemetry-instrumentation-langchain>=0.55.0", ]
OpenInference

Adicione openinference-instrumentation-langchain às suas dependências. O nome do escopo emitido éopeninference.instrumentation.langchain.

requirements.txt:

openinference-instrumentation-langchain>=0.1.62

pyproject.toml:

[project] dependencies = [ "openinference-instrumentation-langchain>=0.1.62", ]
nota

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 intervalos 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 os intervalos usando o traceloop.span.kind atributo, e as versões recentes também são definidas. gen_ai.operation.name

Tipo de extensão Atributo de identificação

Invoque o agente

traceloop.span.kind= workflow (também gen_ai.operation.name =invoke_agent)

Ferramenta de execução

traceloop.span.kind= tool (também gen_ai.operation.name =execute_tool)

Inferência

gen_ai.operation.name = chat

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

Invoque o agente

openinference.span.kind= CHAIN ou AGENT

Ferramenta de execução

openinference.span.kind = TOOL

Inferência

openinference.span.kind = LLM

Como os campos de avaliação são extraídos

Para a extensão do agente de invocação, a entrada e a saída não contêm uma lista limpa por mensagem. Em vez disso, o conteúdo é o estado do LangChain gráfico serializado: uma string JSON que envolve o estado completo. A forma exata desse estado serializado difere entre as duas bibliotecas de instrumentação. Em ambos os casos, o serviço o analisa para encontrar a solicitação do usuário (a mensagem humana) e a resposta do agente (a mensagem da IA).

LangGraph também serializa as funções das mensagens em mais de um formato. Uma função pode aparecer como um valor em minúsculas (human,ai,tool) ou como um nome de classe de LangChain mensagem (HumanMessage,AIMessage,ToolMessage). O serviço reconhece os dois formulários.

A localização desse conteúdo depende de como a telemetria foi coletada. O atributo de identificação (traceloop.span.kindouopeninference.span.kind) está no intervalo em ambos os casos. Para obter mais informações, consulte Configuração e entrega de telemetria.

De registros de eventos

Com a telemetria dividida, o serviço lê o conteúdo do registro do evento correlacionado a cada período:

  • Solicitação do usuário e resposta do agente: do registro de eventos do invocar o agente span, em body.input e. body.output

  • Chamada de ferramenta: o nome da ferramenta na extensão da ferramenta de execução. Os argumentos e resultados da ferramenta vêm do registro de eventos desse período, em body.input body.output e.

Para obter mais informações, consulte Exemplos de extensões em telemetria dividida.

Dos atributos de extensão

Com a telemetria unificada, o mesmo conteúdo permanece no espaço como atributos. Os atributos dependem da biblioteca de instrumentação:

  • OpenTelemetry:

    • Solicitação do usuário e resposta do agente: de gen_ai.task.input e gen_ai.task.output para o intervalo do agente de invocação.

    • 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, no intervalo da ferramenta de execução.

  • OpenInference:

    • Solicitação do usuário e resposta do agente: de input.value e output.value para o intervalo do agente de invocação.

    • Chamada de ferramenta: o nome da ferramenta detool.name, os argumentos e o resultado de input.value eoutput.value, no intervalo da ferramenta de execução.

Para obter mais informações, consulte Exemplos de extensões em telemetria unificada.

Exemplos de extensões em telemetria dividida

Com 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 LangGraph planejamento de viagens em Python implantado no Amazon Bedrock Runtime. AgentCore O mesmo agente é mostrado em cada biblioteca de instrumentação.

nota

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 traceloop.span.kind atributo (workflow) identifica isso como uma extensão do agente de invocação; as versões recentes da biblioteca também gen_ai.operation.name definem =. invoke_agent

{ "traceId": "6a01eef11066751d68f90def0da1f80a", "spanId": "ba1833fa7f097041", "parentSpanId": "836a5ccf9a2186cc", "name": "travel_agent.workflow", "kind": "INTERNAL", "scope": { "name": "opentelemetry.instrumentation.langchain", "version": "0.60.0" }, "startTimeUnixNano": 1778511607308521744, "endTimeUnixNano": 1778511610930280395, "durationNano": 3621758651, "attributes": { "traceloop.span.kind": "workflow", "gen_ai.operation.name": "invoke_agent", "gen_ai.agent.name": "travel_agent", "gen_ai.provider.name": "langgraph", "traceloop.workflow.name": "travel_agent", "session.id": "sea-nyc-trip-2-turns-adot_v17_opentelemetry_0_60_0" }, "status": { "code": "OK" } }

O registro do evento correlacionado acompanha a conversa. Cada mensagem content é o estado do LangChain gráfico serializado. A entrada envolve o estado em uma inputs chave. A saída a envolve em uma outputs chave, com cada mensagem como um objeto LangChain construtor. O prompt do usuário é a mensagem humana e a resposta do agente é a mensagem da IA dentro desse estado serializado.

{ "spanId": "ba1833fa7f097041", "traceId": "6a01eef11066751d68f90def0da1f80a", "scope": { "name": "opentelemetry.instrumentation.langchain" }, "body": { "input": { "messages": [ { "content": "{\"inputs\": {\"messages\": [{\"role\": \"user\", \"content\": \"Hey, how can you help me\"}]}, \"tags\": [], \"metadata\": {\"ls_integration\": \"langchain_create_agent\", \"lc_agent_name\": \"travel_agent\", \"thread_id\": \"sea-nyc-trip-2-turns-adot_v17_opentelemetry_0_60_0\"}, \"kwargs\": {\"name\": \"travel_agent\"}}", "role": "user" } ] }, "output": { "messages": [ { "content": "{\"outputs\": {\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain\", \"schema\", \"messages\", \"HumanMessage\"], \"kwargs\": {\"content\": \"Hey, how can you help me\", \"type\": \"human\", \"id\": \"12345678-1234-1234-1234-123456789012\"}}, {\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain\", \"schema\", \"messages\", \"AIMessage\"], \"kwargs\": {\"content\": \"Hello! I'm your travel planning assistant ...\", \"type\": \"ai\"}}]}, \"kwargs\": {\"tags\": []}}", "role": "assistant" } ] } } }
Execute tool span

O traceloop.span.kind atributo (tool) identifica isso como uma extensão da ferramenta de execução; gen_ai.tool.name contém o nome da ferramenta e gen_ai.operation.name =execute_tool.

{ "traceId": "6a01eefa5c52f3d86a35038f35f5ba30", "spanId": "5b332f3cd15ace04", "parentSpanId": "922a21edc04eba29", "name": "execute_tool search_flights", "kind": "INTERNAL", "scope": { "name": "opentelemetry.instrumentation.langchain", "version": "0.60.0" }, "startTimeUnixNano": 1778511614892698232, "endTimeUnixNano": 1778511614893399618, "durationNano": 701386, "attributes": { "traceloop.span.kind": "tool", "gen_ai.operation.name": "execute_tool", "gen_ai.tool.name": "search_flights", "gen_ai.tool.type": "function", "gen_ai.tool.description": "Search for available flights between cities.", "gen_ai.provider.name": "langgraph", "traceloop.workflow.name": "travel_agent", "session.id": "sea-nyc-trip-2-turns-adot_v17_opentelemetry_0_60_0" }, "status": { "code": "OK" } }

O registro do evento correlacionado carrega a entrada (argumentos) e a saída da ferramenta (resultado, serializado como a LangChain ToolMessage).

{ "spanId": "5b332f3cd15ace04", "traceId": "6a01eefa5c52f3d86a35038f35f5ba30", "scope": { "name": "opentelemetry.instrumentation.langchain" }, "body": { "input": { "messages": [ { "content": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}" } ] }, "output": { "messages": [ { "role": "tool", "name": "search_flights", "content": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"flights\": [ ... ]}" } ] } } }

OpenInference

Com a OpenInference biblioteca, o tipo de extensão é incluído no openinference.span.kind atributo e a entrada e a saída do agente são serializadas no registro do evento correlacionado.

exemplo
Invoke agent span

O openinference.span.kind atributo (CHAINou AGENT quando o gráfico é compilado com um nome) identifica isso como uma extensão do agente de invocação.

{ "traceId": "6a387ee61078243c1cc455ed45c6c313", "spanId": "0a7990d804132a9b", "parentSpanId": "29ae22014173881c", "name": "LangGraph", "kind": "INTERNAL", "scope": { "name": "openinference.instrumentation.langchain", "version": "0.1.66" }, "startTimeUnixNano": 1782087405949310976, "endTimeUnixNano": 1782087408945828864, "durationNano": 2996517888, "attributes": { "openinference.span.kind": "CHAIN", "input.mime_type": "application/json", "output.mime_type": "application/json", "llm.input_messages.0.message.role": "user", "session.id": "sea-nyc-trip-2-turns-oi-0-1-66" }, "status": { "code": "OK" } }

O registro do evento correlacionado acompanha a conversa. O prompt do usuário é a mensagem da função humana e a resposta do agente é a AI-role mensagem nas mensagens serializadas.

{ "spanId": "0a7990d804132a9b", "traceId": "6a387ee61078243c1cc455ed45c6c313", "scope": { "name": "openinference.instrumentation.langchain" }, "body": { "input": { "messages": [ { "role": "user", "content": "{\"messages\": [{\"role\": \"user\", \"content\": \"Hey, how can you help me\"}]}" } ] }, "output": { "messages": [ { "content": "{\"messages\": [{\"type\": \"human\", \"data\": {\"content\": \"Hey, how can you help me\", ...}}, {\"type\": \"ai\", \"data\": {\"content\": \"Hello! I'm your travel planning assistant ...\", ...}}]}", "role": "assistant" } ] } } }
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.

{ "traceId": "6a387ef07b8f4f3732fab45d3c0b51ff", "spanId": "ab105c12cc40048f", "parentSpanId": "9b2d4e72760690b4", "name": "search_flights", "kind": "INTERNAL", "scope": { "name": "openinference.instrumentation.langchain", "version": "0.1.66" }, "startTimeUnixNano": 1782087411724620032, "endTimeUnixNano": 1782087411725306880, "durationNano": 686848, "attributes": { "openinference.span.kind": "TOOL", "tool.name": "search_flights", "tool.description": "Search for available flights between cities.", "input.mime_type": "application/json", "output.mime_type": "application/json", "session.id": "sea-nyc-trip-2-turns-oi-0-1-66" }, "status": { "code": "OK" } }

O registro do evento correlacionado carrega a entrada (argumentos) e a saída da ferramenta (resultado, serializado como a LangChain ToolMessage).

{ "spanId": "ab105c12cc40048f", "traceId": "6a387ef07b8f4f3732fab45d3c0b51ff", "scope": { "name": "openinference.instrumentation.langchain" }, "body": { "input": { "messages": [ { "role": "user", "content": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}" } ] }, "output": { "messages": [ { "content": "{\"type\": \"tool\", \"data\": {\"content\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\", \"type\": \"tool\", \"name\": \"search_flights\", \"tool_call_id\": \"toolu_bdrk_01LzXXJCfpfuS7Bpf7e1qLMg\", \"status\": \"success\"}}", "role": "assistant" } ] } } }

Exemplos de extensões em telemetria unificada

Com a telemetria unificada, o mesmo conteúdo permanece nos atributos de extensão e nenhum registro de evento separado é produzido. Os exemplos a seguir são de um agente de planejamento de LangGraph viagens em Python. O mesmo agente é mostrado em cada biblioteca de instrumentação.

nota

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.task.input atributo contém o prompt do usuário e o gen_ai.task.output atributo mantém o estado serializado com a resposta do agente. Ambos são o estado do LangChain gráfico serializado.

{ "traceId": "6a4de7b85e61747e6b568a1f4768e89d", "spanId": "31ea3d5882dac680", "name": "LangGraph.workflow", "kind": "INTERNAL", "scope": { "name": "opentelemetry.instrumentation.langchain", "version": "0.62.1" }, "attributes": { "traceloop.span.kind": "workflow", "gen_ai.operation.name": "invoke_agent", "gen_ai.agent.name": "LangGraph", "gen_ai.task.input": "{\"inputs\": {\"messages\": [{\"role\": \"user\", \"content\": \"Hey, how can you help me\"}]}, \"tags\": [], \"metadata\": { ... }, \"kwargs\": {\"name\": \"LangGraph\"}}", "gen_ai.task.output": "{\"outputs\": {\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain\", \"schema\", \"messages\", \"HumanMessage\"], \"kwargs\": {\"content\": \"Hey, how can you help me\", \"type\": \"human\"}}, {\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain\", \"schema\", \"messages\", \"AIMessage\"], \"kwargs\": {\"content\": \"Hello! I'm your travel planning assistant ...\", \"type\": \"ai\"}}]}, \"kwargs\": {\"tags\": []}}", "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, serializado como a. LangChain ToolMessage

{ "traceId": "6a4de7c376913db82e6f0f336a16731d", "spanId": "b64c37adefae74f0", "name": "execute_tool search_flights", "kind": "INTERNAL", "scope": { "name": "opentelemetry.instrumentation.langchain", "version": "0.62.1" }, "attributes": { "traceloop.span.kind": "tool", "gen_ai.operation.name": "execute_tool", "gen_ai.tool.name": "search_flights", "gen_ai.tool.description": "Search for available flights between cities.", "gen_ai.tool.call.arguments": "{\"input_str\": \"{'origin': 'SEA', 'destination': 'NYC', 'date': '2025-03-15'}\", \"inputs\": {\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}, \"metadata\": { ... }}", "gen_ai.tool.call.result": "{\"output\": {\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain\", \"schema\", \"messages\", \"ToolMessage\"], \"kwargs\": {\"content\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\", \"type\": \"tool\", \"name\": \"search_flights\", \"status\": \"success\"}}}", "session.id": "sea-nyc-trip-2-turns-unified" }, "status": { "code": "OK" } }

OpenInference

exemplo
Invoke agent span

O input.value atributo contém o prompt do usuário e o output.value atributo mantém o estado serializado com a resposta do agente.

{ "traceId": "6a387ee61078243c1cc455ed45c6c313", "spanId": "b8c0b67876b78b91", "name": "LangGraph", "kind": "INTERNAL", "scope": { "name": "openinference.instrumentation.langchain", "version": "0.1.66" }, "attributes": { "openinference.span.kind": "CHAIN", "input.value": "{\"messages\": [{\"role\": \"user\", \"content\": \"Hey, how can you help me\"}]}", "output.value": "{\"messages\": [{\"type\": \"human\", \"data\": {\"content\": \"Hey, how can you help me\"}}, {\"type\": \"ai\", \"data\": {\"content\": \"Hello! I'm your travel planning assistant ...\"}}]}", "session.id": "sea-nyc-trip-2-turns-oi-0-1-66" }, "status": { "code": "OK" } }
Execute tool span

O input.value atributo contém os argumentos da ferramenta e o output.value atributo contém o resultado da ferramenta, serializado como a. LangChain ToolMessage

{ "traceId": "6a387ef07b8f4f3732fab45d3c0b51ff", "spanId": "58752612d9b22ae1", "name": "search_flights", "kind": "INTERNAL", "scope": { "name": "openinference.instrumentation.langchain", "version": "0.1.66" }, "attributes": { "openinference.span.kind": "TOOL", "tool.name": "search_flights", "tool.description": "Search for available flights between cities.", "input.value": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}", "output.value": "{\"type\": \"tool\", \"data\": {\"content\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\", \"name\": \"search_flights\"}}", "session.id": "sea-nyc-trip-2-turns-oi-0-1-66" }, "status": { "code": "OK" } }

TypeScript suporte de agentes

Um TypeScript LangGraph agente emite os mesmos tipos de intervalo que um agente Python, então o serviço de avaliação o lê da mesma forma. Há três bibliotecas de TypeScript instrumentação, cada uma com seu próprio nome de escopo e convenção de classificação de extensão.

Instrumente seu agente

Adicione a biblioteca de instrumentação para o caminho que você deseja para suas TypeScript dependências. Os exemplos a seguir fixam uma versão mínima; use a versão mais recente disponível, a menos que você tenha um motivo para fixar.

exemplo
ADOT (OpenTelemetry)

Para TypeScript agentes no ADOT, adicione o pacote de autoinstrumentação do AWS Distro Node () @aws/aws-distro-opentelemetry-node-autoinstrumentation às suas dependências. Ele inclui a LangChain instrumentação integrada, que é ativada na inicialização e emite o nome do escopo. @aws/aws-distro-opentelemetry-instrumentation-langchain

package.json:

{ "dependencies": { "@aws/aws-distro-opentelemetry-node-autoinstrumentation": "^0.12.0" } }
Traceloop (OpenTelemetry)

Adicione a LangChain instrumentação Traceloop () @traceloop/instrumentation-langchain às suas dependências. O nome do escopo emitido é@traceloop/instrumentation-langchain.

package.json:

{ "dependencies": { "@traceloop/instrumentation-langchain": "^0.27.0" } }
OpenInference

Adicione @arizeai/openinference-instrumentation-langchain às suas dependências. O nome do escopo emitido é@arizeai/openinference-instrumentation-langchain.

package.json:

{ "dependencies": { "@arizeai/openinference-instrumentation-langchain": "^4.0.14" } }
nota

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 intervalos são identificados

A identificação da extensão depende da biblioteca de instrumentação:

  • ADOT (OpenTelemetry): o pacote de autoinstrumentação do AWS Distro Node (@aws/aws-distro-opentelemetry-node-autoinstrumentation), que emite o nome do escopo, sets gen_ai.operation.name (,,chat) @aws/aws-distro-opentelemetry-instrumentation-langchain invoke_agentexecute_tool, da mesma forma que os outros frameworks. ADOT-native

  • Traceloop (OpenTelemetry): a biblioteca OpenTelemetry JS de Traceloop (@traceloop/instrumentation-langchain) define traceloop.span.kind (workflowpara a extensão do agente de invocação, para a extensão da ferramenta), task correspondendo à biblioteca Python. OpenTelemetry Consulte Como as extensões são identificadas no suporte do agente Python.

  • OpenInference: a biblioteca OpenInference JS (@arizeai/openinference-instrumentation-langchain) define openinference.span.kind (CHAINouAGENT,TOOL,LLM), da mesma forma que a OpenInference biblioteca Python.

Como os campos de avaliação são extraídos

A extração de campo depende da biblioteca de instrumentação:

  • ADOT (OpenTelemetry): a extensão do agente de invocação é um contêiner estrutural e o conteúdo da conversa reside na extensão de inferência (chat), no formato de partes gen_ai.input.messages e nos atributos. gen_ai.output.messages

  • Traceloop (OpenTelemetry): com a biblioteca OpenTelemetry JS do Traceloop, a conversa está nos atributos traceloop.entity.input etraceloop.entity.output, como estado serializado. LangChain Isso corresponde à OpenTelemetry biblioteca Python; consulte Como os campos de avaliação são extraídos no suporte do agente Python.

  • OpenInference: com a biblioteca OpenInference JS, a conversa está nos output.value atributos input.value e, e as mensagens de inferência também aparecem nos atributos llm.input_messages.* indexadosllm.output_messages.*. Isso corresponde à OpenInference biblioteca Python.

Exemplos de períodos de um agente TypeScript

Os exemplos a seguir são de um agente de TypeScript LangGraph planejamento de viagens implantado no Amazon Bedrock AgentCore Runtime com telemetria unificada. O mesmo agente é mostrado em cada uma das três bibliotecas de TypeScript instrumentação.

nota

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 (nativo do ADOT)

Com a ADOT-native biblioteca (do pacote de autoinstrumentação do AWS Distro Node@aws/aws-distro-opentelemetry-node-autoinstrumentation, emitindo o nome do escopo@aws/aws-distro-opentelemetry-instrumentation-langchain), a extensão do agente invoke é um contêiner estrutural e o conteúdo da conversa reside na extensão inference (chat), no formato de partes e nos atributos. gen_ai.input.messages gen_ai.output.messages

exemplo
Invoke agent span

O gen_ai.operation.name atributo (invoke_agent) identifica isso como uma extensão do agente de invocação. O span contém o nome e o modelo do agente, mas não contém o conteúdo da conversa.

{ "traceId": "6a6bd0a1c8d91ed1e70a3906b551618", "spanId": "ba1833fa7f097041", "name": "invoke_agent LangGraph", "kind": "INTERNAL", "scope": { "name": "@aws/aws-distro-opentelemetry-instrumentation-langchain", "version": "0.12.0" }, "attributes": { "gen_ai.operation.name": "invoke_agent", "gen_ai.agent.name": "LangGraph", "gen_ai.provider.name": "openai", "gen_ai.request.model": "gpt-4o-mini", "session.id": "sea-nyc-trip-2-turns" }, "status": { "code": "OK" } }
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. Os gen_ai.tool.call.result atributos gen_ai.tool.call.arguments e contêm os argumentos e o resultado da ferramenta.

{ "traceId": "6a6bd0a25c52f3d86a35038f35f5ba30", "spanId": "5b332f3cd15ace04", "name": "execute_tool search_flights", "kind": "INTERNAL", "scope": { "name": "@aws/aws-distro-opentelemetry-instrumentation-langchain", "version": "0.12.0" }, "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" }, "status": { "code": "OK" } }
Inference span

O gen_ai.operation.name atributo (chat) identifica isso como um intervalo de inferência. Os gen_ai.output.messages atributos gen_ai.input.messages e mantêm a conversa no formato de partes e gen_ai.system_instructions mantêm o prompt do sistema.

{ "traceId": "6a6bd0a1c8d91ed1e70a3906b551618", "spanId": "7c1f9a2b4d6e8a03", "name": "chat gpt-4o-mini", "kind": "INTERNAL", "scope": { "name": "@aws/aws-distro-opentelemetry-instrumentation-langchain", "version": "0.12.0" }, "attributes": { "gen_ai.operation.name": "chat", "gen_ai.provider.name": "openai", "gen_ai.request.model": "gpt-4o-mini", "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 trip ...\"}]}]", "gen_ai.system_instructions": "[{\"type\": \"text\", \"content\": \"You are a travel planning assistant ...\"}]", "session.id": "sea-nyc-trip-2-turns" }, "status": { "code": "OK" } }

OpenTelemetry (Traceloop)

Com a biblioteca OpenTelemetry JS de Traceloop (@traceloop/instrumentation-langchain), o tipo de extensão é transportado no traceloop.span.kind atributo (workflowpara a extensão do agente de invocação, task para a extensão da ferramenta) e gen_ai.operation.name = workflow na extensão do agente de invocação. A conversa está nos traceloop.entity.output atributos traceloop.entity.input e, como LangChain estado serializado.

exemplo
Invoke agent span

O traceloop.span.kind atributo (workflow) identifica isso como uma extensão do agente de invocação. Os traceloop.entity.output atributos traceloop.entity.input e mantêm o LangChain estado serializado, a partir do qual o prompt do usuário (mensagem humana) e a resposta do agente (mensagem de IA) são analisados.

{ "traceId": "6a6bd0b1c8d91ed1e70a3906b551618", "spanId": "ba1833fa7f097041", "name": "workflow RunnableSequence", "kind": "INTERNAL", "scope": { "name": "@traceloop/instrumentation-langchain", "version": "0.27.0" }, "attributes": { "traceloop.span.kind": "workflow", "gen_ai.operation.name": "workflow", "gen_ai.provider.name": "langchain", "traceloop.workflow.name": "RunnableSequence", "traceloop.entity.input": "{\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"HumanMessage\"], \"kwargs\": {\"content\": \"Hey, how can you help me\"}}]}", "traceloop.entity.output": "{\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"AIMessage\"], \"kwargs\": {\"content\": \"I can assist you with planning your trip ...\"}}]}", "session.id": "sea-nyc-trip-2-turns" }, "status": { "code": "OK" } }
Execute tool span

O traceloop.span.kind atributo (task) identifica isso como uma extensão da ferramenta de execução. Os traceloop.entity.output atributos traceloop.entity.input e contêm os argumentos e o resultado da ferramenta.

{ "traceId": "6a6bd0b25c52f3d86a35038f35f5ba30", "spanId": "5b332f3cd15ace04", "name": "task search_flights", "kind": "INTERNAL", "scope": { "name": "@traceloop/instrumentation-langchain", "version": "0.27.0" }, "attributes": { "traceloop.span.kind": "task", "traceloop.entity.name": "search_flights", "traceloop.entity.input": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}", "traceloop.entity.output": "{\"output\": {\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"ToolMessage\"], \"kwargs\": {\"status\": \"success\", \"content\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\"}}}", "session.id": "sea-nyc-trip-2-turns" }, "status": { "code": "OK" } }

OpenInference

Com a biblioteca OpenInference JS (@arizeai/openinference-instrumentation-langchain), o tipo de extensão é transportado no openinference.span.kind atributo. O conteúdo da conversa está nos output.value atributos input.value e, e as mensagens de inferência também aparecem nos atributos llm.input_messages.* indexadosllm.output_messages.*.

exemplo
Invoke agent span

O openinference.span.kind atributo (CHAIN) identifica isso como uma extensão do agente de invocação. Os output.value atributos input.value e mantêm o LangChain estado serializado.

{ "traceId": "6a6bd0c1c8d91ed1e70a3906b551618", "spanId": "0a7990d804132a9b", "name": "LangGraph", "kind": "INTERNAL", "scope": { "name": "@arizeai/openinference-instrumentation-langchain", "version": "4.0.14" }, "attributes": { "openinference.span.kind": "CHAIN", "input.value": "{\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"HumanMessage\"], \"kwargs\": {\"content\": \"Hey, how can you help me\"}}]}", "output.value": "{\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"AIMessage\"], \"kwargs\": {\"content\": \"I can assist you with planning your trip ...\"}}]}", "session.id": "sea-nyc-trip-2-turns" }, "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 output.value atributos input.value e contêm os argumentos e o resultado da ferramenta (serializados como a LangChain ToolMessage).

{ "traceId": "6a6bd0c25c52f3d86a35038f35f5ba30", "spanId": "ab105c12cc40048f", "name": "search_flights", "kind": "INTERNAL", "scope": { "name": "@arizeai/openinference-instrumentation-langchain", "version": "4.0.14" }, "attributes": { "openinference.span.kind": "TOOL", "tool.name": "search_flights", "input.value": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}", "output.value": "{\"output\": {\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"ToolMessage\"], \"kwargs\": {\"status\": \"success\", \"content\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\"}}}", "session.id": "sea-nyc-trip-2-turns" }, "status": { "code": "OK" } }
Inference span

O openinference.span.kind atributo (LLM) identifica isso como um intervalo de inferência. Os llm.input_messages.* atributos mantêm o prompt do sistema e o prompt do usuário, e os llm.output_messages.* atributos mantêm a resposta do agente.

{ "traceId": "6a6bd0c1c8d91ed1e70a3906b551618", "spanId": "1221a062c7f90a8e", "name": "ChatOpenAI", "kind": "INTERNAL", "scope": { "name": "@arizeai/openinference-instrumentation-langchain", "version": "4.0.14" }, "attributes": { "openinference.span.kind": "LLM", "llm.model_name": "gpt-4o-mini", "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.content": "I can assist you with planning your trip ...", "session.id": "sea-nyc-trip-2-turns" }, "status": { "code": "OK" } }

Práticas recomendadas para LangGraph agentes

A forma como você cria e invoca um LangGraph agente afeta o que aparece em sua telemetria e, portanto, a confiabilidade com que o agente pode ser avaliado. As práticas a seguir ajudam a garantir que a solicitação do usuário, a resposta do agente e a atividade da ferramenta sejam recuperáveis.

1. Escolha um padrão de construção do agente

Há duas formas comuns de criar um LangGraph agente:

  • Pré-construído create_agent: a maneira mais rápida de começar. Ele produz um único intervalo de agente de invocação por turno, com a conversa passada pelo loop LangGraph de execução integrado. Use isso quando quiser um agente de ação racional padrão sem fluxo de controle personalizado.

    from langchain.agents import create_agent agent = create_agent(model=model, tools=[search_flights, book_flight])
  • Personalizado StateGraph: oferece controle total sobre nós, bordas e roteamento condicional. Cada execução de nó se torna sua própria extensão, então os rastreamentos são mais granulares. Use isso quando precisar de orquestração personalizada.

    from langgraph.graph import StateGraph, START, END from typing_extensions import TypedDict class State(TypedDict): messages: list graph = StateGraph(State) graph.add_node("generate_response", generate_response) graph.add_node("tools", run_tools) graph.add_edge(START, "generate_response") agent = graph.compile()

Ambos os padrões são avaliados da mesma forma; a diferença é a granularidade do traçado.

2. Use mensagens no estado do seu gráfico (recomendado)

O serviço de avaliação reconstrói a conversa a partir das mensagens de entrada e saída do agente. O uso de um messages campo não é obrigatório, mas permite a extração mais confiável. Para uma personalizaçãoStateGraph, mantenha a conversa em um messages campo em seu estado:

  • Inclua messages em seu estado (recomendado). Você pode adicionar outros campos personalizados (como user_id metadados). Quando messages está presente, a extração padrão encontra diretamente a solicitação do usuário e a resposta do agente. Se messages estiver ausente, o serviço volta a reconstruir a conversa a partir de períodos de inferência individuais, o que é menos confiável.

  • Anexe, não substitua. Siga a LangGraph convenção de acrescentar novas mensagens à lista em vez de sobrescrevê-la, para que o histórico completo da conversa seja preservado.

  • Use tipos de LangChain mensagens canônicas (HumanMessage,, AIMessageToolMessage,SystemMessage). A instrumentação os serializa corretamente e o serviço reconhece suas funções.

3. Passe a mensagem do usuário em um formato compatível

Ao invocar um LangGraph agente, você adiciona a mensagem do usuário ao messages estado do gráfico. LangGraph aceita a mensagem em três formatos intercambiáveis, e o AgentCore Evaluations suporta todos eles. Cada um produz períodos e registros de eventos que o serviço pode ler.

  • Tupla: um (role, content) par:

    agent.invoke({"messages": [("user", user_message)]}, config=config)
  • LangChain objeto de mensagem: a HumanMessage (ou outra classe de mensagem):

    from langchain_core.messages import HumanMessage agent.invoke({"messages": [HumanMessage(content=user_message)]}, config=config)
  • Dicionário: um {"role", "content"} dicionário:

    agent.invoke({"messages": [{"role": "user", "content": user_message}]}, config=config)

Todos os três formatos resultam no mesmo messages estado, portanto, o prompt do usuário e a resposta do agente são extraídos de forma idêntica, independentemente de qual você escolher.