Je hebt vast weleens een chatbot gebouwd die netjes een vraag beantwoordt en dan… stopt. Best handig, maar eerlijk gezegd ook een beetje saai. Wat nou als je AI-systeem zélf kan nadenken, tools kan aanroepen, de resultaten kan bekijken, en dan opnieuw kan redeneren — net zo lang tot het een goed antwoord heeft? Dat is precies waar LangGraph om de hoek komt kijken.
LangGraph is een open-source Python-framework van LangChain waarmee je stateful AI-agents bouwt als gerichte grafen. Geen lineaire keten van stappen, maar een netwerk van nodes (acties) en edges (verbindingen), compleet met conditionele logica, loops en menselijke tussenkomst. Het resultaat? Agents die niet alleen praten, maar ook daadwerkelijk dingen doen.
In deze handleiding bouwen we samen stap voor stap een volledig werkende AI-agent met LangGraph. Van installatie tot tool-calling, van het ReAct-patroon tot human-in-the-loop en geheugen. Alles wat je nodig hebt om in 2026 serieuze AI-agents te bouwen met Python.
Wat is LangGraph en Waarom Heb Je Het Nodig?
LangGraph is een low-level orchestratieframework dat bovenop LangChain is gebouwd. Waar LangChain zich richt op ketens (chains) — lineaire reeksen van stappen — biedt LangGraph een grafenmodel dat cyclische workflows ondersteunt. En dat verschil is cruciaal wanneer je met agents werkt.
Waarom? Simpel: echte agents werken iteratief. Ze redeneren, nemen een actie, observeren het resultaat, en beslissen dan of ze klaar zijn of nóg een actie moeten nemen. Dat is een lus, geen rechte lijn. En precies die lussen zijn waar LangGraph z'n kracht laat zien.
De Kernvoordelen van LangGraph
- Stateful workflows — Je agent onthoudt wat er is gebeurd, ook over meerdere interacties heen.
- Durable execution — Bij een crash hervat je agent precies waar hij was gebleven, dankzij checkpointing.
- Human-in-the-loop — Pauzeer de uitvoering op elk moment voor menselijke goedkeuring of correctie.
- Conditionele routing — Laat je agent zelf beslissen welke stap hij als volgende neemt, op basis van de context.
- Multi-agent orchestratie — Combineer meerdere gespecialiseerde agents in één workflow.
Bedrijven als Klarna, Replit en Elastic gebruiken LangGraph al in productie. Met versie 1.1.0 (uitgebracht op 10 maart 2026) is het framework absoluut volwassen genoeg voor serieuze toepassingen.
Installatie en Projectopzet
Goed, laten we aan de slag gaan. We beginnen met het opzetten van een schone ontwikkelomgeving. Je hebt Python 3.10 of hoger nodig.
# Maak een virtuele omgeving aan
python -m venv langgraph-agent
source langgraph-agent/bin/activate # Linux/macOS
# langgraph-agent\Scripts\activate # Windows
# Installeer de benodigde pakketten
pip install langgraph langchain-anthropic python-dotenv
Maak vervolgens een .env-bestand aan voor je API-sleutel:
ANTHROPIC_API_KEY=jouw-api-sleutel-hier
En laad deze in je Python-script:
from dotenv import load_dotenv
load_dotenv()
LangGraph ondersteunt diverse LLM-providers, waaronder Anthropic (Claude), OpenAI (GPT) en Google (Gemini). In deze handleiding gebruiken we Claude Sonnet 4.6 als ons basismodel — naar mijn ervaring een uitstekende balans tussen snelheid en kwaliteit voor agent-toepassingen.
De Bouwstenen van LangGraph: State, Nodes en Edges
Voordat we code gaan schrijven, is het belangrijk om de drie kernconcepten van LangGraph goed te begrijpen. Eigenlijk draait alles om deze drie elementen.
State: Het Geheugen van Je Graaf
De state is een gedeeld dataobject dat door de hele graaf stroomt. Het bevat alle informatie die je agent nodig heeft: berichten, tussenresultaten, variabelen — werkelijk alles. Elke node leest de huidige state, voert een bewerking uit en geeft een bijgewerkte state terug.
from typing import Annotated, TypedDict
from langgraph.graph import MessagesState
# Optie 1: Gebruik de ingebouwde MessagesState
# (bevat automatisch een 'messages'-veld met de juiste reducer)
# Optie 2: Definieer je eigen state met extra velden
class AgentState(MessagesState):
"""State voor onze agent met extra velden."""
zoekresultaten: list[str]
stappen_teller: int
Wat ik persoonlijk erg elegant vind aan LangGraph's state-systeem is het gebruik van reducers. De MessagesState gebruikt automatisch een reducer die nieuwe berichten toevoegt aan de bestaande lijst, in plaats van ze te overschrijven. Zo bouw je stap voor stap een compleet gespreksverloop op.
Nodes: De Werkpaarden van Je Agent
Nodes zijn waar het echte werk gebeurt. Elke node is een Python-functie die de state ontvangt, iets doet en een gedeeltelijke update teruggeeft. Typische nodes zijn:
- Een LLM-aanroep die het volgende antwoord genereert
- Een tool-executie die een externe API aanroept
- Een verwerkingsstap die data transformeert
- Een validatiestap die output controleert
Edges: De Verbindingen Tussen Nodes
Edges bepalen de volgorde van uitvoering. LangGraph kent twee soorten:
- Directe edges — Vaste verbindingen van node A naar node B. Simpel en voorspelbaar.
- Conditionele edges — Dynamische routering op basis van de huidige state. Dit is eigenlijk waar de magie zit: je agent beslist zelf welke stap hij als volgende neemt.
Je Eerste LangGraph Agent: Een ReAct-Agent met Tool-Calling
Het ReAct-patroon (Reasoning + Acting) is de standaard architectuur voor AI-agents. Het werkt als volgt: de agent redeneert over de vraag, selecteert een tool, voert die tool uit, observeert het resultaat, en herhaalt dit tot hij een definitief antwoord heeft.
Klinkt logisch, toch? Laten we een complete ReAct-agent bouwen die het weer kan opvragen en berekeningen kan uitvoeren.
Stap 1: Definieer de Tools
from langchain_core.tools import tool
from datetime import datetime
@tool
def haal_weer_op(stad: str) -> str:
"""Haal de actuele weersinformatie op voor een Nederlandse stad.
Args:
stad: De naam van de stad (bijv. Amsterdam, Rotterdam, Utrecht)
"""
# In productie: koppel dit aan een echte weer-API
weer_data = {
"Amsterdam": {"temp": 14, "beschrijving": "Bewolkt met af en toe zon", "wind": "3 Bft"},
"Rotterdam": {"temp": 13, "beschrijving": "Licht bewolkt", "wind": "4 Bft"},
"Utrecht": {"temp": 15, "beschrijving": "Zonnig", "wind": "2 Bft"},
}
info = weer_data.get(stad, {"temp": "?", "beschrijving": "Onbekende stad", "wind": "?"})
return f"Weer in {stad}: {info['temp']}°C, {info['beschrijving']}, wind {info['wind']}"
@tool
def bereken(expressie: str) -> str:
"""Voer een wiskundige berekening uit.
Args:
expressie: Een wiskundige expressie (bijv. '2 + 3 * 4')
"""
try:
resultaat = eval(expressie, {"__builtins__": {}})
return f"Resultaat: {resultaat}"
except Exception as e:
return f"Fout bij berekening: {e}"
tools = [haal_weer_op, bereken]
Stap 2: Bouw de Graaf
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.prebuilt import ToolNode
from langchain_anthropic import ChatAnthropic
# Initialiseer het LLM met tool-ondersteuning
llm = ChatAnthropic(model="claude-sonnet-4-6-20250514")
llm_met_tools = llm.bind_tools(tools)
def agent_node(state: MessagesState):
"""De agent-node roept het LLM aan met de beschikbare tools."""
antwoord = llm_met_tools.invoke(state["messages"])
return {"messages": [antwoord]}
def moet_doorgaan(state: MessagesState) -> str:
"""Bepaal of de agent een tool moet aanroepen of kan stoppen."""
laatste_bericht = state["messages"][-1]
# Als het LLM tool-calls heeft gegenereerd, ga naar de tool-node
if laatste_bericht.tool_calls:
return "tools"
# Anders zijn we klaar
return END
# Bouw de graaf
graaf_builder = StateGraph(MessagesState)
# Voeg nodes toe
graaf_builder.add_node("agent", agent_node)
graaf_builder.add_node("tools", ToolNode(tools))
# Voeg edges toe
graaf_builder.add_edge(START, "agent")
graaf_builder.add_conditional_edges("agent", moet_doorgaan, ["tools", END])
graaf_builder.add_edge("tools", "agent")
# Compileer de graaf
agent = graaf_builder.compile()
# Test de agent
resultaat = agent.invoke({
"messages": [("user", "Wat is het weer in Amsterdam en hoeveel is 24 * 365?")]
})
for bericht in resultaat["messages"]:
print(f"{bericht.type}: {bericht.content[:200]}")
Wat hier achter de schermen gebeurt:
- De gebruiker stelt een vraag die twee onderdelen bevat.
- De
agent_nodestuurt de vraag naar Claude, die twee tool-calls genereert. - De
moet_doorgaan-functie detecteert de tool-calls en routeert naar detools-node. - De
ToolNodevoert beide tools uit en stuurt de resultaten terug. - De
agent_nodewordt opnieuw aangeroepen met de tool-resultaten, en formuleert een definitief antwoord. - De
moet_doorgaan-functie detecteert geen tool-calls meer en beëindigt de loop.
Niet zo ingewikkeld als het klinkt, toch?
De Snelle Variant: create_react_agent
Wil je sneller aan de slag? LangGraph biedt een kant-en-klare create_react_agent die al het bovenstaande voor je afhandelt:
from langgraph.prebuilt import create_react_agent
# Eén regel om een volledige ReAct-agent te maken
agent = create_react_agent(
model="anthropic:claude-sonnet-4-6-20250514",
tools=[haal_weer_op, bereken],
prompt="Je bent een behulpzame Nederlandse assistent. Antwoord altijd in het Nederlands.",
)
resultaat = agent.invoke({
"messages": [("user", "Wat is 15% van 2500 en hoe is het weer in Utrecht?")]
})
print(resultaat["messages"][-1].content)
De create_react_agent is ideaal voor prototyping en snelle experimenten. Voor productie wil je echter meestal de graaf handmatig opbouwen — zo heb je volledige controle over de flow en kun je edge cases beter afvangen.
Geheugen en Persistentie met Checkpointers
Oké, nu wordt het echt interessant. Een van de krachtigste features van LangGraph is het checkpointing-systeem. Een checkpointer slaat de state van je graaf op na elke stap (een zogenaamde "superstep"), waardoor je agent geheugen krijgt over meerdere interacties heen.
In-Memory Checkpointer voor Ontwikkeling
from langgraph.checkpoint.memory import MemorySaver
# Maak een checkpointer aan
geheugen = MemorySaver()
# Compileer de graaf met geheugen
agent = graaf_builder.compile(checkpointer=geheugen)
# Gebruik een thread_id om gesprekken te scheiden
config = {"configurable": {"thread_id": "gesprek-1"}}
# Eerste interactie
antwoord1 = agent.invoke(
{"messages": [("user", "Mijn naam is Jan. Wat is het weer in Amsterdam?")]},
config=config
)
print(antwoord1["messages"][-1].content)
# Tweede interactie — de agent onthoudt je naam!
antwoord2 = agent.invoke(
{"messages": [("user", "Herinner je mijn naam nog?")]},
config=config
)
print(antwoord2["messages"][-1].content)
# Output: "Ja, je naam is Jan!"
Best gaaf om te zien hoe dat werkt. De MemorySaver slaat alles op in het werkgeheugen — prima voor ontwikkeling en testen, maar niet geschikt voor productie (want bij een herstart ben je alles kwijt).
SQLite Checkpointer voor Eenvoudige Persistentie
import sqlite3
from langgraph.checkpoint.sqlite import SqliteSaver
# Persistente opslag in een SQLite-bestand
db_verbinding = sqlite3.connect("agent_geheugen.db", check_same_thread=False)
checkpointer = SqliteSaver(db_verbinding)
agent = graaf_builder.compile(checkpointer=checkpointer)
config = {"configurable": {"thread_id": "klant-42"}}
# Nu overleeft het geheugen een herstart van je applicatie
PostgreSQL voor Productie
Voor productieomgevingen pak je het serieuzer aan met PostgresSaver:
from langgraph.checkpoint.postgres import PostgresSaver
with PostgresSaver.from_conn_string(
"postgresql://user:wachtwoord@localhost/agentdb"
) as checkpointer:
checkpointer.setup() # Maakt de benodigde tabellen aan
agent = graaf_builder.compile(checkpointer=checkpointer)
Welke checkpointer moet je wanneer gebruiken? Deze tabel maakt het overzichtelijk:
| Checkpointer | Gebruik | Persistentie |
|---|---|---|
MemorySaver | Ontwikkeling / testen | Alleen in geheugen |
SqliteSaver | Lokale apps / prototypes | SQLite-bestand |
PostgresSaver | Productie | PostgreSQL-database |
Human-in-the-Loop: Menselijke Tussenkomst in Je Workflow
Niet alles kan of mag volledig geautomatiseerd worden. Soms wil je dat een mens toestemming geeft voordat een agent een actie uitvoert — denk aan het versturen van een e-mail, het plaatsen van een bestelling of het wijzigen van klantgegevens. Eerlijk gezegd, voor de meeste zakelijke toepassingen is dit een harde eis.
LangGraph maakt dit verrassend eenvoudig met de interrupt()-functie.
from langgraph.types import interrupt, Command
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.checkpoint.memory import MemorySaver
class BestellingState(MessagesState):
bestelling: dict
goedgekeurd: bool
def maak_bestelling_node(state: BestellingState):
"""Stel een bestelling samen op basis van het gesprek."""
return {
"bestelling": {
"product": "AI Workflow Licentie",
"prijs": 299.00,
"valuta": "EUR"
}
}
def goedkeuring_node(state: BestellingState):
"""Pauzeer voor menselijke goedkeuring."""
beslissing = interrupt({
"vraag": "Wil je deze bestelling plaatsen?",
"details": state["bestelling"]
})
return {"goedgekeurd": beslissing}
def verwerk_bestelling_node(state: BestellingState):
"""Verwerk de bestelling als deze is goedgekeurd."""
if state["goedgekeurd"]:
return {"messages": [("assistant", "Bestelling succesvol geplaatst!")]}
return {"messages": [("assistant", "Bestelling geannuleerd.")]}
# Bouw de graaf
builder = StateGraph(BestellingState)
builder.add_node("maak_bestelling", maak_bestelling_node)
builder.add_node("goedkeuring", goedkeuring_node)
builder.add_node("verwerk", verwerk_bestelling_node)
builder.add_edge(START, "maak_bestelling")
builder.add_edge("maak_bestelling", "goedkeuring")
builder.add_edge("goedkeuring", "verwerk")
builder.add_edge("verwerk", END)
geheugen = MemorySaver()
graaf = builder.compile(checkpointer=geheugen)
config = {"configurable": {"thread_id": "bestelling-1"}}
# Start de workflow — deze pauzeert bij de goedkeurings-node
resultaat = graaf.invoke(
{"messages": [("user", "Ik wil een licentie kopen")]},
config=config
)
# resultaat bevat nu de interrupt-informatie
# Hervat met goedkeuring
definitief = graaf.invoke(Command(resume=True), config=config)
print(definitief["messages"][-1].content)
# Output: "Bestelling succesvol geplaatst!"
Het mooie hieraan is dat de interrupt() geen resources verbruikt terwijl er op goedkeuring wordt gewacht. De state wordt opgeslagen in de checkpointer en kan maanden later worden hervat — zelfs op een compleet andere machine. Dat is behoorlijk krachtig als je erover nadenkt.
Multi-Agent Orchestratie
Voor complexere taken kun je meerdere gespecialiseerde agents combineren tot één systeem. LangGraph biedt hiervoor twee hoofdpatronen.
Supervisor-Patroon
Eén "supervisor"-agent coördineert meerdere specialist-agents. De supervisor ontvangt de taak, bepaalt welke specialist het beste geschikt is, delegeert het werk en integreert de resultaten. Vergelijk het met een teamleider die taken verdeelt over z'n teamleden.
from langgraph.prebuilt import create_react_agent
from langgraph.graph import StateGraph, MessagesState, START, END
# Specialist-agents
onderzoeker = create_react_agent(
model="anthropic:claude-sonnet-4-6-20250514",
tools=[zoek_web, zoek_papers],
prompt="Je bent een onderzoeksspecialist. Zoek relevante informatie.",
)
schrijver = create_react_agent(
model="anthropic:claude-sonnet-4-6-20250514",
tools=[schrijf_document],
prompt="Je bent een technisch schrijver. Schrijf duidelijke documentatie.",
)
def supervisor_node(state: MessagesState):
"""Bepaal welke specialist aan de beurt is."""
# Analyseer de taak en routeer naar de juiste specialist
...
def routeer(state: MessagesState) -> str:
"""Conditionele routing naar de juiste specialist."""
laatste = state["messages"][-1]
if "onderzoek" in laatste.content.lower():
return "onderzoeker"
elif "schrijf" in laatste.content.lower():
return "schrijver"
return END
# Bouw de supervisor-graaf
builder = StateGraph(MessagesState)
builder.add_node("supervisor", supervisor_node)
builder.add_node("onderzoeker", onderzoeker)
builder.add_node("schrijver", schrijver)
builder.add_edge(START, "supervisor")
builder.add_conditional_edges("supervisor", routeer, ["onderzoeker", "schrijver", END])
builder.add_edge("onderzoeker", "supervisor")
builder.add_edge("schrijver", "supervisor")
multi_agent = builder.compile()
Swarm-Patroon
In het swarm-patroon communiceren agents direct met elkaar via handoffs. Elke agent kan zelf beslissen om het werk door te geven aan een andere agent — zonder dat er een centrale supervisor nodig is. LangGraph biedt hiervoor de langgraph-swarm bibliotheek. In de praktijk zie ik het supervisor-patroon het vaakst gebruikt worden, maar voor hele dynamische workflows kan swarm echt een uitkomst zijn.
LangGraph vs. CrewAI: Wanneer Kies Je Wat?
We hebben eerder geschreven over CrewAI voor het bouwen van multi-agent systemen. Dus hoe verhoudt LangGraph zich daartoe? Hier een eerlijke vergelijking:
| Aspect | LangGraph | CrewAI |
|---|---|---|
| Architectuur | Graaf-gebaseerde state machine | Rol-gebaseerd team model |
| Leercurve | Steil — vereist begrip van grafen | Laag — intuïtief rol-concept |
| Flexibiliteit | Maximaal — volledige controle over flow | Goed — binnen het teammodel |
| Cyclische workflows | Ja — kernfunctionaliteit | Beperkt |
| Human-in-the-loop | Ingebouwde interrupt() | Beperkte ondersteuning |
| Debugging | Uitstekend (LangSmith) | Basis |
| Productie-gereedheid | Hoog — battle-tested | Gemiddeld |
| Ideaal voor | Complexe, cyclische productie-workflows | Snel prototypen van team-workflows |
Mijn vuistregel: Begin met CrewAI als je snel wilt prototypen en je workflow grotendeels lineair is. Stap over naar LangGraph zodra je cyclische logica, robuust geheugen of human-in-the-loop nodig hebt in productie. Het is geen schande om met CrewAI te starten en later te migreren — sterker nog, dat is vaak de slimste aanpak.
Best Practices voor Productie
Het bouwen van een werkende agent is één ding. Hem betrouwbaar draaien in productie is een heel ander verhaal. Na het nodige experimenteren zijn dit de belangrijkste lessen die ik kan meegeven:
1. Configureer Altijd een Persistente Checkpointer
Zonder duurzame opslag verliest een procescrash alle in-flight state. Gebruik PostgresSaver in productie en test regelmatig of recovery correct werkt. Je wilt hier niet achter komen wanneer het al te laat is.
2. Beperk het Aantal Tool-Aanroepen
Zonder limiet kan een agent eindeloos blijven loopen — en dat wil je écht niet (zowel voor je gebruikers als voor je API-rekening). Stel altijd een maximum in:
agent = create_react_agent(
model="anthropic:claude-sonnet-4-6-20250514",
tools=tools,
prompt="...",
)
# Beperk het aantal stappen bij aanroep
resultaat = agent.invoke(
{"messages": [("user", "Complexe vraag")]},
config={"recursion_limit": 25} # Max 25 stappen
)
3. Houd het Aantal Tools Beperkt
Intern onderzoek van Anthropic toont aan dat 58 tools al ~55.000 tokens kunnen verbruiken in het systeemprompt. Dat is flink wat context. Bovendien daalt de nauwkeurigheid van toolselectie naarmate er meer tools beschikbaar zijn. Streef naar maximaal 15-20 tools per agent. Heb je er meer nodig? Overweeg dan tool-search of meerdere gespecialiseerde agents.
4. Schrijf Uitstekende Tool-Beschrijvingen
Dit klinkt misschien triviaal, maar de beschrijving van je tools is eerlijk gezegd de belangrijkste optimalisatie voor betrouwbare function calling. Het LLM gebruikt de naam, docstring en parameter-beschrijvingen om te bepalen wanneer en hoe een tool wordt ingezet. Investeer hier echt tijd in — het verschil tussen een vage en een scherpe tool-beschrijving is enorm.
5. Gebruik Streaming voor UX
# Stream de output voor een betere gebruikerservaring
for chunk in agent.stream(
{"messages": [("user", "Vertel me over het weer")]},
stream_mode="updates"
):
for node_naam, update in chunk.items():
print(f"[{node_naam}]: {update}")
Niemand wil tien seconden naar een leeg scherm staren. Streaming maakt het wachten een stuk draaglijker.
6. Monitor met LangSmith
LangSmith is de observability-tool van LangChain. Het biedt gedetailleerde traces per node, inclusief token-verbruik, latency en foutmeldingen. Voor productie-agents is dit eigenlijk onmisbaar — je wilt precies kunnen zien waar een agent vastloopt of te veel tokens verbrandt.
MCP-Integratie: LangGraph met het Model Context Protocol
We hebben eerder uitgebreid geschreven over het Model Context Protocol (MCP). Goed nieuws: LangGraph ondersteunt MCP via het langchain-mcp-adapters pakket. Hiermee kun je elke MCP-server als tool aanbieden aan je LangGraph-agent:
pip install langchain-mcp-adapters
Dit opent een wereld aan mogelijkheden. Je LangGraph-agent kan via MCP verbinding maken met databases, API's, bestandssystemen en meer — allemaal via een gestandaardiseerd protocol. Zeker de moeite waard om te verkennen als je al MCP-servers hebt draaien.
Veelgestelde Vragen
Wat is het verschil tussen LangChain en LangGraph?
LangChain richt zich op het bouwen van lineaire ketens (chains) van LLM-aanroepen, terwijl LangGraph een grafenmodel biedt voor complexe, cyclische workflows. LangGraph is gebouwd bovenop LangChain en is specifiek ontworpen voor het bouwen van stateful AI-agents die iteratief redeneren en handelen. Kort gezegd: gebruik LangChain voor eenvoudige RAG-pipelines en LangGraph wanneer je echte agents nodig hebt.
Is LangGraph geschikt voor productiegebruik?
Ja, absoluut. LangGraph versie 1.1.0 (maart 2026) wordt al gebruikt door grote bedrijven als Klarna, Replit en Elastic. Het framework biedt durable execution, checkpointing met PostgreSQL, human-in-the-loop interrupts en uitgebreide monitoring via LangSmith. Zorg er wel voor dat je een persistente checkpointer configureert en het aantal tool-calls begrenst.
Hoeveel kost het om een LangGraph-agent te draaien?
De kosten bestaan uit twee componenten: LLM API-kosten en infrastructuurkosten. De LLM-kosten hangen af van je modelkeuze en het aantal tokens per interactie. Tool-definities verbruiken input-tokens — bij 20 tools reken je op zo'n 5.000-15.000 extra tokens per aanroep. LangGraph zelf is open-source en gratis. LangGraph Platform (de managed hosting optie) kent eigen tarieven.
Kan LangGraph samenwerken met MCP-servers?
Ja, via het langchain-mcp-adapters pakket kun je MCP-tools naadloos integreren in je LangGraph-agents. Elke MCP-server die tools aanbiedt, kan als tool-node worden opgenomen in je graaf. Dit combineert de gestandaardiseerde toolintegratie van MCP met de krachtige orchestratie van LangGraph.
Moet ik LangGraph of CrewAI kiezen voor mijn project?
Dat hangt echt af van je specifieke use case. Kies CrewAI als je snel wilt prototypen, je workflow grotendeels lineair is en je team minder technisch is. Kies LangGraph als je cyclische workflows nodig hebt, robuust geheugen en human-in-the-loop vereisten hebt, of je agent in productie moet draaien met hoge betrouwbaarheid. Je kunt ook prima met CrewAI beginnen en later overstappen naar LangGraph wanneer je complexiteit toeneemt.