---
title: "Use a fixed workflow when the steps are · Agent Wranglers"
url: https://agentwranglers.se/playbook/ai-features/agents-in-products/workflow-before-agent
updated: 2026-10-20
licence: "All rights reserved"
---

# Use a fixed workflow when the steps are known

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Recommended
- Chapter: [Agents in products](https://agentwranglers.se/playbook/ai-features/agents-in-products)
- Rule: Build a fixed sequence of model calls and code when the steps of a task are known in advance. Use an agent loop, where the model picks the next tool, only when they are not.
- How: Write the task as steps. Some tasks always run the same steps, such as "classify the email, look up the order, draft a reply". Code those in order and call the model only inside steps that need it. A fixed workflow is cheaper, faster and easier to test than a loop. Keep the agent loop for open tasks, such as research across many sources. Give it the limits in this chapter and in [limit cost, steps and loops](https://agentwranglers.se/playbook/adversarial-testing/ai-agents-and-models/cost-and-loop-limits).
- Check: Each agent loop in the code has a decision note that lists the tasks it handles and why fixed steps could not. A search for agent loops finds none without a note.

Example:

```ts
// A fixed workflow: the model works inside steps, code decides the order.
export async function handleSupportEmail(email: Email, user: User) {
  const { intent } = await ai.generate({ promptId: 'classify-email', vars: { body: email.body }, schema: Intent, userId: user.id });
  if (intent === 'return') {
    const order = await orders.latestFor(user.id);
    return ai.generate({ promptId: 'draft-return-reply', vars: { body: email.body, order: JSON.stringify(order) }, schema: Draft, userId: user.id });
  }
  return routeToPerson(email);
}
```

```python
def handle_support_email(email: Email, user: User) -> Draft | None:
    intent = ai.generate("classify-email", {"body": email.body}, Intent, user.id).intent
    if intent == "return":
        order = orders.latest_for(user.id)
        return ai.generate("draft-return-reply", {"body": email.body, "order": order.model_dump_json()}, Draft, user.id)
    return route_to_person(email)
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers ai features playbook: https://agentwranglers.se/playbook/ai-features/agents-in-products/workflow-before-agent`.

- Next: [End every agent run with a known status](https://agentwranglers.se/playbook/ai-features/agents-in-products/agent-run-status)
- [Agents in products](https://agentwranglers.se/playbook/ai-features/agents-in-products)
