

# LlamaIndex
<a name="supported-frameworks-llamaindex"></a>

此頁面說明如何檢測 [LlamaIndex](https://docs.llamaindex.ai/) 代理程式、如何識別範圍，以及如何擷取評估欄位。它會關閉並[採用最佳實務](#llamaindex-best-practices)來建構 LlamaIndex 代理程式，以便可靠地評估它。

 **主題** 
+  [檢測您的代理程式](#llamaindex-instrument) 
+  [如何識別跨度](#llamaindex-span-identification) 
+  [如何擷取評估欄位](#llamaindex-extraction) 
  +  [從事件記錄](#llamaindex-extraction-event-records) 
  +  [從跨度屬性](#llamaindex-extraction-attributes) 
+  [範例跨越事件記錄](#llamaindex-examples-with) 
+  [沒有事件記錄的範例範圍](#llamaindex-examples-without) 
+  [LlamaIndex 代理程式的最佳實務](#llamaindex-best-practices) 

## 檢測您的代理程式
<a name="llamaindex-instrument"></a>

您可以使用兩種檢測程式庫之一來檢測 LlamaIndex 代理程式：**OpenTelemetry** (`opentelemetry-instrumentation-llamaindex`) 或 **OpenInference** ()`openinference-instrumentation-llama-index`。Amazon Bedrock AgentCore Evaluations 支援這兩個程式庫。程式庫會發出不同的範圍名稱，並使用不同的跨度屬性。評估服務會從每個 中擷取相同的值。

當您的代理程式使用 AWS Distro for OpenTelemetry (ADOT) 執行時，例如在 Amazon Bedrock AgentCore 執行期，您不需要新增明確的檢測程式碼。將檢測程式庫新增至專案的相依性已足夠。ADOT 在啟動時發現它並自動啟用它。

為您想要的相依性路徑新增檢測程式庫。除非您有鎖定原因，否則請使用最新的可用版本。

**Example**  
注意：使用 版本 `0.61.0` 或更新版本。這是使用 評估服務測試的最早版本。  
將 `opentelemetry-instrumentation-llamaindex`新增至您的相依性。發出的範圍名稱為 `opentelemetry.instrumentation.llamaindex`。  
 `requirements.txt`:  

```
opentelemetry-instrumentation-llamaindex>=0.61.0
```
 `pyproject.toml`:  

```
[project]
dependencies = [
    "opentelemetry-instrumentation-llamaindex>=0.61.0",
]
```
注意：使用 版本 `4.4.1` 或更新版本。這是使用 評估服務測試的最早版本。  
將 `openinference-instrumentation-llama-index`新增至您的相依性。發出的範圍名稱為 `openinference.instrumentation.llama_index`。  
 `requirements.txt`:  

```
openinference-instrumentation-llama-index>=4.4.1
```
 `pyproject.toml`:  

```
[project]
dependencies = [
    "openinference-instrumentation-llama-index>=4.4.1",
]
```

**注意**  
檢測是設定可觀測性的一個步驟。若要匯出遙測資料進行評估，請完成設定[可觀測性中的完整設定](supported-frameworks.md#supported-frameworks-setup)。

## 如何識別跨度
<a name="llamaindex-span-identification"></a>

用於分類範圍的屬性在兩個檢測程式庫之間不同。

**Example**  
OpenTelemetry 檢測程式庫會使用 `traceloop.span.kind` 屬性來分類跨度。由於 LlamaIndex 會將推論和工具操作標記為 `task`，因此 AgentCore Evaluations `traceloop.entity.name` 會依 屬性來消除它們：`task`實體名稱結尾為 的 `Tool.task` 是執行工具範圍；任何其他`task`則是推論範圍。  


| 跨度類型 | 識別屬性 | 
| --- | --- | 
| 叫用代理程式 |  `traceloop.span.kind` = `workflow`  | 
| 執行工具 |  `traceloop.span.kind` = `tool`，或 `traceloop.span.kind` = `traceloop.entity.name` 結尾為 `task`的 `Tool.task`  | 
| Inference |  `traceloop.span.kind` = `task`（非工具任務） | 
OpenInference 檢測程式庫會使用 `openinference.span.kind` 屬性分類跨度。LlamaIndex 發出 `CHAIN`、 `LLM`和 `TOOL` 跨度；它不會發出`AGENT`跨度。根工作流程範圍 (`CHAIN`) 做為叫用代理程式的範圍。  


| 跨度類型 | 識別屬性 | 
| --- | --- | 
| 叫用代理程式 |  `openinference.span.kind` = `CHAIN`（根工作流程範圍） | 
| 執行工具 |  `openinference.span.kind` = `TOOL`  | 
| Inference |  `openinference.span.kind` = `LLM`  | 
LlamaIndex 會發出數個中`CHAIN`繼跨度 （例如，用於輸出剖析和工具路由）。AgentCore Evaluations 只會將根工作流程範圍視為叫用代理程式範圍，並從追蹤中的推論 (`LLM`) 重建使用者提示和代理程式回應。

## 如何擷取評估欄位
<a name="llamaindex-extraction"></a>

LlamaIndex 代理程式是一種**工作流程**，其最上層範圍會在其子範圍之前發出。該工作流程範圍本身沒有可用的對話內容，因此 AgentCore Evaluations 會從子範圍 （推論和工具範圍） 重建使用者提示和代理程式回應，並將其連接到調用代理程式範圍。

LlamaIndex 也會將內容序列化為巢狀 JSON。工具引數包裝為 `{"kwargs": {…​}}`，工具結果包裝為 `{"blocks": [{"text": "…​"}], …​}`。AgentCore Evaluations 會取消包裝這些表單。當 LlamaIndex ReAct 代理程式以 格式產生輸出時`Thought: …​ Answer: <response>`，AgentCore Evaluations 會在 之後擷取文字`Answer:`做為代理程式回應。

此內容的位置取決於收集遙測的方式。在這兩種情況下，識別屬性 (`traceloop.span.kind` 或 `openinference.span.kind`) 位於跨度。如需詳細資訊，請參閱[跨度、事件記錄和遙測訊號](supported-frameworks-telemetry.md)。

### 從事件記錄
<a name="llamaindex-extraction-event-records"></a>

分割遙測時，AgentCore Evaluations 會從與每個範圍相關的事件記錄中讀取內容：
+  **使用者提示**和**代理程式回應**：從 中的推論範圍事件記錄重建`body.output`。使用 OpenTelemetry 程式庫時，使用者提示來自聊天歷史記錄內容，而客服人員回應來自模型結果內容。使用 OpenInference 程式庫時，使用者提示是純文字輸入訊息，而代理程式回應是模型輸出 (`Answer:`使用 ReAct 代理程式之後的文字）。
+  **工具呼叫**：執行工具範圍中的工具名稱。工具引數和結果來自該範圍的事件記錄、 `body.input`（從 取消包裝`{"kwargs": {…​}}`) 和 `body.output`（從 取消包裝`{"blocks": […​]}`)。

如需範例，請參閱[範例跨越事件記錄](#llamaindex-examples-with)。

### 從跨度屬性
<a name="llamaindex-extraction-attributes"></a>

未分割遙測時，相同內容會保留在範圍上做為屬性。屬性取決於檢測程式庫：
+  **OpenTelemetry**：內容位於每個範圍的 `traceloop.entity.input`和 `traceloop.entity.output` 屬性上。AgentCore Evaluations 會將相同的聊天歷史記錄、結果和工具取消包裝套用至這些值。
+  **OpenInference**：推論內容位於索引的訊息屬性上 (`llm.input_messages. ` 和 `llm.output_messages.`)。工具引數來自 `input.value`（從 取消包裝`{"kwargs": {…​}}`)，工具結果來自 `output.value`（從 取消包裝`{"blocks": […​]}`)。

如需範例，請參閱[沒有事件記錄的範例跨度](#llamaindex-examples-without)。

## 範例跨越事件記錄
<a name="llamaindex-examples-with"></a>

分割遙測時，範圍會攜帶識別屬性，而內容會存在於相關事件記錄中。下列範例來自部署在 Amazon Bedrock AgentCore 執行期上的 LlamaIndex ReAct 行程規劃代理程式。相同的代理程式會顯示在每個檢測程式庫下方。

**注意**  
這些範例不是完整的跨度。它們會顯示來自實際客服人員互動的代表性資料，省略一些欄位，並截斷長值以保證可讀性。

### OpenTelemetry
<a name="llamaindex-examples-with-otel"></a>

**Example**  
`traceloop.span.kind` 屬性 (`workflow`) 將此識別為調用代理程式範圍。工作流程範圍不附帶任何對話內容；AgentCore Evaluations 會從子範圍重建使用者提示和客服人員回應。  

```
{
  "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"
  }
}
```
結尾為 的`traceloop.span.kind`屬性 (`task`) `traceloop.entity.name` 會將此`Tool.task`識別為執行工具範圍。相關事件記錄會攜帶工具引數 （包裝在 中`kwargs`) 和工具結果 （包裝在 中`blocks`)，以及工具名稱。  

```
{
  "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\"}" }
      ]
    }
  }
}
```
`traceloop.span.kind` 屬性 (`task`) 的 結尾`traceloop.entity.name`不是 `Tool.task`，會將此識別為推論範圍。LlamaIndex 代理程式每轉會產生其中數個跨度。在每個字串中，內容會以序列化 JSON 字串的形式封裝至 `body.output`（沒有 `body.input`)。AgentCore Evaluations 會從第一個推論範圍的聊天歷史記錄字串 (`{"input": […​]}`物件） 讀取**使用者提示**，並從最後一個推論範圍的模型結果字串 (`{"result": {"response": …​}}`物件） 讀取**客服人員回應**。  
以下是推論本身。  

```
{
  "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"
  }
}
```
在第一個推論範圍中，事件記錄`body.output`的內容是聊天歷史記錄。使用者提示是巢狀`input`陣列中的 `user`角色文字。  

```
{
  "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\"}"
        }
      ]
    }
  }
}
```
在最後一個推論範圍中，事件記錄`body.output`的內容是模型結果。代理程式回應是巢狀`result.response`物件內的 `assistant`角色文字。  

```
{
  "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
<a name="llamaindex-examples-with-openinference"></a>

**Example**  
根工作流程範圍上的`openinference.span.kind`屬性 (`CHAIN`) 會將此識別為調用客服人員範圍。範圍沒有可用的對話內容；AgentCore Evaluations 會從推論範圍重建使用者提示和客服人員回應。  

```
{
  "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"
  }
}
```
`openinference.span.kind` 屬性 (`TOOL`) 將此識別為執行工具範圍； `tool.name`會保留工具名稱。工具引數和結果會在相互關聯的事件記錄中運作，`blocks`分別包裝在 `kwargs`和 中。  

```
{
  "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\"}" }
      ]
    }
  }
}
```
`openinference.span.kind` 屬性 (`LLM`) 將此識別為推論範圍。訊息角色位於跨屬性上；內容存在於相關事件記錄中。ADOT 會將輸入角色扁平化為 `user`，因此 AgentCore Evaluations 會使用最後一個純文字輸入訊息做為使用者提示。LlamaIndex 會發出重複的 `assistant:`字首輸出訊息，AgentCore Evaluations 會略過該訊息，以便清除複本。  

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

## 沒有事件記錄的範例範圍
<a name="llamaindex-examples-without"></a>

未分割遙測時，相同的內容會保留在跨度屬性上，而且不會產生單獨的事件記錄。下列範例來自 LlamaIndex ReAct 旅行規劃代理程式。相同的代理程式會顯示在每個檢測程式庫下方。

**注意**  
這些範例不是完整的跨度。它們會顯示來自實際客服人員互動的代表性資料，省略一些欄位，並截斷長值以保證可讀性。

### OpenTelemetry
<a name="llamaindex-examples-without-otel"></a>

**Example**  
`traceloop.entity.input` 屬性會保留工具引數 （包裝在 中`kwargs`)，而`traceloop.entity.output`屬性則會保留工具結果 （包裝在 中`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"
  }
}
```
`traceloop.entity.output` 屬性會保留聊天歷史記錄，AgentCore Evaluations 會從中讀取使用者提示。回應來自最後一個推論範圍的模型結果。  

```
{
  "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
<a name="llamaindex-examples-without-openinference"></a>

**Example**  
`input.value` 屬性會保留工具引數 （包裝在 中`kwargs`)，而`output.value`屬性則會保留工具結果 （包裝在 中`blocks`)。  

```
{
  "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"
  }
}
```
訊息內容內嵌在索引屬性上。`llm.input_messages. ` 屬性會保留系統提示和使用者提示，而`llm.output_messages.`屬性則保留模型輸出，AgentCore Evaluations 會從中擷取之後的文字`Answer:`做為客服人員回應。  

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

## LlamaIndex 代理程式的最佳實務
<a name="llamaindex-best-practices"></a>

建置和叫用 LlamaIndex 代理程式的方式會影響其遙測中出現的內容，因此評估代理程式的可靠性。下列實務有助於確保可復原使用者提示、客服人員回應和工具活動。
+  **使用 LlamaIndex 代理程式工作流程。**將代理程式建置為 LlamaIndex 代理程式工作流程 （例如， `ReActAgent`或 `FunctionAgent`)，讓架構發出具有推論和工具子範圍的頂層工作流程範圍。AgentCore Evaluations 會從這些子範圍重建調用代理程式範圍。
+  **將工具註冊為`FunctionTool`物件。**將每個工具定義為 LlamaIndex `FunctionTool`（或使用產生工具的 `@tool`樣式協助程式）。工具跨度由其實體名稱識別，其引數和結果會在 `kwargs`和`blocks`結構 AgentCore Evaluations 取消包裝中序列化。
+  **保持工具結果為文字序列化。**將工具結果傳回為字串或 JSON 序列化值。LlamaIndex 會將它們包裝在文字區塊中；讓它們可序列化，確保以乾淨的方式擷取工具結果。
+  **對於 ReAct 代理程式，請使用標準輸出格式。**AgentCore Evaluations 會從 ReAct 代理程式輸出的 `Answer:`區段擷取最終答案。使用標準 ReAct 提示 (LlamaIndex 預設） 可復原代理程式回應。