View a markdown version of this page

Configurare la LangGraph telemetria per le valutazioni AgentCore - Fondamento Amazon AgentCore

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Configurare la LangGraph telemetria per le valutazioni AgentCore

Questa pagina spiega come strumentare un LangGraph agente, come vengono identificati gli intervalli e come vengono estratti i campi di valutazione. AgentCore Le valutazioni supportano LangGraph gli agenti integrati in Python e TypeScript; questa pagina tratta ogni linguaggio separatamente, nel supporto agli agenti Python e nel supporto agli agenti. TypeScript Si chiude con le migliori pratiche per strutturare un LangGraph agente in modo che possa essere valutato in modo affidabile.

Argomenti

Supporto per agenti Python

Un LangGraph agente Python emette intervalli con il nome dell'ambito () o opentelemetry.instrumentation.langchain (OpenTelemetry). openinference.instrumentation.langchain OpenInference

Strumenta il tuo agente

Puoi strumentare un LangGraph agente con una delle due librerie di strumentazione: OpenTelemetry (opentelemetry-instrumentation-langchain) o OpenInference (openinference-instrumentation-langchain). Amazon Bedrock AgentCore Evaluations supporta entrambe le librerie. Le librerie emettono nomi di ambito diversi e utilizzano attributi span diversi. Il servizio di valutazione estrae gli stessi valori da ciascuno di essi.

Quando l'agente viene eseguito con AWS Distro for OpenTelemetry (ADOT), ad esempio su Amazon Bedrock AgentCore Runtime, non è necessario aggiungere codice di strumentazione esplicito. È sufficiente aggiungere la libreria di strumentazione alle dipendenze del progetto. ADOT la rileva all'avvio e la attiva automaticamente.

Aggiungi la libreria di strumentazione per il percorso che desideri alle tue dipendenze. Gli esempi seguenti fissano una versione minima; utilizzate l'ultima versione disponibile a meno che non abbiate un motivo per bloccarla.

Esempio
OpenTelemetry

NOTA: usa la versione 0.55.0 o successiva. La versione 0.55.0 ha aggiunto il supporto per le più recenti convenzioni OpenTelemetry Generative-AI agent span sul GitHub sito Web, su cui si basa il servizio di valutazione.

Aggiungilo alle tue dipendenze. opentelemetry-instrumentation-langchain Il nome dell'ambito emesso è. opentelemetry.instrumentation.langchain

requirements.txt:

opentelemetry-instrumentation-langchain>=0.55.0

pyproject.toml:

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

Aggiungi openinference-instrumentation-langchain alle tue dipendenze. Il nome dell'ambito emesso è. openinference.instrumentation.langchain

requirements.txt:

openinference-instrumentation-langchain>=0.1.62

pyproject.toml:

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

La strumentazione è un passo verso l'impostazione dell'osservabilità. Per esportare la telemetria per la valutazione, completa la configurazione completa in Imposta l'osservabilità. Imposta l'osservabilità

Come vengono identificati gli intervalli

L'attributo utilizzato per classificare gli intervalli è diverso tra le due librerie di strumentazione.

Esempio
OpenTelemetry

La libreria di OpenTelemetry strumentazione classifica gli intervalli utilizzando l'attributo e vengono impostate anche le versioni recenti. traceloop.span.kind gen_ai.operation.name

Tipo di intervallo Attributo identificativo

Invoca l'agente

traceloop.span.kind= workflow (anche gen_ai.operation.name =) invoke_agent

Strumento di esecuzione

traceloop.span.kind= tool (anche gen_ai.operation.name =execute_tool)

Inferenza

gen_ai.operation.name = chat

OpenInference

La libreria di OpenInference strumentazione classifica gli intervalli utilizzando l'attributo. openinference.span.kind

Tipo di intervallo Attributo identificativo

Invoca l'agente

openinference.span.kind= CHAIN o AGENT

Strumento di esecuzione

openinference.span.kind = TOOL

Inferenza

openinference.span.kind = LLM

Come vengono estratti i campi di valutazione

Per quanto riguarda l'estensione dell'agente invoke, l'input e l'output non contengono un elenco completo di messaggi. Il contenuto è invece lo stato del LangChain grafico serializzato: una stringa JSON che racchiude lo stato completo. La forma esatta di questo stato serializzato differisce tra le due librerie di strumentazione. In entrambi i casi, il servizio lo analizza per trovare il prompt dell'utente (il messaggio umano) e la risposta dell'agente (il messaggio AI).

LangGraph inoltre serializza i ruoli dei messaggi in più di una forma. Un ruolo può apparire come un valore minuscolo (human,ai,tool) o come nome di una classe di LangChain messaggio (HumanMessage,,). AIMessage ToolMessage Il servizio riconosce entrambe le forme.

La posizione di questo contenuto dipende dal modo in cui è stata raccolta la telemetria. L'attributo identificativo (traceloop.span.kindoopeninference.span.kind) è indicato sullo span in entrambi i casi. Per ulteriori informazioni, vedere Configurazione e consegna della telemetria.

Dai registri degli eventi

Con la telemetria divisa, il servizio legge il contenuto del record dell'evento correlato a ciascun intervallo:

  • Richiesta dell'utente e risposta dell'agente: dal record degli eventi di invoke agent span, in e. body.input body.output

  • Chiamata allo strumento: il nome dello strumento tratto dall'intervallo di esecuzione dello strumento. Gli argomenti e i risultati dello strumento provengono dal record degli eventi di quell'intervallo, in body.input e. body.output

Per ulteriori informazioni, consulta Esempi di intervalli di telemetria divisa.

Dagli attributi span

Con la telemetria unificata, lo stesso contenuto rimane nello span come gli attributi. Gli attributi dipendono dalla libreria di strumentazione:

  • OpenTelemetry:

    • Richiesta dell'utente e risposta dell'agente: da gen_ai.task.input e verso l'gen_ai.task.outputintervallo dell'agente invoke.

    • Chiamata allo strumento: il nome dello strumento dagen_ai.tool.name, gli argomenti e il risultato da gen_ai.tool.call.arguments e nell'gen_ai.tool.call.resultintervallo di esecuzione dello strumento.

  • OpenInference:

    • Richiesta dell'utente e risposta dell'agente: da input.value e verso output.value l'intervallo dell'agente invoke.

    • Chiamata allo strumento: il nome dello strumento datool.name, gli argomenti e il risultato da input.value e nell'output.valueintervallo di esecuzione dello strumento.

Per ulteriori informazioni, consulta Esempi di intervalli nella telemetria unificata.

Esempi di intervalli nella telemetria divisa

Con la telemetria divisa, l'intervallo riporta gli attributi identificativi e il contenuto risiede in un record di eventi correlato. I seguenti esempi sono tratti da un agente Python per la pianificazione dei LangGraph viaggi distribuito su Amazon Bedrock Runtime. AgentCore Lo stesso agente è mostrato in ogni libreria di strumentazione.

Nota

Questi esempi non sono intervalli completi. Mostrano dati rappresentativi di un'interazione con un agente reale, con alcuni campi omessi e valori lunghi troncati per motivi di leggibilità.

OpenTelemetry

Esempio
Invoke agent span

L'traceloop.span.kindattributo (workflow) lo identifica come invoke agent span; le versioni recenti della libreria impostano anche =. gen_ai.operation.name 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" } }

Il record dell'evento correlato contiene la conversazione. Quello di ogni messaggio content è lo stato del LangChain grafico serializzato. L'input racchiude lo stato sotto una chiave. inputs L'output lo racchiude sotto una outputs chiave, con ogni messaggio come oggetto costruttore. LangChain Il prompt dell'utente è il messaggio umano e la risposta dell'agente è il messaggio AI all'interno di quello stato serializzato.

{ "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

L'traceloop.span.kindattributo (tool) lo identifica come un intervallo di esecuzione dello strumento; gen_ai.tool.name contiene il nome dello strumento 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" } }

Il record dell'evento correlato contiene l'input (argomenti) e l'output (risultato, serializzato come 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

Con la OpenInference libreria, il tipo span viene inserito nell'openinference.span.kindattributo e l'input e l'output dell'agente vengono serializzati nel record dell'evento correlato.

Esempio
Invoke agent span

L'openinference.span.kindattributo (CHAINo AGENT quando il grafico è compilato con un nome) lo identifica come invoke agent span.

{ "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" } }

Il record dell'evento correlato contiene la conversazione. Il prompt dell'utente è il messaggio relativo al ruolo umano e la risposta dell'agente è il AI-role messaggio contenuto nei messaggi serializzati.

{ "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

L'openinference.span.kindattributo (TOOL) lo identifica come un intervallo di esecuzione dello strumento; tool.name contiene il nome dello strumento.

{ "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" } }

Il record dell'evento correlato contiene l'input (argomenti) e l'output (risultato, serializzato come 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" } ] } } }

Esempi di intervalli di telemetria unificata

Con la telemetria unificata, lo stesso contenuto rimane negli attributi span e non viene prodotto alcun record di evento separato. I seguenti esempi sono tratti da un agente Python per la pianificazione dei viaggi. LangGraph Lo stesso agente è mostrato in ogni libreria di strumentazione.

Nota

Questi esempi non sono intervalli completi. Mostrano dati rappresentativi di un'interazione con un agente reale, con alcuni campi omessi e valori lunghi troncati per motivi di leggibilità.

OpenTelemetry

Esempio
Invoke agent span

L'gen_ai.task.inputattributo contiene il prompt dell'utente e l'gen_ai.task.outputattributo contiene lo stato serializzato con la risposta dell'agente. Entrambi sono lo stato del LangChain grafico serializzato.

{ "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

L'gen_ai.tool.call.argumentsattributo contiene gli argomenti dello strumento e l'gen_ai.tool.call.resultattributo contiene il risultato dello strumento, serializzato come. 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

Esempio
Invoke agent span

L'input.valueattributo contiene il prompt dell'utente e l'output.valueattributo contiene lo stato serializzato con la risposta dell'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

L'input.valueattributo contiene gli argomenti dello strumento e l'output.valueattributo contiene il risultato dello strumento, serializzato come. 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 supporto per agenti

Un TypeScript LangGraph agente emette gli stessi tipi di span di un agente Python, quindi il servizio di valutazione lo legge allo stesso modo. Esistono tre librerie di TypeScript strumentazione, ognuna con il proprio nome di ambito e una convenzione di classificazione dello spazio.

Strumenta il tuo agente

Aggiungete la libreria di strumentazione per il percorso desiderato per le vostre TypeScript dipendenze. Gli esempi seguenti fissano una versione minima; utilizzate l'ultima versione disponibile a meno che non abbiate un motivo per bloccarla.

Esempio
ADOT (OpenTelemetry)

Per TypeScript gli agenti su ADOT, aggiungete il pacchetto di autostrumentazione AWS Distro Node () @aws/aws-distro-opentelemetry-node-autoinstrumentation alle vostre dipendenze. Include la LangChain strumentazione integrata, che si attiva all'avvio ed emette il nome dell'ambito. @aws/aws-distro-opentelemetry-instrumentation-langchain

package.json:

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

Aggiungete la strumentazione Traceloop LangChain () alle vostre dipendenze. @traceloop/instrumentation-langchain Il nome dell'ambito emesso è. @traceloop/instrumentation-langchain

package.json:

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

Aggiungi @arizeai/openinference-instrumentation-langchain alle tue dipendenze. Il nome dell'ambito emesso è. @arizeai/openinference-instrumentation-langchain

package.json:

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

La strumentazione è un passo verso l'impostazione dell'osservabilità. Per esportare la telemetria per la valutazione, completa la configurazione completa in Imposta l'osservabilità. Imposta l'osservabilità

Come vengono identificati gli intervalli

L'identificazione degli intervalli dipende dalla libreria di strumentazione:

  • ADOT (OpenTelemetry): il pacchetto di autostrumentazione AWS Distro Node (@aws/aws-distro-opentelemetry-node-autoinstrumentation), che emette il nome dello scope, imposta gen_ai.operation.name (,,)@aws/aws-distro-opentelemetry-instrumentation-langchain, come gli altri invoke_agent frameworkexecute_tool. chat ADOT-native

  • Traceloop (OpenTelemetry): la libreria OpenTelemetry JS di Traceloop () imposta (per lo span dell'agente invoke, workflow per lo span dello strumento @traceloop/instrumentation-langchaintraceloop.span.kind), corrispondenti alla libreria Python. task OpenTelemetry Vedi Come vengono identificati gli intervalli in Python agent support. Come vengono identificati gli intervalli Supporto per agenti Python

  • OpenInference: la libreria OpenInference JS (@arizeai/openinference-instrumentation-langchain) imposta openinference.span.kind (CHAINoAGENT,TOOL,LLM), la stessa della libreria Python OpenInference .

Come vengono estratti i campi di valutazione

L'estrazione dei campi dipende dalla libreria di strumentazione:

  • ADOT (OpenTelemetry): l'invoke agent span è un contenitore strutturale e il contenuto della conversazione risiede nell'intervallo inference (chat), nel formato delle parti e negli attributi. gen_ai.input.messages gen_ai.output.messages

  • Traceloop (OpenTelemetry): con la libreria OpenTelemetry JS di Traceloop, la conversazione è negli attributi e, come stato serializzato. traceloop.entity.input traceloop.entity.output LangChain Questo corrisponde alla OpenTelemetry libreria Python; vedi Come vengono estratti i campi di valutazione sotto il supporto degli agenti Python. Supporto per agenti Python

  • OpenInference: con la libreria OpenInference JS, la conversazione è negli output.value attributi input.value e e i messaggi di inferenza appaiono anche negli attributi indicizzati. llm.input_messages.* llm.output_messages.* Corrisponde alla libreria Python. OpenInference

L'esempio è tratto da un agente TypeScript

I seguenti esempi sono tratti da un agente di TypeScript LangGraph pianificazione dei viaggi distribuito su Amazon Bedrock AgentCore Runtime con telemetria unificata. Lo stesso agente è mostrato in ciascuna delle tre librerie di strumentazione. TypeScript

Nota

Questi esempi non sono intervalli completi. Mostrano dati rappresentativi di un'interazione con un agente reale, con alcuni campi omessi e valori lunghi troncati per motivi di leggibilità.

OpenTelemetry (nativo ADOT)

Con la ADOT-native libreria (dal pacchetto di autostrumentazione AWS Distro Node, che fornisce il nome dell'ambito@aws/aws-distro-opentelemetry-instrumentation-langchain)@aws/aws-distro-opentelemetry-node-autoinstrumentation, l'invoke agent span è un contenitore strutturale e il contenuto della conversazione vive nell'intervallo inference (chat), nel formato delle parti e negli attributi. gen_ai.input.messages gen_ai.output.messages

Esempio
Invoke agent span

L'gen_ai.operation.nameattributo () lo identifica come un invoke agent span. invoke_agent L'intervallo riporta il nome e il modello dell'agente ma non il contenuto della conversazione.

{ "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

L'gen_ai.operation.nameattributo (execute_tool) lo identifica come un intervallo dello strumento di esecuzione; gen_ai.tool.name contiene il nome dello strumento. Gli gen_ai.tool.call.result attributi gen_ai.tool.call.arguments and contengono gli argomenti e i risultati dello strumento.

{ "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

L'gen_ai.operation.nameattributo (chat) lo identifica come intervallo di inferenza. gen_ai.output.messagesGli attributi gen_ai.input.messages and contengono la conversazione nel formato parts e gen_ai.system_instructions contengono il prompt di 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)

Con la libreria OpenTelemetry JS di Traceloop (@traceloop/instrumentation-langchain), il tipo span viene inserito nell'traceloop.span.kindattributo (workflowper l'invoke agent span, task per lo strumento span) e = nell'invoke agent span. gen_ai.operation.name workflow La conversazione è negli attributi and, come stato serializzato. traceloop.entity.input traceloop.entity.output LangChain

Esempio
Invoke agent span

L'traceloop.span.kindattributo (workflow) lo identifica come un invoke agent span. traceloop.entity.outputGli attributi traceloop.entity.input and mantengono lo LangChain stato serializzato, da cui vengono analizzati il prompt dell'utente (messaggio umano) e la risposta dell'agente (messaggio AI).

{ "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

L'traceloop.span.kindattributo (task) lo identifica come un intervallo dello strumento di esecuzione. Gli traceloop.entity.output attributi traceloop.entity.input and contengono gli argomenti e i risultati dello strumento.

{ "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

Con la libreria OpenInference JS (@arizeai/openinference-instrumentation-langchain), il tipo span viene inserito nell'openinference.span.kindattributo. Il contenuto della conversazione è negli output.value attributi input.value and e i messaggi di inferenza vengono visualizzati anche negli attributi e indicizzatillm.input_messages.*. llm.output_messages.*

Esempio
Invoke agent span

L'openinference.span.kindattributo (CHAIN) lo identifica come un invoke agent span. Gli output.value attributi input.value and mantengono lo stato serializzato. LangChain

{ "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

L'openinference.span.kindattributo (TOOL) lo identifica come un intervallo dello strumento di esecuzione; tool.name contiene il nome dello strumento. output.valueGli attributi input.value and contengono gli argomenti e il risultato dello strumento (serializzati come 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

L'openinference.span.kindattributo (LLM) lo identifica come un intervallo di inferenza. Gli llm.input_messages.* attributi contengono il prompt del sistema e il prompt dell'utente e gli llm.output_messages.* attributi contengono la risposta dell'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" } }

Procedure consigliate per LangGraph gli agenti

Il modo in cui si crea e si richiama un LangGraph agente influisce su ciò che appare nella sua telemetria e quindi sulla sua affidabilità. Le seguenti pratiche aiutano a garantire che il prompt dell'utente, la risposta dell'agente e l'attività dello strumento siano recuperabili.

1. Scegliete un modello di costruzione dell'agente

Esistono due modi comuni per creare un LangGraph agente:

  • Predefinito create_agent: il modo più rapido per iniziare. Produce un singolo intervallo di invoke agent per turno, con la conversazione trasmessa attraverso il ciclo di esecuzione integrato del ciclo LangGraph di esecuzione. Usalo quando desideri un agent eason-act standard senza un flusso di controllo personalizzato.

    from langchain.agents import create_agent agent = create_agent(model=model, tools=[search_flights, book_flight])
  • Personalizzato StateGraph: ti dà il pieno controllo su nodi, bordi e routing condizionale. L'esecuzione di ogni nodo diventa un intervallo a sé stante, quindi le tracce sono più granulari. Usalo quando hai bisogno di un'orchestrazione personalizzata.

    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()

Entrambi i pattern vengono valutati allo stesso modo; la differenza è la granularità della traccia.

2. Usa i messaggi nello stato del grafico (consigliato)

Il servizio di valutazione ricostruisce la conversazione a partire dai messaggi di input e output dell'agente. L'uso di un messages campo non è obbligatorio, ma consente l'estrazione più affidabile. Per consuetudineStateGraph, mantieni la conversazione in un messages campo nel tuo Stato:

  • Includi messages nel tuo Stato (consigliato). Puoi aggiungere altri campi personalizzati (ad esempio user_id metadati). Quando messages è presente, l'estrazione standard trova direttamente il prompt dell'utente e la risposta dell'agente. Se messages è assente, il servizio ricomincia a ricostruire la conversazione partendo da intervalli di inferenza individuali, il che è meno affidabile.

  • Aggiungi, non sostituisci. Segui la LangGraph convenzione di aggiungere nuovi messaggi all'elenco anziché sovrascriverlo, in modo da conservare l'intera cronologia delle conversazioni.

  • Usa tipi di LangChain messaggi canonici (HumanMessage,,,AIMessage). ToolMessage SystemMessage La strumentazione li serializza correttamente e il servizio ne riconosce i ruoli.

3. Trasmetti il messaggio utente in un formato supportato

Quando si richiama un LangGraph agente, si aggiunge il messaggio utente messages allo stato del grafico. LangGraph accetta il messaggio in tre formati intercambiabili e AgentCore Evaluations li supporta tutti. Ciascuno produce intervalli e record di eventi che il servizio è in grado di leggere.

  • Tupla: una (role, content) coppia:

    agent.invoke({"messages": [("user", user_message)]}, config=config)
  • LangChain oggetto messaggio: a HumanMessage (o altra classe di messaggio):

    from langchain_core.messages import HumanMessage agent.invoke({"messages": [HumanMessage(content=user_message)]}, config=config)
  • Dizionario: un {"role", "content"} dizionario:

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

Tutti e tre i formati restituiscono lo stesso messages stato, quindi il prompt dell'utente e la risposta dell'agente vengono estratti in modo identico indipendentemente dalla scelta.