ReAct
ReAct is a compound pattern: planningPlanningBreak a high-level goal into steps, store the plan, and work through it.Opens in a new tab, tool useTool useFunction calling gives the model hands: it asks, and code does the work.Opens in a new tab and a loop, run together. The model reasons, acts, observes the result, and repeats until it can answer.
The loop
- Reason. The LLM looks at the goal and everything so far and decides the next step.
- Act. It emits a tool call.
- Observe. The result goes back into the conversation, and the model reasons again.
The paper that named it says what each half is for:
…reasoning traces help the model induce, track, and update action plans as well as handle exceptions, while actions allow it to interface with external sources, such as knowledge bases or environments, to gather additional information.
In LangGraph
The loop is a state graphState graphsAn agent drawn as nodes that read and write one shared state, joined by edges that say what runs next.Opens in a new tab with two nodes and a conditional edge. The router is the stop condition: no tool calls in the last message means the model has its answer.
from langchain.chat_models import init_chat_modelfrom langchain.tools import toolfrom langgraph.graph import END, START, MessagesState, StateGraph @tooldef search(query: str) -> str: """Search for information.""" return f"Results for: {query}" tools = {"search": search}model = init_chat_model("anthropic:claude-sonnet-5").bind_tools(list(tools.values())) def reason(state: MessagesState): return {"messages": [model.invoke(state["messages"])]} def act(state: MessagesState): calls = state["messages"][-1].tool_calls return {"messages": [tools[c["name"]].invoke(c) for c in calls]} def should_continue(state: MessagesState): return "act" if state["messages"][-1].tool_calls else END builder = StateGraph(MessagesState)builder.add_node("reason", reason)builder.add_node("act", act)builder.add_edge(START, "reason")builder.add_conditional_edges("reason", should_continue, ["act", END])builder.add_edge("act", "reason")graph = builder.compile()The edge from act back to reason is the observe step and the repeat. LangChain’s create_agent builds this same loop: in its words, “a model calling tools in a loop until a given task is complete.”
The cost
Every lap is a model call that re-reads the growing conversation. Token cost and latency climb with the number of laps, and a confused model can keep going. Cap the number of steps. When the steps are predictable, plan firstPlanningBreak a high-level goal into steps, store the plan, and work through it.Opens in a new tab and skip the per-step reasoning. For checking the answer itself, see reflectionReflectionCritique the output before finalizing it: one agent does, another reflects.Opens in a new tab.
Sources
- ReAct: Synergizing Reasoning and Acting in Language Models, arXiv · accessed October 5, 2026
- Workflows and agents, LangGraph docs · accessed October 5, 2026
- Agents, LangChain docs · accessed October 5, 2026