

# Google ADK
<a name="supported-frameworks-google-adk"></a>

이 페이지에서는 [Google 에이전트 개발 키트(ADK)](https://google.github.io/adk-docs/) 에이전트를 계측하는 방법, 스팬을 식별하는 방법, 평가 필드를 추출하는 방법을 설명합니다.

 **주제** 
+  [에이전트 계측](#google-adk-instrument) 
+  [스팬 식별 방법](#google-adk-span-identification) 
+  [평가 필드 추출 방법](#google-adk-extraction) 
  +  [이벤트 레코드에서](#google-adk-extraction-event-records) 
  +  [스팬 속성에서](#google-adk-extraction-attributes) 
+  [이벤트 레코드가 있는 스팬의 예](#google-adk-examples-with) 
+  [이벤트 레코드가 없는 스팬의 예](#google-adk-examples-without) 

## 에이전트 계측
<a name="google-adk-instrument"></a>

**OpenInference** 계측 라이브러리()를 사용하여 Google ADK 에이전트를 계측할 수 있습니다`openinference-instrumentation-google-adk`. 이 라이브러리는 Amazon Bedrock AgentCore Evaluations`openinference.instrumentation.google_adk`가 읽는 범위 이름 로 원격 측정을 내보냅니다.

Amazon Bedrock AgentCore 런타임에서와 같이 에이전트가 AWS Distro for OpenTelemetry(ADOT)를 사용하여 실행되는 경우 명시적 계측 코드를 추가할 필요가 없습니다. 프로젝트의 종속성에 계측 라이브러리를 추가하면 충분합니다. ADOT는 시작 시 이를 검색하고 자동으로 활성화합니다.

종속성에 계측 라이브러리를 추가합니다.

**참고**  
버전 `0.1.13` 이상을 사용합니다. 평가 서비스로 테스트한 가장 빠른 버전입니다.

 `requirements.txt`:

```
openinference-instrumentation-google-adk>=0.1.13
```

 `pyproject.toml`:

```
[project]
dependencies = [
    "openinference-instrumentation-google-adk>=0.1.13",
]
```

**참고**  
계측은 관찰성을 설정하는 한 단계입니다. 평가를 위해 원격 측정을 내보내려면 [관찰성 설정](supported-frameworks.md#supported-frameworks-setup)에서 전체 설정을 완료합니다.

## 스팬 식별 방법
<a name="google-adk-span-identification"></a>

Google ADK는 OpenInference 규칙으로 계측되므로 AgentCore Evaluations는 `openinference.span.kind` 속성을 사용하여 스팬을 분류합니다.


| 범위 유형 | 속성 식별 | 
| --- | --- | 
| 에이전트 호출 |  `openinference.span.kind` = `CHAIN` 또는 `AGENT`  | 
| 도구 실행 |  `openinference.span.kind` = `TOOL`  | 
| Inference |  `openinference.span.kind` = `LLM`  | 

Google ADK는 중첩된 스팬 트리를 내보냅니다. 외부 `invocation`스팬(`CHAIN`)은 `agent_run`스팬()을 래핑`AGENT`한 다음 `call_llm` (`LLM`) 및 `execute_tool` (`TOOL`) 스팬을 래핑합니다. 외부 `CHAIN`스팬에는 사용자 프롬프트가 있습니다. AgentCore Evaluations는 이를 호출 에이전트 스팬으로 사용합니다.

## 평가 필드 추출 방법
<a name="google-adk-extraction"></a>

Google ADK는 대화 콘텐츠를 Gemini 콘텐츠 형식으로 래핑합니다. 사용자 프롬프트는 `new_message` 객체 아래에 로 중첩`{"new_message": {"parts": [{"text": "…​"}], "role": "user"}}`되고 에이전트 응답은 `content` 객체 아래에 로 중첩됩니다`{"content": {"parts": [{"text": "…​"}], "role": "model"}}`. AgentCore Evaluations는 이러한 구조를 언래핑하고 `parts` 텍스트를 줄 바꿈으로 조인합니다. 도구 정의는 직렬화된 Gemini 요청으로 도착합니다. AgentCore Evaluations는에서 사용 가능한 도구를 읽습니다`config.tools[].function_declarations[]`.

이 콘텐츠의 위치는 원격 측정이 수집된 방식에 따라 달라집니다. 식별 속성(`openinference.span.kind`)은 두 경우 모두 스팬에 있습니다. 자세한 내용은 [스팬, 이벤트 레코드 및 원격 측정 신호를](supported-frameworks-telemetry.md) 참조하세요.

### 이벤트 레코드에서
<a name="google-adk-extraction-event-records"></a>

원격 측정이 분할되면 AgentCore Evaluations는 각 범위와 상관관계가 있는 이벤트 레코드에서 콘텐츠를 읽습니다.
+  **사용자 프롬프트**:의 에이전트 스팬 호출 이벤트 레코드에서`body.input`. AgentCore Evaluations는 `new_message.parts` 텍스트를 언래핑합니다.
+  **에이전트 응답**:의 에이전트 스팬 호출 이벤트 레코드에서`body.output`. AgentCore Evaluations는 `content.parts` 텍스트를 언래핑합니다.
+  **도구 호출**: 실행 도구 범위의 `tool.name` 속성에서 도구 이름입니다. 도구 인수와 결과는 `body.input` 및의 해당 스팬의 이벤트 레코드에서 가져옵니다`body.output`.

예제는 [이벤트 레코드가 있는 스팬 예제를 참조하세요](#google-adk-examples-with).

### 스팬 속성에서
<a name="google-adk-extraction-attributes"></a>

원격 측정이 분할되지 않으면 속성과 동일한 콘텐츠가 스팬에 유지됩니다.
+  **사용자 프롬프트** 및 **에이전트 응답**: 에이전트 간접 호출 스팬에서 `input.value` 및 `output.value`에서. AgentCore Evaluations는 `new_message.parts` 및 `content.parts` 텍스트를 언래핑합니다.
+  **도구 호출**: `output.value`실행 도구 범위의의 도구 이름과 및의 `tool.name`인수 `input.value` 및 결과입니다.

예제는 [이벤트 레코드가 없는 스팬 예제를 참조하세요](#google-adk-examples-without).

## 이벤트 레코드가 있는 스팬의 예
<a name="google-adk-examples-with"></a>

원격 측정이 분할되면 스팬은 식별 속성을 전달하고 콘텐츠는 상관관계가 있는 이벤트 레코드에 있습니다. 다음 예제는 Amazon Bedrock AgentCore 런타임에 배포된 Google ADK 여행 계획 에이전트에서 가져온 것입니다.

**참고**  
이 예제는 완전한 범위가 아닙니다. 실제 에이전트 상호 작용의 대표 데이터를 표시하며, 일부 필드는 생략되고 긴 값은 가독성을 위해 잘립니다.

**Example**  
외부 `invocation`스팬의 `openinference.span.kind` 속성(`CHAIN`)은 이를 호출 에이전트 스팬으로 식별합니다. 스팬에는 대화 콘텐츠가 없으며 상관관계가 있는 이벤트 레코드에 있습니다.  

```
{
  "traceId": "6a387ee61078243c1cc455ed45c6c313",
  "spanId": "70f2e87a30c34420",
  "name": "invocation",
  "kind": "INTERNAL",
  "scope": {
    "name": "openinference.instrumentation.google_adk",
    "version": "0.1.14"
  },
  "attributes": {
    "openinference.span.kind": "CHAIN",
    "input.mime_type": "application/json",
    "output.mime_type": "application/json",
    "user.id": "default_user",
    "session.id": "sea-nyc-trip-2-turns-google-adk-adot"
  },
  "status": {
    "code": "OK"
  }
}
```
상관관계가 있는 이벤트 레코드에는 대화가 포함됩니다. 사용자 프롬프트는 아래에 중첩`new_message.parts`되고 에이전트 응답은 아래에 중첩됩니다`content.parts`.  

```
{
  "spanId": "70f2e87a30c34420",
  "traceId": "6a387ee61078243c1cc455ed45c6c313",
  "scope": {
    "name": "openinference.instrumentation.google_adk"
  },
  "body": {
    "input": {
      "messages": [
        {
          "role": "user",
          "content": "{\"new_message\": {\"parts\": [{\"text\": \"Hey, how can you help me\"}], \"role\": \"user\"}, \"state_delta\": null, \"run_config\": null}"
        }
      ]
    },
    "output": {
      "messages": [
        {
          "role": "assistant",
          "content": "{\"model_version\": \"gemini-2.5-flash\", \"content\": {\"parts\": [{\"text\": \"I can help you with your travel plans! I can:\\n- Search and book flights\\n- Find and book hotels\\n- Suggest and book activities\"}], \"role\": \"model\"}, \"finish_reason\": \"STOP\"}"
        }
      ]
    }
  }
}
```
`openinference.span.kind` 속성(`TOOL`)은 이를 실행 도구 범위로 식별합니다.는 도구 이름을 `tool.name` 보유합니다. 도구 인수와 결과는 상관관계가 있는 이벤트 레코드에 있습니다.  

```
{
  "traceId": "6a387ef07b8f4f3732fab45d3c0b51ff",
  "spanId": "9028a8dd94943456",
  "name": "execute_tool search_flights",
  "kind": "INTERNAL",
  "scope": {
    "name": "openinference.instrumentation.google_adk",
    "version": "0.1.14"
  },
  "attributes": {
    "openinference.span.kind": "TOOL",
    "gen_ai.operation.name": "execute_tool",
    "gen_ai.tool.name": "search_flights",
    "gen_ai.tool.type": "FunctionTool",
    "gen_ai.tool.call.id": "adk-12345678-1234-1234-1234-123456789012",
    "tool.name": "search_flights",
    "tool.parameters": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}",
    "session.id": "sea-nyc-trip-2-turns-google-adk-adot"
  },
  "status": {
    "code": "OK"
  }
}
```

```
{
  "spanId": "9028a8dd94943456",
  "traceId": "6a387ef07b8f4f3732fab45d3c0b51ff",
  "scope": {
    "name": "openinference.instrumentation.google_adk"
  },
  "body": {
    "input": {
      "messages": [
        { "role": "user", "content": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}" }
      ]
    },
    "output": {
      "messages": [
        {
          "role": "assistant",
          "content": "{\"id\": \"adk-12345678-...\", \"name\": \"search_flights\", \"response\": {\"origin\": \"SEA\", \"destination\": \"NYC\", \"flights\": [ ... ]}}"
        }
      ]
    }
  }
}
```
`call_llm` 스팬의 `openinference.span.kind` 속성(`LLM`)은 이를 추론 스팬으로 식별합니다. 모델 메타데이터와 인덱싱된 `llm.input_messages. ` 및 `llm.output_messages.` 속성에서 모델 호출에 대한 메시지를 전달합니다.  

```
{
  "traceId": "6a387ee61078243c1cc455ed45c6c313",
  "spanId": "1c4e5f8a2b9d0e73",
  "name": "call_llm",
  "kind": "INTERNAL",
  "scope": {
    "name": "openinference.instrumentation.google_adk",
    "version": "0.1.14"
  },
  "attributes": {
    "openinference.span.kind": "LLM",
    "gen_ai.operation.name": "generate_content",
    "gen_ai.request.model": "gemini-2.5-flash",
    "llm.model_name": "gemini-2.5-flash",
    "llm.input_messages.0.message.role": "system",
    "llm.input_messages.1.message.role": "user",
    "llm.input_messages.1.message.contents.0.message_content.text": "Hey, how can you help me",
    "llm.output_messages.0.message.role": "model",
    "llm.output_messages.0.message.contents.0.message_content.text": "I can help you plan your trip ...",
    "session.id": "sea-nyc-trip-2-turns-google-adk-adot"
  },
  "status": {
    "code": "OK"
  }
}
```

## 이벤트 레코드가 없는 스팬의 예
<a name="google-adk-examples-without"></a>

원격 측정이 분할되지 않으면 동일한 콘텐츠가 스팬 속성에 유지되고 별도의 이벤트 레코드가 생성되지 않습니다. 다음은 Google ADK 여행 계획 에이전트의 예입니다.

**참고**  
이 예제는 완전한 범위가 아닙니다. 실제 에이전트 상호 작용의 대표 데이터를 표시하며, 일부 필드는 생략되고 긴 값은 가독성을 위해 잘립니다.

**Example**  
`input.value` 속성에는 사용자 프롬프트(아래에 중첩됨`new_message.parts`)가 있고 `output.value` 속성에는 에이전트 응답(아래에 중첩됨)이 있습니다`content.parts`.  

```
{
  "traceId": "6a4de7b85e61747e6b568a1f4768e89d",
  "spanId": "31ea3d5882dac680",
  "name": "invocation",
  "kind": "INTERNAL",
  "scope": {
    "name": "openinference.instrumentation.google_adk",
    "version": "0.1.13"
  },
  "attributes": {
    "openinference.span.kind": "CHAIN",
    "input.value": "{\"user_id\": \"test_user\", \"session_id\": \"sea-nyc-trip-2-turns-google-adk-unified\", \"new_message\": {\"parts\": [{\"text\": \"Hey, how can you help me\"}], \"role\": \"user\"}}",
    "input.mime_type": "application/json",
    "output.value": "{\"model_version\": \"gemini-2.5-flash\", \"content\": {\"parts\": [{\"text\": \"I can help you plan your trip! I can:\\n- Search and book flights\\n- Find and book hotels\\n- Suggest and book activities\"}], \"role\": \"model\"}, \"finish_reason\": \"STOP\"}",
    "output.mime_type": "application/json",
    "session.id": "sea-nyc-trip-2-turns-google-adk-unified"
  },
  "status": {
    "code": "OK"
  }
}
```
`input.value` 속성에는 도구 인수가 있고 `output.value` 속성에는 도구 결과가 있습니다.  

```
{
  "traceId": "6a4de7c376913db82e6f0f336a16731d",
  "spanId": "b64c37adefae74f0",
  "name": "execute_tool search_flights",
  "kind": "INTERNAL",
  "scope": {
    "name": "openinference.instrumentation.google_adk",
    "version": "0.1.13"
  },
  "attributes": {
    "openinference.span.kind": "TOOL",
    "gen_ai.operation.name": "execute_tool",
    "gen_ai.tool.name": "search_flights",
    "gen_ai.tool.call.id": "adk-12345678-1234-1234-1234-123456789012",
    "tool.name": "search_flights",
    "tool.parameters": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}",
    "input.value": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}",
    "output.value": "{\"id\": \"adk-12345678-...\", \"name\": \"search_flights\", \"response\": {\"origin\": \"SEA\", \"destination\": \"NYC\", \"flights\": [ ... ]}}",
    "session.id": "sea-nyc-trip-2-turns-google-adk-unified"
  },
  "status": {
    "code": "OK"
  }
}
```
`call_llm` 스팬의 `openinference.span.kind` 속성(`LLM`)은 이를 추론 스팬으로 식별합니다. 모델 호출에 대한 메시지는 인덱싱된 `llm.input_messages. ` 및 `llm.output_messages.` 속성에서 인라인입니다.  

```
{
  "traceId": "6a4de7b85e61747e6b568a1f4768e89d",
  "spanId": "2d5f6a9b3c0e1f84",
  "name": "call_llm",
  "kind": "INTERNAL",
  "scope": {
    "name": "openinference.instrumentation.google_adk",
    "version": "0.1.13"
  },
  "attributes": {
    "openinference.span.kind": "LLM",
    "gen_ai.operation.name": "generate_content",
    "gen_ai.request.model": "gemini-2.5-flash",
    "llm.model_name": "gemini-2.5-flash",
    "llm.input_messages.0.message.role": "system",
    "llm.input_messages.1.message.role": "user",
    "llm.input_messages.1.message.contents.0.message_content.text": "Hey, how can you help me",
    "llm.output_messages.0.message.role": "model",
    "llm.output_messages.0.message.contents.0.message_content.text": "I can help you plan your trip ...",
    "session.id": "sea-nyc-trip-2-turns-google-adk-unified"
  },
  "status": {
    "code": "OK"
  }
}
```