ReAct is the cycle that turns tool use into an agent: thought, action, observation, repeat. The model reasons about what to do, does one thing, sees what happened, and reasons again with that result in hand.
The loop is short:
const messages = [{ role: 'user', content: task }]
for (let step = 0; step < MAX_STEPS; step++) {
const response = await model({ messages, tools })
messages.push(response) // thought + action
// no action means it is answering
if (!response.toolCalls?.length) break
for (const call of response.toolCalls) {
const result = await runTool(call)
messages.push({ // observation
role: 'tool',
toolCallId: call.id,
content: result,
})
}
}Everything the agent has learned lives in messages, which is why the loop works and also why it degrades: the history *is* the state.
What a trace looks like
Thought: Tests fail on CI, not locally. Check the CI config.
Action: read_file(".github/workflows/test.yml")
Observation: node-version: 18
Thought: Local is Node 22. Check what the package requires.
Action: read_file("package.json")
Observation: "engines": { "node": ">=20" }
Thought: That is it. CI runs 18, the package needs 20+.Nothing here could have been planned up front. Step two only makes sense once step one has returned.
Where it is the right shape
When the path depends on what you find. Debugging, exploration, research, anything where the second move is a function of the first result. If you can write the steps down before starting, prompt chaining is cheaper and far easier to debug.
The costs
- Context grows every step. Each observation is appended forever, so long runs hit context rot. Truncate old observations, or write findings to a scratchpad and drop the raw output.
- Errors compound. A wrong conclusion at step three shapes steps four through twelve, and the loop rarely revisits it.
- Bound the steps.
MAX_STEPSis not optional. Without it a confused agent will keep paying for its own confusion.
Related terms
Tool use
Tool use lets a model do more than produce text: you expose named actions with typed inputs, and the model calls them to read data, run code, or reach the outside world. It is the bridge from talking to doing.
Read definition →PatternValidatedPlan-and-execute
Plan-and-execute writes the whole plan first, then carries out the steps. Separating the two makes the plan reviewable before any work happens, which is the entire point.
Read definition →ConceptAgents vs. workflows
A workflow follows a path you designed in advance; an agent decides its own path at run time by calling tools in a loop toward a goal. Knowing which one you actually need is the first context-engineering decision.
Read definition →PatternProvenPrompt chaining
Prompt chaining breaks a task into a fixed sequence of steps, feeding each step’s output into the next. It is the simplest workflow pattern, and it beats one giant prompt whenever a task has natural stages.
Read definition →