Bestseller #2
Bestseller #3
Design Pattern · Language Models
ReAct
Reasoning & Acting in Sequential Loops
◆
ReAct (Reasoning + Acting) is a prompting paradigm that interleaves chain-of-thought reasoning with actionable tool calls inside a tight loop. Instead of answering in one shot, the model repeatedly asks itself “what do I think?” then “what should I do?”, observes the result, and iterates — mirroring how a careful human expert reasons through an unfamiliar problem.
Originally introduced for task-solving agents, ReAct has become the backbone of most modern agentic AI systems: web-browsing assistants, code interpreters, database query agents, and multi-step orchestrators. Yao et al., 2022 · “ReAct: Synergizing Reasoning and Acting in Language Models”
Originally introduced for task-solving agents, ReAct has become the backbone of most modern agentic AI systems: web-browsing assistants, code interpreters, database query agents, and multi-step orchestrators. Yao et al., 2022 · “ReAct: Synergizing Reasoning and Acting in Language Models”
The Core Loop
Thought
The model narrates its internal reasoning in plain language — what it knows, what it doesn’t, and what strategy it will use next. This scratchpad is never sent to a tool; it exists only to improve the quality of the next action.
Action
Based on its reasoning, the model emits a structured tool call — a search query, a code execution, an API request, or any other discrete external operation. One action per step keeps the loop auditable and debuggable.
Observation
The environment (search engine, code runtime, database) returns a result. This raw output is appended to the context verbatim — no summarization — so the model can reason over exactly what happened.
Repeat
The model re-enters the Thought stage with an enriched context window. It may loop many times: refining its plan, correcting mistakes, or decomposing a complex task into sub-problems before finally deciding enough information has been gathered.
Answer
When the model determines it has sufficient grounding, it emits a final response — grounded in concrete observations rather than hallucinated from parametric memory alone.
Prompt Skeleton
react_agent.py
# System prompt fragment ────────────────────────────── SYSTEM = """ You solve tasks in a Thought → Action → Observation loop. Thought: Reason about the current state and what to do next. Action: Call exactly ONE tool using the format below. Observation: The tool result will be appended automatically. Repeat until you know the answer, then emit a Final Answer. Available tools: search(query), calc(expr), lookup(key) """ # ───────────────────────────────────────────────────── def react_loop(question: str, max_steps: int = 10): history = [("user", question)] for step in range(max_steps): # ① Generate next Thought + Action response = llm(SYSTEM, history) thought = parse_thought(response) # free-form text action = parse_action(response) # tool name + args if action.name == "final_answer": return action.args["answer"] # ⑤ Done # ② Execute tool obs = execute_tool(action) # ③ Append to context and loop history += [ ("assistant", f"Thought: {thought}\nAction: {action}"), ("tool", f"Observation: {obs}"), ] raise TimeoutError("max_steps reached without final answer")
Key Properties
Grounded
Answers are anchored to real observations from tools, dramatically reducing hallucination compared to single-pass generation.
Auditable
Every reasoning step is visible in the transcript. Debugging is straightforward — you can see exactly where the agent went wrong.
Self-Correcting
If a tool returns unexpected data, the next Thought can revise the strategy. Mistakes in early steps don’t necessarily propagate to the final answer.
Tool-Agnostic
Any deterministic function — search, code, APIs, databases — can be a tool. The loop structure is independent of what the tools actually do.
Controllable
Step count, allowed tools, and exit conditions are all configurable. You decide the budget and surface area the agent has access to.
Example Trace — “What is the population of France times π?”
Thought 1
I need the current population of France. I’ll search for it before doing any arithmetic.
Action 1
search(“population of France 2024”)
Obs 1
France population 2024: approximately 68,400,000
Thought 2
Good — 68.4 million. Now I multiply by π ≈ 3.14159. I’ll use the calc tool for precision rather than estimating.
Action 2
calc(“68400000 * 3.14159265358979”)
Obs 2
214,884,937.8456…
Thought 3
I have both inputs from verified sources. The computation is complete. I can now give a final answer.
Answer
The population of France (~68.4 million) multiplied by π ≈ 214,884,938.
Bestseller #1
Bestseller #2
Bestseller #3
Bestseller #4

