AI Agent Patterns

 

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).