Welcome to this video on ReAct: Building Agents that Reason Before Acting.
In this video, you'll explore how React enables step-by-step agent reasoning. You'll
identify key components like thought, action, and observation.
You'll construct a working React agent in LangGraph.
And finally, you'll analyze how the agent reasons through tool calls to generate a final
response.
React agents are designed for complex tasks that require step-by-step reasoning. For example,
you might begin with a system prompt like,
You are a helpful AI assistant that thinks step-by-step and uses tools when needed.
You can also prompt the LLM to respond in the following ways.
Identify the information needed. Use tools when appropriate.
Get clear and useful answers. And finally, walk through its reasoning process.
The system message should instruct the LLM to format its output using a structured pattern.
First, it starts with Thought, where the LLM reasons about what to do next.
Then comes Action, the name of the tool to use.
Next is Action Input, the input provided to the selected tool.
After that is Observation, the result returned by the tool.
And then Final Answer, the complete response to the user based on what the tool returned.
Let's start with a simple example. You're a frequent traveler who owns multiple apartments
in different cities and access to an LLM that can use two tools.
A search tool that provides the current weather.
And a clothing recommendation tool that suggests what to wear based on what's in your closet.
In the block diagram, the LLM is shown in blue.
The green box represents the environment.
The LLM must interact with the environment through these tools.
It reasons step-by-step, uses tool feedback, and iterates toward a final answer.
In this case, what to wear.
Consider the question, what's the weather in Tokyo and what should I wear?
The LLM must use tools to obtain data from the environment, in this case, the current
weather, and check what clothes are available using the clothing recommendation tool.
The LLM outputs the thought, I need to look up the weather in Tokyo first.
The LLM determines the action, in this case, to use the search tool.
At the same time, the LLM generates the action input, Tokyo weather today.
This serves as input to the tool, which in turn interacts with the environment to retrieve
the relevant information.
The tool returns an observation after accessing the environment.
Tokyo is 22°C with sunny skies.
The observation and chat history are passed back into the LLM.
The chat history is always included, even if not shown explicitly.
The LLM takes the new input and processes a thought.
Now I should recommend clothing for 22°C sunny weather.
Next, the action.
It selects the tool, recommend_clothing.
The action input is produced, 22°C sunny weather.
After the observation, light clothing recommended, t-shirt, shorts, sunglasses.
Finally, the LLM reaches its last thought.
It now has all the information it needs.
It provides the final answer.
Tokyo is 22°C and sunny today.
I recommend wearing light clothing like a t-shirt, shorts, and sunglasses.
Since there are no further tool calls, the process ends here.
Now let's see how to implement this in LangGraph.
The code example you are going to look at emphasizes simplicity by minimizing the schema,
prompts, and auxiliary functions.
It works well for basic use cases, but refer to the LangGraph documentation for more advanced
implementations.
Define a search tool by wrapping a TavilySearchResults object with the @ tool decorator.
Create a recommend_clothing tool that analyzes keywords in the LLM's response,
such as rain or wet, to suggest appropriate clothing, as described in the docstring.
The schema is essentially a dictionary-like state where the key is messages and the value
is a growing list of messages exchanged during the conversation.
Sequence[BaseMessage] holds a list of any message type, HumanMessage, AIMessage, or
ToolMessage.
Add_messages appends new messages each time a node runs.
Annotated is required to turn the messages field into the correct form so that LangGraph
knows to apply add_messages.
The agent state object behaves like a dictionary where messages is a key and its value is a
list that stores all the messages exchanged in the conversation.
Next, load the GPT model using Lengchain's OpenAI wrapper.
Then create a list of tools and a dictionary mapping each tool's name to the tool itself.
Define a system message that instructs the agent to respond step-by-step and use tools
when necessary.
The agent_scratchpad variable automatically stores the reasoning history in the format.
Thought, to action, to action input, to observation, along with the user's input sequence.
While many implementations store the user's input, or question, and tool messages separately,
for brevity, store everything in the scratchpad.
Next, chain the prompt to the model and bind the tools to form the agent.
Define the first node in the graph, which takes the agent state.
The state is passed to the model through scratch_pad.
The model's response is returned and appended to the message history.
Create a tool calling node.
Create a new graph using agent state to track the data.
Add a node named agent that runs the call_model function.
Next, add a node named tools that runs the tool_node function.
Finally, add an edge from agent to tools.
Define a should_continue function to control the agent's flow.
Pair it with a conditional edge that decides the next step.
It takes the state from the agent and retrieves the last message.
Based on that message, the graph routes to either the tools node or the end node.
If the message has no tool calls, it returns end.
This maps to the end node in the graph.
Otherwise, it returns continue, and conditional edge maps continue to the tools node.
Here, agent is set at the starting node of the graph.
It compiles the workflow into an executable graph.
This function will help print out results from the graph.
Define the input message from the user to start the graph.
What's the weather like in Zurich?
And what should I wear based on the temperature?
Next, run the graph and print each state update step-by-step using the print_stream
function.
The trace of the full reasoning process starting from the human message can be seen.
The first AI message includes a tool call to the search tool with its parameters.
The tool returns a result.
The second AI message calls the clothing recommendation tool.
The second tool result is added to the state.
Finally, the LLM generates the last AI message with the complete answer.
You can sketch what's happening in the graph.
The initial human message is passed to the call_model via the state.
The LLM responds, and an AI message is appended to the state messages variable.
The state is then passed to the should_continue node.
The last message, an AI message, is extracted from the state.
If it includes a tool call, the conditional edge returns continue and routes to the tool
node.
Similarly, the tool node extracts the tool call from the state.
The tool name is identified.
The tool parameters are selected based on the chosen tool.
The result is wrapped in a tool message and passed back to the model.
This process repeats until no more tool calls are made.
At that point, the final response is generated.
The graph reaches the end node.
In this video, you learned that
React agents perform step-by-step reasoning and use tools to answer complex queries.
Their output follows a structured format.
Thought ➝ action ➝ action input ➝ observation ➝ final answer.
Tool results (observations) feed back into the reasoning process to guide next steps.
LangGraph is used to implement the React workflow connecting reasoning and tool nodes.
The process continues until a final answer is generated with no further tool calls required.