LlamaIndex
En esta página se explica cómo instrumentar a un LlamaIndexagente, cómo se identifican los intervalos y cómo se extraen los campos de evaluación. Termina con las mejores prácticas para estructurar un LlamaIndex agente de modo que pueda evaluarse de forma fiable.
Temas
Instrumente a su agente
Puede instrumentar un LlamaIndex agente con cualquiera de las dos bibliotecas de instrumentación: OpenTelemetry(opentelemetry-instrumentation-llamaindex) o OpenInference(openinference-instrumentation-llama-index). Amazon Bedrock AgentCore Evaluations es compatible con ambas bibliotecas. Las bibliotecas emiten distintos nombres de ámbito y utilizan distintos atributos de ámbito. El servicio de evaluación extrae los mismos valores de cada uno.
Cuando su agente utiliza la AWS Distro for OpenTelemetry (ADOT), como en Amazon Bedrock AgentCore Runtime, no necesita añadir código de instrumentación explícito. Basta con añadir la biblioteca de instrumentación a las dependencias de su proyecto. ADOT la descubre al inicio y la activa automáticamente.
Añada la biblioteca de instrumentación de la ruta que desee a sus dependencias. Usa la última versión disponible, a menos que tengas un motivo para marcarla.
ejemplo
- OpenTelemetry
-
NOTA: Usa la versión 0.61.0 o posterior. Esta es la primera versión probada con el servicio de evaluación.
Añada opentelemetry-instrumentation-llamaindex a sus dependencias. El nombre del ámbito emitido esopentelemetry.instrumentation.llamaindex.
requirements.txt:
opentelemetry-instrumentation-llamaindex>=0.61.0
pyproject.toml:
[project]
dependencies = [
"opentelemetry-instrumentation-llamaindex>=0.61.0",
]
- OpenInference
-
NOTA: Utilice la versión 4.4.1 o posterior. Esta es la primera versión probada con el servicio de evaluación.
Añada openinference-instrumentation-llama-index a sus dependencias. El nombre del ámbito emitido esopeninference.instrumentation.llama_index.
requirements.txt:
openinference-instrumentation-llama-index>=4.4.1
pyproject.toml:
[project]
dependencies = [
"openinference-instrumentation-llama-index>=4.4.1",
]
Cómo se identifican los intervalos
El atributo utilizado para clasificar los intervalos difiere entre las dos bibliotecas de instrumentación.
ejemplo
- OpenTelemetry
-
La biblioteca de OpenTelemetry instrumentación clasifica los tramos mediante el atributo. traceloop.span.kind Como LlamaIndex etiqueta tanto las operaciones de inferencia como las de herramientatask, AgentCore Evaluations las elimina de la ambigüedad según el traceloop.entity.name atributo: a task cuyo nombre de entidad termina en Tool.task es un intervalo de herramientas de ejecución; cualquier otro es un intervalo de inferencia. task
| Tipo de intervalo |
Atributo identificativo |
|
Invoca al agente
|
traceloop.span.kind = workflow
|
|
Ejecute la herramienta
|
traceloop.span.kind=tool, o traceloop.span.kind = task con traceloop.entity.name terminación en Tool.task
|
|
Inferencia
|
traceloop.span.kind= task (no es una tarea de herramientas)
|
- OpenInference
-
La biblioteca de OpenInference instrumentación clasifica los tramos mediante el atributo. openinference.span.kind LlamaIndex emite CHAINLLM, y TOOL abarca; no emite intervalos. AGENT El intervalo raíz del flujo de trabajo (aCHAIN) actúa como intervalo del agente de invocación.
| Tipo de intervalo |
Atributo identificativo |
|
Invoca al agente
|
openinference.span.kind= CHAIN (intervalo de flujo de trabajo raíz)
|
|
Ejecute la herramienta
|
openinference.span.kind = TOOL
|
|
Inferencia
|
openinference.span.kind = LLM
|
LlamaIndex emite varios intervalos intermedios CHAIN (por ejemplo, para el análisis de salida y el enrutamiento de herramientas). AgentCore Evaluations solo trata el intervalo raíz del flujo de trabajo como el intervalo del agente de invocación y reconstruye el mensaje del usuario y la respuesta del agente a partir de los intervalos de inferencia () del rastreo. LLM
Cómo se extraen los campos de evaluación
El LlamaIndex agente es un flujo de trabajo y su intervalo de nivel superior se emite antes que el intervalo secundario. Ese intervalo de flujo de trabajo no contiene contenido de conversación propio que se pueda utilizar, por lo que AgentCore Evaluations reconstruye el mensaje del usuario y la respuesta del agente a partir de los intervalos secundarios (los intervalos de inferencia y herramienta) y los adjunta al intervalo de invocación del agente.
LlamaIndex también serializa el contenido como JSON anidado. Los argumentos de la herramienta se empaquetan como y {"kwargs": {…}} los resultados de la herramienta se empaquetan como. {"blocks": [{"text": "…"}], …} AgentCore Las evaluaciones desentrañan estos formularios. Cuando un LlamaIndex ReAct agente genera un resultado en el formularioThought: … Answer: <response>, AgentCore Evaluations extrae el texto siguiente Answer: como respuesta del agente.
La ubicación de este contenido depende de cómo se recopiló la telemetría. El atributo de identificación (traceloop.span.kindoopeninference.span.kind) está en el intervalo en ambos casos. Para obtener más información, consulte Intervalos, registros de eventos y señales de telemetría.
De los registros de eventos
Cuando se divide la telemetría, AgentCore Evaluations lee el contenido del registro de eventos correlacionado con cada intervalo:
-
Mensaje del usuario y respuesta del agente: reconstruidos a partir de los registros de eventos de los intervalos de inferencia, en. body.output En la OpenTelemetry biblioteca, el mensaje del usuario proviene del contenido del historial de chat y la respuesta del agente del contenido del resultado del modelo. En la OpenInference biblioteca, el mensaje del usuario es el mensaje de entrada de texto sin formato y la respuesta del agente es la salida del modelo (con el texto utilizado después Answer: para un agente). ReAct
-
Llamada de herramienta: el nombre de la herramienta que aparece en el intervalo de herramientas de ejecución. Los argumentos y el resultado de la herramienta provienen del registro de eventos de ese intervalo, en body.input (unwrapped from{"kwargs": {…}}) y body.output (unwrapped from{"blocks": […]}).
Para ver ejemplos, consulte Ejemplos de intervalos con registros de eventos.
De los atributos de span
Cuando la telemetría no está dividida, el mismo contenido permanece en el tramo que los atributos. Los atributos dependen de la biblioteca de instrumentación:
-
OpenTelemetry: el contenido se encuentra en los traceloop.entity.output atributos traceloop.entity.input y de cada tramo. AgentCore Las evaluaciones aplican el mismo historial de chat, resultados y herramientas a estos valores.
-
OpenInference: el contenido de la inferencia se encuentra en los atributos del mensaje indexado (y). llm.input_messages.
llm.output_messages. Los argumentos de la herramienta provienen de input.value (se desempaquetan de{"kwargs": {…}}) y los argumentos de la herramienta son el resultado de output.value (se desempaquetan de). {"blocks": […]}
Para ver ejemplos, consulte Ejemplos de intervalos sin registros de eventos.
Un ejemplo de tramos con registros de eventos
Cuando se divide la telemetría, el intervalo contiene los atributos de identificación y el contenido reside en un registro de eventos correlacionado. Los siguientes ejemplos provienen de un agente de LlamaIndex ReAct planificación de viajes desplegado en Amazon Bedrock AgentCore Runtime. En cada biblioteca de instrumentación se muestra el mismo agente.
Estos ejemplos no son períodos completos. Muestran datos representativos de una interacción real entre agentes, omitiendo algunos campos y truncando los valores largos para facilitar la lectura.
OpenTelemetry
ejemplo
- Invoke agent span
-
El traceloop.span.kind atributo (workflow) lo identifica como un intervalo de agentes de invocación. El intervalo de flujo de trabajo no incluye contenido de conversación; AgentCore las evaluaciones reconstruyen el mensaje del usuario y la respuesta del agente a partir de los intervalos secundarios.
{
"traceId": "6a01eef11066751d68f90def0da1f80a",
"spanId": "ba1833fa7f097041",
"name": "ReActAgent.workflow",
"kind": "INTERNAL",
"scope": {
"name": "opentelemetry.instrumentation.llamaindex",
"version": "0.61.0"
},
"attributes": {
"traceloop.span.kind": "workflow",
"traceloop.entity.name": "ReActAgent.workflow",
"session.id": "sea-nyc-trip-2-turns-llamaindex-otel"
},
"status": {
"code": "OK"
}
}
- Execute tool span
-
El traceloop.span.kind atributo (task) que traceloop.entity.name termina en lo Tool.task identifica como un intervalo de herramientas de ejecución. El registro de eventos correlacionados incluye los argumentos de la herramienta (incluidoskwargs) y el resultado de la herramienta (incluidoblocks), junto con el nombre de la herramienta.
{
"traceId": "6a01eefa5c52f3d86a35038f35f5ba30",
"spanId": "5b332f3cd15ace04",
"name": "FunctionTool.task",
"kind": "INTERNAL",
"scope": {
"name": "opentelemetry.instrumentation.llamaindex",
"version": "0.61.0"
},
"attributes": {
"traceloop.span.kind": "task",
"traceloop.entity.name": "FunctionTool.task",
"session.id": "sea-nyc-trip-2-turns-llamaindex-otel"
},
"status": {
"code": "OK"
}
}
{
"spanId": "5b332f3cd15ace04",
"traceId": "6a01eefa5c52f3d86a35038f35f5ba30",
"scope": {
"name": "opentelemetry.instrumentation.llamaindex"
},
"body": {
"input": {
"messages": [
{ "role": "user", "content": "{\"kwargs\": {\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}}" }
]
},
"output": {
"messages": [
{ "content": "{\"blocks\": [{\"block_type\": \"text\", \"text\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\"}], \"tool_name\": \"search_flights\"}" }
]
}
}
}
- Inference span
-
El traceloop.span.kind atributo (task), con una traceloop.entity.name que no termina enTool.task, lo identifica como un intervalo de inferencia. Un LlamaIndex agente produce varios de estos intervalos por turno. En cada uno de ellos, el contenido se empaqueta body.output (no existebody.input), como una cadena JSON serializada. AgentCore Evaluations lee el mensaje del usuario desde la cadena del historial de chat (un {"input": […]} objeto) del primer intervalo de inferencia y la respuesta del agente desde la cadena de resultados del modelo (un {"result": {"response": …}} objeto) del último intervalo de inferencia.
A continuación se muestra el intervalo de inferencia en sí mismo.
{
"traceId": "6a01eef11066751d68f90def0da1f80a",
"spanId": "d9a1f0c7b3e64a20",
"name": "BaseWorkflowAgent.task",
"kind": "INTERNAL",
"scope": {
"name": "opentelemetry.instrumentation.llamaindex",
"version": "0.61.0"
},
"attributes": {
"traceloop.span.kind": "task",
"traceloop.entity.name": "BaseWorkflowAgent.task",
"session.id": "sea-nyc-trip-2-turns-llamaindex-otel"
},
"status": {
"code": "OK"
}
}
En el primer intervalo de inferencia, el body.output contenido del registro del evento es el historial de chat. El mensaje de usuario es el texto user -role que se encuentra dentro de la matriz input anidada.
{
"spanId": "d9a1f0c7b3e64a20",
"traceId": "6a01eef11066751d68f90def0da1f80a",
"scope": {
"name": "opentelemetry.instrumentation.llamaindex"
},
"body": {
"output": {
"messages": [
{
"content": "{\"input\": [{\"role\": \"user\", \"blocks\": [{\"block_type\": \"text\", \"text\": \"Hey, how can you help me\"}]}], \"current_agent_name\": \"Agent\"}"
}
]
}
}
}
En el último intervalo de inferencia, el body.output contenido del registro de eventos es el resultado del modelo. La respuesta del agente es el texto assistant -role que se encuentra dentro del objeto result.response anidado.
{
"spanId": "826bc829697a9610",
"traceId": "6a01eef11066751d68f90def0da1f80a",
"scope": {
"name": "opentelemetry.instrumentation.llamaindex"
},
"body": {
"output": {
"messages": [
{
"content": "{\"result\": {\"response\": {\"role\": \"assistant\", \"blocks\": [{\"block_type\": \"text\", \"text\": \"Here are the available flights from Seattle to New York City ...\"}]}}, \"current_agent_name\": \"Agent\"}"
}
]
}
}
}
OpenInference
ejemplo
- Invoke agent span
-
El openinference.span.kind atributo (CHAIN) del intervalo raíz del flujo de trabajo lo identifica como un intervalo de agentes de invocación. El intervalo no contiene contenido de conversación utilizable; AgentCore Evaluations reconstruye el mensaje del usuario y la respuesta del agente a partir de los intervalos de inferencia.
{
"traceId": "6a387ee61078243c1cc455ed45c6c313",
"spanId": "0a7990d804132a9b",
"name": "ReActAgent.run",
"kind": "INTERNAL",
"scope": {
"name": "openinference.instrumentation.llama_index",
"version": "4.4.1"
},
"attributes": {
"openinference.span.kind": "CHAIN",
"input.mime_type": "application/json",
"output.mime_type": "text/plain",
"session.id": "sea-nyc-trip-2-turns-llamaindex-oi"
},
"status": {
"code": "OK"
}
}
- Execute tool span
-
El openinference.span.kind atributo (TOOL) lo identifica como un intervalo de herramientas de ejecución; tool.name contiene el nombre de la herramienta. Los argumentos y el resultado de la herramienta se encuentran en el registro de eventos correlacionados, incluidos kwargs y blocks respectivamente.
{
"traceId": "6a387ef07b8f4f3732fab45d3c0b51ff",
"spanId": "ab105c12cc40048f",
"name": "FunctionTool.acall",
"kind": "INTERNAL",
"scope": {
"name": "openinference.instrumentation.llama_index",
"version": "4.4.1"
},
"attributes": {
"openinference.span.kind": "TOOL",
"tool.name": "search_flights",
"tool.description": "search_flights(origin: str, destination: str, date: str) -> str ...",
"session.id": "sea-nyc-trip-2-turns-llamaindex-oi"
},
"status": {
"code": "OK"
}
}
{
"spanId": "ab105c12cc40048f",
"traceId": "6a387ef07b8f4f3732fab45d3c0b51ff",
"scope": {
"name": "openinference.instrumentation.llama_index"
},
"body": {
"input": {
"messages": [
{ "content": "{\"kwargs\": {\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}}" }
]
},
"output": {
"messages": [
{ "content": "{\"blocks\": [{\"text\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\"}], \"tool_name\": \"search_flights\"}" }
]
}
}
}
- Inference span
-
El openinference.span.kind atributo (LLM) lo identifica como un intervalo de inferencia. Las funciones de los mensajes se encuentran en los atributos span; el contenido reside en el registro de eventos correlacionados. ADOT aplana las funciones de entradauser, por lo que AgentCore Evaluations utiliza el último mensaje de entrada de texto sin formato como mensaje de usuario. LlamaIndex emite un mensaje de salida duplicado con el assistant: prefijo, que AgentCore Evaluations omite en favor de la copia limpia.
{
"traceId": "6a387ee61078243c1cc455ed45c6c313",
"spanId": "1221a062c7f90a8e",
"name": "OpenAI.astream_chat",
"kind": "INTERNAL",
"scope": {
"name": "openinference.instrumentation.llama_index",
"version": "4.4.1"
},
"attributes": {
"openinference.span.kind": "LLM",
"llm.system": "openai",
"llm.model_name": "gpt-4o-mini",
"llm.input_messages.0.message.role": "system",
"llm.input_messages.1.message.role": "user",
"llm.output_messages.0.message.role": "assistant",
"session.id": "sea-nyc-trip-2-turns-llamaindex-oi"
},
"status": {
"code": "OK"
}
}
{
"spanId": "1221a062c7f90a8e",
"traceId": "6a387ee61078243c1cc455ed45c6c313",
"scope": {
"name": "openinference.instrumentation.llama_index"
},
"body": {
"input": {
"messages": [
{ "role": "user", "content": "{\"messages\": [ ... ]}" },
{ "role": "user", "content": "You are designed to help with a variety of tasks ..." },
{ "role": "user", "content": "Hey, how can you help me" }
]
},
"output": {
"messages": [
{ "role": "assistant", "content": "assistant: Thought: ... Answer: I can help you plan your trip ..." },
{ "role": "assistant", "content": "Thought: ... Answer: I can help you plan your trip ..." }
]
}
}
}
El ejemplo abarca espacios sin registros de eventos
Cuando la telemetría no está dividida, el mismo contenido permanece en los atributos del tramo y no se genera ningún registro de eventos independiente. Los siguientes ejemplos son de un agente de planificación de LlamaIndex ReAct viajes. En cada biblioteca de instrumentación se muestra el mismo agente.
Estos ejemplos no son períodos completos. Muestran datos representativos de una interacción real entre agentes, omitiendo algunos campos y truncando los valores largos para facilitar la lectura.
OpenTelemetry
ejemplo
- Execute tool span
-
El traceloop.entity.input atributo contiene los argumentos de la herramienta (incluidoskwargs) y el traceloop.entity.output atributo contiene el resultado de la herramienta (incluido). blocks
{
"traceId": "6a4de7c376913db82e6f0f336a16731d",
"spanId": "b64c37adefae74f0",
"name": "FunctionTool.task",
"kind": "INTERNAL",
"scope": {
"name": "opentelemetry.instrumentation.llamaindex",
"version": "0.61.0"
},
"attributes": {
"traceloop.span.kind": "task",
"traceloop.entity.name": "FunctionTool.task",
"traceloop.entity.input": "{\"kwargs\": {\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}}",
"traceloop.entity.output": "{\"blocks\": [{\"block_type\": \"text\", \"text\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"flights\\\": [ ... ]}\"}], \"tool_name\": \"search_flights\"}",
"session.id": "sea-nyc-trip-2-turns-unified"
},
"status": {
"code": "OK"
}
}
- Inference span
-
El traceloop.entity.output atributo contiene el historial de chat, desde el que AgentCore Evaluations lee la solicitud del usuario. La respuesta proviene del resultado del modelo en el último intervalo de inferencia.
{
"traceId": "6a4de7b85e61747e6b568a1f4768e89d",
"spanId": "31ea3d5882dac680",
"name": "BaseWorkflowAgent.task",
"kind": "INTERNAL",
"scope": {
"name": "opentelemetry.instrumentation.llamaindex",
"version": "0.61.0"
},
"attributes": {
"traceloop.span.kind": "task",
"traceloop.entity.name": "BaseWorkflowAgent.task",
"traceloop.entity.output": "{\"input\": [{\"role\": \"user\", \"blocks\": [{\"block_type\": \"text\", \"text\": \"Hey, how can you help me\"}]}], \"current_agent_name\": \"Agent\"}",
"session.id": "sea-nyc-trip-2-turns-unified"
},
"status": {
"code": "OK"
}
}
OpenInference
ejemplo
- Execute tool span
-
El input.value atributo contiene los argumentos de la herramienta (incluidoskwargs) y el output.value atributo contiene el resultado de la herramienta (incluidoblocks).
{
"traceId": "6a387ef07b8f4f3732fab45d3c0b51ff",
"spanId": "d5a1c9e70b46f312",
"name": "FunctionTool.acall",
"kind": "INTERNAL",
"scope": {
"name": "openinference.instrumentation.llama_index",
"version": "4.4.2"
},
"attributes": {
"openinference.span.kind": "TOOL",
"tool.name": "search_flights",
"input.value": "{\"kwargs\": {\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}}",
"output.value": "{\"blocks\": [{\"text\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"flights\\\": [ ... ]}\"}], \"tool_name\": \"search_flights\"}",
"session.id": "sea-nyc-trip-2-turns-oi"
},
"status": {
"code": "OK"
}
}
- Inference span
-
El contenido del mensaje está integrado en los atributos indexados. Los llm.input_messages.
atributos contienen el mensaje del sistema y el mensaje del usuario, y los llm.output_messages. atributos contienen el resultado del modelo, del que AgentCore Evaluations extrae el texto después Answer: como respuesta del agente.
{
"traceId": "6a387ee61078243c1cc455ed45c6c313",
"spanId": "c9f0a2b41d773e88",
"name": "OpenAI.astream_chat",
"kind": "INTERNAL",
"scope": {
"name": "openinference.instrumentation.llama_index",
"version": "4.4.2"
},
"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 designed to help with a variety of tasks ...",
"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": "Thought: ... Answer: I can help you plan your trip ...",
"session.id": "sea-nyc-trip-2-turns-oi"
},
"status": {
"code": "OK"
}
}
Mejores prácticas para los LlamaIndex agentes
La forma en que se crea e invoca un LlamaIndex agente afecta a lo que aparece en su telemetría y, por lo tanto, a la fiabilidad con la que se puede evaluar el agente. Las siguientes prácticas ayudan a garantizar que se puedan recuperar el mensaje del usuario, la respuesta del agente y la actividad de la herramienta.
-
Utilice un flujo de trabajo de LlamaIndex agente. Cree su agente como un flujo de trabajo de LlamaIndex agente (por ejemplo, una ReActAgent oFunctionAgent) para que el marco emita un intervalo de flujo de trabajo de nivel superior con intervalos de inferencia y secundarios de herramientas. AgentCore Las evaluaciones reconstruyen el intervalo de agentes invocado a partir de estos intervalos secundarios.
-
Registre las herramientas como objetos. FunctionTool Defina cada herramienta como una LlamaIndex FunctionTool (o utilice ayudantes de @tool estilo que produzcan una). Los intervalos de herramientas se identifican por el nombre de su entidad y sus argumentos y resultados se serializan en el resumen de Evaluaciones kwargs y blocks estructuras AgentCore .
-
Mantenga los resultados de la herramienta serializables en texto. Devuelve los resultados de la herramienta como cadenas o valores. JSON-serializable LlamaIndex los envuelve en un bloque de texto; al mantenerlos serializables, se asegura de que el resultado de la herramienta se capture de forma limpia.
-
Para los ReAct agentes, utilice el formato de salida estándar. AgentCore Las evaluaciones extraen la respuesta final de la Answer: sección del resultado de un ReAct agente. El uso del ReAct mensaje estándar (el LlamaIndex predeterminado) permite recuperar la respuesta del agente.