Augments LabsAugments ADK

Custom Spans

The tracing module exposes typed factory functions for every built-in span kind (agent, function, generation, response, handoff, guardrail) plus custom_span() for application-authored instrumentation.

The tracer registry

Tracing is opt-in. Until an application calls set_tracer(...), every span factory returns a NoOpSpan β€” zero cost on the hot path.

from augments.adk.tracing import set_tracer, get_tracer
 
class MyBackendTracer:
    def agent_span(self, data): ...
    def function_span(self, data): ...
    # ... one method per span kind
    def custom_span(self, data): ...
 
set_tracer(MyBackendTracer())

The installed tracer implements the Tracer protocol (seven factory methods, one per span kind) and is fetched lazily via get_tracer() inside every factory, so swapping tracers at runtime is a single call.

custom_span(name, *, data=None, span_id=None, disabled=False)

The only tracing factory the ADK exposes for application code.

from augments.adk.tracing import custom_span
 
with custom_span("rank_search_results", data={"n": len(results)}) as span:
    ranked = rank(results)
    span.data.data["elapsed_ms"] = elapsed
  • name β€” short human-readable span name
  • data β€” arbitrary JSON-safe payload (merged into the span's CustomSpanData)
  • span_id β€” optional caller-assigned identifier
  • disabled β€” return a NoOpSpan regardless of the installed tracer

The span is a context manager: start() runs on entry, finish() on exit, and any exception is recorded via set_error() before re-raising.

Typed span-data classes

Each built-in span kind has a frozen dataclass payload in augments.adk.types.tracing.span_data. This is the "G4" layer β€” typed observability instead of untyped dict attributes:

FactoryData classFields
agent_spanAgentSpanDataname, handoffs, tools, output_type, metadata
function_spanFunctionSpanDataname, input, output, mcp_data
generation_spanGenerationSpanDatainput, output, model, model_config, usage
response_spanResponseSpanDataresponse_id, input
handoff_spanHandoffSpanDatafrom_agent, to_agent
guardrail_spanGuardrailSpanDataname, triggered
custom_spanCustomSpanDataname, data

AgentSpanData.metadata is the home for arbitrary per-run tags passed via RunConfig.tracing_metadata β€” see docs/tracing/tracing.md.

All seven classes subclass SpanData and are frozen dataclasses β€” safe to pass across the tracer boundary without defensive copying.

Recording errors without raising

with custom_span("risky_step") as span:
    try:
        do_work()
    except RecoverableError as e:
        span.set_error(str(e), data={"type": type(e).__name__})
        return fallback()

set_error() populates the span's error dict; the context manager's __exit__ only records a fresh error if one hasn't already been set (via the captured exc_val).

See also

  • src/augments/adk/tracing/tracer.py β€” Tracer protocol + registry
  • src/augments/adk/tracing/spans.py β€” Span, NoOpSpan, factory functions
  • src/augments/adk/types/tracing/span_data.py β€” typed payload dataclasses
  • examples/tracing/custom_span_example.py β€” runnable example
  • tests/unit/tracing/ β€” tracer, span, and span-data tests