Graph Engineering: The Missing Architecture for AI Agents

Graph Engineering: The Missing Architecture for AI Agents

If you’ve built an AI agent recently, there’s a good chance you’ve accidentally built a graph.

You may not have called it that.

Maybe your code looks something like this:

const research = await researchTopic(topic);

const draft = await writeDraft(research);

const review = await reviewDraft(draft);

const final = await improveDraft(draft, review);

At first, this feels perfectly reasonable.

Research the topic.

Write something.

Review it.

Improve it.

Done.

But there’s a problem hiding in that innocent-looking sequence:

everything is waiting for everything else.

And that becomes increasingly expensive, slow, and fragile as your agents become more capable.

The interesting thing about modern AI systems isn’t just that we can give an LLM more tools.

It’s that we can start designing the work itself.

And that is where graph engineering comes in.

The problem with the straight line

The simplest AI workflow looks like this:

A → B → C → D

A has to finish before B starts.

B has to finish before C starts.

C has to finish before D starts.

This is completely fine when those dependencies are real.

The problem is that we often create dependencies that don’t actually exist.

Imagine an agent tasked with producing a report about three competitors.

A naïve implementation might look like:

Research Competitor A

        ↓

Research Competitor B

        ↓

Research Competitor C

        ↓

Write Report

But ask yourself:

Does researching Competitor B actually depend on finishing the research for Competitor A?

Usually, no.

They’re independent pieces of work.

So why are we forcing them to happen sequentially?

A better architecture is:

                 ┌─ Competitor A ─┐

                 │                │

Question ────────┼─ Competitor B ─┼──→ Write Report

                 │                │

                 └─ Competitor C ─┘

Now the three research tasks can happen at the same time.

This is the first important idea in graph engineering:

Don’t create dependencies that don’t exist.

A graph is just your workflow made explicit

The word “graph” can make this sound much more complicated than it is.

At its simplest, a graph has two things:

Nodes

A node represents a piece of work.

For example:

  • Research a company

  • Search for documentation

  • Extract information

  • Write a draft

  • Check a claim

  • Review code

  • Generate a summary

A node doesn’t necessarily mean “an AI agent”.

It could be a function.

An API call.

A database query.

A human approval.

Another model.

Or an entire sub-workflow.

Edges

An edge represents a relationship between pieces of work.

In the simplest case, it means:

“B needs something produced by A.”

So:

Research → Write

means the writing step depends on the research.

Once you start thinking this way, an AI workflow stops looking like a pile of prompts and starts looking much more like software architecture.

And that’s the interesting shift.

You’ve already been using graphs

Software engineers shouldn’t find this concept particularly exotic.

We have been using graphs for a long time.

A build system has dependencies.

A package manager has dependencies.

A CI pipeline has dependencies.

A database query has dependencies.

A distributed system has services communicating with other services.

Even something as simple as JavaScript promises can express a graph.

Compare:

await researchA();

await researchB();

await researchC();

with:

await Promise.all([

  researchA(),

  researchB(),

  researchC(),

]);

The second version doesn’t make the individual operations smarter.

It changes the dependency structure.

The work that was unnecessarily sequential is now concurrent.

AI agents introduce a similar problem, except the cost of getting the architecture wrong can be much higher.

Instead of wasting a few milliseconds, you might waste:

  • seconds or minutes of latency

  • thousands of tokens

  • expensive model calls

  • context window

  • tool calls

  • and potentially the reliability of the entire workflow

The fake edge

This is one of the most useful questions you can ask when designing an agent system:

Does this step actually depend on the previous step?

Call it the fake edge test.

Suppose you have:

Search → Summarise → Fact Check

Perhaps that is correct.

The summariser needs the search results.

The fact checker needs the summary.

But now consider:

Search A → Search B → Search C → Summarise

Maybe that’s not actually a chain.

It might really be:

Search A ─┐

Search B ─┼──→ Summarise

Search C ─┘

The arrows in the first diagram aren’t representing real dependencies.

They’re just representing the order in which the programmer happened to write the code.

That’s a dangerous distinction.

Execution order and dependency order are not the same thing.

Good graph engineering is largely about discovering the difference.

Parallelism is only the beginning

It’s tempting to think that graphs are mainly about making AI systems faster.

That’s certainly part of it.

But parallelism is actually the easy part.

The more interesting property is that a graph allows different pieces of work to have different responsibilities.

Consider an AI coding system.

A simple agent might do this:

Write Code

    ↓

Run Tests

    ↓

Fix Code

    ↓

Done

A graph can introduce independent perspectives:

                 ┌─ Security Review ──┐

                 │                    │

Write Code ──────┼─ Test Suite ───────┼──→ Fix

                 │                    │

                 └─ Code Review ──────┘

Now the system isn’t just executing instructions.

It’s creating a small system of checks and balances.

One component writes.

Another tests.

Another looks for security problems.

Another reviews the design.

The output from those processes can then influence the next step.

This is where graphs become much more interesting than simple chains.

The diamond pattern

One pattern appears again and again in useful agent systems.

It’s the diamond:

             ┌─ Agent A ─┐

             │           │

Input ───────┼─ Agent B ─┼──→ Verify ─→ Synthesise

             │           │

             └─ Agent C ─┘

You start with one problem.

You split it into independent pieces.

Those pieces are worked on in parallel.

Then you bring the results back together.

This pattern is powerful because it separates two fundamentally different problems:

exploration and synthesis.

The workers explore.

The final node makes sense of what they found.

You can use the same structure for:

  • researching a market

  • analysing a codebase

  • comparing products

  • reviewing documents

  • investigating an incident

  • generating a report

  • analysing customer feedback

  • evaluating multiple solutions

The specific agents change.

The architecture doesn’t.

Give agents different jobs

There’s another mistake I see frequently in agentic systems.

We create several agents but give them essentially the same job.

For example:

Agent 1: "Review this answer."

Agent 2: "Review this answer."

Agent 3: "Review this answer."

That isn’t necessarily useful redundancy.

If all three agents approach the problem in exactly the same way, they may simply reproduce the same mistake.

A better graph gives each node a different responsibility.

For example:

              ┌─ Factual accuracy

              │

Draft ────────┼─ Completeness

              │

              ├─ Contradictions

              │

              └─ Style

Now each reviewer is looking for something different.

This is an important principle:

Independence is more valuable than duplication.

Verification should be a first-class node

One of the most useful things you can do with a graph is make verification explicit.

Instead of:

Research → Write → Done

you can build:

Research → Write → Verify → Final

Or, even better:

          ┌──────────────→ Verify ──────┐

          │                              ↓

Research ───────────────→ Write ─────→ Final

The exact structure depends on the problem.

But the important idea is that verification is part of the architecture rather than an afterthought.

This changes how you think about reliability.

Instead of asking:

“How do I make my agent never make mistakes?”

you start asking:

“What should happen when this agent makes a mistake?”

That’s a much more realistic engineering question.

Errors shouldn’t automatically kill the workflow

A straight-line workflow tends to behave like this:

A → B → C → D

If B fails, C never happens.

But sometimes that’s the wrong behaviour.

Suppose three independent research agents are investigating a question:

A ─┐

B ─┼──→ Synthesis

C ─┘

If B fails, perhaps A and C still provide useful information.

The graph can decide what to do.

Maybe:

A ───────────┐

             │

B ──→ Retry ─┤

             ├──→ Synthesis

C ───────────┘

Or perhaps B’s failure is itself useful information:

A ───────────┐

             │

B ──→ Failed ├──→ Synthesis

             │

C ───────────┘

This is a subtle but important change in mindset.

Failure becomes data.

The system can decide how to respond to it instead of blindly propagating it.

But graphs aren’t magic

There’s a temptation in AI engineering to assume that adding more agents automatically makes a system better.

It doesn’t.

A graph can make a bad system more complicated.

Imagine this:

Agent

Agent

Agent

Agent

Agent

You’ve now created five opportunities for failure instead of one.

And if every agent receives a huge context window, your costs can explode.

Graphs introduce their own problems:

Context explosion

Every node potentially produces information that another node needs to consume.

If you’re not careful, the graph becomes a giant context-passing machine.

Shared state

Two nodes may appear independent but actually depend on the same mutable resource.

That hidden dependency can create race conditions and inconsistent results.

Error propagation

Parallelism doesn’t automatically provide reliability.

If three agents independently make the same wrong assumption, your graph may simply produce three copies of the same mistake.

Orchestration complexity

At some point, the graph itself becomes difficult to understand.

That’s a signal.

If you need a 40-node workflow to accomplish something a single agent can reliably do, you’ve probably over-engineered it.

Not everything needs a graph

This is probably the most important warning.

Don’t use a graph because graphs are interesting.

If the workflow is genuinely sequential:

A → B → C

then keep it sequential.

If a single agent can solve the problem reliably, use a single agent.

If a simple loop works, use a loop.

The goal isn’t to maximise the number of nodes.

The goal is to create the simplest architecture that gives you the behaviour you need.

A graph becomes particularly useful when you have one or more of these:

  • independent work that can run concurrently

  • multiple specialised agents

  • verification or critique

  • retries or recovery paths

  • branching decisions

  • human approval

  • long-running workflows

  • different sources of evidence

  • failure isolation

  • complex dependencies

If none of those exist, you may not need one.

How to design your first agent graph

You don’t need an agent framework to start thinking this way.

Take an existing workflow and write down every meaningful piece of work.

For example, imagine you’re building an agent that researches a company.

Start with:

Research company

Write report

Then decompose the research:

Company

   ↓

Research ──→ Products

   │

   ├───────→ Competitors

   │

   ├───────→ Financials

   │

   └───────→ Recent news

Now ask:

Which of these actually depend on each other?

Probably very few.

So:

Products ────────┐

Competitors ─────┤

Financials ──────┼──→ Verify → Synthesise

Recent news ─────┘

That’s already a graph.

Then ask another question:

What could go wrong?

Perhaps financial information needs additional verification.

So:

Financials → Financial Verification

Maybe the final report should only be produced once enough evidence exists.

Now you’ve introduced another dependency.

This is how a graph should emerge:

from the requirements of the system, not from a desire to use a graph.

Think in contracts, not just prompts

One of the biggest changes I’d recommend when building more sophisticated graphs is to stop thinking about nodes as “prompts”.

Think about them as software components with contracts.

Instead of:

“Research this company.”

Think:

Input:

    companyName

Output:

    {

      claims: [...],

      sources: [...],

      confidence: ...

    }

Now the next node knows exactly what it is receiving.

This makes the graph easier to reason about.

It also makes failures easier to diagnose.

If the synthesis node produces a bad result, you can inspect the output from each upstream node.

That’s much closer to debugging normal software.

And that’s where I think the most interesting future of agent engineering is heading.

AI agents are becoming distributed systems

The more capable our agents become, the less useful it is to think of them as isolated chatbots.

A serious agent system may have:

  • multiple models

  • multiple tools

  • external APIs

  • databases

  • queues

  • persistent state

  • retries

  • verification

  • human approval

  • scheduled work

  • parallel execution

At that point, you’re not really building “a prompt”.

You’re building a distributed system where some of the workers happen to be language models.

That means many of the lessons from traditional software engineering become relevant again:

dependencies matter.

interfaces matter.

failure modes matter.

observability matters.

timeouts matter.

retries matter.

contracts matter.

architecture matters.

The fact that one of your components happens to be an LLM doesn’t make those principles disappear.

The real shift

I think the most useful way to think about graph engineering is this:

We’re moving from agent prompting to agent architecture.

The early generation of AI applications focused heavily on:

“What prompt should I give the model?”

The next generation increasingly asks:

“What should the system do when the model is wrong?”

And then:

“Which work should happen independently?”

And:

“Which outputs should be trusted?”

And:

“Who checks the checker?”

And:

“What happens when a node fails?”

Those are architecture questions.

Not prompt questions.

The graph is not the product

There’s one final distinction worth making.

A graph itself isn’t valuable.

A graph is simply a way of expressing the architecture of a system.

The value comes from what that architecture allows you to achieve:

  • faster execution

  • better verification

  • clearer failure handling

  • independent reasoning

  • better observability

  • more reliable automation

The best graph is usually the one you barely notice.

It’s just the structure that makes the system behave correctly.

Start with the dependencies

If you take one thing away from this article, make it this:

Don’t ask what agents you need. Ask what work needs to happen, and what each piece of work actually depends on.

Start with the simplest workflow.

Draw the nodes.

Draw the edges.

Then challenge every edge.

Does this dependency really exist?

If it doesn’t, remove it.

If two things can happen independently, run them independently.

If something needs verification, make verification explicit.

If something can fail, design the recovery path.

And if none of that is necessary?

Don’t build a graph.

Build the simple thing.

That’s good engineering too.

Final thought

AI agents are often described as if they’re a completely new category of software.

In some ways, they are.

But the problems we encounter when combining them aren’t entirely new.

We’re still dealing with dependencies.

We’re still dealing with concurrency.

We’re still dealing with failures.

We’re still dealing with systems that need to communicate with one another.

The difference is that some of our workers can now reason, use tools, and operate on tasks that previously required a human.

That makes the architecture more important, not less.

The future of AI engineering probably isn’t one incredibly capable agent doing everything.

It’s systems of specialised workers that know what they need, what they can do independently, when to ask for help, and how to recover when something goes wrong.

And those systems look a lot like graphs.

// Share this post