Pick the cleanest representation for an agent that explores three branches in parallel
Three sibling branch spans under the planner, each tagged with outcome; the final answer links back to the kept branch by id.
Picture an architect sketching three different floor plans before choosing one. The right way to record the work is keeping all three sketches in a folder labeled 'options', stamping each one kept or discarded, and noting which one made it to the final blueprint. The wrong ways are: tossing the rejected sketches (you cannot defend the choice later), filing them in three separate cabinets with no cross-reference (nobody can find them together), or wadding them into one drawing on top of each other (unreadable). The agent tree wants the same thing: all branches preserved, tagged with their fate, and connected to the final answer.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Agent branching is where naive tracing falls over. A simple linear LLM call traces cleanly with default auto-instrumentation. The moment the agent fans out to consider multiple options in parallel, the question of how to represent that fan-out in the span tree becomes load-bearing.
Get it right and you have a debuggable trace tree, accurate cost attribution, and queryable analytics. Get it wrong and you have either an incomprehensible trace (everything in one span) or a fragmented set of disconnected traces that cannot be correlated back to the user request.
Why parallel branches are not the same as sequential steps
A sequential LLM workflow has a natural span shape: parent span for the request, child spans for each step in order. The duration and parent-child relationships fully describe the work.
A branching workflow is different. The planner emits N exploration tasks, each runs independently (often concurrently), each produces a candidate answer, and a selector picks the winner. Three things happen that the sequential model does not handle: branches overlap in time, branches are independent (no parent-child between them), and the final selection has a relationship with one specific branch that is not the parent-child relationship.
A correct trace representation has to capture all three. Sibling spans under a common parent get the first two. The third, the selection relationship, needs either an attribute on the final span pointing to the kept branch_id, or an OTel span link from the final span to the kept branch's span context.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
Real products, models, and research that use this idea.
- LangGraph's parallel-branch checkpointer emits per-branch spans that nest under the orchestrator step.
- Tree of thought reasoning implementations in research code typically use a sibling-span shape with depth and branch-id attributes.
What an interviewer would ask next. Try answering before peeking at the approach.
QHow would you handle 50 branches without exploding the trace UI?
Talk about per-branch sampling, collapsing siblings in the UI, and aggregate summary spans.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Discarding losing branches because they did not produce the final answer. The losing branches are the most useful debugging signal when the agent picks badly.
60 second bullets to scan on the way to the call.
Justify sibling spans over a single span with concatenated state
Explain why losing branches are valuable debugging signal
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.