Skip to content

GenerateContent spans missing opt-in support for capturing instructions, inputs, and outputs. #608

@peterkarabinovic

Description

@peterkarabinovic

Description

In the migration from v0.4.0 to v0.5.0, the telemetry package moved from custom gcp.vertex.agent.* attributes to standard OpenTelemetry Semantic Conventions for Generative AI — which is great.

However, in v0.4.0, TraceLLMCall stored the full LLM request (including system instructions and input messages) and LLM response in span attributes:

// v0.4.0 - TraceLLMCall in internal/telemetry/telemetry.go
attribute.String("gcp.vertex.agent.llm_request", safeSerialize(llmRequestToTrace(llmRequest)))
attribute.String("gcp.vertex.agent.llm_response", safeSerialize(event.LLMResponse))

In v0.5.0, StartGenerateContentSpan + TraceGenerateContentResult only capture:

  • gen_ai.operation.name
  • gen_ai.request.model
  • gen_ai.response.finish_reasons
  • gen_ai.usage.input_tokens
  • gen_ai.usage.output_tokens

The LLM input messages, output messages, and system instructions are no longer recorded, and there is no opt-in mechanism to enable their capture.

Expected Behavior

According to the OpenTelemetry Semantic Conventions — Capturing instructions, inputs, and outputs:

OpenTelemetry instrumentations SHOULD NOT capture them by default, but SHOULD provide an option for users to opt in.

The spec defines three attributes for this purpose:

Attribute Description
gen_ai.system_instructions The system message/instructions provided to the model
gen_ai.input.messages The chat history provided to the model as input
gen_ai.output.messages Messages returned by the model

The ADK Go library should:

  1. Not capture these by default (already the case in v0.5.0)
  2. Provide an opt-in option for users who need this data for debugging, monitoring, or custom span processing (currently missing)

Use Case

We use a custom SpanProcessor (via telemetry.AddSpanProcessor()) to collect LLM span data and publish it to Kafka for observability. In v0.4.0, we relied on gcp.vertex.agent.llm_request and gcp.vertex.agent.llm_response to extract the actual conversation content. After upgrading to v0.5.0, this data is no longer available and there is no way to opt in to receiving it.

Suggested Approach

A possible approach would be adding a configuration option (e.g., via telemetry.EnableContentCapture() or a config struct) that, when enabled, populates the standard semantic convention attributes on the generate_content spans:

// Example API surface
telemetry.SetCaptureContent(true)

// Then in StartGenerateContentSpan / TraceGenerateContentResult:
if captureContent {
    span.SetAttributes(
        attribute.String("gen_ai.system_instructions", ...),
        attribute.String("gen_ai.input.messages", ...),
    )
    // ... and in TraceGenerateContentResult:
    span.SetAttributes(
        attribute.String("gen_ai.output.messages", ...),
    )
}

This would align with the OTel spec's recommendation and restore the ability to capture conversation content for users who opt in.

Environment

  • adk-go version: v0.5.0 (issue introduced in migration from v0.4.0)
  • Go version: 1.26
  • Relevant file: internal/telemetry/telemetry.go

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions