Designing Resilient AI Agent Graphs: Retries, Fallbacks, and GraphRAG
Learn how to build fault-tolerant AI agent workflows using explicit failure branches, retry logic, LangGraph, and when GraphRAG outperforms plain RAG or agent loops.
This article is published in English.
When Failures Happen: Planning Alternate Routes
Picking up from where the earlier discussion left off, imagine the financial research agent has grown noticeably more sophisticated by this point.
Recall the sample question a portfolio manager might pose, something along the lines of asking why a particular stock dropped following its earnings report, and what risks deserve attention going forward. The graph is able to take that kind of question apart, pull data from multiple sources, run analysis on the results, draft a response, verify it, and route it to a human reviewer when needed — essentially, a human-in-the-loop pattern.
There's one piece we haven't addressed so far, though: what happens when a step in that process breaks?
Picture the graph reaching the branch responsible for market data.
It fires off a request for price movements and trading volume, but the data provider fails to respond.
In that situation, moving straight into the Analyze step as though nothing happened isn't an option.
At the same time, killing the whole run outright is usually too extreme, since production-grade systems need some form of fallback behavior.
This is exactly why failure deserves to be treated as its own branch within the graph, not an afterthought.
The original, simple flow looks like this:
Search Market Data
↓
Analyze
We can reshape it into something like this instead:
Search Market Data
/ \
↓ ↓
Success Failure
↓ ↓
Analyze Retry (how to handle this!?)
With this structure, the graph has an explicit answer for what to do once a request fails.
Managing Retry Logic
Should the retry succeed, the workflow simply resumes as normal.
If it fails again, though, it might make more sense to switch to a different data source or escalate to human review rather than hammering the same request repeatedly.
Here's a more detailed version of that branching:
Search Market Data
/ \
↓ ↓
Success Failure
↓ ↓
Analyze Retry
↓
┌──────┴──────┐
↓ ↓
Success Failure
↓ ↓
Analyze Alternative
Source
What matters here is not how many retries you allow — it's the fact that failure handling is baked into the graph's design from the start. As the diagram shows, different kinds of failure can lead down different paths.
Say the market data API simply times out. Retrying is reasonable, since the issue is likely transient.
But suppose the request goes through fine and simply returns nothing useful for the time period in question. Repeating that exact request won't accomplish anything.
In that case, a better move is to query an alternative, approved data source.
And if that still comes up empty, the situation is probably worth escalating to a human reviewer. This is the kind of detail that separates a fragile workflow from a dependable one.
The routing function driving this might look like:
def route_after_market_search(state):
if state["market_data"]:
return "analyze"
if state["retry_count"] < 2:
return "retry"
return "human_review"
These conditions give the graph clear boundaries — it's allowed to retry, but not indefinitely.
The same principle extends across the rest of the graph, since plenty of things can go wrong along the way:
- A retrieval step can fail
- A call to the LLM can fail
- A given source can be temporarily unreachable
- A generated response can fail a validation check
Rather than wrapping the entire application in one massive error handler, you can decide, node by node, what should happen right at the point where something breaks.
This is part of why modeling a workflow as a graph is appealing. When a failure occurs, you're not stuck asking a vague question like "why did the agent fail?"
Instead, you can trace the exact path the run took and pinpoint precisely where things went wrong:
Understand
↓
Search Filings ✓
↓
Search Earnings ✓
↓
Search Market Data ✗
↓
Retry ✓
↓
Analyze
↓
Write
↓
Check
That gives you something concrete to dig into rather than a black box.
Naturally, as the graph expands, managing all of this by hand starts to demand real effort — and that's a fair concern.
At that point you're dealing with execution logic, state management, conditional routing, retry handling, persistence, and some way to inspect what actually happened during a given run.
This is precisely the kind of situation where a framework saves you from reinventing the same orchestration machinery on every project.
That's the gap LangGraph is built to fill.
LangGraph
With a framework in place, your workflow can split into separate research tasks, merge those results afterward, retry failed steps, pause so a human can weigh in, and keep track of state as execution moves from one stage to the next.
Of course, defining that graph and actually running it still requires work.
You could hand-roll all of the orchestration yourself, but doing so means you end up maintaining a substantial amount of infrastructure that sits around your core AI logic.
LangGraph is designed to handle exactly that layer.
LangGraph is a framework built for constructing stateful, graph-based agent workflows. Rather than treating an agent as a single loop that keeps asking a language model what to do next, you explicitly define the nodes, the transitions between them, the shared state, and the overall execution flow.
Going back to the NVIDIA research agent from earlier, its structure could be sketched like this:
Question
↓
Understand
↓
┌──────────┼──────────┐
↓ ↓ ↓
Filings Earnings Market
↓ ↓ ↓
└──────────┼──────────┘
↓
Analyze
↓
Write
↓
Check
↙ ↓ ↘
Search Rewrite Human
↓ ↓ Review
└───────┴───────┘
↓
Send
What's notable is that the graph's structure and the actual application logic can coexist in the same codebase.
A stripped-down LangGraph implementation of that same workflow might look like:
from langgraph.graph import StateGraph, END
builder = StateGraph(ResearchState)
builder.add_node("understand", understand)
builder.add_node("search_filings", search_filings)
builder.add_node("search_earnings", search_earnings)
builder.add_node("search_market", search_market)
builder.add_node("analyze", analyze)
builder.add_node("write", write)
builder.add_node("check", check)
builder.set_entry_point("understand")
builder.add_edge("understand", "search_filings")
builder.add_edge("understand", "search_earnings")
builder.add_edge("understand", "search_market")
builder.add_edge("analyze", "write")
builder.add_edge("write", "check")
The snippet above is intentionally minimal so you can focus on the underlying mental model — tying together the nodes, edges, and state concepts introduced earlier in this series.
- Each node handles one unit of work
- The graph defines how those units connect to one another
- State is what passes information from one node to the next
That's really all there is to it. This mental model is far easier to reason about than trying to cram everything into one massive agent prompt.
You can look at the graph itself and understand what the workflow is supposed to do before you even dig into how each individual node is implemented.
Say you wanted to insert a human-approval step before the final answer goes out — you'd be modifying the workflow's shape directly:
Check
↓
Human Review
↓
Send
There's no need to bury that kind of decision inside a prompt somewhere. The structure itself makes it explicit and easy for your team to follow.
Why Choose LangGraph Over a Plain Agent Loop?
A conventional agent loop typically follows this shape:
Think
↓
Choose Tool
↓
Use Tool
↓
Think Again
↓
Choose Tool
↓
...
In this setup, the model has substantial latitude in deciding what happens next. That flexibility is genuinely valuable when the task at hand is open-ended by nature.
But a financial research workflow like the one described here includes several decision points you'll likely want to keep under tighter control. This distinction is the crux of the matter.
Not every workflow calls for an agent loop.
Consider a few examples:
- You may need the system to gather specific evidence before it's allowed to produce an answer.
- You may want market data and filings pulled independently of one another.
- You may require a verification step before anything gets forwarded to a human reviewer.
- You may want the process to halt automatically after a set number of retries.
These aren't the kinds of choices you necessarily want left to the model's improvisation on each run. Inside a loop, there's no way to guarantee the model will make the same call every time.
A graph lets you bake those constraints directly into the workflow's structure. The model still gets to reason within each individual node, but the surrounding system dictates where it's permitted to go next.
That's the key difference to hold onto. The goal isn't to strip reasoning out of the agent — it's to decide deliberately where that reasoning should live and where deterministic orchestration is the better fit.
As you continue building out workflows that operate on structured financial data, a new question emerges.
Right now, our agent pulls documents and figures from various sources. But what happens when the underlying information carries connections that actually matter?
- Companies employ executives
- Those executives often serve on corporate boards
- One company may acquire another
- A regulatory filing might mention a different company entirely
- A single portfolio can include many companies
- Every company belongs to some industry sector
Up to this point, we've treated each piece of data as isolated. Yet the links shown above are hard to represent if your knowledge base is nothing more than a stack of standalone documents.
This brings us to another core concept: GraphRAG.
GraphRAG
Up to now, we've used graphs primarily to govern how the agent behaves. But graphs can serve a second purpose too:
organizing the knowledge itself.
In our running example, a conventional RAG setup might pull documents mentioning NVIDIA's earnings, forward guidance, revenue figures, margins, and how the market reacted.
That approach works fine when the answer lives mostly inside a handful of relevant documents. But financial questions aren't always that contained.
A meaningful answer often depends on linking together information scattered across several separate documents.
Now picture wanting to understand not just what NVIDIA reported, but how various pieces of that report relate to one another (which is exactly the situation we're dealing with).
That's precisely where a knowledge graph earns its keep.
Rather than storing knowledge purely as text chunks, we can model the important entities and the relationships between them:
NVIDIA ──→ produces ──→ GPUs
│
├──→ reports ──→ Earnings
│
├──→ depends on ──→ Suppliers
│
├──→ competes with ──→ AMD
│
└──→ operates in ──→ AI Infrastructure
The graph now captures connections that might never surface from reading any single document in isolation.
RAG Compared to GraphRAG
Standard RAG typically works by fetching relevant snippets and feeding them to the model as context. Here's a stripped-down view of that flow:
Question
↓
Retrieve relevant chunks
↓
LLM
↓
Answer
GraphRAG introduces an extra layer. The system can lean on entity relationships to figure out which information actually matters:
Question
↓
Identify entities
↓
Traverse relationships
↓
Retrieve relevant information
↓
LLM
↓
Answer
For our financial research agent, this becomes valuable whenever a question requires tying together multiple entities or documents at once.
Suppose the portfolio manager asks: what risks could hit NVIDIA if demand for AI infrastructure cools off?
Answering that well may require linking NVIDIA to its products, its customers, its suppliers, its competitors, broader market conditions, and risks it has already flagged in past filings.
A graph gives the retrieval system a structured path for exploring all those connections.
NVIDIA
/ | \
/ | \
Products Suppliers Competitors
| | |
↓ ↓ ↓
AI GPUs Supply Risk AMD
|
↓
AI Infrastructure
|
↓
Demand
From there, the model can reason over everything pulled in from those linked entities.
This doesn't imply GraphRAG always beats plain RAG. The extra structure pays off specifically when the relationships between pieces of information are central to the question being asked.
If the answer sits neatly inside a single earnings report, a conventional retrieval pipeline is probably sufficient.
If answering the question means pulling together information spread thin across many entities and sources, a graph-based setup starts looking a lot more appealing.
There's another distinction worth keeping straight here too: your workflow graph and your knowledge graph are two different things entirely.
The workflow graph answers the question of what the agent should do next. The knowledge graph answers the question of what connects to what within the data you're working with.
In our system, both can coexist side by side:
WORKFLOW GRAPH:
Question
↓
Retrieve
↓
Analyze
↓
Write
↓
Check
while, underneath, the retrieval layer operates on:
KNOWLEDGE GRAPH:
NVIDIA
├── Products
├── Suppliers
├── Competitors
├── Executives
├── Filings
└── Industry
Notice the split in responsibility: one structure governs execution, while the other organizes knowledge and the relationships within it.
Once these two ideas start reinforcing each other, the financial research agent becomes considerably more capable.
- The workflow determines how the research gets carried out.
- The knowledge graph determines what pieces of information are connected.
Naturally, this raises a follow-up question: if graphs unlock this much control, should every workflow be built as one?
Not necessarily.
In plenty of cases, a straightforward agent loop is all a problem actually calls for.
So rather than converting every AI workflow into a graph by default, it's worth comparing the two approaches directly and figuring out when the added complexity of graph engineering genuinely pays off.
It's worth remembering that graphs hand you more control, but that control comes bundled with extra work: you now have to design and maintain that structure yourself.
If the underlying task is genuinely simple, wrapping it in a graph can actually make the system harder to follow without buying you much in return.
Go back to the financial research agent example. Say the user asks something like: summarize NVIDIA's latest earnings report.
That's a narrow, self-contained request.
You could handle it by pulling the relevant report and handing it to the model to produce a summary:
Question
↓
Retrieve Report
↓
Summarize
↓
Answer
There's no real branching and no complicated logic to manage. A plain RAG pipeline or a basic agent loop would handle this just fine.
Now compare that with a broader ask, where the user wants to understand what drove the post-earnings drop in the stock price, wants that outcome measured against what analysts had projected, wants a list of risks worth tracking going forward, and wants a chance to sign off on the findings before they get folded into a portfolio report.
That's an entirely different kind of problem.
This version involves several kinds of research, pulls from different sources, needs validation, may require multiple attempts, and includes a human-review step.
The workflow now looks closer to this:
Question
↓
Understand
↓
┌──────────┼──────────┐
↓ ↓ ↓
Filings Earnings Market
↓ ↓ ↓
└──────────┼──────────┘
↓
Analyze
↓
Write
↓
Check
↙ ↓ ↘
Search Rewrite Human
↓ ↓ Review
└───────┴──────┘
↓
Send
At this level of complexity, spelling out the workflow explicitly starts paying off.
So, When an Agent Loop Is Enough?
An agent loop tends to be the right call when the model benefits from some freedom to choose which tool to reach for next.
For instance:
Question
↓
LLM decides what to do
↓
Tool
↓
LLM decides what to do next
↓
Tool
↓
Answer
When the task is exploratory and you can't predict the number of steps in advance, that flexibility is genuinely valuable.
The agent might decide it needs to check an earnings transcript, then pull a specific metric, then look for more context. You don't have to map out every possible path ahead of time.
When a Graph Starts Making More Sense?
A graph earns its keep once the workflow has rules that actually matter.
For the financial research system, those rules might look like:
Retrieve evidence
↓
Run analysis
↓
Generate draft
↓
Verify claims
↓
Human review
↓
Publish
These are workflow-level constraints, and a graph lets you encode them directly instead of hoping the model infers them on its own.
The Tradeoff
A graph buys you control, but it also means taking on more architecture.
You now have to think through:
- how state is structured
- routing logic
- what happens when something fails
- retry behavior
- persistence
- observability
- testing
- versioning
None of that is inherently bad — it just means the graph needs to justify the overhead it introduces.
For the NVIDIA research agent, building out the entire graph up front just because graphs are interesting wouldn't make sense.
Instead, the extra structure should be introduced only as the workflow actually demands it:
- Start simple.
- Add branching once branching is genuinely needed.
- Add parallel execution once tasks can truly run independently of each other.
- Add checkpoints once the workflow needs to pause or recover from an interruption.
- Add a human-review step once the stakes justify the extra friction.
- Bring in GraphRAG once the relationships inside the knowledge itself start to matter.
That way, the graph exists because the problem requires it, not because it's available.
Final Thoughts
This is probably the central lesson from working through this design.
A graph isn't there to make an AI system look sophisticated. It exists to make the workflow easier to reason about and control.
The financial research agent built up over this discussion can now branch, retry, pause, loop in a human reviewer, and even lean on relationships between pieces of knowledge when it's useful to do so.
Still, none of this means every system needs a graph. Sometimes a plain RAG pipeline is the right amount of machinery. Sometimes an agent loop covers everything the problem asks for.
The real skill is recognizing the point at which a problem has grown complicated enough that a graph becomes worth the investment.