Architecting AI Agents
Reasoning and ReAct Patterns
From Chains to Agents
Simple LLM chains are powerful, but they operate like a straight line. You provide a prompt, and the model generates a single, final answer. This works well for direct questions but falls short when a task requires multiple steps, access to live data, or adapting to new information.
To solve more complex problems, we need to move from a linear chain to a dynamic loop. We need an agent that can think, act, and learn from the results. This is the core idea behind the ReAct framework, which stands for "Reasoning and Acting."
Instead of just answering, a ReAct agent reasons about what it needs to do, performs an action, observes the outcome, and then reasons again.
This creates a powerful cycle: Thought → Action → Observation. The model isn't just executing a pre-defined script; it's generating its own script on the fly. It uses an to figure out its next move, much like a person thinking through a problem step by step.
The Thought-Action-Observation Loop
The ReAct pattern transforms the LLM from a simple text generator into a reasoning engine that controls a workflow. The process is iterative and stateful, allowing the agent to build on its previous steps.
Let's walk through an example. Suppose the goal is: "What was the score of the last Super Bowl, and who was the MVP?"
-
Thought: The LLM receives the goal. It reasons, "I need to find the most recent Super Bowl score and the MVP. I don't have this information internally. I should search for 'last Super Bowl score and MVP'."
-
Action: The agent executes a action. It formats a command like
search(query='last Super Bowl score and MVP'). -
Observation: The search tool runs and returns a result: "Super Bowl LVIII: Kansas City Chiefs 25, San Francisco 49ers 22. MVP: Patrick Mahomes."
-
Thought: The agent receives this observation. It reasons, "I have found the score and the MVP. I can now answer the user's question directly."
-
Action: The agent generates the final answer for the user: "The Kansas City Chiefs defeated the San Francisco 49ers 25-22 in Super Bowl LVIII. The MVP was Patrick Mahomes."
This loop continues until the agent determines it has enough information to fully address the user's request. It can handle errors, refine its searches, and chain multiple tools together, all guided by its internal reasoning process.
Prompting for ReAct
Getting this behavior doesn't happen automatically. It requires careful prompt engineering. The prompt must instruct the model on the format of the thought-action-observation cycle and provide examples. It's a form of in-context learning where the model learns the agentic pattern from the prompt itself.
A typical ReAct prompt template includes:
- A system message explaining the goal and the tools available.
- Instructions on the required
Thought:andAction:format. - A few examples (few-shot learning) of the loop in action.
- The user's query and a placeholder for the agent's scratchpad.
You are a helpful assistant that can answer questions.
You have access to the following tools:
- `search(query)`: Searches the web for information.
To answer, you must use the following format:
Thought: You should always think about what to do.
Action: The action to take, should be one of [search]
Action Input: The input to the action.
Observation: The result of the action.
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer.
Final Answer: The final answer to the original input question.
--- PREVIOUS CONVERSATION ---
{chat_history}
--- NEW INPUT ---
Question: {input}
--- SCRATCHPAD ---
{agent_scratchpad}
The {agent_scratchpad} is where the magic happens. After each step, the entire history of thoughts, actions, and observations is fed back into the prompt. This gives the model the context of its previous steps, allowing it to maintain a coherent plan.
However, this creates a significant challenge: overhead. Because the entire reasoning history is included in each new call to the LLM, the context window can fill up quickly. A long and complex task might generate thousands of tokens in its scratchpad, leading to higher costs and potentially hitting the model's context limit.
Managing this trade-off between reasoning depth and token consumption is a key skill in building effective and efficient AI agents. For complex tasks, the structured reasoning of the ReAct pattern is often worth the extra cost.
What is the correct sequence of steps in the core loop of the ReAct framework?
What is the primary role of the agent_scratchpad in the ReAct pattern?