Fundamentals to Advanced — with Framework Comparisons and Real Project Analysis
This document covers every major AI agent
execution pattern — from the simplest REPL loop through production-grade
stateful graph systems — alongside a detailed comparison of LangGraph, AutoGen,
and CrewAI.
Part 0 — Graph Fundamentals
A graph is a data structure made of two
things: nodes (the things) and edges (the connections between things).
Understanding graph types is essential before exploring agent frameworks,
because most modern agent runtimes are graph execution engines.
Figure 0.1 — Basic undirected graph
Types of Graphs
Directed graph — edges have a direction. 'A
calls B' is not the same as 'B calls A'.
Figure 0.2 — Directed graph
DAG (Directed Acyclic Graph) — directed, no
cycles. Used for pipelines where execution never goes back to a previous step.
Figure 0.3 — DAG: parallel paths, no cycles
Cyclic directed graph — has loops. Used in
agent frameworks for the ReAct tool loop: the agent node and tool node loop
back to each other until a condition is met.
Figure 0.4 — Cyclic graph: agent loop
Why Graphs for Agents?
An agent workflow maps naturally onto a
graph. Before graph-based frameworks, agent control flow was hidden inside LLM
prompts or tangled if/else chains. Representing it as an explicit graph makes
execution visible, testable, and modifiable without touching the LLM logic. The
graph is the map of execution.
Graph Concept | Agent Equivalent |
Node | Unit of work (LLM call, tool call, router, human approval) |
Directed edge | After this, run that |
Conditional edge | Go left if X, go right if Y |
Cycle | Keep looping until condition is met |
DAG | Linear pipeline, no re-execution |
State Machines
A state machine is a system that can be in
exactly one state at a time, with defined rules for transitioning between
states. It has three core concepts:
·
States — a finite set of conditions the
system can be in.
·
Transitions — events or conditions that
move the system from one state to another.
·
Current state — the state the system is
in right now.
Figure 0.5 — State machine: one active state at a time
LangGraph is a state machine runtime. Its
nodes are states, its edges are transitions, and its typed state dict is the
current state — carrying all accumulated data as execution moves through the
graph. The checkpointer snapshots the current state after every transition so
it can be resumed or rewound.
MapReduce — Fan-Out and Fan-In
MapReduce is a programming model for
processing large datasets in parallel, introduced by Google in 2004. It has two
phases:
·
Map — split the input into independent
chunks and process each in parallel (fan-out).
·
Reduce — collect all partial results and
merge them into a single output (fan-in).
Figure 0.6 — MapReduce: parallel fan-out then fan-in
aggregate
In agent frameworks this pattern appears
whenever you have a list of independent work items that can be processed
concurrently — document chunks, search queries, code files. LangGraph
implements it via the Send API: the split node dispatches N parallel branches
(fan-out), each runs independently, and an aggregate node merges the results
(fan-in). Wall-clock time is bounded by the slowest worker, not the sum of all
workers.
Vector Embeddings and Vector Databases
An embedding is a list of numbers (a
vector) that represents the meaning of a piece of text. An embedding model
reads text and outputs a vector — typically 768 to 1536 numbers. The key
property: text with similar meaning produces vectors that point in similar
directions in that high-dimensional space. This is measured with cosine
similarity.
A vector database stores these vectors and
answers the question: 'Given this query vector, which stored vectors are most
similar?' This is semantic search — it finds relevant content even when the
words don't match exactly.
Figure 0.7 — Vector embeddings: text → vector → similarity
search
Why this matters for agents: keyword search
fails when the query uses different words than the document. Vector search
finds conceptually related content regardless of exact wording. This is the
foundation of RAG (Retrieval-Augmented Generation) and every memory-augmented
agent pattern — inject only the relevant chunks into the prompt rather than the
entire knowledge base, keeping context windows focused and token costs low.
|
Term |
What it means |
|
Embedding |
A vector (list of numbers) representing the meaning of text |
|
Cosine similarity |
How similar two vectors are — 1.0 = identical direction, 0 =
unrelated |
|
Vector DB |
Database optimised for nearest-neighbour search over embeddings
(ChromaDB, Pinecone, pgvector) |
|
Top-K |
The K most similar chunks returned by the search — typically 3-5 |
|
RAG |
Retrieval-Augmented Generation — fetch relevant chunks, inject
into prompt, LLM reasons from them |
Part 1 — Foundational Agent Patterns
1. REPL (Read-Eval-Print Loop)
The simplest pattern. The agent reads
input, calls the LLM, outputs a response, and loops. No memory, no tool use, no
planning. Essentially a chatbot loop.
Figure 1.1 — REPL pattern
2. ReAct (Reasoning + Acting)
The dominant pattern for tool-using agents.
The LLM alternates between Thought, Action, and Observation in a scratchpad
loop until it reaches a final answer. Reasoning and acting are interleaved —
each observation feeds back into the next thought, grounding the LLM in real
results.
Figure 1.2 — ReAct: interleaved reasoning and acting
3. Plan-and-Execute
Separates planning from execution. A
planner LLM generates a step-by-step plan upfront; an executor agent runs each
step. Better for long-horizon tasks. A re-planner triggers if execution fails,
which is the key differentiator from ReAct.
Figure 1.3 — Plan-and-Execute with re-planning
4. Reflection / Self-Critique
The agent generates output, then a second
LLM call critiques it, and the agent revises. Loops until a quality gate is
passed.
Figure 1.4 — Reflection loop
Variants:
·
Reflexion — stores failed attempts in
memory to avoid repeating mistakes.
·
Constitutional AI — critique against a
fixed set of principles.
5. Multi-Agent (Orchestrator + Subagents)
One orchestrator decomposes a task and
delegates to specialist subagents. Subagents can run in parallel. The
orchestrator maintains shared state and synthesizes results.
Figure 1.5 — Multi-Agent with parallel subagents
6. Tree of Thoughts (ToT)
Extends chain-of-thought by exploring a
tree of reasoning paths rather than one linear chain. The model evaluates
intermediate steps and prunes dead branches (BFS or DFS). Best for
combinatorial search problems: puzzles, theorem proving, multi-step math.
Figure 1.6 — Tree of Thoughts with pruning
7. Memory-Augmented Agent
Any pattern above extended with explicit
memory stores. The agent reads from and writes to memory on each cycle,
enabling long-term recall across sessions.
Figure 1.7 — Memory-Augmented Agent: four memory stores
8. Event-Driven Agentic Loop
The agent is triggered by external events
(webhooks, file changes, cron, ETW telemetry) rather than user input. Runs
autonomously, emits structured outputs to downstream systems.
Figure 1.8 — Event-Driven loop
Pattern Selection Heuristic
|
Scenario |
Best Pattern |
|
| |
|
Single-turn Q&A |
REPL |
|
Tool use, web search |
ReAct |
|
Long multi-step task |
Plan-and-Execute |
|
Quality-sensitive generation |
Reflection |
|
Parallelizable subtasks |
Multi-Agent |
|
Search / optimization problems |
Tree of Thoughts |
|
Long-term recall across sessions |
Memory-Augmented |
|
Persistent autonomous work |
Event-Driven |
Part 2 — LangGraph Patterns In Depth
LangGraph is built on one foundational
abstraction — stateful directed graphs — and layers several agent patterns on
top of it. The key design principle: control flow lives in your code, not in
the LLM's output. This makes agent behavior explicit, inspectable, and
testable.
Core Abstraction — State Machine
Figure 2.1 — LangGraph core: stateful graph with
checkpointing
Nodes are Python functions (LLM calls, tool
calls, logic). Edges are transitions (fixed or conditional). State is a typed
dict that flows through every node and accumulates changes. It is checkpointed
after each node execution.
Human-in-the-Loop via Interrupt + Checkpointer
Figure 2.2 — LangGraph HITL: pause, edit, resume
graph = workflow.compile(
checkpointer=checkpointer,
interrupt_before=["approve_action"] # pause before this node
)
graph.update_state(config, {"approved": True}) # human edits state
graph.invoke(None, config) # resume
Map-Reduce via Send API
Figure 2.3 — LangGraph Map-Reduce: parallel fan-out / fan-in
LangGraph Pattern-to-Primitive Mapping
|
LangGraph Primitive |
Agent Pattern Enabled |
|
| |
|
Cycles |
ReAct, Reflection |
|
Conditional edges |
Plan-and-Execute, Supervisor |
|
Send API (parallel) |
Map-Reduce, Multi-Agent fan-out |
|
Interrupt + Checkpointer |
Human-in-the-Loop, Resume |
|
Subgraphs |
Multi-Agent composition |
Part 3 — Framework Comparison: LangGraph vs AutoGen vs
CrewAI
|
Framework |
Core Abstraction |
Mental Model |
|
| ||
|
LangGraph |
Stateful directed graph |
You are the architect — explicit nodes, edges, state |
|
AutoGen |
Conversational agents |
Agents are actors that talk to each other |
|
CrewAI |
Role-based crew |
Agents are employees with job descriptions |
Determinism vs Emergence Spectrum
Figure 3.1 — Determinism spectrum: LangGraph → CrewAI →
AutoGen
Multi-Agent Topology Support
|
Topology |
LangGraph |
AutoGen |
CrewAI |
|
| |||
|
Sequential pipeline |
Graph edges |
initiate_chat chain |
Sequential process |
|
Supervisor → workers |
Supervisor subgraph |
GroupChat with selector |
Hierarchical process |
|
Peer-to-peer conversation |
Manual graph cycle |
Native (core feature) |
Not native |
|
Parallel fan-out |
Send API |
Async agents |
Partial (async tasks) |
|
Nested subgraphs |
Native |
Nested GroupChat |
Nested crews (v0.8+) |
Human-in-the-Loop
|
Capability |
LangGraph |
AutoGen |
CrewAI |
|
| |||
|
Interrupt before node |
Native (interrupt_before) |
human_input_mode on agent |
Limited |
|
Approve tool call |
Native |
human_input_mode=ALWAYS |
Not native |
|
Resume from checkpoint |
Native |
Not built-in |
Not built-in |
|
Edit state mid-run |
Native |
Not built-in |
Not built-in |
When to Use Which Framework
|
Use Case |
Best Fit |
Why |
|
| ||
|
Production workflow with approvals |
LangGraph |
Checkpointing, interrupt, audit trail |
|
Data science / coding assistant |
AutoGen |
Native code execution sandbox |
|
RAG pipeline, document processing |
LangGraph |
Map-reduce, parallel fan-out |
|
Quick prototype multi-agent system |
CrewAI |
Minimal boilerplate, role-based intuition |
|
Research / experimental agents |
AutoGen |
Emergent conversation, flexible |
|
Long-running background automation |
LangGraph |
Persistent state, resume on failure |
|
Regulated / auditable systems |
LangGraph |
Time-travel and state snapshots |
Part 4 — LangGraph State Persistence in Production
LangGraph persists state via a checkpointer
attached to the compiled graph. After every node execution, the full state dict
is serialized and saved. The graph becomes resumable from any point. Every run
is identified by a thread_id.
Production Checkpoint Architecture
Figure 4.1 — Checkpoint architecture: stateless app +
Postgres store
Checkpointer Backends
|
Backend |
Use Case |
Notes |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MemorySaver |
Dev / testing only |
Lost on process restart |
|
SqliteSaver |
Single-process production |
File-based, simple |
|
PostgresSaver |
Multi-process production |
Recommended for scale |
|
RedisSaver |
High-throughput |
TTL support |
|
Custom |
Any store |
Implement BaseCheckpointSaver |
Resume After Failure
Figure 4.2 — Resume: nodes already completed are not re-run
Time-Travel and Branching
Figure 4.3 — Time-travel: fork from any past checkpoint
Use cases:
·
Debug production failures by
replaying with modified input.
·
A/B test different agent
decisions from a shared starting point.
·
Recover from bad agent
decisions without restarting from scratch.
Production Gotchas
|
Gotcha |
Detail |
|
| |
|
State size bloat |
Store S3 keys / DB IDs in state, not raw document content |
|
Serialization |
Everything in state must be JSON-serializable; Pydantic models
work |
|
Thread ID design |
Use domain IDs (order-123) not random UUIDs for external lookups |
|
Checkpoint retention |
Checkpoints accumulate forever — add TTL policy or cleanup job |
|
Idempotency |
Re-run nodes must be idempotent; LLM calls are not naturally
idempotent |
Part 5 — Quick Reference
|
Pattern |
Control Flow |
Memory |
Best For |
|
| |||
|
REPL |
None |
None |
Simple chatbot |
|
ReAct |
LLM-driven loop |
In-context |
Tool use, search |
|
Plan-and-Execute |
Planner LLM |
State dict |
Long-horizon tasks |
|
Reflection |
Quality gate loop |
In-context |
Quality-sensitive generation |
|
Multi-Agent |
Orchestrator |
Shared state |
Parallelizable subtasks |
|
Tree of Thoughts |
BFS/DFS search |
In-context |
Optimization, proofs |
|
Memory-Augmented |
Any |
Vector DB / KB |
Long-term recall |
|
Event-Driven |
External event |
Persistent |
Background automation |
|
LangGraph Graph |
Code-defined |
Checkpointer |
Production workflows |
|
AutoGen GroupChat |
Emergent conv. |
Chat history |
Coding agents, research |
|
CrewAI Process |
Task pipeline |
Embedding store |
Role-based workflows |
The Key Architectural Principle
LLM on the critical path = latency +
reliability risk. Keep LLMs advisory or escalation-only for safety-critical,
latency-sensitive, or regulated systems. Use deterministic engines as the
primary layer; bring the LLM in only when confidence is low or human escalation
is warranted.
This principle appears in
ai-threat-state-graph (CAAD loop, LLM off critical path) and ai-procwatch-mcp
(two-tier triage, Ollama first, Claude escalation only).
No comments:
Post a Comment