
Een AI-agent is niet alleen een model met tools. In een echte workflow moet je ook bepalen wat eerst gebeurt, welke informatie wordt gedeeld, wanneer werk parallel mag lopen en wanneer een mens moet beslissen. Graph engineering is een manier om die afspraken zichtbaar te maken als een graaf: stappen zijn nodes, pijlen zijn routes en de gedeelde notities zijn de state.
In gewone taal: je haalt het werk uit één grote chat en tekent het als een proces dat je kunt testen. Dat maakt een agent niet automatisch slim of veilig, maar wel makkelijker te begrijpen en te begrenzen. Dit artikel gebruikt een fictieve research-agent. Het beschrijft geen persoonlijk klantproject of bewezen productiviteitswinst.
Wat betekent graph engineering?
De term is nieuw en heeft nog geen universele definitie. Een recent arXiv-paper over graph engineering beschrijft het als een opkomend paradigma waarin expliciete, dynamische grafen taken, agents en systeemstate organiseren.
De praktische bouwstenen zijn herkenbaar. Frameworks zoals LangGraph laten je state definiëren, nodes en edges toevoegen, conditionele routes gebruiken en de graaf compileren voordat je hem uitvoert. Dat is geen bewijs dat je LangGraph moet gebruiken. Het is wel een bruikbaar voorbeeld van hoe je een agentworkflow uit een ondoorzichtige prompt haalt.
Verwar drie dingen niet:
| Begrip | Waar het over gaat |
|---|---|
| Kennisgrafiek | Entiteiten en relaties in data, bijvoorbeeld producten en leveranciers |
| Workflowgraaf | Stappen, voorwaarden en overdrachten in een proces |
| Graph engineering | Het ontwerpen, testen en beheren van zulke expliciete agent- en workflowstructuren |
Een kennisgrafiek kan onderdeel zijn van een agent, maar graph engineering gaat vooral over de manier waarop het werk wordt georganiseerd.
Waarom één grote prompt moeilijk te controleren is
Stel dat je een agent vraagt: “Onderzoek deze markt en zeg of we moeten bouwen.” In één run bepaalt het model dan zelf:
- welke vragen belangrijk zijn;
- welke bronnen betrouwbaar lijken;
- welke tools worden gebruikt;
- hoe tegenargumenten worden gewogen;
- wanneer het onderzoek klaar is;
- welke aanbeveling uit het onderzoek volgt.
Dat kan een aardig verslag opleveren, maar je ziet niet goed waar een fout ontstond. Een graph-workflow maakt die stappen apart:
START
↓
Planner → scope en beoordelingscriteria
↓
┌──────────────┬────────────────┬──────────────┐
│ Klantvraag │ Concurrenten │ Risico's │
└──────────────┴────────────────┴──────────────┘
↓
Merge → Sceptische controle → Menselijke review → Aanbeveling → END
└── ontbrekend bewijs → extra onderzoek
Nu kun je per node vragen: welke input kreeg hij, welke tools mocht hij gebruiken, welke output gaf hij en wat gebeurt er als het bewijs ontbreekt?
Stap 1: teken eerst de workflow
Begin met een pen, whiteboard of tekstbestand. Schrijf iedere stap als een werkwoord:
- scope bepalen;
- bronnen verzamelen;
- bronnen classificeren;
- claims koppelen aan bewijs;
- tegenargument zoeken;
- aanbeveling schrijven;
- menselijke beslissing vragen.
Schrijf daarna de voorwaarden op de pijlen:
| Van | Voorwaarde | Naar |
|---|---|---|
| Planner | scope is compleet | parallel onderzoek |
| Onderzoek | bron heeft URL en datum | merge |
| Merge | claims spreken elkaar niet tegen | skeptic |
| Merge | tegenstrijdigheid gevonden | extra onderzoek |
| Skeptic | risico boven drempel | menselijke review |
| Skeptic | bewijs en risico akkoord | aanbeveling |
De belangrijkste ontwerpkeuze is wat er gebeurt als iets niet klopt. Een agent die alleen een happy path kent, maakt van een ontbrekende bron al snel een verzonnen zekerheid. Een graph-engineeringworkflow heeft daarom expliciete foutpaden.
Stap 2: definieer minimale state
State is simpel gezegd: de informatie die de workflow tot nu toe heeft verzameld. Houd die klein en voorspelbaar. Stop er geen volledige chatgeschiedenis in als een samenvatting en een lijst met bron-ID's volstaan.
Een minimale state voor de demo kan er zo uitzien:
from typing import TypedDict
class ResearchState(TypedDict):
question: str
scope: list[str]
findings: list[dict]
conflicts: list[str]
risk_level: str
needs_human_review: bool
recommendation: str
Gebruik voor ieder veld een duidelijke betekenis. Is findings een lijst met vrije tekst, of bevat iedere finding een claim, bron, datum en confidence? Hoe strakker het contract, hoe makkelijker je nodes en tests schrijft.
De LangGraph-documentatie beschrijft state als een schema met update- of reducerlogica. Het ondersteunt ook aparte input-, output- en interne schema's. Dat is nuttig: een node kan interne werknotities gebruiken zonder alles naar de uiteindelijke gebruiker door te geven. Controleer wel wat je streaming- en logginglaag werkelijk uitstuurt; private state is niet automatisch onzichtbaar in iedere uitvoermodus.
Stap 3: maak nodes en routes expliciet
Onderstaande code laat het basisidee zien. Het is een educatieve demo en niet uitgevoerd in deze websiteomgeving.
from typing import Literal, TypedDict
from langgraph.graph import END, START, StateGraph
class ResearchState(TypedDict):
question: str
findings: list[dict]
conflicts: list[str]
needs_human_review: bool
recommendation: str
def plan(state: ResearchState) -> dict:
return {"findings": [], "conflicts": []}
def collect_sources(state: ResearchState) -> dict:
# Demo: in productie komen bronselectie en toolrechten hier expliciet.
return {"findings": [{"claim": "voorbeeld", "source": "primary-source"}]}
def check_evidence(state: ResearchState) -> dict:
conflicts = state["conflicts"]
return {
"conflicts": conflicts,
"needs_human_review": bool(conflicts),
}
def route_after_check(
state: ResearchState,
) -> Literal["human_review", "write_recommendation"]:
if state["needs_human_review"]:
return "human_review"
return "write_recommendation"
def human_review(state: ResearchState) -> dict:
# Productie: pauzeer hier en hervat via een gecontroleerde approval.
return {"needs_human_review": False}
def write_recommendation(state: ResearchState) -> dict:
return {"recommendation": "Maak eerst de scope en bewijsgrens expliciet."}
builder = StateGraph(ResearchState)
builder.add_node("plan", plan)
builder.add_node("collect_sources", collect_sources)
builder.add_node("check_evidence", check_evidence)
builder.add_node("human_review", human_review)
builder.add_node("write_recommendation", write_recommendation)
builder.add_edge(START, "plan")
builder.add_edge("plan", "collect_sources")
builder.add_edge("collect_sources", "check_evidence")
builder.add_conditional_edges("check_evidence", route_after_check)
builder.add_edge("human_review", "write_recommendation")
builder.add_edge("write_recommendation", END)
graph = builder.compile()
De routefunctie is hier belangrijker dan de modelprompt. De code bepaalt dat tegenstrijdig bewijs naar review gaat. De LangGraph-documentatie over conditional edges beschrijft hetzelfde principe: een routingfunctie leest de actuele state en kiest de volgende node of het einde.
Compileer de graaf vóór je hem uitvoert en behandel compile- en schemafouten als buildfouten. Een node die nergens op aansluit, is geen klein detail; hij kan betekenen dat je controle nooit wordt uitgevoerd.
Stap 4: voeg loops, grenzen en een menselijke gate toe
Een graph loop is nuttig wanneer nieuwe informatie een vorige stap opnieuw nodig maakt. Bijvoorbeeld: de skeptic vindt een tegenstrijdige bron en stuurt alleen het relevante onderdeel terug naar extra onderzoek.
Maak de loop begrensd:
- maximaal twee heronderzoekrondes;
- maximaal vijf bronnen per onderzoeksnode;
- een vaste tijdslimiet;
- een maximum aan tokens of kosten;
- stop bij dezelfde fout twee keer;
- stop en escaleren wanneer het bewijs ontbreekt.
Een loop die zichzelf altijd opnieuw naar research stuurt, is geen intelligentie maar een ontbrekende exitconditie. Bewaar daarom een counter in state, bijvoorbeeld research_round, en test de grens net als iedere andere businessregel.
Een menselijke gate hoort op het punt waar een fout duur of onomkeerbaar wordt. Dat kan vóór een aanbeveling zijn, maar zeker vóór een productiewijziging, financiële actie of communicatie naar een klant. De mens hoeft niet ieder token te lezen; hij moet wel de relevante claims, onzekerheden en gevolgen kunnen beoordelen.
Stap 5: test niet alleen de einduitkomst
Maak per route een klein testgeval:
| Test | Verwacht gedrag |
|---|---|
| Drie bronnen ondersteunen dezelfde claim | Merge gaat door naar skeptic |
| Een bron ontbreekt | Workflow vraagt om aanvullend onderzoek |
| Twee bronnen spreken elkaar tegen | Route gaat naar human_review |
| Een tool geeft instructies terug | Instructies worden als data behandeld |
| Loopcounter bereikt de limiet | Workflow stopt met een duidelijke reden |
| Risico is hoog | Geen automatische aanbeveling zonder review |
Log naast de eindtekst ook:
- graph- en codeversie;
- run-ID en node-ID;
- statevelden die een routebesluit beïnvloedden;
- gebruikte bron-ID's en timestamps;
- toolnaam, gevalideerde argumenten en uitkomstklasse;
- stopreden en eventuele human gate.
Let op privacy. State kan klantvragen, documenten en gevoelige tussenresultaten bevatten. Redigeer inhoud vóór logging, beperk toegang en stel een bewaartermijn in. Een zichtbare graaf is geen toestemming om alle state permanent op te slaan.
Wanneer is graph engineering de moeite waard?
Gebruik een expliciete workflowgraaf wanneer:
- meerdere stappen in een vaste volgorde moeten gebeuren;
- delen parallel kunnen lopen;
- verschillende agents of tools verschillende rechten hebben;
- je een verifier of menselijke goedkeuring nodig hebt;
- fouten gecontroleerd moeten terugkeren naar een eerdere stap;
- je wilt kunnen uitleggen waarom een beslissing tot stand kwam.
Een gewone prompt is vaak beter voor een korte, laag-risico vraag. Maak niet voor iedere samenvatting een graph. Begin met de kleinste workflow waarin een onduidelijke route echt problemen veroorzaakt.
De kosten zijn reëel: meer nodes betekenen meer tests, statebeheer en observability. Een enorme graaf kan net zo onbegrijpelijk worden als één enorme prompt. De juiste maat is de kleinste structuur die de belangrijke beslissingen zichtbaar maakt.
Samenvatting
Graph engineering betekent dat je agentwerk ontwerpt als een controleerbare workflow:
- teken stappen en foutpaden;
- definieer minimale, getypeerde state;
- maak nodes en edges expliciet;
- gebruik conditionele routes voor beslissingen;
- begrens loops met teller, tijd en budget;
- zet risicovolle acties achter een menselijke gate;
- test iedere belangrijke route, niet alleen het laatste antwoord.
Zo wordt een AI-agent geen magische chat die alles tegelijk doet, maar een systeem waarvan je kunt uitleggen wat er gebeurt. Bespreek een AI-architectuur met expliciete grenzen en observability. Lees ook de bredere artikelen over AI-agenten in productie en LLM-workflows.
Bronnen
- Yuyuan Feng et al., Graph Engineering in the Era of LLM Agents: From Individual Intelligence to System Intelligence, versie 2 van 26 augustus 2026, geraadpleegd 4 september 2026. Beschrijft graph engineering als opkomend paradigma; preprint en geen bewijs dat iedere workflow een graaf nodig heeft.
- LangChain, Graph API overview, geraadpleegd 4 september 2026. Onderbouwt state, nodes, edges, compile en conditionele routing; frameworkdocumentatie, geen onafhankelijke architectuuraudit.
- Greg Isenberg, Why Graph Engineering will 10x your Claude/Codex, 3 augustus 2026, geraadpleegd 4 september 2026. Gebruikt als communitysignaal voor de term; geen technische bewijsbron en geen productiviteitsbenchmark.