Tutorial: Flow fundamentals
Level 3 – Lesson 2 of 5 – Understand flows, steps, and transitions for structured multi-turn interactions.
Flows enforce a specific sequence of steps – the step prompt stays anchored at the end of conversation history, preventing the model from improvising and keeping it focused on collecting, validating, and acting on information reliably.
Use flows when order matters: collecting a booking reference, verifying identity, routing based on input. Without flows, the LLM guesses the sequence, which leads to inconsistent outcomes.
For reference documentation on flows, see the Flows overview. This lesson focuses on how flows work and when to use them.
When to use flows vs other tools
If the interaction takes more than 2–3 turns and the steps must happen in a specific order, you probably need a flow.
How flows work
A flow is a sequence of steps. Each step contains:
- A prompt – instructions the model follows for this step
- Functions – scoped to this step only, used for transitions and actions
- A transition – how the flow moves to the next step (or exits)
Enter the flow
A start function calls conv.goto_flow("flow_name"). This can be triggered from agent behavior, a knowledge topic, or another function.
Step activates
The step prompt is injected as a system message at the end of the conversation history. The model follows these instructions.
The persistent prompt
The step prompt is always the last message in the conversation history. This is the most important thing to understand about flows.
Unlike content returned from a function (which appears at a specific point in history and becomes less relevant as more turns happen), the step prompt is re-injected on every turn. It cannot be “forgotten” by the model.
Function content
Flow step
The function result moves further back in history with each turn.
This persistent control is why flows are more reliable than prompting alone for multi-turn interactions.
Check your understanding
Why is the flow step prompt more persistent than content returned from a function?
- It uses a special LLM mode that locks behavior
- It is always re-injected as the last message in conversation history
- It overrides all other prompting
- It is stored in a separate memory system
Answer: It is always re-injected as the last message in conversation history
The step prompt is always appended as the last system message. This means it stays relevant regardless of how many turns pass – unlike function content, which moves further back in history over time.
Creating and entering a flow
There are two ways to create a flow:
- Go to Flows and create one directly
- Create one from any behavior menu (e.g., inside a managed topic action)
When you create a flow, Agent Studio generates:
- The flow itself (with a start step)
- A corresponding start function that contains
conv.goto_flow("flow_name")
The start function is what triggers entry into the flow. You must expose it somewhere – in agent behavior, a knowledge topic, or another function. If a flow has no entry point, it exists but cannot be reached.
A common mistake: creating a flow but forgetting to expose the start function. The flow exists but is never entered because nothing triggers conv.goto_flow.
Step transitions
Each step shows only its own functions to the model. When the model calls a flow function, that function can:
- Save data (to
conv.state) - Call an API
- Move to the next step using
flow.goto_step("step_name") - Exit the flow using
conv.exit_flow()
When transitioning between steps:
- The previous step prompt is removed
- The new step prompt is injected
- Only the new step’s functions are visible
This means the model cannot skip ahead, look at future steps, or call functions from a previous step.
Check your understanding
You create a flow with three steps but the model skips step 2 and jumps to step 3. What is the most likely cause?
- Step 2’s prompt is too short for the model to act on
- Step 2 has no prompt defined
- A flow function in step 1 transitions directly to step 3 via goto_step
- The model can see all steps and chooses the most relevant one
Answer: A flow function in step 1 transitions directly to step 3 via goto_step
The model cannot see other steps – it only sees the current step prompt and its functions. If a step is skipped, the transition function must be routing directly past it. Open the flow function in step 1 and check whether its goto_step call jumps to step 3 instead of step 2.
To move from one flow step to the next, call: flow.______(“step_name”)
Answer: goto_step
What happens without transitions
If you tell the model to ask for a phone number but don’t define what happens next, the model improvises. It may start asking for names, emails, or other details based on its training patterns.
This is not a model failure – it is a design failure. You did not give it the next step.
Always define explicit transitions between steps. Never rely on the model to “know what to do next.”
Transition pitfalls
Neither conv.goto_flow nor flow.goto_step interrupt the execution of your function. If you have multiple conditions, be careful not to overwrite one transition with another.
Incorrect
Correct (return)
Correct (elif)
This is one of the most common bugs in flow functions. Always use explicit return statements or if/elif/else chains to prevent unintended transition overwrites.
Exiting a flow
When conv.exit_flow() is called:
- The step prompt disappears from conversation history
- The model returns to normal behavior (behavioral rules, knowledge, global functions)
- Any state saved during the flow persists in
conv.state
Try it yourself
Challenge: Design a two-step registration flow
Design a flow that collects a phone number and then a full name.
Plan:
- What is the start step prompt?
- What flow function transitions from step 1 to step 2?
- What does the second step prompt say?
- How does the flow exit?
Hint
Each step should have a clear prompt (one instruction) and a flow function that saves the collected value and transitions. The final function should call conv.exit_flow().
Example solution
Step 1 prompt: “Ask the user for the phone number we can contact them on. Once they provide it, call save_phone_number.”
Step 1 function (save_phone_number):
Step 2 prompt: “Ask the user for their full name. Once they provide it, call save_name.”
Step 2 function (save_name):
Check your understanding
After exiting a flow, what happens to values saved in conv.state during the flow?
- They are deleted when the flow exits
- They persist and remain accessible for the rest of the conversation
- They are only available if you re-enter the same flow
- They are moved to a separate flow-specific storage
Answer: They persist and remain accessible for the rest of the conversation
conv.state persists across the entire conversation – it is not scoped to the flow. Values saved during a flow (e.g., conv.state.phone_number) remain accessible after the flow exits, so later functions and topics can use them.

