PTENES
Skip to content
MODULE 4.1

🧩 Nodes, edges, and state

You already know what a graph is. Now comes the practical part: how to design each at the, where to put the decision on the edge, and exactly what travels from one step to the next. This is where theory becomes a system that actually runs.

6
Topics
40
Minutes
Intermediate
Level
Practice
Type
Progress in this module
0%0 of 6
1

🧱 Treat the node as a unit of work

A node can be an AI agent, a model call, a piece of regular code, or even a human decision in the middle of the workflow. The question you need to ask before drawing any node is simple: does this actually need AI? The answer isn’t always yes.

A deterministic in the — one if, a query to a database, a script that only formats data—it’s cheaper, faster, and more reliable than throwing everything at the model. The rule the industry has converged on: code handles predictable routing, while the model handles what requires interpretation or judgment.

🆕 New here? Two words before you continue

  • Deterministic node: a step that always produces the same result for the same input—with no AI model in the middle. A if valor > 100 is deterministic.
  • Orchestrator: the node (or agent) that decides where to send the next task — the graph’s “manager,” not the one that performs the task itself.
at the model tools permissions instructions cost cap if approved state: resultado_valido=true if rejected state: motivo_erro filled in the configuration lives inside the node; the decision lives on the edge that leaves it

What to look at: the five cyan boxes inside the node. Each one can be different in each node of your graph — which is why they stay within in the box, not scattered throughout the system. The two outgoing arrows already show what topic 2 will unpack: the condition lives there, on the edge.

✓ Good candidate for a non-deterministic approach

  • ✓Validate email format — a regex is enough; no judgment needed
  • ✓Checking a balance through an API — direct call, exact response
  • ✓Route by a category already marked in the database — a switch

✗ Do you really need a model

  • ✗Judge whether a text is offensive — requires interpreting context
  • ✗Summarize a long document in natural language
  • ✗Decide which of the three ambiguous responses the client meant

Key concepts

Node = unit

Agent, code, human, or model

Deterministic

Cheaper and more reliable

Code routes

Model judges

Not everything is AI

Industry rule of thumb

2

🔀 Put the decision on the edge

A conditional edge — the one that carries an "if" — and where routing lives: "if approved, continue; if rejected, go back." That’s exactly what separates a graph from a queue. If all your edges are unconditional (they always go to the same next place), you haven’t written a graph — you’ve written a pipeline disguised.

💡 Quick test: is your workflow a graph or a pipeline?

Look at each edge in your diagram and ask: "does this line exist only because a specific condition was met, or will it always be followed?" If the answer is always "it always follows," you have a sequence — useful, but not really a graph.

  • •Pipeline: step 1 → step 2 → step 3, always in that order, without exception
  • •Graph: step 1 → (if X) step 2, (if Y) step 3, (if neither X nor Y) go back to step 1
writer validator publish if approved if rejected (returns with error_reason) two conditional edges leaving the same node = it’s already a graph

What to look at: the two arrows leaving the validator go to different places, depending on a condition. This branching — not the number of nodes — is what makes this diagram a graph. If only the green arrow existed, it would just be a three-step pipeline.

Key concepts

Conditional edge

Loads an “if”

Routing

Lives on the edge, not the node

Pipeline

Sequence without a condition

Quick test

"Does this edge always follow?"

3

📦 Define the state that gets passed along

Exactly what passes from one node to the next? This question seems small, but it defines half the success of your graph. The state schema — the agreed format for what travels along the edges—it's a contract, and contracts are written, not improvised.

Passing the entire conversation from one node to another seems safe, but cancels out the benefit of clean context: the next node sees again how the work was done, not just what was produced — and this fills its context with noise. Passing too little makes the next node work blind, without the data it needed.

1

Pass too much: the entire conversation

Full history of messages, intermediate reasoning, and previous attempts.

The next node spends tokens reading the “how” when it only needed the “what.” Cluttered context, higher cost.

2

Pass too little: just a loose text

A "result" field with no status, no source, and no confidence metadata.

The next node doesn’t know whether it was validated, who generated it, or whether it can be trusted. It works blind.

3

The middle ground: explicit state schema

Named fields, with a type and an owner: resultado, status, origem.

Each node reads only the fields it needs and writes the fields it’s responsible for filling in. That’s a contract.

💡 Practical tip

Write the state schema before before writing the first node. If you can’t list the fields that will travel, you don’t understand the flow well enough to code it yet — and you’ll end up dumping the entire conversation because it’s easier than thinking.

Key concepts

State schema

Agreed-upon state format

Contract

If it writes, it isn't improvised

Too much

Cancels clean context

Too little

That works blind

4

⚙️ Configure Each Node Separately

Model, tools, permissions, instructions, and cost cap (the maximum limit that node can spend before it’s interrupted) can differ for each node. A strong model for the hard step and a cheap one for the easy step; a writing tool only on the node that writes; internet access only for whoever researches.

This per-node configuration is what gives the graph real economic value—and where the cost truly drops. A system that uses the same expensive model at every step just because “it’s simpler to configure once” is burning money on steps that a cheaper model could handle just as well.

Agent system diagram: the user makes a request to a central orchestrator, which connects to a planner, a researcher, an executor with its own tools, and a validator that sends feedback back to the orchestrator. There is also a memory block with context and history connected to the orchestrator, and the final result is delivered to the user. A note indicates that each node can be an agent or a resource.
What to look at: not every box in this diagram is an agent. "Memory" and "tools" are nodes that are resources, not agents—they don’t make decisions; they only store or execute. And notice the validator’s arrow pointing back to the orchestrator: that conditional return edge is what makes this design a real graph, rather than a linear pipeline of boxes in a queue.

📊 What to configure, node by node

  • Model — the stronger (more expensive) one only where the decision is truly difficult
  • Tools — writing, code execution, internet access: enabled only for those who need it
  • Permissions — who can change sensitive data, who can only read it
  • Cost cap — a token/dollar limit per node, so no step can exceed the budget on its own

Key concepts

Cost cap

Maximum per node

Config per node

Not one global config

Economic value

And where the cost drops

Focused tool

Only those who need it receive it

5

🚫 Avoid the degenerate graph

A single-node graph with all the tools and all the instructions, running until it runs out: that’s a reinvented loop, and the graph structure isn’t doing anything for you. You paid the complexity cost of "thinking in graphs" and didn’t reap any of the benefits — per-node configuration, differentiated costs, conditional routing.

Practical test: if you can’t give two nodes in your diagram different configurations, you probably didn’t need two nodes. Merge them. A degenerate graph like this isn’t “wrong”—it’s just not a graph; it’s a loop with a pretty drawing on top.

loop loop state explicit graph + + = the graph is a composition of loops with explicit state — not a replacement

What to look at: the equation doesn’t have "fewer loops" anywhere—it has loop more loop more a new ingredient: the explicit state that travels between them (what you saw in topic 3). A graph with just one node, without this composition, is only a loop pretending to be a graph.

⚠️ Warning: complexity without benefit

If you designed five nodes but they all use the same model, the same tools, and no edge has a condition, you gained nothing from the design—you just paid the cost of maintaining five configuration files instead of one. Simplify back to one loop, or add the differentiation that was missing.

Key concepts

Degenerate graph

A node, everything allowed

Practical test

Different configs or combine

Composition

Graph = loops + state

Not a replacement

Graph doesn’t kill the loop

6

📏 Choose the right granularity (and write your grafo.json)

Too large and the graph doesn't help at all—you’re back to the black box of a orchestrator doing everything alone. When it’s too small, you pay coordination overhead on top of trivial work — more edges, more state to pass around, more chances for errors, with no benefit.

Practical rule: one node per change in context, tool, or responsibility. If two steps use the same context and the same tools, they're probably just one node. If a step changes from "writing" to "validating," that's a change in responsibility—two nodes.

✓ Split into two nodes when

  • ✓One step writes, the other validates — different responsibilities
  • ✓One uses an expensive model, the other only needs a script
  • ✓One needs internet access, the other can’t have it

✗ Merge into a single node when

  • ✗Both steps use exactly the same model and tools
  • ✗You only separated them to "keep things organized," with no real difference
  • ✗The edge between them never had any condition

🧪 Practical example: grafo.json with per-node configuration

Objective: evolve the graph skeleton introduced in module 1.3, now with config per node (model, tools, cost cap) and conditional edges quando. Copy and paste into a file grafo.json, and read it with any script.

{
  "nos": {
    "escritor": {
      "modelo": "<modelo-medio>",
      "ferramentas": ["escrever_arquivo"],
      "teto_custo_usd": 0.05
    },
    "validador": {
      "modelo": "<modelo-forte>",
      "ferramentas": [],
      "teto_custo_usd": 0.02
    },
    "formatador": {
      "modelo": null,
      "ferramentas": ["script_deterministico"],
      "teto_custo_usd": 0.00
    }
  },
  "arestas": [
    { "de": "escritor", "para": "validador", "quando": "sempre" },
    { "de": "validador", "para": "formatador", "quando": "resultado_valido == true" },
    { "de": "validador", "para": "escritor", "quando": "resultado_valido == false" }
  ]
}

How to verify: check that escritor e validador there are models different ({'<'}medium-strength model{'>'} vs. {'<'}strong model{'>'}) and that formatador doesn't even use a model—it's a pure deterministic node. If two of your nodes had the same config, the test from topic 5 applies: combine them; you didn't need two.

Now swap it for yours: replace <modelo-medio> e <modelo-forte> using the actual names of your models, and the conditions in quando according to the business rules of your workflow. If a node is left with no exit condition that differs from the others, review the granularity.

Quick check (nothing is blocked): You have two nodes that use the same model, the same tools, and the same unconditional outgoing edge. What should you do?

Key concepts

Granularity

Neither large nor microscopic

Practical rule

A node per context change

when

Explicit condition on the edge

Config per node

Model, tools, ceiling

📌 Module Summary

✓
Node = unit of work — an agent, model, code, or human. Not everything needs AI.
✓
The decision lives on the edge — a conditional edge is what separates a graph from a pipeline.
✓
State is a contract — not the entire conversation, and not too little. An explicit schema.
✓
Config per node — different models, tools, and cost limits are where the economic value lies.
✓
Avoid the degenerate case — one node with everything enabled and a loop disguised as a graph.
✓
The right granularity — one node per change in context, tool, or responsibility.

Next Module:

4.2 — Org graph vs. work graph: how the agent graph reflects (or doesn’t reflect) your company’s people graph.