Skip to main content
This page builds on the concepts in Agentex Tracing Overview and Span Hierarchy & Best Practices. Make sure you’re familiar with creating spans and setting parent_id before diving into multi-agent propagation.

The Problem

In a multi-agent system, each agent creates its own trace by default (trace_id = task_id, and each agent has its own task). The result is fragmented observability: the orchestrator’s trace shows only its own spans, and each sub-agent’s work lives in a separate, disconnected trace. You end up with three separate traces instead of one unified view of the entire workflow.

The Solution: Trace ID Propagation

Pass the orchestrator’s trace_id to every sub-agent so all spans land in a single trace tree. You also thread parent_span_id through each dispatch so the hierarchy forms correctly. Two things make this work:
  1. Same trace_id everywhere: the orchestrator’s task_id is used as the trace_id for all sub-agent spans
  2. Threaded parent_span_id: each dispatch passes the current span’s ID so sub-agent work nests correctly

Context Propagation in Temporal

For Temporal-based agents, trace context flows automatically through the interceptor system: The workflow instance exposes self._task_id, self._trace_id, and self._parent_span_id. The outbound interceptor copies these into Temporal activity headers (context-task-id, context-trace-id, context-parent-span-id). On the activity side, the inbound interceptor reads those headers into ContextVars (streaming_task_id, streaming_trace_id, streaming_parent_span_id) that the tracing model picks up automatically.

Setting Up Context in Your Workflow

ContextInterceptor reads self._task_id, self._trace_id, and self._parent_span_id from the workflow instance. Setting these attributes is all you need. The interceptor handles header propagation automatically.

Multi-Agent Code Example

Orchestrator Agent

The orchestrator creates spans for each sub-agent dispatch and passes its trace_id and parent_span_id through:

Sub-Agent (Child)

The sub-agent uses the incoming trace_id from the orchestrator instead of its own task_id:

Resulting Unified Trace Tree

With trace propagation, the entire multi-agent workflow appears under a single trace:

Verification

1

Run your orchestrator agent

Start the orchestrator: agentex agents run --manifest manifest.yaml
2

Trigger sub-agent dispatch

Send a task or message that causes the orchestrator to dispatch work to sub-agents.
3

Check spans via Agentex API

Query for all spans in the trace:
Verify that sub-agent spans share the orchestrator’s trace_id.
4

Verify hierarchy

Check that each span’s parent_id references an existing span’s id. Sub-agent spans should nest under the orchestrator’s dispatch spans.
5

Confirm in the SGP UI

Open the Trace Detail View, filter by the orchestrator’s task_id, and confirm the unified tree shows orchestrator and sub-agent spans together.

Troubleshooting

The sub-agent is using its own task_id as trace_id instead of the orchestrator’s. Check that:
  • The orchestrator passes its task_id as trace_id when creating the sub-agent task
  • The sub-agent reads and uses the propagated trace_id (e.g., params.trace_id or params.task.id)
  • All adk.tracing.span() calls in the sub-agent use the propagated trace_id
Parent-child relationships are missing. Check that:
  • parent_span_id is passed through the dispatch (not just trace_id)
  • Sub-agent spans set parent_id to the received parent_span_id
  • Inside the sub-agent, child operations (LLM calls, tools) receive parent_span_id=span.id from the enclosing turn span
The workflow’s self._parent_span_id was not set before executing the activity. Ensure:
  • self._parent_span_id = span.id is set before calling workflow.execute_activity()
  • The turn span is created and its id is captured before any activity execution
  • For Temporal workflows, the ContextInterceptor is registered in the worker’s interceptor list