# Set State and Transform Nodes — OpenAI Agent Builder Workflows

Source: https://www.skillbyai.com/en/openai-agent-builder/d-state

> Update state deliberately and reshape outputs before use.

## Small, explicit updates

Data nodes such as **set state** and **transform** update workflow variables and reshape outputs (rename fields, convert types, pick a subset) without a model call. Use them to keep agent nodes simple: the agent produces a structured result, a transform turns it into exactly what the next node needs, and set state records it. Prefer creating a new state value over silently mutating many fields, and keep a short history of key decisions for debugging. Product details such as node names and menus change; check the current OpenAI documentation.

## Move clean data between nodes

Workflows stay understandable when data is reshaped explicitly and state updates are deliberate.

![Three ideas: set state, transform, templating.](assets/figures/openai-agent-builder/section-4-map.svg) — Figure 4.1 — Set state, transform and templating.

## Updating state and transforming an output, 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. A set-state step upgrades the customer tier and increments attempts; a transform converts an agent's raw output (uppercase category, priority as text) into a clean record that is appended to history. The original state is left unchanged.

```python
import copy
state = {"customer_tier": "standard", "attempts": 0, "history": []}
def set_state(state, **updates):            # like a "set state" node: returns a new state
    new = copy.deepcopy(state); new.update(updates); return new
def transform(raw):                         # like a "transform" node: reshape an agent output
    return {"category": raw["cat"].lower(), "priority": int(raw["prio"])}
s1 = set_state(state, customer_tier="gold", attempts=state["attempts"] + 1)
out = transform({"cat": "BILLING", "prio": "2"})
s2 = set_state(s1, history=s1["history"] + [out])
print("before:", state)
print("after :", s2)
```

Output:

```
before: {'customer_tier': 'standard', 'attempts': 0, 'history': []}
after : {'customer_tier': 'gold', 'attempts': 1, 'history': [{'category': 'billing', 'priority': 2}]}
```

## Convert types at the boundary

Turn strings into numbers and normalise case in one transform step, so every later condition can trust the types.

**Quiz:** What is a transform node good for?

- [ ] Generating images
- [ ] Training the model
- [ ] Hosting the UI
- [x] Reshaping data between nodes without a model call

*Answer:* Reshaping data between nodes without a model call. Deterministic reshaping is cheaper and more reliable than asking a model.
