Module 4 of 10, lesson 1 of 5
Reasoning loops and architectures
Choose between ReAct and planning up front, then between one agent and a more complex setup.
Two ways to reason
ReAct alternates thought, action and observation. The agent decides each step after seeing the result of the previous one. It adapts well to surprises, at the cost of many model calls.
ReWOO plans the whole approach first, then runs the tools, then writes the synthesis. You can review the plan before anything happens, and token use drops. In exchange, the agent copes less well if an intermediate result contradicts the plan.
| ReAct | ReWOO | |
|---|---|---|
| Decision | At each step | Up front |
| Cost | Higher | Lower |
| Surprises | Handled well | Handled less well |
| Human control | During execution | On the plan, before acting |
Four setups
- Single agent: simple, cheap, easy to debug. It saturates on broad tasks.
- Vertical: one agent directs the others. Roles are clear, but the lead can slow down or block the whole system.
- Horizontal: peers with no central authority. Good for parallel work and exploration, expensive to coordinate.
- Hybrid: leadership changes with the phase. Flexible, but hard to design and control.
Always bound the loop
An agent that can’t interpret its results may repeat the same actions forever. Set a maximum number of steps, a budget, and a stop condition that hands over to a human.
Start with one agent, and add complexity only when you hit a measured limit.
Worked example: Spotting a stuck agent
A step limit stops the loop late. Comparing recent calls stops it as soon as the agent repeats itself.
function isStuck(calls, window = 3) {
if (calls.length < window) return false;
const recent = calls.slice(-window).map((c) => JSON.stringify(c));
return new Set(recent).size === 1;
}
const lookup = { tool: 'get_order', input: { id: 4512 } };
isStuck([lookup, lookup, lookup]);
true
Three identical calls mean the same result three times. The agent has nothing new to work with, so hand over to a person instead of paying for more steps.
Try it in the editor
const sameCall = (a, b) => a.name === b.name && a.input === b.input;async function runAgent({ model, tools, prompt, maxSteps = 20 }) { const messages = [{ role: 'user', content: prompt }]; let previous = null; let repeats = 0; for (let step = 0; step < maxSteps; step += 1) { const response = await model.create({ messages });