LangChain-agents: de complete technische gids voor 2026

20 juni 2026
14 min leestijd

20 juni 2026
14 min leestijd
LangChain-agentsHover to exploreEen LLM die vragen beantwoordt is nuttig. Een LLM die dingen kan doen — je database bevragen, een Slack-bericht sturen, een refund afhandelen en daarna terugkoppelen wat er gebeurd is — is een product. LangChain-agents zijn in 2026 de standaardmanier om die loop te bouwen. Deze gids gaat van het mentale model tot productiecode: de agent-loop, tools schrijven, memory en state, structured output, streaming, foutafhandeling, en wat volgens r/LangChain, r/LocalLLaMA en de AI-hoek van X wel en niet werkt.
Deze gids is gebaseerd op de LangChain v1 agent-documentatie, de LangGraph-documentatie en terugkerende discussies op r/LangChain en @LangChainAI op X.
Elke LangChain-agent draait dezelfde loop, welk model je ook gebruikt:
ToolMessage aan het gesprek.Meer is het niet. De verfijning zit in welke tools je aanbiedt en hoe je de loop begrenst, niet in magie binnen het framework.
Met create_agent uit LangChain v1 blijft er nauwelijks boilerplate over:
from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search_orders(order_id: str) -> str:
"""Look up an order by ID and return its current status."""
# Replace with your real DB call
return f"Order {order_id}: Shipped, arriving 2026-06-23."
@tool
def issue_refund(order_id: str, reason: str) -> str:
"""Issue a full refund for an order given a reason."""
return f"Refund issued for order {order_id}. Reason: {reason}."
agent = create_agent(
model="anthropic:claude-sonnet-4-6",
tools=[search_orders, issue_refund],
system_prompt=(
"You are a helpful customer support agent. "
"Always look up the order before issuing a refund."
),
)
result = agent.invoke({
"messages": [{"role": "user", "content": "Refund order #4821 — it arrived broken."}]
})
print(result["messages"][-1].content)
Onder water roept de agent search_orders("4821") aan, leest het resultaat, roept dan issue_refund("4821", "arrived broken") aan en geeft ten slotte een bevestiging terug — allemaal binnen één invoke, zonder handmatige orkestratie.
De grootste hefboom op de kwaliteit van een agent is het ontwerp van je tools, niet de keuze van je model. Het model kiest een tool puur op basis van de functienaam, de docstring en het argumentschema. Zijn die slecht, dan redt geen enkele prompt-truc je nog.
Regels die in de praktijk standhouden:
search_and_refund() is een valkuil: splits hem. Het model moet elke stap los kunnen aanroepen."Error: order not found" terug in plaats van een exception te gooien — dan kan de agent het opnieuw proberen of de fout uitleggen in plaats van om te vallen.from langchain.tools import tool
from pydantic import BaseModel, Field
class SearchInput(BaseModel):
order_id: str = Field(description="The numeric order ID, e.g. '4821'")
include_history: bool = Field(
default=False,
description="Set True to include the full shipment history"
)
@tool(args_schema=SearchInput)
def search_orders(order_id: str, include_history: bool = False) -> str:
"""
Look up an order's current status by order ID.
Call this FIRST before any action that modifies the order.
Returns: status string, or an error message if not found.
"""
try:
order = db.get_order(order_id)
if not order:
return f"Error: order {order_id} not found."
base = f"Order {order_id}: {order.status}, ETA {order.eta}."
if include_history:
base += f" History: {order.shipment_history}"
return base
except Exception as e:
return f"Error fetching order: {str(e)}"
Standaard is elke agent.invoke() stateless: de agent vergeet de vorige beurt zodra hij klaar is. Voor gesprekken over meerdere beurten moet je de state expliciet meegeven. LangChain biedt twee patronen:
Patroon A — checkpointing per thread met LangGraph (aanbevolen voor productie)
from langchain.agents import create_agent
from langgraph.checkpoint.memory import MemorySaver
# MemorySaver keeps state in RAM; swap for PostgresSaver in production
checkpointer = MemorySaver()
agent = create_agent(
model="anthropic:claude-sonnet-4-6",
tools=[search_orders, issue_refund],
checkpointer=checkpointer,
)
# Same thread_id = same conversation memory
config = {"configurable": {"thread_id": "user-123-session-456"}}
# Turn 1
agent.invoke(
{"messages": [{"role": "user", "content": "What is the status of order 4821?"}]},
config=config,
)
# Turn 2 — agent remembers turn 1
agent.invoke(
{"messages": [{"role": "user", "content": "Go ahead and refund it."}]},
config=config,
)
Patroon B — samenvatten bij lange contexten
Groeit een thread voorbij het contextvenster van je model, gebruik dan SummarizationMiddleware om oude berichten vóór elke modelaanroep automatisch samen te persen tot een lopende samenvatting. De agent verliest de letterlijke geschiedenis maar houdt de strekking — genoeg voor de meeste support- en assistent-toepassingen.
Vaak wil je dat de agent informatie verzamelt en een gevalideerd object teruggeeft in plaats van een lap tekst. Geef een Pydantic-model mee aan response_format en de agent levert binnen dezelfde loop een getypeerd object op, zonder losse parsestap:
from pydantic import BaseModel
from langchain.agents import create_agent
class SupportTicket(BaseModel):
order_id: str
issue_type: str # "refund" | "late_delivery" | "wrong_item"
recommended_action: str
confidence: float # 0.0 – 1.0
agent = create_agent(
model="anthropic:claude-sonnet-4-6",
tools=[search_orders],
response_format=SupportTicket,
system_prompt=(
"Classify the customer's issue and recommend an action. "
"Always search the order before classifying."
),
)
result = agent.invoke({"messages": [
{"role": "user", "content": "My order 4821 never arrived — it's been 3 weeks."}
]})
ticket: SupportTicket = result["structured_response"]
print(ticket.issue_type) # "late_delivery"
print(ticket.recommended_action) # "escalate to carrier"
print(ticket.confidence) # 0.92
Het grootste UX-probleem van agents is latency: de gebruiker ziet niets tot de hele loop klaar is. Streaming lost dat op door tokens en tool-events te tonen zodra ze er zijn. LangChain kent twee streaming-modi:
# Mode 1 — stream final output tokens only
for chunk in agent.stream(
{"messages": [{"role": "user", "content": "Status of order 4821?"}]},
stream_mode="messages",
):
if chunk[1].get("langgraph_node") == "agent":
print(chunk[0].content, end="", flush=True)
# Mode 2 — stream every event (tool calls, results, tokens)
for event in agent.stream(
{"messages": [{"role": "user", "content": "Status of order 4821?"}]},
stream_mode="updates",
):
kind = list(event.keys())[0]
if kind == "tools":
print(f"[tool] {event['tools']['messages'][0].name}")
elif kind == "agent":
for msg in event["agent"]["messages"]:
print(msg.content, end="", flush=True)
Gebruik in de praktijk stream_mode="updates" in elke UI met een live "aan het denken"-paneel: zo laat je zien welke tool de agent aanroept zonder op het eindantwoord te wachten.
Elke agent die geld kan uitgeven, een bericht kan versturen of naar een database kan schrijven, heeft menselijke goedkeuring nodig voor onomkeerbare acties. LangChain v1 geeft je twee opties: middleware voor eenvoudige gevallen, LangGraph-interrupts voor volledige controle.
# Simple approach — middleware
from langchain.agents.middleware import HumanInTheLoopMiddleware
agent = create_agent(
model="anthropic:claude-sonnet-4-6",
tools=[search_orders, issue_refund, send_email],
middleware=[
HumanInTheLoopMiddleware(
interrupt_on={"issue_refund": True, "send_email": True}
)
],
)
# Advanced approach — LangGraph interrupt node
from langgraph.types import interrupt
def human_approval_node(state):
last_tool_call = state["messages"][-1]
# Pause execution and surface the tool call to your UI
decision = interrupt({
"tool": last_tool_call.name,
"args": last_tool_call.tool_input,
"prompt": "Approve this action?",
})
if decision["approved"]:
return state # continue
# Inject a rejection message back into the graph
return {"messages": [ToolMessage(content="Action rejected by user.", ...)]}
Middleware heb je sneller draaiend. De LangGraph-interrupt is flexibeler: je kunt argumenten aanpassen in plaats van alleen goedkeuren of afwijzen. In klantprojecten beginnen we vrijwel altijd met middleware en pakken we pas interrupts als gebruikers een tool-aanroep moeten kunnen bewerken voordat die uitgevoerd wordt.
Dit onderscheid zorgt voor veel verwarring. In LangChain van 2022–2023 was ReAct (Reason + Act) het hoofdpatroon: het model werd gevraagd een "Thought / Action / Observation"-kladblok in platte tekst te produceren, dat LangChain parste om te bepalen wat er aangeroepen moest worden. Het werkte, maar was fragiel — elke afwijking van het formaat brak de parser.
In 2026 gebruikt create_agent native tool calling: het model levert een gestructureerde tool-aanroep in de API-response in plaats van in vrije tekst. Dat is betrouwbaarder, goedkoper (geen dubbele prompt) en wordt door elke grote provider ondersteund. ReAct is nu een terugvaloptie voor modellen zonder native tool calling, niet meer de standaardroute.
| Kenmerk | ReAct (legacy) | Native tool calling (standaard in v1) |
|---|---|---|
| Formaat | Kladblok in vrije tekst | Gestructureerde API-response |
| Betrouwbaarheid | Gevoelig voor formaat | Gevalideerd tegen schema |
| Parallelle tool-aanroepen | Nee | Ja (waar ondersteund) |
| Geschikt voor | Lokale modellen zonder tool calling | Al het andere |
LANGSMITH_API_KEY en LANGSMITH_TRACING=true in. Elke invoke, elke tool-aanroep en elke token wordt automatisch getraceerd. Daar ben je om twee uur 's nachts blij mee als er iets omvalt in productie.MemorySaver is prima lokaal, maar wissel hem vóór livegang om voor PostgresSaver of RedisSaver — anders wist een serverherstart alle gespreksstate.Na maanden meelezen op r/LangChain, r/LocalLLaMA en de AI-engineeringhoek van X komt het beeld uit de community neer op een paar terugkerende punten:
langchain / langchain-core / langgraph) verwart beginners nog steeds." Het LangChain-team erkent dat. Het mentale model is schoner in v1, maar de installatie laat mensen bij de eerste poging nog struikelen."De vraag in 2026 is niet 'moet ik LangChain gebruiken?' maar 'heb ik checkpointing, observability en provider-onafhankelijke tool calling nodig — of zit ik op één provider, drie stappen, en volstaat een directe call?' Weet welk probleem je hebt voordat je een framework kiest."
LangChain-agents zijn de juiste keuze zodra je minstens twee van deze dingen nodig hebt:
Pak in plaats daarvan de SDK van de provider als:
LangChain-agents zijn in 2026 geen tutorialspeelgoed meer. Met create_agent, native tool calling, state met checkpoints, structured output, streaming en middleware dekt het framework inmiddels alles wat een productie-agent nodig heeft. De leercurve is echt — vooral bij tool-ontwerp en het checkpoint-model van LangGraph — maar je krijgt er een agent voor terug die je kunt observeren, pauzeren, aan een mens kunt overdragen en naar een ander model kunt omzetten zonder je code te herschrijven. Dat is een stevige basis voor elke AI-MVP.
IdeaToMVP Academy
4-week live cohort for founders. Learn to ship AI agents, scope MVPs, and automate your business — taught by the same team that writes these guides.