LlamaIndex
Esta página explica como instrumentar um LlamaIndexagente, como os intervalos são identificados e como os campos de avaliação são extraídos. Ele termina com as melhores práticas para estruturar um LlamaIndex agente para que ele possa ser avaliado de forma confiável.
Tópicos
Instrumente seu agente
Você pode instrumentar um LlamaIndex agente com qualquer uma das duas bibliotecas de instrumentação: OpenTelemetry(opentelemetry-instrumentation-llamaindex) ou OpenInference(openinference-instrumentation-llama-index). O Amazon Bedrock AgentCore Evaluations oferece suporte às duas bibliotecas. As bibliotecas emitem nomes de escopo diferentes e usam atributos de extensão diferentes. O serviço de avaliação extrai os mesmos valores de cada um.
Quando seu agente é executado com a AWS Distro for OpenTelemetry (ADOT), como no Amazon Bedrock AgentCore Runtime, você não precisa adicionar código de instrumentação explícito. Adicionar a biblioteca de instrumentação às dependências do seu projeto é suficiente. O ADOT o descobre na inicialização e o ativa automaticamente.
Adicione a biblioteca de instrumentação para o caminho que você deseja para suas dependências. Use a versão mais recente disponível, a menos que você tenha um motivo para fixar.
exemplo
- OpenTelemetry
-
NOTA: Use a versão 0.61.0 ou posterior. Essa é a versão mais antiga testada com o serviço de avaliação.
Adicione opentelemetry-instrumentation-llamaindex às suas dependências. O nome do escopo emitido éopentelemetry.instrumentation.llamaindex.
requirements.txt:
opentelemetry-instrumentation-llamaindex>=0.61.0
pyproject.toml:
[project]
dependencies = [
"opentelemetry-instrumentation-llamaindex>=0.61.0",
]
- OpenInference
-
NOTA: Use a versão 4.4.1 ou posterior. Essa é a versão mais antiga testada com o serviço de avaliação.
Adicione openinference-instrumentation-llama-index às suas dependências. O nome do escopo emitido éopeninference.instrumentation.llama_index.
requirements.txt:
openinference-instrumentation-llama-index>=4.4.1
pyproject.toml:
[project]
dependencies = [
"openinference-instrumentation-llama-index>=4.4.1",
]
A instrumentação é uma etapa na configuração da observabilidade. Para exportar a telemetria para avaliação, conclua a configuração completa em Configurar observabilidade.
Como os vãos são identificados
O atributo usado para classificar extensões difere entre as duas bibliotecas de instrumentação.
exemplo
- OpenTelemetry
-
A biblioteca de OpenTelemetry instrumentação classifica as extensões usando o atributo. traceloop.span.kind Como LlamaIndex marca tanto a inferência quanto as operações da ferramenta comotask, AgentCore as avaliações as desambiguam pelo traceloop.entity.name atributo: a task cujo nome da entidade termina em Tool.task é uma extensão da ferramenta de execução; qualquer outra task é uma extensão de inferência.
| Tipo de extensão |
Atributo de identificação |
|
Invocar agente
|
traceloop.span.kind = workflow
|
|
Ferramenta de execução
|
traceloop.span.kind=tool, ou traceloop.span.kind = task com traceloop.entity.name terminação em Tool.task
|
|
Inferência
|
traceloop.span.kind= task (não é uma tarefa de ferramenta)
|
- OpenInference
-
A biblioteca de OpenInference instrumentação classifica as extensões usando o atributo. openinference.span.kind LlamaIndex emiteCHAIN,LLM, e se TOOL estende; não emite AGENT intervalos. O intervalo (aCHAIN) do fluxo de trabalho raiz atua como o intervalo do agente de invocação.
| Tipo de extensão |
Atributo de identificação |
|
Invocar agente
|
openinference.span.kind= CHAIN (extensão do fluxo de trabalho raiz)
|
|
Ferramenta de execução
|
openinference.span.kind = TOOL
|
|
Inferência
|
openinference.span.kind = LLM
|
LlamaIndex emite vários intervalos CHAIN intermediários (por exemplo, para análise de saída e roteamento de ferramentas). AgentCore As avaliações tratam somente a extensão do fluxo de trabalho raiz como a extensão do agente de invocação e reconstroem a solicitação do usuário e a resposta do agente a partir das extensões de inference (LLM) no rastreamento.
Como os campos de avaliação são extraídos
O LlamaIndex agente é um fluxo de trabalho e sua extensão de nível superior é emitida antes da extensão secundária. Esse período de fluxo de trabalho não contém conteúdo de conversação próprio utilizável, então o AgentCore Evaluations reconstrói o prompt do usuário e a resposta do agente a partir dos períodos secundários (os intervalos de inferência e de ferramentas) e os anexa ao intervalo de invocação do agente.
LlamaIndex também serializa o conteúdo como JSON aninhado. Os argumentos da ferramenta são agrupados como {"kwargs": {…}} e os resultados da ferramenta são agrupados como{"blocks": [{"text": "…"}], …}. AgentCore As avaliações revelam esses formulários. Quando um LlamaIndex ReAct agente produz uma saída no formulárioThought: … Answer: <response>, o AgentCore Evaluations extrai o texto depois Answer: como resposta do agente.
A localização desse conteúdo depende de como a telemetria foi coletada. O atributo de identificação (traceloop.span.kindouopeninference.span.kind) está no intervalo em ambos os casos. Para obter mais informações, consulte Espaços, registros de eventos e sinais de telemetria.
De registros de eventos
Quando a telemetria é dividida, o AgentCore Evaluations lê o conteúdo do registro do evento correlacionado a cada período:
-
Solicitação do usuário e resposta do agente: reconstruída a partir dos registros de eventos dos intervalos de inferência, em. body.output Com a OpenTelemetry biblioteca, o prompt do usuário vem do conteúdo do histórico de bate-papo e a resposta do agente do conteúdo do resultado do modelo. Com a OpenInference biblioteca, o prompt do usuário é a mensagem de entrada de texto sem formatação e a resposta do agente é a saída do modelo (com o texto depois de Answer: usado para um ReAct agente).
-
Chamada de ferramenta: o nome da ferramenta a partir da extensão da ferramenta de execução. Os argumentos e o resultado da ferramenta vêm do registro de eventos desse intervalo, em body.input (desembrulhado de{"kwargs": {…}}) e body.output (desempacotado de{"blocks": […]}).
Para ver exemplos, consulte Exemplos de períodos com registros de eventos.
De atributos de extensão
Quando a telemetria não é dividida, o mesmo conteúdo permanece na extensão como atributos. Os atributos dependem da biblioteca de instrumentação:
-
OpenTelemetry: o conteúdo está nos traceloop.entity.output atributos traceloop.entity.input e de cada extensão. AgentCore As avaliações aplicam o mesmo histórico de bate-papo, resultados e ferramentas de desempacotamento a esses valores.
-
OpenInference: o conteúdo da inferência está nos atributos da mensagem indexada (llm.input_messages.
ellm.output_messages.). Os argumentos da ferramenta vêm de input.value (desembrulhados de{"kwargs": {…}}) e o resultado da ferramenta de output.value (desembrulhado de{"blocks": […]}).
Por exemplo, consulte Exemplos de períodos sem registros de eventos.
Exemplos de períodos com registros de eventos
Quando a telemetria é dividida, o intervalo carrega os atributos de identificação e o conteúdo fica em um registro de evento correlacionado. Os exemplos a seguir são de um agente de LlamaIndex ReAct planejamento de viagens implantado no Amazon Bedrock Runtime. AgentCore O mesmo agente é mostrado em cada biblioteca de instrumentação.
Esses exemplos não são extensões completas. Eles mostram dados representativos de uma interação real do agente, com alguns campos omitidos e valores longos truncados para facilitar a leitura.
OpenTelemetry
exemplo
- Invoke agent span
-
O traceloop.span.kind atributo (workflow) identifica isso como uma extensão do agente de invocação. O período do fluxo de trabalho não contém conteúdo de conversação; o AgentCore Evaluations reconstrói o prompt do usuário e a resposta do agente a partir dos períodos secundários.
{
"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
-
O traceloop.span.kind atributo (task) com uma traceloop.entity.name terminação em Tool.task identifica isso como uma extensão da ferramenta de execução. O registro do evento correlacionado carrega os argumentos da ferramenta (agrupadoskwargs) e o resultado da ferramenta (incluídoblocks), junto com o nome da ferramenta.
{
"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
-
O traceloop.span.kind atributo (task), com um traceloop.entity.name que não termina emTool.task, identifica isso como um intervalo de inferência. Um LlamaIndex agente produz vários desses intervalos por turno. Em cada um, o conteúdo é compactado body.output (não hábody.input), como uma string JSON serializada. AgentCore As avaliações leem o prompt do usuário da string do histórico de bate-papo (um {"input": […]} objeto) no primeiro período de inferência e a resposta do agente da string de resultado do modelo (um {"result": {"response": …}} objeto) no último período de inferência.
A seguir está o período de inferência em si.
{
"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"
}
}
No primeiro período de inferência, o body.output conteúdo do registro do evento é o histórico do bate-papo. O prompt do usuário é o texto user -role dentro da matriz aninhadainput.
{
"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\"}"
}
]
}
}
}
No último período de inferência, o body.output conteúdo do registro do evento é o resultado do modelo. A resposta do agente é o texto assistant -role dentro do objeto aninhadoresult.response.
{
"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
exemplo
- Invoke agent span
-
O openinference.span.kind atributo (CHAIN) na extensão raiz do fluxo de trabalho identifica isso como uma extensão do agente de invocação. O intervalo não contém conteúdo de conversa utilizável; o AgentCore Evaluations reconstrói o prompt do usuário e a resposta do agente a partir dos períodos de inferência.
{
"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
-
O openinference.span.kind atributo (TOOL) identifica isso como uma extensão da ferramenta de execução; tool.name contém o nome da ferramenta. Os argumentos e o resultado da ferramenta estão no registro do evento correlacionado, agrupados em kwargs e 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
-
O openinference.span.kind atributo (LLM) identifica isso como um intervalo de inferência. As funções das mensagens estão nos atributos de extensão; o conteúdo reside no registro de eventos correlacionado. O ADOT nivela as funções de entrada parauser, portanto, o AgentCore Evaluations usa a última mensagem de entrada de texto sem formatação como solicitação do usuário. LlamaIndex emite uma mensagem de saída com assistant: prefixo duplicado, que o AgentCore Evaluations ignora em favor da cópia limpa.
{
"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 ..." }
]
}
}
}
Exemplos de períodos sem registros de eventos
Quando a telemetria não é dividida, o mesmo conteúdo permanece nos atributos de span e nenhum registro de evento separado é produzido. Os exemplos a seguir são de um agente de LlamaIndex ReAct planejamento de viagens. O mesmo agente é mostrado em cada biblioteca de instrumentação.
Esses exemplos não são extensões completas. Eles mostram dados representativos de uma interação real do agente, com alguns campos omitidos e valores longos truncados para facilitar a leitura.
OpenTelemetry
exemplo
- Execute tool span
-
O traceloop.entity.input atributo contém os argumentos da ferramenta (agrupadoskwargs) e o traceloop.entity.output atributo contém o resultado da ferramenta (incluídoblocks).
{
"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
-
O traceloop.entity.output atributo contém o histórico do bate-papo, a partir do qual o AgentCore Evaluations lê o prompt do usuário. A resposta vem do resultado do modelo no último período de inferência.
{
"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
exemplo
- Execute tool span
-
O input.value atributo contém os argumentos da ferramenta (agrupadoskwargs) e o output.value atributo contém o resultado da ferramenta (incluídoblocks).
{
"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
-
O conteúdo da mensagem está embutido nos atributos indexados. Os llm.input_messages.
atributos contêm o prompt do sistema e o prompt do usuário, e os llm.output_messages. atributos contêm a saída do modelo, da qual o AgentCore Evaluations extrai o texto depois Answer: como resposta do 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"
}
}
Melhores práticas para LlamaIndex agentes
A forma como você cria e invoca um LlamaIndex agente afeta o que aparece em sua telemetria e, portanto, a confiabilidade com que o agente pode ser avaliado. As práticas a seguir ajudam a garantir que a solicitação do usuário, a resposta do agente e a atividade da ferramenta sejam recuperáveis.
-
Use um fluxo de trabalho de LlamaIndex agente. Crie seu agente como um fluxo de trabalho de LlamaIndex agente (por exemplo, um ReActAgent ouFunctionAgent) para que a estrutura emita uma extensão de fluxo de trabalho de alto nível com inferência e extensões secundárias de ferramentas. AgentCore As avaliações reconstroem o intervalo do agente de invocação a partir desses períodos secundários.
-
Registre ferramentas como FunctionTool objetos. Defina cada ferramenta como uma LlamaIndex FunctionTool (ou use ajudantes @tool -style que produzam uma). As extensões de ferramentas são identificadas pelo nome da entidade e seus argumentos e resultados são serializados nas blocks estruturas kwargs e as AgentCore avaliações desembrulham.
-
Mantenha o texto dos resultados da ferramenta serializáveis. Retorne os resultados da ferramenta como cadeias de caracteres ou JSON-serializable valores. LlamaIndex os envolve em um bloco de texto; mantê-los serializáveis garante que o resultado da ferramenta seja capturado de forma limpa.
-
Para ReAct agentes, use o formato de saída padrão. AgentCore As avaliações extraem a resposta final da Answer: seção da saída de um ReAct agente. Usar o ReAct prompt padrão (o LlamaIndex padrão) mantém a resposta do agente recuperável.