---
title: "Trace subagents"
description: "Keep delegated work in its parent trace or fork it into a linked trace when it needs independent evaluation."
seo:
  title: "Trace AI Subagents | Judgment Docs"
  description: "Choose nested or forked tracing for AI subagents and verify linked parent and child traces in Judgment."
---

Keep ordinary delegated work inside the parent's trace. Fork a linked trace
only when a subagent performs a meaningful unit of work that should be
inspected or evaluated on its own.

## Choose nested or forked tracing

| Shape | Use it when | Result |
| --- | --- | --- |
| Nested span | The subagent is one step in the parent's run and does not need independent evaluation. | The subagent and all its work remain in the parent trace. |
| Forked trace | The subagent owns a substantial task with its own input, output, and evaluation boundary. | The parent keeps a lightweight invocation span and the subagent runs in a separate linked trace. |

Do not fork only because the implementation uses another class, process, or
model. The product boundary is whether the delegated result stands on its own.

## Fork substantial delegated work

Set `fork=True` in Python or `fork: true` in TypeScript on the observed agent
function:

**Python**

```python
from judgeval import Tracer

@Tracer.observe(
    span_type="agent",
    span_name="research_subagent",
    fork=True,
)
def research_subagent(task: str) -> str:
    return research(task)
```

**TypeScript**

```typescript
const researchSubagent = Tracer.observe(
  async function researchSubagent(task: string): Promise<string> {
    return research(task);
  },
  {
    spanType: "agent",
    spanName: "research_subagent",
    fork: true,
  },
);
```

Call the function while the parent trace is active. The SDK records the link
between the parent invocation and forked trace. Keep the delegated task as the
forked trace input and the returned result as its output.

For lower-level control in Python, use
[`Tracer.start_linked_trace()`](/sdk-reference/python/trace/tracer#start_linked_trace).

If the subagent resumes after a queue or approval wait, also follow the
[Durable work](/documentation/tracing/durable-work) boundary: start a new trace
for the resumed autonomous part and keep the stable job or conversation session
ID.

## Verify

Run one parent request that invokes the subagent. Confirm that:

1. The parent trace contains a lightweight subagent invocation span.
2. The subagent work appears in its own trace with the expected input, output,
   model calls, and tools.
3. Judgment shows the relationship between the parent and forked trace.
4. Independent judges run on the subagent trace only when that was the intended
   evaluation boundary.

## Troubleshooting

| Symptom | Check |
| --- | --- |
| Subagent work remains in the parent | Confirm the observed subagent function has the fork option and runs while the parent is active. |
| Forked trace has no parent relationship | Start the fork from inside the active parent trace rather than from detached background work. |
| Too many separately scored traces | Keep small delegated steps nested; fork only independently meaningful work. |
| Resumed work extends a stale trace | Treat queues and approval waits as durable boundaries and start a new trace in the same session. |

## Related pages

- [Tracing data model](/documentation/tracing)
- [Add attributes and context](/documentation/tracing/attributes)
- [Durable work](/documentation/tracing/durable-work)
