Anti-patterns
This page collects common implementation mistakes that make agents harder to reason about, harder to maintain, or more likely to behave incorrectly at runtime.
The general rule is simple: keep prompts focused on conversation, keep Python focused on deterministic logic, and make control flow explicit.
Flow navigation¶
Flow functions must always advance the flow.
A flow function should never leave the agent sitting in the same logical place without a clear next step.
Avoid¶
- returning from a flow function without changing step or flow
- leaving navigation implicit
- assuming the model will somehow recover the flow state on its own
Prefer¶
flow.goto_step(...)- returning an explicit transition
- making the next state obvious in code
A stuck flow is usually a control-flow bug
If a flow function does not move the agent forward, the conversation can become stuck in an invalid or confusing state.
Metrics and logging¶
Metrics and logs should capture important events, not generate noise.
Avoid¶
- writing the same metric repeatedly in a loop
- emitting metrics every turn without a clear reason
- swallowing external API failures silently
Prefer¶
write_once=Truewhen an event should only be recorded once- logging meaningful outcomes around API calls and validation failures
- using
conv.log.info(...),conv.log.warning(...), andconv.log.error(...)to make important behavior visible
Good logging explains the shape of the call
Logs and metrics should help you understand what happened in the conversation, not bury you in repetitive trivia.
Logic in prompts vs code¶
Do not put deterministic branching logic into prompts or YAML instructions.
Prompts are for conversational behavior. Python is for comparisons, routing, validation, and state-driven decisions.
Wrong¶
Encoding branching logic in prompts, for example:
Right¶
Implement the check in Python and transition to the correct step or flow explicitly.
Why this matters¶
When branching logic is buried in prompts:
- behavior becomes harder to test
- routing becomes harder to debug
- the agent becomes more dependent on model interpretation for deterministic behavior
-
Prompts
Use prompts for collecting information, presenting information, and guiding conversational style.
-
Python
Use Python for comparisons, routing, validation, retries, and state-based decisions.
“Anything else?” and exiting flows¶
Do not create a dedicated “Anything else?” step just to wrap up a flow.
When the flow is finished, exit the flow and return the appropriate closing prompt there.
Avoid¶
- adding a special cleanup step whose only purpose is to ask whether the user needs anything else
- calling
conv.exit_flow()and then also navigating somewhere else
Wrong¶
or
In both cases, the navigation overrides the exit.
Right¶
Use one of these approaches:
- exit the flow and return the closing content
- navigate to another step or flow
Do not do both.
Exit and navigation are mutually exclusive
If you call conv.exit_flow() and then also transition elsewhere, the transition wins.
end_turn=False¶
end_turn=False is easy to misuse.
It should only be used when the agent speaks and then immediately performs another action in the same turn, without waiting for user input.
Wrong¶
Using end_turn: False after the agent asks a question and is waiting for a reply.
That produces awkward control flow, because the question should simply be part of the normal utterance.
Right¶
Use end_turn: False only when the agent must continue immediately, for example:
- the agent says something
- then immediately calls a function in the same turn
Example pattern:
If the user is expected to answer, put the full question in the utterance and let the turn end normally.
Quick reference¶
| Anti-pattern | Better approach |
|---|---|
| Flow function returns without navigation | Always call flow.goto_step(...) or return a transition |
| Metric written repeatedly in a loop | Use write_once=True where appropriate |
| Branching logic in prompts | Put routing logic in Python |
| Dedicated “Anything else?” step | Exit the flow and return the closing prompt directly |
conv.exit_flow() plus navigation |
Choose exit or transition, not both |
end_turn=False while waiting for a user answer |
Only use it when the agent continues immediately in the same turn |
Design principle¶
When in doubt:
- make control flow explicit
- keep prompts conversational
- keep code deterministic
- prefer simple, testable paths over clever prompt tricks