Beyond n8n for Workflow Automation: Agent Graphs as Your Universal Agent Harness
Beyond n8n for Workflow Automation: Agent Graphs as Your Universal Agent Harness
Beyond n8n for Workflow Automation: Agent Graphs as Your Universal Agent Harness
Published March 20, 2026
Hardcoded multi-agent orchestration is brittle: topology lives in framework-specific code, changes require redeploys, and bottlenecks are hard to see. Agent Graphs externalize that topology into LaunchDarkly, while your application continues to own execution.
In this tutorial, you’ll build a small multi-agent workflow, traverse it with the SDK, monitor per-node latency on the graph itself, and update a slow node’s model without changing application code.
LaunchDarkly provides graph structure, config, and observability. Your application owns execution semantics: you write the code that interprets edges and runs agents.

In this tutorial, you’ll add Agent Graphs to an existing multi-agent workflow:
By the end, you’ll have a multi-agent system where topology metadata changes happen in the UI, picked up by your traversal code on the next request.
Every multi-agent framework handles orchestration differently:
The topology is scattered across code. Agent Graphs make it visible: you see the entire workflow in one view, edit connections in the UI, and traverse it with graph-aware SDK methods.
If you’ve built multi-agent systems with LangGraph, OpenAI Swarm, or Strands, you’ve hit these walls:
For a detailed comparison of LangGraph, OpenAI Swarm, and Strands, see Compare AI orchestrators. Agent Graphs work with multiple agent frameworks.
Agent Graphs solve these by giving you a visual graph builder where you:
is_terminal(), is_root(), and get_edges() instead of manual trackingBefore building a graph, you need AgentControl configs for each agent. If you already have configs, skip to Step 2.
For this tutorial, we’ll use three configs:
This is where Agent Graphs diverge from code-based orchestration. Instead of writing add_edge() calls, you’ll see your topology and modify it visually.
Open your LaunchDarkly dashboard and navigate to AI > Agent graphs.

chatbot-flow and click Create graph.
supervisor-agentsecurity-agent and support-agent as nodes

supervisor-agent to both child agentssupervisor-agent → security-agent:

supervisor-agent → support-agent:

security-agent → support-agent:

Notice what you’re seeing: the entire workflow topology in one view. This graph is your architecture diagram, always current. Each node shows which config variation it serves. The edges show routing logic that would otherwise be buried in conditional statements. When you need to add a new agent or change routing, you do it here, not in code.
LaunchDarkly doesn’t execute your graph. It provides:
Your code:
The handoff JSON is arbitrary metadata. You define the schema, you interpret it. LaunchDarkly stores and delivers it.
Install the LaunchDarkly AI SDK:
Initialize the clients in your code:
Build a context for targeting and tracking:
This section walks through the integration code, starting with the building block (what runs at each node), then showing how nodes are orchestrated.
The key to dynamic execution is create_generic_agent. Every node uses the same implementation—no agent registry, no hardcoded agent types:
The generic agent pattern means:
create_generic_agent functionThe AgentService class is the entry point for processing messages through your Agent Graph:
The _execute_graph method fetches the graph from LaunchDarkly and uses traverse() with skip logic for conditional routing:
The execute_node callback implements skip logic—the core pattern that enables conditional routing:
The _routed_to set tracks which nodes should execute:
_routed_to_routed_to, execute it; otherwise skip_routed_toThis enables conditional routing: the supervisor routes to either security OR support, and only the chosen path executes.
The _select_next_node method determines which node to route to based on the agent’s routing decision:
The key insight: your graph topology comes from LaunchDarkly, not hardcoded orchestration. Change the graph in the UI, and your code picks up the new structure on the next request.
With the AgentService wired up (as shown in Step 4), you can now process messages through your Agent Graph. The service handles:
traverse()Test it by sending a message:
Now go back to the LaunchDarkly UI. Add a new node or change an edge. Run your code again. Topology changes are picked up by your traversal code on subsequent SDK evaluations.
This is the key differentiator: monitoring happens on the graph itself, not in a separate dashboard. You see metrics overlaid on the same visual topology you built, so bottlenecks are immediately obvious.
The sample repo includes full instrumentation: calls to tracker.track_success(), tracker.track_error(), and tracker.track_tool_call() in the agent execution path. After running some traffic, open your Agent Graph to see the results.
Navigate to AI > Agent graphs > chatbot-flow. You’ll see a metrics bar at the top of the graph view where you can toggle different metrics on and off.
Here’s what makes this different from traditional APM: the metrics appear directly on your workflow visualization. No mental mapping between a dashboard and your code. No correlating trace IDs. The slow node lights up on the graph.
Turn on Latency to see duration data overlaid directly on your graph:
Turn on Invocations to see how often each node is reached. This reveals which paths your users take most frequently. In a routing graph, you’ll quickly see whether most queries go through security or skip directly to support.
Turn on Tool calls to see the average number of tool invocations per node. If an agent is calling tools excessively, you’ll spot it here.
Click Monitoring to see all metrics over time. This view shows:

To see which specific tools are called, you need to track them in your code using the tracker. The SDK sends this data to LaunchDarkly, which displays it in the monitoring view.
Run the traffic generator from the sample repo to send queries through your graph:
This sends a mix of queries (some with PII, some without) to exercise both the security and support paths. After a few minutes, you’ll see metrics populate on the graph.
With traffic flowing, suppose the security-agent starts averaging 5 seconds per call. With latency metrics enabled on the graph, you see it immediately: the security-agent node shows a high duration value while other nodes stay fast.
The invocation numbers also tell a story. If security-agent shows 50 invocations and support-agent shows 80, you know ~30 queries are bypassing security (the clean path). This helps you understand whether the slow agent is affecting most users or just a subset.
Without Agent Graphs, you’d need custom logging, Datadog queries, and manual correlation. With Agent Graphs, you see the problem in 30 seconds.
The security-agent is slow because it’s using claude-sonnet-4 for PII detection. A smaller, faster model may be sufficient for this task.
In the LaunchDarkly dashboard, update the pii-detector variation:
Anthropic.claude-sonnet-4-6 to Anthropic.claude-haiku-4-5-20251001Or use Agent Skills to make the change from your coding assistant:
No code changes. No deploy. Changes are picked up on subsequent SDK evaluations.
Run the traffic generator again and watch the latency drop.
No deploys. No PRs. The fix is live.
Agent Graphs work with multiple frameworks. This conceptual example shows how the pattern translates to OpenAI Agents SDK:
Same graph definition, adapted to each framework’s execution model. The topology metadata lives in LaunchDarkly; your code interprets and executes it.
Start simple: Begin with a linear graph (A → B → C) before adding conditional routing.
Use handoff data for context passing: Include metadata like action type, reason, or state that the next agent needs to continue the workflow.
Track everything: Call tracker.track_success() and tracker.track_error() in every node for complete visibility. Use node.get_config().create_tracker().track_tool_call(tool_name) to track which tools agents invoke.
Test with targeting: Use LaunchDarkly targeting to route test users to experimental graph configurations.
Handle missing edges: Decide what happens when no edge matches a routing decision or when a target node is disabled. Recommend: fail closed, log diagnostics, and track routing failures.
Keep execution state request-scoped: Store execution state inside the context object (ctx) passed through traversal, not in instance-level variables. Treat graph traversal as request-scoped to avoid concurrency issues.
You now have a multi-agent system where:
When you spot a slow agent in monitoring, you can swap the model from the dashboard without a deploy.
traverse, reverse_traverse, get_edges(), and handoff dataHardcoded orchestration was fine when you had one agent. With multi-agent systems, it becomes a liability. Every change requires a deploy. Every incident requires a developer.
Agent Graphs flip this. Define your workflow in LaunchDarkly, integrate it with your framework, and fix many problems without touching code. Your agents become as dynamic as your feature flags.
Ready to stop hardcoding? Get started with AgentControl and create your first Agent Graph.