07 Oct Build Your First LangGraph Graph Step by Step
Now let’s build a small, complete graph from scratch and watch it run step by step. Here are the steps with the code.
What we are building
A text analyzer with two nodes:
START -> count_words -> label_length -> END
- count_words counts the words in a text
- label_length labels the text as short, medium, or long
The full code
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
# 1. State
class State(TypedDict):
text: str
word_count: int
level: str
# 2. Nodes
def count_words(state: State):
return {"word_count": len(state["text"].split())}
def label_length(state: State):
count = state["word_count"]
if count < 10:
level = "short"
elif count < 30:
level = "medium"
else:
level = "long"
return {"level": level}
# 3. Build the graph
builder = StateGraph(State)
builder.add_node("count_words", count_words)
builder.add_node("label_length", label_length)
builder.add_edge(START, "count_words")
builder.add_edge("count_words", "label_length")
builder.add_edge("label_length", END)
# 4. Compile and run
graph = builder.compile()
result = graph.invoke({"text": "LangGraph helps you build AI apps as graphs"})
print(result)
Output:
{'text': 'LangGraph helps you build AI apps as graphs', 'word_count': 8, 'level': 'short'}
How it works
- We pass in only text. The fields word_count and level don’t exist yet. They appear once a node writes them.
- count_words splits the text into words and stores the count (8).
- label_length reads that count, which was written by the previous node, and picks a label.
- The final state contains all three fields.
Watching each step with stream()
invoke() gives only the final result. To see what each node did, use stream():
for step in graph.stream(
{"text": "LangGraph helps you build AI apps as graphs"},
stream_mode="updates",
):
print(step)
Output:
{'count_words': {'word_count': 8}}
{'label_length': {'level': 'short'}}
Each line shows the node’s name and the update it returned. This is very useful for debugging, and we will use it a lot later.
invoke() vs stream()
- invoke() returns the final state only. Use it when you just want the result.
- stream() returns updates as they happen. Use it when you want to see progress or debug.
Try different inputs
long_text = "word " * 35
print(graph.invoke({"text": long_text})["level"])
Output:
long
The same graph handles any input. You define the workflow once and reuse it.
Common mistakes in your first graph
- Reading a field before it exists: if label_length ran before count_words, state[“word_count”] would raise a KeyError. Edge order matters.
- Node name mismatch: add_edge(“count_word”, …) (missing the “s”) fails because that node doesn’t exist.
- Returning a value instead of a dict: a node must return {“word_count”: 8}, not just 8.
Summary
- A complete graph follows five steps: define state, write nodes, add nodes, connect edges, compile
- Nodes pass data to each other through the shared state
- invoke() returns the final state, and stream() shows every step
- Fields you haven’t written yet simply don’t exist in the state
Practice
- Add a third node, count_characters, that stores the character count in a new field
- Use stream() to confirm that all three nodes run in order
- Change the thresholds in label_length so “medium” starts at 5 words
If you liked the tutorial, spread the word and share the link and our website, Studyopedia, with others.
For Videos, Join Our YouTube Channel:Â Join Now
Read More:
- Generative AI Tutorial
- AI Ethics
- Machine Learning Tutorial
- Deep Learning Tutorial
- Ollama Tutorial
- Retrieval Augmented Generation (RAG) Tutorial
- ChatGPT Tutorial
- Microsoft Copilot Tutorial
No Comments