AI agent brain connected to tools through the ReAct reasoning loop, with glowing neural pathways and data streams on a dark blue background

AI agent brain connected to tools through the ReAct reasoning loop, with glowing neural pathways and data streams on a dark blue background

A Step-by-Step Guide to Building Intelligent, Streaming AI Systems

Picture this: a customer service agent that looks up live order data while talking to you. A coding assistant that checks the actual documentation before answering. A data analyst that queries your database, notices an anomaly, runs a follow-up query, and explains what it found; all in a single fluid response that streams word by word as it works.

That is not a chatbot. That is a LangChain ReAct agent: a system that reasons about problems, acts through tools, and delivers results in real time. The gap between a chatbot and an agent is the difference between a parrot and a researcher. This article shows you how to build the researcher.

We will go from zero to a production-ready agent with memory, streaming output, role-based access control, and human approval workflows. Every concept builds on the last, and the central thread throughout is the ReAct pattern: the simple three-step loop that makes all of it possible.

Meet the ReAct Agent

A LangChain agent is not a text predictor. It is a reasoning engine built on the ReAct pattern: Reason, Act, Observe.

Here is how it works. The agent receives your request and starts thinking. It reasons about what information it needs. Then it acts by calling a tool: maybe a database query, a web API, or a calculator. The tool returns an observation, and the agent analyzes that result. If it needs more information, it loops back and reasons again. When it has enough, it produces a final answer.

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#1a1a2e', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#e94560', 'lineColor': '#e94560', 'secondaryColor': '#16213e', 'tertiaryColor': '#0f3460', 'fontFamily': 'Inter, sans-serif'}}}%%
flowchart TD
    A["<b>User Request</b><br/>HumanMessage"] -->|"enters loop"| B

    subgraph REACT["<b>ReAct Loop</b>"]
        direction TB
        B["<b>REASON</b><br/>Model analyzes request<br/>and plans next step"]
        B -->|"needs data"| C["<b>ACT</b><br/>Model issues tool call<br/>via AIMessage"]
        C --> D["<b>OBSERVE</b><br/>Tool executes and returns<br/>result as ToolMessage"]
        D -->|"needs more info"| B
    end

    B -->|"has answer"| E["<b>Final Response</b><br/>AIMessage with answer"]

    style A fill:#0f3460,stroke:#e94560,stroke-width:2px,color:#ffffff
    style B fill:#1a1a2e,stroke:#e94560,stroke-width:3px,color:#ffffff
    style C fill:#16213e,stroke:#e94560,stroke-width:2px,color:#ffffff
    style D fill:#16213e,stroke:#e94560,stroke-width:2px,color:#ffffff
    style E fill:#0f3460,stroke:#e94560,stroke-width:2px,color:#ffffff
    style REACT fill:#0a0a1a,stroke:#e94560,stroke-width:2px,color:#ffffff

The loop is the key insight. A chatbot generates one response and stops. An agent keeps going until it has a complete, verified answer. That persistent loop is what enables the agent to handle multi-step problems that require real data.

Under the hood, LangChain agents run on LangGraph: a framework for durable, stateful execution. LangGraph manages the loop, the state between steps, and recovery from errors. You get that infrastructure for free.

Model Independence: Swap Providers with One String

One of the strongest architectural advantages is model independence. The ReAct loop is decoupled from the underlying model. Swap providers by changing a single string:

// Use Anthropic
model: "anthropic:claude-sonnet-4-5-20250929"

// Or switch to OpenAI
model: "openai:gpt-5-mini"

No code changes. No API rewiring. The agent's tools, memory, middleware, and streaming behavior remain identical across providers.

Creating Your First Agent

What it does: createAgent wires together a model, a set of tools, and a system prompt into a full ReAct loop powered by LangGraph. One call gives you an agent that can reason, call tools, and stream results.

Why this approach: Instead of manually wiring model calls, tool dispatchers, and state management, createAgent handles the boilerplate. You focus on what the agent does, not how the loop runs.

When to use it: Any time you need an AI system that must take actions, retrieve external data, or handle multi-step reasoning rather than producing a single static response.

import { createAgent } from "langchain";

const agent = createAgent({
    model: "anthropic:claude-sonnet-4-5-20250929",
    tools: [executeSQL],
    systemPrompt,
    contextSchema,
});