LangChain Mastery

Course Content

LangChain Mastery

7 sections · 109 lessons

What is the ReAct framework in LangChain agents?


What you need to know

Why the combination helps

  • Reasoning alone (chain of thought) can only use what is already in the prompt. It cannot check a fact, so it guesses confidently.
  • Acting alone (calling tools with no plan) wastes calls and does not notice when a result is useless.
  • ReAct lets each observation change the plan. If a search returns nothing, the model can rephrase and try again.

The original text format

The first LangChain version described the format in the prompt and parsed the model's text output:

Text
Thought: I need the current stock for SKU X200.Action: check_stockAction Input: {"sku": "X200", "store_id": "BLR-04"}Observation: 3Thought: It is in stock. I can answer.Final Answer: Yes, 3 units are available at the Koramangala store.

A parser pulled out Action: and Action Input: with regular expressions. When the model wrote "Action : check stock" or forgot the input line, the parser raised an OutputParserException. This was the most common agent bug in 2023.

The modern version

Chat models now support native tool calling: the model returns a structured tool call with a name and JSON arguments in a separate field of its reply. There is nothing to parse, so the format errors disappear.

Legacy text ReAct

  • Format described in the prompt
  • Regex parser extracts the action
  • OutputParserException on drift
  • initialize_agent(... ZERO_SHOT_REACT_DESCRIPTION)

Modern ReAct loop

  • Tool schemas sent as JSON
  • Model returns structured tool_calls
  • No parsing step to break
  • create_agent in LangChain 1.x

The loop survived; the text format did not. LangGraph's old create_react_agent was named after the loop, and in LangGraph 1.0 it was deprecated in favour of LangChain's create_agent, which is the same idea with middleware added.

Where the "thought" went

With native tool calling, the model may write a short reasoning text alongside its tool call, or, on reasoning models, think internally before responding. You do not need to force "Thought:" lines. If you want the reasoning visible for debugging, ask for a one-line reason in the system prompt, or read it from the trace in LangSmith.

A real-life example

A help-centre support bot for a broadband company gets: "My connection dropped yesterday and I was charged a late fee. Why?"

  1. The model reasons it needs the account's outage history and billing, and calls get_outages(account_id).
  2. Observation: an area outage from 2 pm to 9 pm yesterday.
  3. It calls get_invoice(account_id). Observation: the payment was made on the 16th; the due date was the 15th.
  4. It answers: the late fee is from the payment date, not the outage, and links the help article on fee waivers.

A chain-of-thought-only bot, with no tools, guessed that the outage caused the missed payment and promised a refund the policy did not allow. The ReAct loop found the actual cause in two tool calls.

Follow-up questions to expect

  • "How is ReAct different from chain of thought?" — Chain of thought reasons over what is in the prompt; ReAct also calls tools and reasons over their results.
  • "Why did the text-based ReAct agent fail so often?" — It depended on the model following an exact text format; small drifts broke the regex parser.
  • "Is create_react_agent still the API?" — It was LangGraph's prebuilt helper and is deprecated since LangGraph 1.0; use langchain.agents.create_agent.