Skip to lesson

NVIDIANVIDIA-Certified Professional: Agentic AI2026-101.6 Apply logic trees, prompt chains, and stateful orchestration for multi-step reasoning.

Bound adaptive work inside explicit state graphs

Completed by the knowledge check

Learning objective

Model workflows as state graphs and choose predetermined versus adaptive control

Core idea

A state graph makes three things explicit: the information describing execution, the operations that update it, and the transitions that select what runs next. The presence of an LLM does not determine whether control is adaptive. The deciding question is whether code fixes the path or the model selects actions from observations.

Use predetermined control for known dependencies and adaptive control where the next useful operation cannot be selected beforehand. Keep both inside an execution model with defined state updates and terminal outcomes. Checkpoint persistence and safe resumption belong to 5.4.2; here the decision is the graph those checkpoints would preserve.

How it works

Separate state, work, and transitions

In Python LangGraph, StateGraph(State) defines a graph over a state schema. Nodes perform operations and return state updates. add_edge() defines fixed transitions, while add_conditional_edges() uses a routing function to select destinations from state. START and END identify entry and completion boundaries. Call compile() before invoking the graph; compilation performs basic structural checks, including checks for orphaned nodes.

Define state according to the decisions nodes must make. A research assistant might need the question, retrieved findings, unresolved questions, a draft, and an iteration counter. These are application-defined fields, not built-in LangGraph names. Keep a result separate from the field describing whether more work is required. Otherwise, the presence of a fluent draft can be mistaken for successful completion.

LangGraph accepts TypedDict schemas and also supports Pydantic BaseModel state for recursive data validation. The documentation notes a performance cost for Pydantic compared with TypedDict or dataclasses. Select validation where it protects a meaningful boundary; do not treat a Python type declaration alone as proof that a model-generated update has passed runtime checks. See 1.6.1 for typed intermediate results.

A graph state is an execution representation. It is not automatically the same thing as the prompt the model reads or the retained knowledge a later task should retrieve. Pass each node the fields it needs and construct model inputs deliberately. See 5.4.1 for the distinction between execution state, conversation memory, and retained task knowledge.

Choose how updates combine

Each state key has a reducer that determines how updates become the next state. Without an explicit reducer, an update replaces that key’s value. Nodes can return partial updates rather than reconstruct the whole state.

Use replacement for fields such as the selected route or accepted draft when only one value should govern the next step. Use an accumulating reducer when the state should preserve multiple findings. LangGraph documents Annotated[list, operator.add] as a list-accumulation pattern. The reducer expresses an execution decision: returning another list appends it instead of replacing the existing list.

That choice also determines failure modes. An accumulating list can retain stale findings after a revision, and returning an empty list does not clear a merging reducer’s existing content. LangGraph’s Overwrite type bypasses the reducer when explicit replacement is required. Prefer a field whose update semantics match its purpose rather than compensating for the wrong reducer in every prompt.

Through the reducer, an update replaces a key’s value or appends to it, unless Overwrite bypasses the reducer.

Through the reducer, an update replaces a key's value or appends to it, unless Overwrite bypasses the reducerStarts at a node's partial updates. It passes through the state key's reducer, where without an explicit reducer it replaces that key's value and with an accumulating reducer it appends instead of replacing, unless Overwrite bypasses the reducer. All three paths join at the next state.without explicit reduceraccumulatingOverwritepartial updatesstate key'sreducerreplaces thatkey's valueappends instead ofreplacingbypasses thereducernext state

Locate the adaptive decision

LangChain distinguishes workflows with predetermined code paths from agents that dynamically determine their processes and tool use. A conditional edge can still be predetermined control: code checking whether all required fields exist is a fixed rule even when its input came from a model. Conversely, an agent node that chooses its next tool from observations introduces adaptive behavior inside an otherwise fixed graph.

Compare control choices at the boundary where they differ:

ControlDeciding conditionMechanismCost or failure mode
Fixed sequenceEvery task has the same dependenciesNeMo sequential_executor and tool_listSerial latency; no dynamic branch selection
Predetermined branchingKnown predicates determine the pathadd_conditional_edges() with code predicatesRules must cover incomplete and exceptional state
Adaptive loopObservations determine the next useful actionModel/tool node cycle with conditional terminationVariable tokens, latency, and repeated work
Hybrid graphMost work is fixed, but one region needs explorationFixed outer edges around a bounded adaptive subflowBoth outer invariants and inner stopping rules need owners

The branch classifier in 1.6.2 selects a handler. A state graph additionally specifies what information survives that choice, how results update it, and whether execution returns for another decision. Do not infer the latter behaviors merely from a router’s presence.

Define termination before adding a loop

An adaptive loop needs an accepted outcome and an exhaustion outcome. For example, a code predicate can route to END after all required source checks pass, or to an application-defined incomplete-result node after the iteration allowance is consumed. Increasing the allowance does not repair an acceptance predicate that can never become true.

LangGraph’s recursion_limit limits graph super-steps, not elapsed seconds or total tool calls. Parallel nodes can occupy the same super-step. Starting in LangGraph 1.0.6, the default limit is 1,000 super-steps; a runtime override belongs in the config dictionary passed to invoke or stream. Exceeding the limit raises GraphRecursionError. Use it as a backstop, and use the RemainingSteps managed value when the graph needs to take a completion path before exhausting that backstop. The task’s business counter and the graph’s execution limit answer different questions.

Avoid mixing competing transition mechanisms. LangGraph’s Command can update state and select a destination with goto, but its dynamic edges do not cancel static edges already defined on the same node. Defining both can run both destinations. Use one routing approach per node so an apparently exclusive completion path does not also launch another work step.

Connect the graph to NVIDIA execution

NVIDIA NeMo Agent Toolkit documents workflow._type: langgraph_wrapper for existing LangGraph agents. Its required graph parameter identifies the graph in module_path:variable_name form. Optional dependencies adds directories to the Python path, and env supplies an environment file or dictionary. The integration’s prerequisite package is nvidia-nat-langchain.

The wrapper adds the toolkit’s configuration, observability, and evaluation integration around the graph. For configurable components, NVIDIA documents replacing hardcoded component initialization with retrieval through the NeMo Agent Toolkit builder. Wrapping a graph does not make its control choices predetermined; those choices remain in its nodes and transitions.

Architecture / decision scenario

A manufacturing firm’s research assistant compares supplier qualification documents. The delivery team has a 45-second per-request budget. A measured fixed extraction-and-draft path takes 15 seconds, while one additional search-and-review round takes 8 seconds. The procurement engineering owner must choose a fixed three-search sequence, an unrestricted agent, or fixed intake and output stages surrounding bounded exploration.

Two thirds of trial requests need one search; one third need three. Always running three spends two unnecessary searches on most requests. An unrestricted loop can exceed the deadline. The owner chooses the hybrid graph: intake establishes the required supplier fields, a research node updates findings, and a conditional edge checks unresolved fields and an application-defined three-round allowance.

At three rounds, the modeled path consumes 39 seconds, leaving 6 seconds within the budget. This is a planning estimate, not a graph-enforced deadline. The acceptance predicate routes complete findings to drafting; exhaustion routes missing fields to an explicit incomplete result. Findings accumulate with a reducer, while each accepted draft replaces its predecessor. The team exposes this graph through langgraph_wrapper, using LangGraph 1.0.6 or later without a runtime override. The 1,000-super-step default remains a backstop for runaway graph execution, and RemainingSteps counts against that limit. The application-owned three-round predicate stops normal research work much earlier. The team records complete versus exhausted outcomes separately before tuning the exploration allowance.

Common exam traps

  • Calling any graph containing an LLM adaptive.
  • Assuming TypedDict alone provides runtime validation.
  • Returning an empty list to clear a field with an accumulating reducer.
  • Treating recursion_limit as a wall-clock or tool-call limit.
  • Combining Command(goto=...) and a static edge while expecting exclusive routing.
  • Assuming a wrapper supplies missing acceptance or exhaustion conditions.

What to remember

Model state, updates, transitions, and termination separately. Predetermined control fixes the path or predicates; adaptive control delegates action selection from observations. Keep exploration bounded, choose reducers intentionally, and distinguish business completion from graph exhaustion.

Knowledge check

References