Skip to content
Forward Deployed

Forward Deployed
Lessons and contents
Learn

ReAct with LangChain `create_agent`

Source
From the RAG & Agents Engineering course
By
Sourav Banerjee
Last updated
9 Nov 2026

Report an issue

create_agent

What you'll learn

  • Explain what the agent factory builds, and why everything from LangGraph still applies to it.
  • Predict how many model calls a task needs from whether its tool calls depend on each other.
  • Diagnose an agent that searches until its call cap stops it, and rank the fixes.
  • Choose a call cap from the call counts your golden questions need.

Lesson 1 of T7.2 wired the ReAct loop node by node. Every Larkspur agent would repeat that wiring: a model node, a tool node, a router and the edge back. LangChain 1.x packages the wiring as one function.

create_agent takes a model, a list of tools and a system prompt, and returns the ReAct loop as a compiled LangGraph graph. Inspecting the graph it returns shows the loop from lesson 1 of T7.2, with the nodes renamed:

Edge Kind Taken when
start to model Fixed Every run begins with a model call
model to tools Conditional The model's reply contains tool calls
tools to model Conditional Always after the tools run: the feedback loop
model to end Conditional The model's reply contains no tool calls

Table 1: The four edges of the graph the factory returns.

Diagram: __start__; model; tools; __end__Diagram: __start__; model; tools; __end__

Figure 1: The compiled graph. Four nodes, and the same feedback edge as lesson 1 of T7.2.

Because the result is a graph, everything from T4.3 and T4.4 applies to it. Streaming shows each new message as it arrives, a checkpointer plus a thread id gives the agent memory, and the input and output are both message lists. The answer is the last message of the returned list; the rest is the trace.

Dependent and independent calls

The loop is fixed, but the model decides how much to do in each turn. Two recorded runs with stub tools show the difference:

Request Model turn 1 Model turn 2 Model turn 3 Model calls
What's the stock price of Google? Once you get it, send an email to an analyst. Stock-price call Email call, body quoting the price Answer 3
Weather in Bangalore and Mumbai, and 25 times 4 Three tool calls at once Answer 2

Table 2: Dependent calls take a turn each; independent calls share one.

  • Dependent calls take one turn each. The email body needs the price, so the email call cannot be written until the price comes back as an observation.
  • Independent calls share a turn. None of the three lookups needs another's result, so the model requested all three in one reply and the tool node ran them before the model's second and last call.

A third case costs one call: given only a restaurant search tool, the agent answered Who are the members of the A-Team? from its own knowledge without searching, because the tool's description said it covers the restaurant.

Memory is a thread

The factory has no memory class. A checkpointer stores the message list after every step, and runs that pass the same thread id continue the same conversation. Three turns on one thread, then the last question on a fresh one:

Thread Question Messages on the thread How the question was read
A What is the capital of France? 2 Paris
A Any suggestions what to visit there? 4 "There" resolved to Paris
A What about China? 6 What to visit in China
B (new) What about China? 4 As a question about the restaurant, the only context the agent had

Table 3: The same words on two threads.

Thread B shows the failure we call thread amnesia: on a new thread a follow-up loses its referent, and the agent fills the gap from whatever it does have, here its restaurant tool.

Migrating from LangChain 0.x

Older material builds this loop with an agent executor or LangGraph's prebuilt ReAct agent. The mapping:

LangChain 0.x LangChain 1.x
Agent executor, or the prebuilt ReAct agent with a prompt argument create_agent with a system prompt
A maximum iteration count A model-call limit middleware
Verbose printing Streaming the message list
A conversation memory class A checkpointer plus a thread id
Input and output strings Message lists in, message lists out

Table 4: What replaces what.

Renaming the function is not enough: the factory has no prompt argument, so old code that passes one fails with a type error until it is renamed to the system prompt. LangGraph's prebuilt ReAct agent is deprecated since LangGraph v1.0.

Tools come in three weights: ready-made ones from the community package (an LLM-backed calculator, for example), a decorated function, and a tool class that carries configuration such as which vector store to search. In every case the model chooses tools by name and description, so the description is prompt text.

Call limits and runaway loops

A loop that decides its own length can run long. The recorded failure uses a restaurant FAQ indexed badly: ten entries stored as questions only, with the answers lost. The question is When does the restaurant open?, and every search returns four FAQ questions and no opening hours. We ran three agents against it, each under a cap of 3 model calls:

Agent Searches Model calls What the user got
Plain prompt 1 2 "I couldn't find the specific opening hours", with a suggestion to check the website
Told to keep searching and never admit failure 3, each reworded 3, cap reached The cap's own notice: "Model call limits exceeded: run limit (3/3)"
Fixed tool over the complete FAQ, same cap 1 2 "Opens at 11:30 AM and closes at 10:00 PM, Tuesday to Sunday"

Table 5: One answerless index, three agents, the same cap.

The second row is a runaway loop: the agent rewords its search and gets the same answerless questions back each time. The cap bounded the bill, but the user still has no opening hours, and the message they see was written by the middleware, not the model.

Fix what the model sees before raising the cap

Rank the fixes by how much they change what reaches the model:

Fix Where it lives
1. Store each question with its answer Ingestion
2. Retrieve more entries (six instead of four) The retriever
3. Format results under a clear heading The tool's return value
4. Say in the description what the tool returns The tool's description
5. Raise the call cap The agent's middleware

Table 6: Five fixes for a runaway loop, most effective first.

Fix 5 is the weakest: it buys more attempts at a retrieval problem. With fixes 1 to 4 applied, the third row of Table 5 needed one search and one answer under the same cap.

How the cap decides

The model-call limit middleware counts model calls per run and, optionally, per thread across runs. It checks the count before each model call:

Diagram: Before each model call; Calls made below the limit?; Call the model; Exit behaviour; Append limit message, stop; Raise an errorDiagram: Before each model call; Calls made below the limit?; Call the model; Exit behaviour; Append limit message, stop; Raise an error

Figure 2: The cap is checked before the model runs, so the last allowed call is the one that matters.

The check runs before the call, so a run that needs four model calls is cut off at a cap of 3 even when its evidence is already in the message list. In the lesson 1 of T7.2 lab the three golden questions need 2, 3 and 4 calls:

Cap Export (needs 2) Refund (needs 3) Outage (needs 4) Answered
2 Answered Stopped, evidence 1.00 Stopped, evidence 0.00 1 of 3
3 Answered Answered Stopped, evidence 1.00 2 of 3
4 Answered Answered Answered 3 of 3

Table 7: Golden questions answered at each cap in the lab.

We call the stopped-with-evidence rows the starved final call: the cap spent its budget on searches and blocked the one call that would have written the answer. Set the cap from the largest call count your golden questions need, add headroom for rewording, and alert when the share of runs that hit it rises. A rising share points at retrieval (Table 6), not at the cap.

Limits of this evidence

  • Stub tools and a toy index. The stock, email, weather and restaurant tools return fixed data; the call counts show the loop's shape, not a production workload.
  • One recorded run each. A live model may search a different number of times; the persistent agent's three searches are one run.
  • A scripted model in Table 7. The lab's counts are computed, but its searches are the ones a model might write.

Run the notebooks

The code for this lesson is in these notebooks. Colab runs one in your browser: install the packages its first cell imports and set the API keys it reads. To run every notebook as written, clone the repository and use its uv environment.

Notebook GitHub Colab
React with create agent Open on GitHub Open in Colab

Key Takeaways

  • create_agent returns the ReAct loop as a compiled LangGraph graph, so streaming, checkpointers and thread-id memory work as usual. Pass a system prompt; the old prompt argument fails with a type error.
  • Dependent tool calls take one model turn each and independent ones share a turn, so the same loop costs 2 or 3 model calls depending on the task.
  • When an agent loops without an answer, fix the data, the retrieval depth, the result format and the tool description first. A higher cap buys more attempts; a cap below what your golden questions need starves the final answering call.

Check yourself

1. Why does the weather-and-arithmetic request finish in two model calls, while fetching a stock price and emailing it needs three?

The three weather and arithmetic lookups are independent, so the model requested all of them in one reply and the tool node ran them before the model's second and last call. The email body needs the price, so the stock-price call must return its observation before the model can write the email call, which costs a turn of its own.

2. Your golden questions need 2, 3 and 4 model calls. What happens at a cap of 2, and how should you set the cap?

Only the export question is answered. The refund run already holds both evidence chunks when the cap stops it, and the outage run has found neither. Set the cap from the largest count the golden set needs, with headroom, and alert when runs hit it.

3. The restaurant FAQ agent rewords its search until the call cap ends the run, and the user never gets the opening hours. Why is raising the cap the weakest fix?

The fault is in retrieval: the index stored the questions without their answers, so every search returns answerless questions. A higher cap only buys more attempts at the same problem. Storing each answer, retrieving more, formatting the results and describing what the tool returns got the answer in one search under the same cap.

Rate your confidence and keep notes on the module page.