Transcript only (default)

ReAct (Autonomous Agent) diagramQuestion, Agent, Search, Calculator, Answer. Step captions follow the diagram.QuestionAgentSearchCalculatorAnswerReAct (Autonomous Agent) diagramQuestion, Agent, Search, Calculator, Answer. Step captions follow the diagram.QuestionAgentSearchCalculatorAnswer

All steps

"How many years apart were the Eiffel Tower and Golden Gate Bridge completed?"

A search fails and the agent adapts

Parts of this pattern
Question Input / output
The question to solve, e.g. how many years apart the Eiffel Tower and Golden Gate Bridge were completed.
Agent LLM call
Writes a Thought and one Action each turn, reading every Observation, until it gives a Final Answer.
Search Tool
The search tool: looks up facts such as the Eiffel Tower's completion year.
Calculator Tool
The calculator tool: does exact arithmetic on figures the agent has gathered, like 1937-1889.
Answer Input / output
The Final Answer the agent writes once it judges it has enough information.
Question → Agent
The question is inserted into the ReAct prompt, which sets the Thought/Action/Observation format.Question: How many years apart were the Eiffel Tower and Golden Gate Bridge completed?
Agent → Searchaction
A search action the agent chose after its Thought; generation stops before any Observation.Thought: I need the Eiffel Tower's completion year. Action: search[Eiffel Tower completion year]
Search → Agentobservation
The search result is appended to the transcript as an Observation for the next Thought.Observation: The Eiffel Tower was completed in 1889.
Agent → Calculatoraction
A calculator action, used once both dates are in the transcript.Thought: I have both dates; subtract. Action: calculator[1937-1889]
Calculator → Agentobservation
The computed number returns as an Observation the agent can use in its answer.Observation: 48
Agent → Answerfinal
When the agent writes Final Answer instead of an Action, the loop ends and the answer is returned.Thought: I now have enough information. Final Answer: 48 years apart (1889 vs 1937).

To-do notes

The agent keeps its plan and findings in an external notes file, rereading and updating it every turn, so progress survives a long run.

ReAct (Autonomous Agent): To-do notes diagramTask, Agent, Notes file, Search, Answer. Step captions follow the diagram.TaskAgentNotes fileto-do listSearchAnswerReAct (Autonomous Agent): To-do notes diagramTask, Agent, Notes file, Search, Answer. Step captions follow the diagram.TaskAgentNotes fileto-do listSearchAnswer

All steps
Parts of this pattern
Task Input / output
A long task, such as 'Compare the refund policies of our five main competitors'.
Agent LLM call
Reads its notes at the start of every turn, takes one action, and updates the notes as items are finished.
Notes file Memory
A to-do list with findings, kept outside the transcript and put back into the prompt on every turn.
Search Tool
The search tool: looks up each competitor's refund policy.
Answer Input / output
The Final Answer, written from the notes once every item is ticked off.
Task → Agent
The task enters the ReAct prompt, which also tells the agent to keep its plan in the notes file.Task: Compare the refund policies of our five main competitors.
Agent → Searchaction
The agent's next action, chosen from the first unticked item in its notes.Thought: Next on the list is Initech. Action: search[Initech refund policy]
Search → Agentobservation
The search result is appended to the transcript as an Observation.Observation: Initech refunds any purchase within 60 days.
Agent → Notes fileupdate
The agent ticks off the item and records the finding with its update_notes action.Action: update_notes[TODO: [x] Acme [x] Globex [x] Initech ... Found: Initech 60 days]
Notes file → Agentnotes
At the start of every turn the current notes go into the prompt, so the plan stays in view after old turns are dropped.TODO: [x] Acme [x] Globex [ ] Initech [ ] Umbrella [ ] Hooli. Found: Acme 30 days, Globex 14 days.
Agent → Answerfinal
When every item is ticked, the agent writes its Final Answer from the notes.Final Answer: Refund windows: Initech 60 days, Acme 30, Hooli 30, Globex 14, Umbrella none.

Context compaction

When the transcript nears the context limit, a summarizer compresses it and the loop continues in a fresh window that starts from the summary.

ReAct (Autonomous Agent): Context compaction diagramTask, Agent, Tools, Summarizer, Answer. Step captions follow the diagram.TaskAgentToolssearch_logs, read_fileSummarizerAnswerReAct (Autonomous Agent): Context compaction diagramTask, Agent, Tools, Summarizer, Answer. Step captions follow the diagram.TaskAgentToolssearch_logs,read_fileSummarizerAnswer

All steps
Parts of this pattern
Task Input / output
A long investigation, such as 'Find out why checkout requests started failing last night'.
Agent LLM call
Runs the Thought, Action, Observation loop; plain code checks the transcript size before each of its turns.
Tools Tool
The agent's tools: log search and file reading, whose large outputs grow the transcript quickly.
Summarizer LLM call
Compresses the transcript into the goal, decisions, facts found and next step when it nears the context limit.
Answer Input / output
The Final Answer the agent writes once it has found the cause.
Task → Agent
The task enters the ReAct prompt and starts the first context window.Task: Find out why checkout requests started failing last night.
Agent → Toolsaction
Each turn's tool call, as in plain ReAct.Action: search_logs[service=checkout level=error since=22:00]
Tools → Agentobservation
Tool output is appended as an Observation; log searches and file reads make it grow fast.Observation: 1,204 lines: PaymentError: invalid merchant key (first at 22:14)
Agent → Summarizerhistory
When the transcript passes the token threshold, the history, except the last few turns, goes to the summarizer instead of to the next turn.Transcript at 152k of 200k tokens: 37 turns of log searches and file reads.
Summarizer → Agentsummary
The summary starts a fresh window, followed by the last few turns verbatim; the loop resumes from there.Progress so far: errors began at 22:14, after deploy 4512. Ruled out the database and the cache. Next: diff the payments config.
Agent → Answerfinal
When the agent writes a Final Answer, the loop ends.Final Answer: Deploy 4512 rotated the merchant key in config but not in the vault; checkout has failed since 22:14.

← → neighboursesc atlas

Agent Loops

ReAct (Autonomous Agent)

Also known as Reason+Act · Agent loop · Autonomous agent

Alternate Thought, Action (tool call) and Observation until the model decides it is done.

Transcript only: Introduced by Yao et al. (2022) · Princeton University and Google Research (Brain team)

Published at ICLR 2023. The Thought, Action, Observation loop it introduced is the basis of most tool-using agents.

To-do notes: Popularized by Anthropic Applied AI team (2025) · Anthropic

Described as structured note-taking in 'Effective context engineering for AI agents' (September 2025), a technique for long-horizon tasks.

Context compaction: Popularized by Anthropic Applied AI team (2025) · Anthropic

Described as compaction in 'Effective context engineering for AI agents' (September 2025), a technique for long-horizon tasks.

Measured over one run

Transcript only

Nodes
5. Boxes in the diagram: models, tools, stores, people and plain code.
LLM calls
4. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
Tool calls
3. Messages sent to a tool node in the first scenario.
Steps
5. Steps in the first scenario, with repeated steps counted every time they run.
Scenarios
2. Distinct example runs you can switch between on the diagram.
Loop
no. Whether the flow cycles back on itself until a condition is met.
Parallel
no. Whether two or more messages are in flight at the same time.
Branch
no. Whether the flow takes one path out of several, chosen at run time.
Human in the loop
no. Whether a person appears as a node, to approve, correct or answer.
Autonomy
high. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
Cost
high. Relative token spend per request.
Latency
high. Relative wall-clock time per request.

To-do notes

Nodes
5. Boxes in the diagram: models, tools, stores, people and plain code.
LLM calls
2. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
Tool calls
1. Messages sent to a tool node in the first scenario.
Steps
5. Steps in the first scenario, with repeated steps counted every time they run.
Scenarios
1. Distinct example runs you can switch between on the diagram.
Loop
no. Whether the flow cycles back on itself until a condition is met.
Parallel
no. Whether two or more messages are in flight at the same time.
Branch
no. Whether the flow takes one path out of several, chosen at run time.
Human in the loop
no. Whether a person appears as a node, to approve, correct or answer.
Autonomy
high. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
Cost
high. Relative token spend per request.
Latency
high. Relative wall-clock time per request.

Context compaction

Nodes
5. Boxes in the diagram: models, tools, stores, people and plain code.
LLM calls
5. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
Tool calls
3. Messages sent to a tool node in the first scenario.
Steps
6. Steps in the first scenario, with repeated steps counted every time they run.
Scenarios
1. Distinct example runs you can switch between on the diagram.
Loop
yes. Whether the flow cycles back on itself until a condition is met.
Parallel
no. Whether two or more messages are in flight at the same time.
Branch
no. Whether the flow takes one path out of several, chosen at run time.
Human in the loop
no. Whether a person appears as a node, to approve, correct or answer.
Autonomy
high. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
Cost
high. Relative token spend per request.
Latency
high. Relative wall-clock time per request.

Counted from the first scenario's timeline when the site is built.

Problem

Some tasks cannot be planned in advance because the next step depends on what the last one revealed. To answer “how many years apart were the Eiffel Tower and the Golden Gate Bridge completed?”, an assistant first has to find two dates, and only then can it subtract. A single prompt cannot see the future, and a fixed workflow does not know which lookup comes next.

How it works

ReAct interleaves reasoning with acting. On every turn the agent writes a short Thought about what it knows and what is missing, then an Action: a call to one of its tools. Your code runs that tool and appends the result to the transcript as an Observation. The model is called again with the longer transcript, so each new Thought can build on the last Observation.

In the example, the first turn searches for the Eiffel Tower and gets 1889. The second searches for the bridge and gets 1937. The third turn switches to the calculator, because the agent has both numbers and only needs the difference. Different turns use different tools: search for facts, the calculator for arithmetic. When the agent writes a Final Answer instead of an Action, the loop ends and the answer goes to the answer node.

The Thought lines matter. They let the model track its subgoals, notice that an observation was an error, and change approach instead of repeating itself.

When to use

  • The number and order of steps cannot be predicted from the input.
  • Each step’s result decides the next, as in research, debugging or navigating an unfamiliar system.
  • You can bound the damage: sandboxed tools, a step limit and a cost cap.

When to avoid

  • The path is known. A workflow such as prompt chaining or routing is cheaper, faster and easier to test.
  • You cannot sandbox the tools or limit spend. An autonomous loop with write access and no budget is an incident waiting to happen.
  • Latency matters. Every turn is a full model call over a growing transcript.

Trade-offs

ReAct buys flexibility with predictability. Cost and latency grow with the number of turns, and the transcript gets longer each time, so later calls cost more than early ones. Behavior is harder to test because two runs can take different routes to the same answer. In exchange, you handle tasks no one wrote a flowchart for.

Failure modes

  • Loops: the agent repeats the same failing action. Cap the steps and detect repeated actions.
  • Hallucinated observations: the model writes its own “Observation:” line. Stop generation at that token.
  • Context bloat: long tool outputs crowd out the task. Truncate or summarize observations. On long runs, keep the plan in an external notes file (the To-do notes tab) or compress the history when it nears the limit (the Context compaction tab).
  • Early quitting: the agent answers from memory without verifying. Tell it explicitly to check facts with a tool.

Build it with your AI

Transcript only

Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.

Implement the ReAct (Autonomous Agent) pattern in this codebase, using the LLM client and language we already use.

## Goal

Answer a question that needs several lookups by letting one model alternate Thought, Action and Observation, choosing each next action from the last result, until it writes a Final Answer.

## How it works

1. Fill the ReAct system prompt with the tool descriptions and the question; this is the start of the transcript.
2. Call the model with the transcript, stopping generation at the text 'Observation:' so it cannot write one itself.
3. Parse the reply. If it contains 'Final Answer:', return the text after it. Otherwise read its Action line as tool_name[input].
4. Run the named tool with that input and append 'Observation: ' plus the result to the transcript. If the tool fails or times out, append the error message as the Observation.
5. If the Action line does not parse or names an unknown tool, append an Observation saying so and listing the valid tool names.
6. Call the model again with the longer transcript and repeat.

## Prompts

### ReAct system prompt

```markdown
Answer the question by interleaving Thought, Action and Observation.

Available actions:
{{tool_descriptions}}

Use exactly this format:
Thought: what you know and what you need next
Action: tool_name[input]
Observation: (written by the system, never by you)

When you can answer, write:
Thought: I now have enough information.
Final Answer: your answer

Rules:
- One action per turn. Wait for the observation.
- If an action fails, say why in your next Thought and try a different approach.
- Do not answer from memory when a tool can verify the fact.

Question: {{question}}
```

## Stop rule

Stop when the model writes a Final Answer, or after 10 turns. At the cap, append 'You must answer now.' and make one last call; return that answer flagged as having hit the turn limit.

## Requirements

- Make the turn cap (default 10) and the per-tool timeout (default 10 seconds) parameters.
- Truncate each Observation to a set length (default 2,000 characters) so one large result cannot fill the context.
- End the loop early with a 'stuck' status if the same Action with the same input repeats 3 times in a row.
- Log the full transcript, plus each tool's latency and the token counts per turn.
- Add a test with a stub LLM scripted to emit search[Eiffel Tower], search[Golden Gate], calculator[1937-1889] and then 'Final Answer: 48'; assert four model calls, three tool calls in that order, and the answer '48'.

To-do notes

Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.

Implement the ReAct (Autonomous Agent) pattern (To-do notes variant) in this codebase, using the LLM client and language we already use.

## Goal

Run a long ReAct loop that keeps its plan and findings in an external notes file, so its progress survives when old turns drop out of the context.

## How it works

1. Create an empty notes file for the run and give the agent one extra action, update_notes[text], which replaces the file's contents.
2. Before every model call, put the current notes at the top of the prompt, above the most recent turns.
3. Call the model with the ReAct system prompt, the notes and the recent transcript, and parse its Thought and Action as in plain ReAct.
4. Run the action. For update_notes, save the text and return 'notes saved' as the Observation; on a tool error, return the error text as the Observation.
5. Keep only the last 8 turns of the transcript in the prompt; the notes carry everything older.
6. When the model writes a Final Answer, return it together with the final notes.

## Prompts

### ReAct system prompt

```markdown
Answer the question by interleaving Thought, Action and Observation.

Available actions:
{{tool_descriptions}}

Use exactly this format:
Thought: what you know and what you need next
Action: tool_name[input]
Observation: (written by the system, never by you)

When you can answer, write:
Thought: I now have enough information.
Final Answer: your answer

Rules:
- One action per turn. Wait for the observation.
- If an action fails, say why in your next Thought and try a different approach.
- Do not answer from memory when a tool can verify the fact.

Question: {{question}}
```

## Stop rule

Stop on a Final Answer, or after 40 turns. At the cap, return the notes with a status saying the run stopped early, so a new run can resume from them.

## Requirements

- Make the turn cap (default 40), the kept-turn window (default 8) and the notes size limit (default 4,000 characters) parameters.
- Reject an update_notes call over the size limit with an Observation asking for a shorter version, and keep the old notes.
- Store the notes outside the process, in a file or a database row, so a crashed run can resume from them.
- Log every notes revision with its turn number.
- Add a test with a stub LLM that calls update_notes['[x] A [ ] B'] on turn 1; with the window set to 8, assert the turn-10 prompt contains '[x] A [ ] B' but not turn 1's transcript.

Context compaction

Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.

Implement the ReAct (Autonomous Agent) pattern (Context compaction variant) in this codebase, using the LLM client and language we already use.

## Goal

Keep a ReAct loop running past the context limit by summarizing its history whenever the transcript nears the limit, then continuing from the summary in a fresh window.

## How it works

1. Run the ReAct loop as usual with the ReAct system prompt: call the model, run its Action, append the Observation.
2. Before each model call, count the transcript's tokens. Below the threshold, carry on as normal.
3. At or above the threshold, send the transcript, minus the last 3 turns, to a summarizer call that must keep the goal, decisions made, facts found with their sources, and the next step.
4. Start a new transcript: the original question, the summary under a 'Progress so far' heading, then the 3 kept turns verbatim.
5. Continue the loop from the new transcript, and return the Final Answer when the model writes one.

## Prompts

### ReAct system prompt

```markdown
Answer the question by interleaving Thought, Action and Observation.

Available actions:
{{tool_descriptions}}

Use exactly this format:
Thought: what you know and what you need next
Action: tool_name[input]
Observation: (written by the system, never by you)

When you can answer, write:
Thought: I now have enough information.
Final Answer: your answer

Rules:
- One action per turn. Wait for the observation.
- If an action fails, say why in your next Thought and try a different approach.
- Do not answer from memory when a tool can verify the fact.

Question: {{question}}
```

## Stop rule

Stop on a Final Answer, or after 60 turns in total. If a fresh window is still over the threshold after compaction, stop with a 'context exhausted' status and return the summary.

## Requirements

- Make the threshold a fraction of the model's context window (default 0.75) and the kept-turn count (default 3) parameters.
- If the summarizer call fails, retry it once; if it fails again, drop the oldest half of the turns instead and log that no summary was made.
- Keep the original question verbatim in every window; never summarize it.
- Log each compaction with the token counts before and after.
- Add a test with a stub token counter that reports 160k of 200k tokens on turn 5; assert the summarizer is called exactly once and the turn-6 prompt contains the stub summary and not turn 1's Observation.

Prompt templates

Transcript only · To-do notes · Context compaction

ReAct system prompt
Answer the question by interleaving Thought, Action and Observation.
Available actions:
{{tool_descriptions}}
Use exactly this format:
Thought: what you know and what you need next
Action: tool_name[input]
Observation: (written by the system, never by you)
When you can answer, write:
Thought: I now have enough information.
Final Answer: your answer
Rules:
- One action per turn. Wait for the observation.
- If an action fails, say why in your next Thought and try a different approach.
- Do not answer from memory when a tool can verify the fact.
Question: {{question}}

Related patterns

Composes well with:

Sources

  1. ReAct: Synergizing Reasoning and Acting in Language Models (Yao et al., 2022)
  2. Building effective agents (Anthropic, 2024)

From the Agentic Atlas by Joran Kikke · Edit on GitHub · Suggest a correction