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",
]
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
|
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.
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.
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.
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.
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"
}
}
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 .
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
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.