

# OpenAI 代理程式
<a name="supported-frameworks-openai-agents"></a>

此頁面說明如何檢測 [OpenAI Agents](https://openai.github.io/openai-agents-python/) 代理程式、如何識別範圍，以及如何擷取評估欄位。

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

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

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

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

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

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

```
opentelemetry-instrumentation-openai-agents>=0.61.0
```
 `pyproject.toml`:  

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

```
openinference-instrumentation-openai-agents>=1.5.0
```
 `pyproject.toml`:  

```
[project]
dependencies = [
    "openinference-instrumentation-openai-agents>=1.5.0",
]
```

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

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

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

**Example**  
OpenTelemetry 檢測程式庫會使用 `gen_ai.operation.name` 屬性來分類跨度。  


| 跨度類型 | 識別屬性 | 
| --- | --- | 
| 叫用代理程式 |  `gen_ai.operation.name` = `invoke_agent`  | 
| 執行工具 |  `gen_ai.operation.name` = `execute_tool`  | 
| Inference |  `gen_ai.operation.name` = `chat`  | 
OpenAI 代理程式也會發出內部轉界範圍，其中 `gen_ai.operation.name` = `unknown`。評估服務會略過這些項目。
OpenInference 檢測程式庫會使用 `openinference.span.kind` 屬性分類跨度。  


| 跨度類型 | 識別屬性 | 
| --- | --- | 
| 叫用代理程式 |  `openinference.span.kind` = `AGENT`或 `CHAIN`  | 
| 執行工具 |  `openinference.span.kind` = `TOOL`  | 
| Inference |  `openinference.span.kind` = `LLM`  | 
使用 OpenInference 程式庫時， `AGENT`和 `CHAIN` 範圍是空的結構容器：它們不會攜帶任何對話內容。使用者提示和代理程式回應會從相同追蹤中的推論 (`LLM`) 重建。

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

OpenAI 代理程式會以組件型格式序列化訊息，其中每則訊息都會攜帶`parts`一組類型內容區塊 （例如 `[{"role": "user", "parts": [{"type": "text", "content": "…​"}]}]`)。透過 OpenTelemetry 程式庫，AgentCore Evaluations 會剖析這些部分中的文字。使用 OpenInference 程式庫時，模型輸出是完整的 OpenAI 回應物件，而 AgentCore Evaluations 會從 讀取回應文字`output[].content[].text`。

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

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

分割遙測時，AgentCore Evaluations 會從與每個範圍相關的事件記錄中讀取對話內容。工具輸入和輸出的位置在兩個程式庫之間不同：
+  **OpenTelemetry**：
  +  **使用者提示**和**客服人員回應**：在 `body.input`和 中，從調用客服人員的事件記錄`body.output`。
  +  **工具呼叫**：來自 的工具名稱`gen_ai.tool.name`，以及`gen_ai.tool.call.arguments``gen_ai.tool.call.result`執行工具範圍上的引數和結果。使用 OpenTelemetry 程式庫時，即使分割遙測，工具引數和結果仍會保留在跨屬性上。
+  **OpenInference**：
  +  **使用者提示**和**代理程式回應**：從推論範圍的事件記錄重建。AgentCore Evaluations 會從 `body.input`和 讀取訊息`body.output`，然後使用使用者提示和客服人員回應來回填空的調用客服人員範圍。
  +  **工具呼叫**：執行工具範圍`tool.name`上來自 的工具名稱。工具引數和結果來自 `body.input`和 中的跨度事件記錄`body.output`。

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

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

未分割遙測時，相同內容會保留在範圍上做為屬性。屬性取決於檢測程式庫：
+  **OpenTelemetry**：
  +  **使用者提示**和**客服人員回應**：調用客服人員範圍`gen_ai.output.messages`上的 `gen_ai.input.messages`和 。
  +  **工具呼叫**：執行工具範圍`gen_ai.tool.call.result`上來自 的工具名稱`gen_ai.tool.name`，以及來自 和 的引數`gen_ai.tool.call.arguments`和結果。
+  **OpenInference**：
  +  **使用者提示**和**客服人員回應**：從推論範圍上的索引訊息屬性 (`llm.input_messages. ` 和 `llm.output_messages.`)，然後回填至空的調用客服人員範圍。
  +  **工具呼叫**：執行工具範圍`output.value`上來自 的工具名稱`tool.name`，以及來自 和 的引數`input.value`和結果。

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

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

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

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

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

**Example**  
`gen_ai.operation.name` 屬性 (`invoke_agent`) 將此識別為調用代理程式範圍。  

```
{
  "traceId": "6a01eef11066751d68f90def0da1f80a",
  "spanId": "3a300b0b3fe650e4",
  "name": "invoke_agent openaiOtelTravel",
  "kind": "INTERNAL",
  "scope": {
    "name": "opentelemetry.instrumentation.openai_agents",
    "version": "0.62.1"
  },
  "attributes": {
    "gen_ai.operation.name": "invoke_agent",
    "gen_ai.agent.name": "openaiOtelTravel",
    "gen_ai.system": "openai",
    "gen_ai.provider.name": "openai",
    "gen_ai.request.model": "gpt-4o-mini-2024-07-18",
    "session.id": "sea-nyc-trip-2-turns-openai-otel"
  },
  "status": {
    "code": "OK"
  }
}
```
相關事件記錄會承載對話。每個訊息的 `content`都是 OpenAI 組件格式陣列；使用者提示字元是使用者訊息的文字，客服人員回應則是助理訊息的文字。  

```
{
  "spanId": "3a300b0b3fe650e4",
  "traceId": "6a01eef11066751d68f90def0da1f80a",
  "scope": {
    "name": "opentelemetry.instrumentation.openai_agents"
  },
  "body": {
    "input": {
      "messages": [
        {
          "role": "user",
          "content": "[{\"role\": \"user\", \"parts\": [{\"type\": \"text\", \"content\": \"Hey, how can you help me\"}]}]"
        }
      ]
    },
    "output": {
      "messages": [
        {
          "role": "assistant",
          "content": "[{\"role\": \"assistant\", \"parts\": [{\"type\": \"text\", \"content\": \"I can assist you with planning your trips ...\"}]}]"
        }
      ]
    }
  }
}
```
`gen_ai.operation.name` 屬性 (`execute_tool`) 將此識別為執行工具範圍； `gen_ai.tool.name`會保留工具名稱。使用 OpenTelemetry 程式庫時，即使分割遙測，工具引數和結果仍會保留在跨屬性上。  

```
{
  "traceId": "6a01eefa5c52f3d86a35038f35f5ba30",
  "spanId": "3cbc4ea5f73fef81",
  "name": "execute_tool search_flights",
  "kind": "INTERNAL",
  "scope": {
    "name": "opentelemetry.instrumentation.openai_agents",
    "version": "0.62.1"
  },
  "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-openai-otel"
  },
  "status": {
    "code": "OK"
  }
}
```
`gen_ai.operation.name` 屬性 (`chat`) 將此識別為推論範圍。此範圍會攜帶模型中繼資料，以及在 中可供代理程式使用的工具`gen_ai.tool.definitions`清單。在 `body.input`和 中的相關事件記錄中，模型呼叫的對話訊息是即時的`body.output`。  

```
{
  "traceId": "6a01eef11066751d68f90def0da1f80a",
  "spanId": "7c1f9a2b4d6e8a03",
  "name": "openai.response",
  "kind": "INTERNAL",
  "scope": {
    "name": "opentelemetry.instrumentation.openai_agents",
    "version": "0.62.1"
  },
  "attributes": {
    "gen_ai.operation.name": "chat",
    "gen_ai.provider.name": "openai",
    "gen_ai.request.model": "gpt-4o-mini-2024-07-18",
    "gen_ai.response.model": "gpt-4o-mini-2024-07-18",
    "gen_ai.usage.input_tokens": 269,
    "gen_ai.usage.output_tokens": 78,
    "gen_ai.tool.definitions": "[{\"type\": \"function\", \"function\": {\"name\": \"search_flights\", \"description\": \"Search for available flights between cities.\", \"parameters\": { ... }}}]",
    "session.id": "sea-nyc-trip-2-turns-openai-otel"
  },
  "status": {
    "code": "OK"
  }
}
```

```
{
  "spanId": "7c1f9a2b4d6e8a03",
  "traceId": "6a01eef11066751d68f90def0da1f80a",
  "scope": {
    "name": "opentelemetry.instrumentation.openai_agents"
  },
  "body": {
    "input": {
      "messages": [
        {
          "role": "user",
          "content": "[{\"role\": \"user\", \"parts\": [{\"type\": \"text\", \"content\": \"Hey, how can you help me\"}]}]"
        }
      ]
    },
    "output": {
      "messages": [
        {
          "role": "assistant",
          "content": "[{\"role\": \"assistant\", \"parts\": [{\"type\": \"text\", \"content\": \"I can assist you with planning your trips ...\"}]}]"
        }
      ]
    }
  }
}
```

### OpenInference
<a name="openai-agents-examples-with-openinference"></a>

使用 OpenInference 程式庫時，呼叫代理程式 (`AGENT`) 的範圍是空的容器。AgentCore Evaluations 會從推論 (`LLM`) 範圍重建使用者提示和代理程式回應，其內容存在於相關事件記錄中。

**Example**  
`openinference.span.kind` 屬性 (`AGENT`) 將此識別為調用代理程式範圍。跨度沒有對話內容。  

```
{
  "traceId": "6a387ee61078243c1cc455ed45c6c313",
  "spanId": "9a1c7dce81b692cd",
  "name": "openaiOInfTravel",
  "kind": "INTERNAL",
  "scope": {
    "name": "openinference.instrumentation.openai_agents",
    "version": "1.5.0"
  },
  "attributes": {
    "openinference.span.kind": "AGENT",
    "graph.node.id": "openaiOInfTravel",
    "llm.system": "openai",
    "session.id": "sea-nyc-trip-2-turns-openai-oi"
  },
  "status": {
    "code": "OK"
  }
}
```
`openinference.span.kind` 屬性 (`TOOL`) 將此識別為執行工具範圍； `tool.name`會保留工具名稱。工具引數和結果會即時存在於相關事件記錄中。  

```
{
  "traceId": "6a387ef07b8f4f3732fab45d3c0b51ff",
  "spanId": "b4e78cb0a06a6fe2",
  "name": "search_flights",
  "kind": "INTERNAL",
  "scope": {
    "name": "openinference.instrumentation.openai_agents",
    "version": "1.5.0"
  },
  "attributes": {
    "openinference.span.kind": "TOOL",
    "tool.name": "search_flights",
    "input.mime_type": "application/json",
    "output.mime_type": "application/json",
    "session.id": "sea-nyc-trip-2-turns-openai-oi"
  },
  "status": {
    "code": "OK"
  }
}
```

```
{
  "spanId": "b4e78cb0a06a6fe2",
  "traceId": "6a387ef07b8f4f3732fab45d3c0b51ff",
  "scope": {
    "name": "openinference.instrumentation.openai_agents"
  },
  "body": {
    "input": {
      "messages": [
        { "role": "user", "content": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}" }
      ]
    },
    "output": {
      "messages": [
        { "role": "assistant", "content": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"flights\": [ ... ]}" }
      ]
    }
  }
}
```
`openinference.span.kind` 屬性 (`LLM`) 將此識別為推論範圍。訊息角色和工具定義位於跨屬性上；訊息內容存在於相關事件記錄中。ADOT 會將輸入角色扁平化為 `user`，因此 AgentCore Evaluations 會使用最後一個純文字輸入訊息做為使用者提示。輸出訊息是 OpenAI 回應物件，AgentCore Evaluations 會從中讀取回應文字。  

```
{
  "traceId": "6a387ee61078243c1cc455ed45c6c313",
  "spanId": "1221a062c7f90a8e",
  "name": "response",
  "kind": "INTERNAL",
  "scope": {
    "name": "openinference.instrumentation.openai_agents",
    "version": "1.5.0"
  },
  "attributes": {
    "openinference.span.kind": "LLM",
    "llm.model_name": "gpt-4o-mini-2024-07-18",
    "llm.input_messages.0.message.role": "system",
    "llm.input_messages.1.message.role": "user",
    "llm.output_messages.0.message.role": "assistant",
    "llm.tools.0.tool.json_schema": "{\"type\": \"function\", \"function\": {\"name\": \"search_flights\", ...}}",
    "session.id": "sea-nyc-trip-2-turns-openai-oi"
  },
  "status": {
    "code": "OK"
  }
}
```

```
{
  "spanId": "1221a062c7f90a8e",
  "traceId": "6a387ee61078243c1cc455ed45c6c313",
  "scope": {
    "name": "openinference.instrumentation.openai_agents"
  },
  "body": {
    "input": {
      "messages": [
        { "role": "user", "content": "[{\"content\": \"Hey, how can you help me\", \"role\": \"user\"}]" },
        { "role": "user", "content": "You are a travel planning assistant. Help users plan trips ..." },
        { "role": "user", "content": "Hey, how can you help me" }
      ]
    },
    "output": {
      "messages": [
        {
          "role": "assistant",
          "content": "{\"id\": \"resp_abc123...\", \"output\": [{\"type\": \"message\", \"content\": [{\"type\": \"output_text\", \"text\": \"I can assist you with planning your trips ...\"}]}]}"
        }
      ]
    }
  }
}
```

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

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

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

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

**Example**  
`gen_ai.input.messages` 屬性會保留使用者提示，而 `gen_ai.output.messages` 屬性會保留客服人員回應。兩者都是 OpenAI 組件格式陣列。  

```
{
  "traceId": "6a4de7b85e61747e6b568a1f4768e89d",
  "spanId": "50656fd77904d125",
  "name": "invoke_agent openaiOtelTravel",
  "kind": "INTERNAL",
  "scope": {
    "name": "opentelemetry.instrumentation.openai_agents",
    "version": "0.62.1"
  },
  "attributes": {
    "gen_ai.operation.name": "invoke_agent",
    "gen_ai.agent.name": "openaiOtelTravel",
    "gen_ai.system": "openai",
    "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 trips ...\"}]}]",
    "session.id": "sea-nyc-trip-2-turns-unified"
  },
  "status": {
    "code": "OK"
  }
}
```
`gen_ai.tool.call.arguments` 屬性會保留工具引數，而 `gen_ai.tool.call.result` 屬性則會保留工具結果。  

```
{
  "traceId": "6a4de7c376913db82e6f0f336a16731d",
  "spanId": "8840e8e23724ebd7",
  "name": "execute_tool search_flights",
  "kind": "INTERNAL",
  "scope": {
    "name": "opentelemetry.instrumentation.openai_agents",
    "version": "0.62.1"
  },
  "attributes": {
    "gen_ai.operation.name": "execute_tool",
    "gen_ai.tool.name": "search_flights",
    "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-unified"
  },
  "status": {
    "code": "OK"
  }
}
```
`gen_ai.operation.name` 屬性 (`chat`) 將此識別為推論範圍。模型中繼資料和`gen_ai.tool.definitions`屬性 （可供代理程式使用的工具清單） 會內嵌在跨度上。  

```
{
  "traceId": "6a4de7b85e61747e6b568a1f4768e89d",
  "spanId": "9b2c1e5f7a3d0846",
  "name": "openai.response",
  "kind": "INTERNAL",
  "scope": {
    "name": "opentelemetry.instrumentation.openai_agents",
    "version": "0.62.1"
  },
  "attributes": {
    "gen_ai.operation.name": "chat",
    "gen_ai.provider.name": "openai",
    "gen_ai.request.model": "gpt-4o-mini-2024-07-18",
    "gen_ai.response.model": "gpt-4o-mini-2024-07-18",
    "gen_ai.usage.input_tokens": 269,
    "gen_ai.usage.output_tokens": 78,
    "gen_ai.tool.definitions": "[{\"type\": \"function\", \"function\": {\"name\": \"search_flights\", \"description\": \"Search for available flights between cities.\", \"parameters\": { ... }}}]",
    "session.id": "sea-nyc-trip-2-turns-unified"
  },
  "status": {
    "code": "OK"
  }
}
```

### OpenInference
<a name="openai-agents-examples-without-openinference"></a>

**Example**  
`input.value` 屬性會保留工具引數，而 `output.value` 屬性則會保留工具結果。  

```
{
  "traceId": "6a387ef07b8f4f3732fab45d3c0b51ff",
  "spanId": "d5a1c9e70b46f312",
  "name": "search_flights",
  "kind": "INTERNAL",
  "scope": {
    "name": "openinference.instrumentation.openai_agents",
    "version": "1.5.1"
  },
  "attributes": {
    "openinference.span.kind": "TOOL",
    "tool.name": "search_flights",
    "input.value": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}",
    "output.value": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"flights\": [ ... ]}",
    "session.id": "sea-nyc-trip-2-turns-oi"
  },
  "status": {
    "code": "OK"
  }
}
```
訊息內容內嵌在索引屬性上。`llm.input_messages. ` 屬性會保留系統提示和使用者提示，而`llm.output_messages.`屬性會保留客服人員回應。AgentCore Evaluations 會從此範圍重建使用者提示和代理程式回應，並回填空的調用代理程式 (`AGENT`) 範圍。  

```
{
  "traceId": "6a387ee61078243c1cc455ed45c6c313",
  "spanId": "c9f0a2b41d773e88",
  "name": "response",
  "kind": "INTERNAL",
  "scope": {
    "name": "openinference.instrumentation.openai_agents",
    "version": "1.5.1"
  },
  "attributes": {
    "openinference.span.kind": "LLM",
    "llm.model_name": "gpt-4o-mini-2024-07-18",
    "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.contents.0.message_content.text": "I can assist you with planning your trips ...",
    "session.id": "sea-nyc-trip-2-turns-oi"
  },
  "status": {
    "code": "OK"
  }
}
```