๐ŸŸข AI Engineering

Build Your First LangGraph โ€” Nodes, Edges & State

๐Ÿ“… Aug 5, 2026 โฑ 6 min read

Time to build. We'll make the smallest possible LangGraph โ€” a one-node chatbot โ€” so the machinery (state, node, edges, compile, run) is crystal clear. Every bigger graph is this same skeleton with more nodes.

Step 1: define the state

The state is a shared object passed between nodes. For a chatbot it holds the message list. The add_messages reducer tells LangGraph to append new messages rather than overwrite them.

pip install langgraph langchain-anthropic
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages

class State(TypedDict):
    # "append, do not replace" โ€” that is what add_messages means
    messages: Annotated[list, add_messages]

Step 2: write a node

A node is a plain function: it takes the current state and returns the update to merge back in. Ours calls the model and returns its reply.

from langchain.chat_models import init_chat_model
model = init_chat_model("claude-opus-5", model_provider="anthropic")

def chatbot(state: State):
    reply = model.invoke(state["messages"])
    return {"messages": [reply]}   # add_messages appends this

Step 3: wire the graph

Add the node, then connect edges. START and END are special markers for where the graph begins and finishes.

builder = StateGraph(State)
builder.add_node("chatbot", chatbot)
builder.add_edge(START, "chatbot")     # entry -> our node
builder.add_edge("chatbot", END)       # our node -> exit

graph = builder.compile()              # ready to run

Step 4: run it

result = graph.invoke({"messages": [
    {"role": "user", "content": "Give me one tip for the GATE exam."}
]})
print(result["messages"][-1].content)

The input message flowed into the state, the chatbot node ran, its reply was appended, and the graph hit END. That's the full lifecycle.

Streaming progress

Real graphs have many nodes; .stream() lets you watch each one fire โ€” great for debugging and progress UIs.

for step in graph.stream({"messages": [{"role": "user", "content": "Hi"}]}):
    print(step)     # one dict per node as it completes

The pattern you'll reuse forever

Define state โ†’ write nodes โ†’ add nodes โ†’ connect edges โ†’ compile โ†’ invoke. Every LangGraph app, from a chatbot to a multi-agent system, is this exact recipe. The magic starts when edges become conditional and point backward to form a loop โ€” which is exactly how we build a real tool-using agent next.

Related: what LangGraph is ยท try the ideas in our code playground.

โ† All Articles