# The Workflow Mental Model: Nodes, Edges and State — OpenAI Agent Builder Workflows

Source: https://www.skillbyai.com/en/openai-agent-builder/i-model

> Every workflow is a graph that moves a state through steps.

## Graph plus state

A workflow is a **directed graph**. **Nodes** do work: call an agent, run a tool, check a guardrail, branch, loop, wait for approval, or reshape data. **Edges** decide what runs next. A shared **state** (input variables, intermediate results, flags) flows through the graph; nodes read from it and write to it. Thinking this way helps you design clean flows: name the state fields, decide which node owns each one, and make every path end at an end node with a well-defined output.

## A workflow as a small Python state machine, run

I ran this with plain Python 3. It is a small model of the workflow idea, not Agent Builder itself, and no model is called. Four requests travel through classify, route, an optional approval step and an answer step. A small refund goes straight to the answer, a 300 refund passes approval, and a 900 refund is rejected at approval and ends without a reply.

```python
# A plain-Python model of a canvas workflow: nodes read and write a shared state.
def classify(state):
    text = state["input"].lower()
    state["category"] = "refund" if "refund" in text else "question"
    return "route"
def route(state):                      # if/else node
    return "approval" if state["category"] == "refund" and state["amount"] > 100 else "answer"
def approval(state):                   # user approval node
    state["approved"] = state["amount"] <= 500
    return "answer" if state["approved"] else "end"
def answer(state):                     # agent node (stubbed reply)
    state["reply"] = f"Handled {state['category']} for {state['amount']}"
    return "end"
nodes = {"classify": classify, "route": route, "approval": approval, "answer": answer}

def run(state):
    node, path = "classify", []
    while node != "end":
        path.append(node)
        node = nodes[node](state)
    return " -> ".join(path + ["end"]), state.get("reply", "rejected")

for s in [{"input": "How do I export data?", "amount": 0},
          {"input": "Refund please", "amount": 40},
          {"input": "Refund please", "amount": 300},
          {"input": "Refund please", "amount": 900}]:
    print(run(dict(s)))
```

Output:

```
('classify -> route -> answer -> end', 'Handled question for 0')
('classify -> route -> answer -> end', 'Handled refund for 40')
('classify -> route -> approval -> answer -> end', 'Handled refund for 300')
('classify -> route -> approval -> end', 'rejected')
```

## Draw the state table first

List each state field, its type, which node writes it and which nodes read it before building anything.

**Quiz:** In a workflow graph, what do edges represent?

- [ ] Token prices
- [ ] The model's weights
- [ ] The user's password
- [x] Which node runs next

*Answer:* Which node runs next. Nodes do work; edges decide the path.
