Architecture Handbook
GenAI Architecture
DOC-GENAI-2026
Architecture Field Handbook · July 2026

GenAI
Architecture

// "An LLM call is not an application. The architecture around the call is the application."

A comprehensive reference for architecting generative AI systems — from single-call inference to retrieval-augmented pipelines, from single agents to multi-agent orchestration. Covers the full decision space: model serving, RAG, fine-tuning, context engineering, agent design patterns, memory, guardrails, and production-grade agentic system design.

GenAI Architecture RAG Patterns Agent Design Multi-Agent Systems Guardrails MCP & Tool Use
01

What Is GenAI Architecture

// FROM MODEL CALLS TO SYSTEMS

GenAI architecture is the discipline of designing the system around a foundation model — the retrieval, context assembly, tool access, memory, orchestration, guardrails, and observability that turn a raw next-token predictor into a reliable product. The model is the engine; architecture is the chassis, transmission, and steering that determine whether the engine is useful, safe, and cost-effective in production.

Three architectural concerns dominate almost every GenAI system, and this handbook is structured around them: (1) GenAI architecture patterns — how you get the right knowledge and context in front of a model (RAG, fine-tuning, embeddings, caching); (2) agent patterns — how a model reasons, calls tools, and iterates toward a goal; and (3) agentic system design — how you compose many agents, tools, and safety layers into a system that can run with reduced or zero human supervision.

Non-Agentic GenAI

A single (or chained) LLM call with retrieved or provided context, producing one output per input. No autonomous looping, no tool-driven branching. Examples: RAG Q&A, summarization, classification, content generation pipelines.

Agentic GenAI

The model decides its own next action — which tool to call, whether to retrieve more information, when it's done — in a loop, with an explicit stopping condition. Examples: coding agents, research agents, customer-support resolution agents.

Multi-Agent Systems

Multiple specialized agents (each potentially a different model, prompt, or tool scope) coordinate through an orchestrator, message bus, or shared state to solve tasks no single agent handles well alone.

The core architectural tension: every GenAI system trades off capability (more context, more tools, more autonomy) against cost, latency, and controllability. Good architecture makes this trade-off explicit and tunable per use case, rather than defaulting to "give the model everything and let it decide."
02

The GenAI Reference Stack

// SEVEN LAYERS, BOTTOM TO TOP

Nearly every production GenAI system — RAG app, coding agent, support bot — can be decomposed into the same seven layers. Not every system needs every layer fully built out, but knowing the full stack helps you see what you're skipping and why.

L7 · Experience
Application / UX Layer
Chat UI, IDE plugin, API endpoint, voice interface. Streams tokens, renders tool-call progress, surfaces citations and confidence, and collects user feedback signals for evaluation.
L6 · Orchestration
Agent / Workflow Orchestration
Decides what happens next: single-call chain, graph-based workflow, or autonomous agent loop. Owns state machine, branching logic, and multi-agent coordination (LangGraph, custom state machines, Temporal-style durable execution).
L5 · Tools & Actions
Tool Use, Function Calling, MCP Connectors
The action surface — APIs, databases, code execution, browser control, external services — exposed to the model as callable, schema-defined functions. Includes permissioning and sandboxing.
L4 · Context & Memory
Retrieval, Context Assembly, Memory Stores
RAG pipelines, vector/keyword/graph retrieval, conversation and long-term memory, context window budget management, and prompt/context compression.
L3 · Model Serving
Inference & Routing
Model gateway/router, multi-model fallback, batching, streaming, prompt caching, rate limiting, and cost-aware model selection (small model for easy calls, large for hard ones).
L2 · Foundation Model
Base or Fine-Tuned LLM/VLM
The frontier or open-weight model itself — API-hosted, self-hosted, or fine-tuned/distilled variant. Selection driven by task, latency, cost, and data-residency constraints.
L1 · Safety & Observability
Guardrails, Evals, Tracing (cross-cutting)
Not really a "bottom" layer — it cuts across all others. Input/output filtering, PII redaction, prompt-injection defense, tracing, cost/latency dashboards, and offline + online evaluation.
Start top-down when scoping, bottom-up when building. Decide what the user experiences first (L7), then work down to find the minimum L1–L6 needed to deliver it. But build and harden bottom-up: get model serving and safety solid before layering orchestration and multi-agent complexity on top of a shaky foundation.
03

Model Layer & Serving Patterns

// ROUTING, FALLBACK, AND COST-AWARE INFERENCE

The model layer is rarely "one model, one endpoint" in production. It's a small distributed system in its own right: routing requests to the right model, falling back on failure, caching repeated prefixes, and batching where latency budgets allow.

Model Gateway / Router

A thin service in front of one or more model providers. Normalizes request/response schemas across providers, applies retry/backoff, enforces rate limits and budgets per tenant, and centralizes API-key management. Examples of the pattern: LiteLLM, Portkey, or a custom gateway.

Model Cascade / Routing by Difficulty

Route "easy" requests to a small, cheap, fast model and escalate to a larger model only when a cheap classifier, confidence score, or the small model's own uncertainty signals it can't handle the task. Cuts cost and latency substantially at scale without much quality loss.

Multi-Provider Fallback

If the primary provider errors, rate-limits, or times out, fail over to a secondary provider or a self-hosted model. Requires prompt templates that are portable across providers and a health-check loop that tracks provider latency/error rates in real time.

Self-Hosted vs API-Hosted

Self-hosting (vLLM, TGI, SGLang) buys data residency, fixed infrastructure cost at scale, and custom fine-tunes — at the cost of ops burden (GPU fleet, autoscaling, quantization tuning). API-hosted models buy speed-to-market and access to frontier capability without infra ownership.

Serving ConcernTechniqueEffect
LatencyStreaming responses, speculative decoding, prompt cachingLower time-to-first-token and perceived latency
ThroughputContinuous batching (vLLM/TGI), KV-cache reuseHigher requests/sec per GPU
CostModel cascades, prompt caching, output length limits, smaller distilled modelsLower $ per resolved request
ReliabilityMulti-provider fallback, circuit breakers, timeout budgetsGraceful degradation instead of hard failure
DeterminismLow/zero temperature, seeded sampling, structured output (JSON schema / grammars)More reproducible behavior for evals and automation
Config — Model Router with Cascade + Fallback
# model-router.yaml — illustrative routing policy routes: - name: classification_or_extraction match: { task_type: ["classify", "extract"] } primary: { provider: anthropic, model: claude-haiku-4-5 } escalate_if: confidence < 0.7 escalate_to: { provider: anthropic, model: claude-sonnet-5 } - name: complex_reasoning match: { task_type: ["agentic_planning", "code_generation"] } primary: { provider: anthropic, model: claude-sonnet-5 } fallback: { provider: anthropic, model: claude-opus-4-8 } fallback_policy: on_error: [retry_once, switch_provider, return_cached_if_available] timeout_ms: 30000 circuit_breaker: error_threshold_pct: 25 window_seconds: 60 cooldown_seconds: 120 caching: prompt_prefix_cache: true # cache system prompt + static context response_cache_ttl: 3600 # for idempotent, non-personalized calls
04

RAG Architecture Patterns

// RETRIEVAL-AUGMENTED GENERATION, END TO END

Retrieval-Augmented Generation grounds model outputs in external, up-to-date, and authoritative data instead of relying solely on parametric (trained-in) knowledge. RAG is the single most common GenAI architecture pattern because it solves the two biggest LLM limitations — stale knowledge and hallucination — without retraining the model.

📥
Ingest
Load & Chunk
🧬
Encode
Embed
🗄️
Store
Vector / Hybrid Index
🔍
Retrieve
Query + Rerank
🧩
Assemble
Context Window
✍️
Generate
Grounded Answer

RAG Pattern Variants

Naive RAG Baseline

Single retrieval pass → top-k chunks → stuffed into the prompt → one generation call. Fast to build, works for narrow, well-chunked knowledge bases. Fails on multi-hop questions and queries that need synthesis across many documents.

Advanced RAG Production Default

Adds query rewriting/expansion, hybrid (dense + sparse) retrieval, reranking, and metadata filtering before generation. This is the realistic production baseline — naive RAG rarely survives contact with real user queries.

Agentic RAG Iterative

The model itself decides whether to retrieve, what to query for, and whether retrieved context is sufficient — looping retrieval and generation until it has enough grounding. Handles multi-hop and ambiguous queries at the cost of latency and complexity.

GraphRAG Structured Knowledge

Builds a knowledge graph (entities + relationships) from the corpus, often with LLM-assisted extraction, then retrieves via graph traversal and/or community summaries alongside or instead of vector search. Strong for "what connects to what" and global-summary questions that pure chunk retrieval handles poorly.

HyDE (Hypothetical Document Embeddings)

The model first generates a hypothetical answer to the query, then embeds that hypothetical answer to search the index — closing the semantic gap between short questions and long documents. Useful when queries and documents live in very different linguistic registers.

Corrective RAG (CRAG)

A lightweight evaluator scores retrieved chunks for relevance; low-relevance results trigger a fallback (query rewrite, web search, or a "not confident" response) instead of feeding weak context straight to generation. Reduces hallucination from bad retrieval.

Chunking Strategy

StrategyHow It WorksBest For
Fixed-sizeSplit every N tokens with overlap (e.g. 512 tokens, 15% overlap)Simple, homogeneous text; fast baseline
Recursive / structure-awareSplit on headings → paragraphs → sentences, respecting document structureMarkdown, HTML, structured docs
Semantic chunkingSplit where embedding similarity between adjacent sentences drops sharplyLong-form prose where topic boundaries matter
Sentence-windowEmbed single sentences; retrieve with surrounding sentence window for contextPrecise retrieval + readable surrounding context
Parent-document / hierarchicalEmbed small chunks for retrieval precision; return the larger parent chunk/section for generationBalancing retrieval precision with generation context
Table/code-awareKeep tables, code blocks, and structured elements intact rather than splitting mid-structureTechnical docs, financial reports, source code

Retrieval & Reranking

Hybrid Dense + Sparse Retrieval
  • Dense (embeddings): captures semantic similarity, robust to paraphrasing
  • Sparse (BM25 / keyword): captures exact term matches — IDs, codes, rare terms embeddings often miss
  • Combine via reciprocal rank fusion (RRF) or weighted score blending
Reranking Cross-Encoder Second Pass
  • Retrieve top-50 cheaply with bi-encoder/BM25, then rerank with a cross-encoder for top-5
  • Cross-encoders score query+doc jointly — far more accurate than embedding cosine similarity alone
  • Cohere Rerank, BGE-reranker, or a fine-tuned cross-encoder are common choices
RAG failure modes to design against: (1) retrieval returns plausible-but-wrong chunks and the model confidently synthesizes a wrong answer; (2) relevant information spans multiple chunks that never get retrieved together (multi-hop failure); (3) the index goes stale relative to the source of truth; (4) chunk boundaries split a fact from its qualifier ("as of 2023..." gets separated from the number it modifies).
05

Fine-Tuning & Adaptation Architecture

// WHEN TO CHANGE THE WEIGHTS INSTEAD OF THE PROMPT

Fine-tuning bakes knowledge or behavior into model weights rather than supplying it at inference time. It is the right tool for a narrower set of problems than most teams assume — most "we need to fine-tune" problems are actually RAG or prompt-engineering problems in disguise.

NeedRight ToolWhy
Model needs facts it doesn't know / that change oftenRAGFine-tuning is a poor way to inject frequently-changing factual knowledge — it's slow to update and doesn't reliably "recall" specific facts
Model needs to follow a specific output format or tone consistentlyPrompting + few-shot, or light fine-tuningOften solvable with better system prompts and examples before touching weights
Model needs a new skill/behavior pattern (e.g. a specific tool-call style, a narrow domain reasoning style)Fine-tuning (SFT/LoRA)Behavior distillation across many examples generalizes better via weights than via ever-longer prompts
Need to shrink a large model into a small, cheap, fast one for a narrow taskDistillation fine-tuningTrain a small model on the large model's outputs for the specific task distribution
Need consistent alignment to human/organizational preferencesRLHF / DPO / preference tuningPreference optimization shapes judgment and style, not factual recall
Full Fine-Tuning

Update all model weights. Highest capability ceiling, highest cost, highest infrastructure requirement (multi-GPU, large memory). Risk of catastrophic forgetting of general capability. Reserved for teams with the data volume and infra to justify it.

LoRA / QLoRA (Parameter-Efficient)

Freeze the base model, train small low-rank adapter matrices injected into attention/MLP layers. Trains 0.1–1% of parameters, runs on far less hardware, and adapters can be swapped per task/tenant at inference time without redeploying the base model.

Instruction / SFT (Supervised Fine-Tuning)

Train on curated (instruction, ideal-response) pairs to shape behavior — format compliance, tool-call style, domain tone. The most common fine-tuning pattern for production GenAI products layered on top of a strong base model.

Preference Tuning (DPO / RLHF)

Train on (chosen, rejected) response pairs to shape judgment — which of two plausible responses is better. Used to reduce specific failure patterns (excessive hedging, refusals, verbosity) once SFT has established base behavior.

Architectural Considerations for Fine-Tuned Models in Production

Adapter Serving at Scale

With LoRA, you can serve many task- or tenant-specific adapters on one base model deployment (e.g. via multi-LoRA serving in vLLM), switching adapters per request instead of hosting N full model copies — a major cost lever for multi-tenant GenAI products.

Eval Before and After Every Fine-Tune

Fine-tuning without a regression eval suite is how teams silently degrade general capability while fixing one narrow behavior. Maintain a fixed eval set spanning the target skill and general capability, run before/after every training run, and gate promotion on both improving or holding steady.

Data Pipeline Is the Real Product

Most of the engineering effort in a fine-tuning program is the data pipeline: collection, deduplication, quality filtering, PII scrubbing, and versioning of training data — not the training run itself, which is often a few lines of a training framework's API.

06

Embedding & Vector Store Architecture

// THE INDEX THAT MAKES RETRIEVAL POSSIBLE

Every RAG and semantic-search system rests on an embedding model and a vector index. The choices here — embedding model, index algorithm, and storage engine — drive retrieval quality, latency, and cost far more than most teams expect.

Embedding Model Selection
  • General-purpose: OpenAI/Voyage/Cohere embedding APIs — strong out of the box, no infra to manage
  • Open-weight: BGE, E5, GTE families — self-hostable, tunable, no per-call cost at scale
  • Domain-tuned: fine-tuned or contrastively-trained embeddings for legal, medical, or code domains outperform general models on in-domain retrieval
  • Multi-vector: ColBERT-style late-interaction models trade index size for materially better retrieval precision
Vector Index Algorithms
  • HNSW — graph-based approximate nearest neighbor; the default for most production vector DBs. Fast queries, higher memory footprint
  • IVF (+PQ) — cluster-then-search; lower memory via product quantization, some recall trade-off
  • Exact / brute-force — fine for <100K vectors, guarantees perfect recall
  • DiskANN — disk-resident graph index for billion-scale corpora that don't fit in memory
Store TypeExamplesChoose When
Dedicated vector DBPinecone, Weaviate, Qdrant, MilvusVector search is a primary workload, need managed scaling and hybrid search built-in
Postgres extensionpgvectorAlready running Postgres; want vectors alongside relational data in one system; moderate scale
Search-engine nativeElasticsearch/OpenSearch with vector fieldsAlready running a search stack; need tight hybrid lexical+vector search
In-memory / embeddedFAISS, Chroma (local mode)Prototyping, small corpora, offline batch pipelines
Graph databaseNeo4j, graph + vector hybridsGraphRAG, relationship-heavy retrieval alongside similarity search
Config — Index & Metadata Schema Pattern
# Vector record schema — always index metadata alongside the vector { "id": "doc_4821_chunk_07", "vector": [0.0123, -0.0456, ...], "text": "Refunds are processed within 5-7 business days...", "metadata": { "source_doc_id": "doc_4821", "source_url": "https://docs.example.com/refunds", "title": "Refund Policy", "section": "Timelines", "last_updated": "2026-06-15", "access_tier": "public", # enables per-tenant/ACL filtering "chunk_index": 7, "token_count": 187 } } # Metadata filtering at query time avoids leaking one tenant's # or access tier's documents into another's retrieval results. query_filter = { "access_tier": {"$in": ["public", user.tier]} }
Re-embed on model upgrade, always. Vectors from different embedding model versions are not comparable — mixing them silently degrades retrieval quality with no error thrown. Track the embedding model version in your index metadata and re-embed the full corpus whenever it changes.
07

Prompt & Context Architecture

// CURATING WHAT THE MODEL ACTUALLY SEES

Context engineering — deciding exactly what tokens occupy the context window on a given call — is now widely recognized as a bigger lever on output quality than prompt wording alone. Large context windows make it tempting to include everything; disciplined architecture curates instead of dumps.

Context ComponentPurposeDesign Note
System / role promptStable behavioral contract: persona, constraints, output formatKeep static across calls to maximize prompt-cache hits
Retrieved context (RAG)Grounding facts relevant to the current queryRank by relevance; cite sources; cap token budget explicitly
Conversation historyContinuity across turnsSummarize or truncate older turns rather than keeping full verbatim history forever
Tool definitions & schemasWhat actions the model can take this turnOnly include tools relevant to the current task — irrelevant tools add tokens and confusion
Memory (long-term)User preferences, past decisions, durable factsRetrieve selectively based on relevance, not injected wholesale every turn
Output format specJSON schema, XML tags, or structured grammarConstrains generation for reliable downstream parsing

Context Compression Techniques

Summarization / Rolling Memory

Periodically compress older conversation turns into a running summary, keeping only recent turns verbatim. Trades some fidelity for a bounded context size regardless of conversation length.

Selective Retrieval Over Full History

Instead of keeping all history in-context, embed and store past turns, then retrieve only the turns relevant to the current query — turning conversation history into its own mini-RAG system.

Prompt Caching

Providers cache the KV-state of a repeated prompt prefix (system prompt, tool definitions, static context) so subsequent calls only pay compute for the changed suffix — a significant cost and latency lever for agentic loops that re-send similar context every turn.

Structured Extraction Before Injection

Instead of injecting raw retrieved documents, pre-extract only the fields/facts relevant to the task (e.g. via a cheap extraction pass) — trading one extra small model call for a much smaller, denser context payload to the expensive call.

Context budget as a first-class design artifact. Treat the context window like a memory budget in embedded systems: allocate a fixed token budget per component (system prompt, retrieved context, history, tools), monitor actual usage against it, and alert when any component's budget grows unbounded.
08

Caching & Cost Optimization Architecture

// THE LEVERS THAT DETERMINE UNIT ECONOMICS

GenAI unit economics are dominated by tokens in and tokens out. Architecture-level caching and routing decisions typically save far more than prompt micro-optimization.

Prompt / Prefix Caching

Cache the compute for a static prompt prefix (system instructions, few-shot examples, tool schemas) so repeated calls only process the new suffix. Biggest win for agent loops that resend near-identical context every turn.

Semantic Response Caching

Cache full responses keyed by semantic similarity of the input (not just exact match) for idempotent, non-personalized queries — FAQ-style questions are the classic case. Requires a freshness/invalidation policy tied to the underlying data.

Model Cascading

Send the bulk of traffic to a small/cheap model; escalate only the subset that needs it to a larger model. Typically the single largest cost lever in high-volume GenAI products, often cutting cost 5-10x with minimal quality loss.

LeverTypical SavingsTrade-off
Prompt/prefix cachingMeaningful reduction on repeated-context callsRequires stable prompt structure; cache misses on any prefix change
Model cascadingOften the largest single lever at scaleRequires a reliable difficulty classifier or confidence signal
Output length cappingProportional to reduction in generated tokensRisk of truncating legitimately long, necessary answers
Batching (async/offline workloads)Lower per-unit cost on batch-eligible endpointsNot usable for interactive, latency-sensitive paths
Retrieval-context trimmingReduction proportional to unnecessary context removedRequires reranking quality high enough to trust fewer, better chunks
Cache invalidation is the hard part, as always. A stale cached RAG answer that no longer reflects an updated policy document is worse than a cache miss — it's confidently wrong. Tie cache TTLs and invalidation triggers to the actual update cadence of the underlying source data, not an arbitrary fixed duration.
09

Multimodal Architecture Patterns

// TEXT, IMAGE, AUDIO, AND VIDEO IN ONE PIPELINE

Multimodal GenAI systems combine text with images, audio, or video — either as input (a vision-language model reading a document image) or output (image/audio generation). The architecture question is where modality conversion happens: at ingestion, inside the model, or as a separate specialist step.

Native Multimodal Model

A single VLM/omni model directly consumes image/audio/video tokens alongside text tokens in one context window (e.g. reading a scanned invoice image and answering questions about it directly). Simplest architecture when the model's native multimodal capability covers the task.

Modality-to-Text Pipeline

Convert non-text modalities to text first (OCR, ASR transcription, image captioning) using specialist models, then run the rest of the pipeline (RAG, agents) purely in the text domain. Simpler to debug, cache, and index — text is easy to search and version.

Specialist Generation Models

For output generation (image, audio, video), route to purpose-built generative models rather than the primary reasoning LLM — an orchestrating text model calls an image-generation model as a tool, keeping reasoning and generation concerns separate.

Multimodal RAG

Index images/tables/charts alongside text — via multimodal embeddings (e.g. CLIP-style) that place images and text captions in the same vector space, or by generating text descriptions of visual elements at ingestion time for standard text retrieval.

Input TypeCommon PipelineKey Design Note
Scanned documents / PDFs with layoutLayout-aware OCR or native VLM reading → structured text/JSONPreserve table/layout structure; don't flatten tables to plain text
Audio (calls, meetings)ASR transcription → diarization → text pipelineStore timestamps and speaker labels as metadata for downstream retrieval
Charts and diagramsVLM description generation → indexed alongside source imageStore both the generated description and a reference to the original image for citation
VideoFrame sampling + VLM captioning, or native video-understanding modelFrame sampling rate is a cost/completeness trade-off; scene-change detection beats fixed intervals
10

Evaluation & Guardrails Architecture

// PROVING THE SYSTEM WORKS AND STAYS SAFE

Evaluation and guardrails are not an afterthought bolted onto a finished GenAI system — they're an architectural layer that must be designed alongside retrieval and generation, because "does this work" and "is this safe" are the two questions that determine whether a GenAI product survives contact with real users.

Offline Evaluation
  • Golden datasets with known-correct answers, run on every model/prompt/pipeline change
  • Retrieval metrics: recall@k, MRR, NDCG for RAG pipelines
  • Generation metrics: faithfulness/groundedness, answer relevance, LLM-as-judge scoring against a rubric
  • Regression gate: block deploys that degrade the golden set below a threshold
Online Evaluation
  • Implicit signals: thumbs up/down, regeneration rate, session abandonment
  • Shadow evaluation: run a new pipeline version alongside production, compare outputs without serving them
  • A/B testing for prompt, retrieval, or model changes on live traffic
  • Continuous LLM-as-judge sampling on a slice of live traffic for drift detection

Guardrail Layers

LayerChecksPlacement
Input guardrailsPrompt injection detection, jailbreak patterns, PII in user input, off-topic/abuse filteringBefore the request reaches the model
Retrieval guardrailsAccess-control filtering by tenant/role, source trust scoring, freshness checksBetween retrieval and context assembly
Output guardrailsToxicity/harm classifiers, PII leakage detection, factuality/groundedness checks against retrieved sources, format validationBefore the response is returned to the user
Tool-call guardrailsArgument validation against schema, allowlisted operations, destructive-action confirmationBefore a tool call executes (see §17 for agent-specific guardrails)
Business-rule guardrailsDomain-specific hard constraints (e.g. never quote a price outside a valid range)Deterministic post-processing, not left to model judgment
Pipeline — Guardrail Chain Around a Generation Call
# Guardrail chain — fails closed, not open def handle_request(user_input, session): # 1. Input guardrails if injection_detector.flags(user_input): return refuse("input_flagged") clean_input = pii_redactor.redact(user_input) # 2. Retrieval with access control chunks = retriever.search(clean_input, filter={"tenant": session.tenant}) if relevance_scorer.max_score(chunks) < MIN_RELEVANCE: return low_confidence_response() # CRAG-style fallback # 3. Generation response = model.generate(system_prompt, chunks, clean_input) # 4. Output guardrails — fail CLOSED on any check failure if not groundedness_checker.is_grounded(response, chunks): return escalate_to_human_or_refuse() if pii_leakage_scanner.flags(response): response = pii_redactor.redact(response) if not toxicity_classifier.is_safe(response): return refuse("output_flagged") log_trace(user_input, chunks, response) # for offline eval + audit return response
Fail closed, not open. When a guardrail check itself errors or times out, the safe default is to refuse or escalate — not to silently skip the check and return the ungated model output. A guardrail that can be bypassed by breaking it is not a guardrail.
11

Core Agent Design Patterns

// HOW A MODEL REASONS TOWARD A GOAL

An agent is a model wrapped in a loop that observes, decides, acts, and evaluates — repeatedly — until a goal is met or a stop condition triggers. The pattern you choose determines how the model reasons at each step and how much autonomy it has over its own next action.

ReAct (Reason + Act)

The model interleaves explicit reasoning ("Thought: ...") with actions ("Action: call_tool(...)") and observations ("Observation: tool result"), repeating until it produces a final answer. The most widely used agent pattern — simple to implement, and the reasoning trace aids debuggability.

Plan-and-Execute

The model first produces a multi-step plan up front, then executes each step (possibly with a separate, cheaper executor model), replanning only if a step fails or new information invalidates the plan. Reduces the number of expensive planning calls versus step-by-step ReAct for long tasks.

Reflection / Self-Critique

After producing an output, the model (or a separate critic call) reviews its own work against the goal or a rubric, and revises if it falls short — looping a bounded number of times. Improves quality on tasks with a checkable success criterion at some added latency/cost per revision cycle.

Tree of Thoughts / Search-Based

Instead of committing to one reasoning path, the agent explores multiple candidate reasoning branches, scores them (via self-evaluation or a separate scorer), and expands the most promising ones — trading significant compute for better performance on tasks with many plausible-but-wrong paths.

Router / Triage Pattern

A lightweight classifier or cheap model first determines which specialized downstream flow, prompt, or agent should handle the request, before any expensive reasoning happens. Common as the entry point of larger agentic systems (see §14).

Ralph Loop / Run-to-Goal

A simple, durable loop: repeat "attempt the goal, run the verifier, feed the result back" until the verifier passes or a budget is exhausted — de-emphasizing sophisticated in-context planning in favor of a tight, deterministic-verifier-driven cycle. Popularized in coding-agent contexts (see the companion Loop Engineering Handbook for depth).

Choosing a Pattern

Task ShapeRecommended PatternWhy
Single tool call resolves it, but which tool is unclearReAct, single iterationMinimal overhead; reasoning trace picks the right action
Long, mostly-known multi-step task (e.g. "set up a project")Plan-and-ExecuteAvoids re-planning from scratch on every step; cheaper executor for routine steps
Output quality matters more than latency, checkable success criterion existsReflection loop with a verifierBounded, verifier-gated revision beats a single unchecked pass
Many plausible solution paths, need to compare before committingTree of Thoughts / searchExplores alternatives instead of committing to the first plausible path
Long-running autonomous task with a clear pass/fail gate (tests, build)Ralph loop / run-to-goalDeterministic verifier is more trustworthy than in-context self-assessment
Pseudocode — ReAct Loop Skeleton
def react_loop(goal, tools, max_steps=10): scratchpad = [] for step in range(max_steps): response = model.generate( system=REACT_SYSTEM_PROMPT, messages=[goal] + scratchpad, tools=tools ) if response.is_final_answer: return response.answer # Model chose an action — execute it thought = response.thought action = response.tool_call observation = execute_tool(action.name, action.args) scratchpad.append({ "thought": thought, "action": action, "observation": observation }) return escalate("max_steps_exceeded", scratchpad)
12

Tool Use & Function Calling Patterns

// THE ACTION SURFACE OF AN AGENT

Tool use is what turns a model from a text generator into an agent that can act on the world — query a database, call an API, run code, browse the web. The architecture of the tool layer determines reliability, safety, and how easily new capabilities can be added.

Native Function Calling

The model provider's API accepts a list of tool schemas (name, description, JSON-schema parameters) and returns structured tool-call requests instead of free text when it decides to act. The standard, most reliable mechanism — parsing is deterministic, not regex-on-free-text.

MCP (Model Context Protocol)

An open, standardized protocol for exposing tools/resources to models across providers and hosts — a connector written once can be reused across agent frameworks and even across model vendors, rather than writing bespoke tool-calling glue per integration.

Code-Execution-as-Tool

Instead of exposing many narrow tools, give the model a sandboxed code interpreter and let it write code to accomplish tasks (data manipulation, math, chained API calls) — trading a larger, more general capability surface for more careful sandboxing requirements.

Retrieval-as-Tool

Expose the RAG retriever itself as a callable tool ("search_docs(query)") rather than always injecting retrieved context automatically — letting the agent decide when it actually needs to look something up, which is the core of Agentic RAG (§04).

Tool Design Principles

Narrow, Well-Named Tools Beat Broad Ones

get_order_status(order_id) is far more reliable than a generic query_database(sql) tool — narrow tools constrain the model's action space, are easier to validate, and are easier to permission granularly.

Descriptions Are Part of the Prompt

Tool name, description, and parameter descriptions are read by the model exactly like prompt text — ambiguous or incomplete tool descriptions cause misuse just as ambiguous instructions do. Write them with the same care as a system prompt.

Idempotent Tools Where Possible

Design tools so repeated identical calls are safe (or explicitly guard against duplicate side effects) — agent loops sometimes retry or repeat calls, and non-idempotent tools (e.g. "charge_card") need explicit deduplication/confirmation logic.

Return Structured, Bounded Observations

Tool results returned to the model should be concise and structured (not a raw 50KB API dump) — truncate, summarize, or paginate large results before they re-enter the context window on the next loop iteration.

JSON — Well-Formed Tool Schema
{ "name": "get_refund_eligibility", "description": "Check whether an order is eligible for a refund based on order age, item category, and return policy. Returns eligibility status and the applicable policy reason.", "input_schema": { "type": "object", "properties": { "order_id": { "type": "string", "description": "The order ID, format ORD-XXXXXXXX" } }, "required": ["order_id"] } } // Anti-pattern to avoid: // { "name": "run_query", "description": "Runs a query", // "input_schema": { "properties": { "sql": {"type": "string"} } } } // — too broad, no validation surface, high blast radius on misuse.
Destructive actions need an explicit confirmation gate. Any tool that deletes, charges, sends, or irreversibly modifies state should require either a human-in-the-loop confirmation step or a two-phase "propose then confirm" tool-call pattern — never let a single model decision directly trigger an irreversible action in a fully autonomous loop.
13

Agent Memory Architectures

// GIVING A STATELESS MODEL STATE

LLMs are stateless between calls — every form of "memory" an agent has is architecture, not a model capability. Memory design determines whether an agent gets smarter over time or relearns the same lessons in every session.

Short-Term / Working Memory

The current context window — conversation history, current task state, scratchpad from the active reasoning loop. Bounded by context window size; managed via truncation, summarization, or selective retrieval (see §07).

Episodic Memory

A record of past interactions/sessions — what happened, what was decided, outcomes. Typically stored as embeddings for semantic retrieval ("has this user asked something like this before?") plus structured metadata (timestamps, outcomes).

Semantic / Long-Term Memory

Durable facts distilled from experience — user preferences, learned domain facts, corrected mistakes — kept separate from raw episodic logs and periodically consolidated/deduplicated so it doesn't grow unbounded.

Procedural Memory (Skills)

Reusable "how to do X" knowledge — a SKILL.md-style file, a learned tool-use pattern, or a cached successful plan for a recurring task type — loaded into context when a matching task type recurs, so the agent doesn't rediscover the same procedure from scratch.

Memory TypeStorage PatternWrite TriggerRead Trigger
WorkingIn-context, ephemeralEvery turnEvery turn (current context)
EpisodicVector store / log DB, timestampedEnd of session/taskSemantic similarity to current query
SemanticStructured store (KV, small DB), curatedExplicit distillation step, human-reviewed ideallyRelevance to current task type
ProceduralVersioned skill files / prompt libraryAfter a successful, generalizable task completionTask-type match at loop start
Memory poisoning is a real failure mode. If an agent writes its own long-term/procedural memory unsupervised, one bad inference gets baked into every future session and compounds — the agent gets consistently, confidently wrong in a way that's hard to trace back. Require human review before agent-authored content enters persistent, cross-session memory.
14

Multi-Agent Orchestration Patterns

// WHEN ONE AGENT ISN'T THE RIGHT UNIT OF WORK

Multi-agent architectures split work across specialized agents instead of asking one agent/prompt to do everything. The payoff is separation of concerns, parallelism, and the ability to use different models per role — the cost is coordination complexity and harder debugging.

Orchestrator-Worker (Hub and Spoke)

A central orchestrator agent decomposes the task, dispatches subtasks to specialized worker agents, and integrates their results. The most common and easiest-to-debug multi-agent pattern — the orchestrator is a single point of coordination and observability.

Sequential Pipeline

Agents run in a fixed sequence, each consuming the previous agent's output (e.g. researcher → writer → editor). Simple, predictable, easy to reason about — but rigid; doesn't adapt if a downstream agent discovers upstream work needs revisiting.

Implementer / Verifier Separation

One agent (often a faster/cheaper model) produces work; a structurally separate agent (often a stronger model, different instructions) verifies it against a spec or rubric. The agent that wrote the output should never be the sole judge of its own correctness.

Parallel / Fan-Out Fan-In

Dispatch the same or related subtasks to multiple agents in parallel (e.g. independent failing tests fixed by separate agents in isolated worktrees), then merge results. Cuts wall-clock time for decomposable, independent work.

Debate / Adversarial

Multiple agents argue different positions or independently solve the same problem, with a judge agent (or human) selecting or synthesizing the best answer — useful for reducing single-model blind spots on ambiguous or high-stakes decisions, at multiplied cost.

Blackboard / Shared State

Agents don't communicate directly — they read and write to a shared state store ("blackboard"), each contributing when it has relevant expertise. Flexible for loosely-coupled agents but harder to reason about causality and debug than direct orchestration.

Coordination Mechanisms

MechanismHow It WorksTrade-off
Direct orchestrator callsOrchestrator invokes each agent as a function/subagent call, gets a return valueSimple, synchronous; orchestrator is a bottleneck and single point of failure
Message queue / event busAgents publish/subscribe to events (task created, result ready)Decoupled, scalable, async — harder to trace a single task's full lifecycle
Shared document / state storeAgents read/write a common artifact (plan doc, shared memory)Good for loosely coordinated work; race conditions possible without locking
Durable workflow engineA workflow engine (e.g. Temporal-style) tracks state, retries, and step history explicitlyStrong reliability and resumability guarantees; more infra to operate
Pseudocode — Orchestrator-Worker with Verifier
def orchestrate(task): subtasks = orchestrator_agent.decompose(task) results = [] for subtask in subtasks: worker_result = worker_agent.execute( subtask, model="fast-cheap-model" ) # Structural separation: a DIFFERENT agent verifies verdict = verifier_agent.review( subtask, worker_result, model="strong-model" ) if verdict.passed: results.append(worker_result) else: retry_result = worker_agent.execute( subtask, feedback=verdict.reason ) results.append(retry_result) return orchestrator_agent.synthesize(results)
Default to the simplest pattern that works. Multi-agent systems multiply cost, latency, and failure surface. A single well-prompted agent with good tools often outperforms a poorly-decomposed multi-agent system. Reach for orchestrator-worker or verifier separation only when a single agent demonstrably fails at the task's breadth or needs structurally independent judgment.
15

End-to-End Agentic System Architecture

// COMPOSING THE PIECES INTO A PRODUCTION SYSTEM

A production agentic system composes every pattern above into one coherent architecture. Below is a reference topology for a general-purpose agentic assistant — the shape most production systems converge on regardless of domain.

Entry
Trigger & Router
User message, webhook, or scheduled trigger enters the system. A lightweight router/triage step classifies intent and complexity before any expensive reasoning starts.
Gate
Input Guardrails
Injection detection, PII redaction, abuse/off-topic filtering, and auth/permission resolution for the requesting user or system.
Context
Memory & Retrieval Assembly
Fetch relevant episodic/semantic memory, run RAG retrieval if needed, and assemble the bounded context payload per §07's budget model.
Orchestration
Agent Loop / Multi-Agent Graph
The core reasoning loop (ReAct, Plan-Execute, etc.) or multi-agent graph (§14) executes, calling tools and possibly subagents, bounded by turn/time/cost budgets.
Action
Tool Execution Layer
Sandboxed, permissioned tool/MCP connector execution with argument validation and destructive-action confirmation gates.
Verify
Verification & Stop Condition
Deterministic checks where possible (tests, schema validation) plus LLM-reviewer checks where necessary, deciding whether the loop is done, needs another iteration, or must escalate.
Gate
Output Guardrails
Groundedness/factuality checks, PII/toxicity scanning, format validation before the response leaves the system.
Persist
Memory Write & Trace Logging
Write episodic memory and (if reviewed) semantic/procedural memory updates; log the full trace for observability and offline evaluation.
Exit
Response / Escalation
Return the final response to the user, or route to a human escalation path if the verifier failed or a budget was exhausted.
Every layer above is independently swappable. A well-architected agentic system lets you change the model, the vector store, the orchestration framework, or the guardrail provider without rewriting the others — because each layer talks to its neighbors through a stable, narrow interface rather than reaching across layers.
16

Orchestration & Workflow Engines

// STATE MACHINES, GRAPHS, AND DURABLE EXECUTION

The orchestration layer is where you encode how an agent or multi-agent system moves between steps — and it's the layer most prone to becoming an unmaintainable tangle of if/else logic if not deliberately architected as a graph or state machine from the start.

Graph-Based Orchestration

Model the workflow as a directed graph of nodes (agent calls, tool calls, conditional branches) and edges (transitions, possibly conditional on state). Frameworks like LangGraph make branching, looping, and cyclical agent behavior explicit and inspectable rather than buried in imperative code.

Durable / Workflow-Engine Orchestration

For long-running or business-critical agentic workflows, a durable execution engine (Temporal-style) persists workflow state at every step, enabling automatic retry, resumption after a crash, and long-running (hours to days) workflows without holding state in process memory.

Simple Sequential Chains

For non-agentic pipelines (fixed RAG Q&A, a summarize-then-format pipeline), a plain sequential chain of calls is sufficient and simpler to debug than a full graph engine — don't reach for graph orchestration when a straight-line pipeline suffices.

Event-Driven Orchestration

Steps trigger on events (new document ingested, webhook received, scheduled interval) rather than a synchronous call chain — natural fit for loop-engineering-style autonomous systems that discover their own work (see the companion Loop Engineering Handbook).

State Management Across Turns

State ElementWhere It LivesWhy It Matters
Conversation/task stateExplicit state object passed through the graph (not implicit in message history alone)Makes branching logic and conditionals legible and testable
Tool-call resultsAttached to state, not just re-derived from raw message historyEnables downstream nodes to reference structured results directly
Budget countersExplicit fields (turns used, cost spent, time elapsed)Enforceable stop conditions independent of model behavior
Human-in-the-loop flagsExplicit interrupt/checkpoint stateAllows pausing a graph mid-execution for approval, then resuming from that exact point
Pseudocode — Graph-Based Agent Workflow
# Conceptual graph definition — nodes + conditional edges graph = WorkflowGraph(state_schema=AgentState) graph.add_node("triage", triage_node) graph.add_node("retrieve", retrieval_node) graph.add_node("agent", agent_reasoning_node) graph.add_node("tool_exec", tool_execution_node) graph.add_node("verify", verification_node) graph.add_node("human_review", human_checkpoint_node) graph.set_entry_point("triage") graph.add_edge("triage", "retrieve") graph.add_edge("retrieve", "agent") graph.add_conditional_edges("agent", lambda state: ( "tool_exec" if state.wants_tool_call else "verify" if state.has_draft_answer else "human_review" )) graph.add_edge("tool_exec", "agent") # loop back after tool use graph.add_conditional_edges("verify", lambda state: ( "END" if state.verified else "agent" )) compiled = graph.compile() result = compiled.invoke(initial_state)
17

Guardrails, Safety & Human-in-the-Loop

// AGENT-SPECIFIC SAFETY BEYOND §10

Agentic systems introduce safety concerns beyond single-call generation, because they can take actions, not just produce text. This section covers the agent-specific layer on top of the general guardrails in §10.

Scoped Permissions Per Agent/Tool

Every agent and every tool it can call should operate under least-privilege scope — read-only until proven reliable, write access limited to exactly the operations the task requires. An agent should never hold broader permissions than a junior engineer would for the equivalent task.

Human-in-the-Loop Checkpoints

Insert mandatory human approval before high-stakes or irreversible actions (production deploys, financial transactions, external communications) — implemented as an explicit graph node that pauses execution and waits for approval, not a suggestion the agent can talk itself out of.

Budget & Blast-Radius Limits

Hard caps on turns, tool calls, cost, and wall-clock time per task, plus scope limits on which files/systems/records an agent can touch — enforced outside the model's control so a reasoning failure can't cascade into an unbounded resource or damage event.

Prompt Injection Defense

Treat all content the agent reads from untrusted sources (web pages, emails, documents, tool outputs) as potentially adversarial input that may contain embedded instructions — structurally separate system instructions from retrieved/tool content, and never let content read by a tool silently expand the agent's permissions.

Escalation Design

TriggerEscalation ActionUrgency
Budget (turns/cost/time) 50% consumedNotify owner asynchronously (Slack, dashboard)Low — informational
Budget fully exhausted without successStop loop, summarize partial progress, page ownerMedium
Same failure repeats N consecutive timesStop loop immediately — repetition signals a structural blocker, not transient noiseHigh
Forbidden action attempted (scope violation)Kill the agent run immediately, alert security/on-callCritical
Destructive action pending confirmationBlock and wait for explicit human approval before proceedingAlways required, not urgency-based
Self-assessment is not verification. An agent's claim that it "completed the task successfully" is not evidence — it's a hypothesis that needs an independent, ideally deterministic, check. Design every agentic workflow so success is proven by something outside the acting agent's own judgment: a test suite, a schema validator, a separate reviewer model, or a human.
18

Observability & Evaluation for Agents

// SEEING WHAT AN AUTONOMOUS SYSTEM ACTUALLY DID

Agentic systems fail in ways traditional software doesn't — a plausible-sounding but wrong intermediate reasoning step, a tool called with subtly wrong arguments, a loop that "succeeds" against a weak verifier. Observability architecture for agents needs to capture the full reasoning trace, not just inputs and outputs.

Full Trace Logging
  • Every model call: prompt, response, tokens, latency, cost
  • Every tool call: name, arguments, result, execution time
  • Every reasoning/planning step, not just the final output
  • Full state snapshots at each orchestration graph transition
Agent-Specific Metrics
  • Turns/steps per completed task (trending down = the system is improving via memory/skills)
  • Tool-call success/error rate, by tool
  • Human intervention rate (target: trending down over time)
  • Cost and latency per completed task, not just per call
  • Loop termination reason distribution (success / budget / escalation)
Observability LayerTooling PatternPrimary Consumer
Distributed tracingOpenTelemetry spans per model/tool call, correlated by session/task IDEngineers debugging a specific failed run
Structured trace storePurpose-built LLM/agent observability platform (trace explorer, prompt diffing)Engineers iterating on prompts/pipelines
Aggregate dashboardsCost, latency, success-rate, escalation-rate time seriesTeam leads monitoring system health
Offline eval harnessGolden dataset re-run on every pipeline/prompt/model changeCI gate before deploy
Online eval samplingContinuous LLM-as-judge scoring on a slice of live trafficDrift and regression detection in production
Log the reasoning, not just the result. When an agentic task fails, the single most useful debugging artifact is the full step-by-step trace of what it thought, what it tried, and what each tool returned — not just "it produced the wrong final answer." Design trace logging as a first-class output of the orchestration layer, not an afterthought bolted on for debugging one incident.
19

Deployment & Scaling Architecture

// RUNNING GENAI AND AGENTS IN PRODUCTION

Deploying GenAI and agentic systems combines familiar distributed-systems concerns (scaling, isolation, retries) with GenAI-specific ones (long-running non-idempotent tool calls, streaming, variable-latency model calls).

Synchronous vs Async Execution

Short RAG Q&A fits a synchronous request/response model with streaming. Multi-step agentic tasks that can run minutes-to-hours need an async job model: submit task → return a job ID → client polls or subscribes for status/streaming updates → final result delivered via webhook/callback.

Isolation Per Agent Run

Each agent execution (especially code-execution or file-modifying agents) should run in an isolated sandbox/container/worktree so parallel runs don't collide and a compromised or buggy run can't affect others — mirroring the worktree-isolation pattern from loop engineering.

Horizontal Scaling of Orchestration Workers

The orchestration/agent-execution layer should be stateless and horizontally scalable, with task state persisted externally (workflow engine, database) — not held in a single long-lived process — so orchestration workers can be added, removed, or restarted without losing in-flight tasks.

Rate Limiting & Backpressure

Both inbound (protect the system from being overwhelmed) and outbound (respect model-provider rate limits, avoid cascading retries that amplify load) rate limiting are needed — with queueing and backpressure signals rather than silent request drops.

Environment & Release Strategy

EnvironmentModel/Prompt PolicyGuardrail Posture
DevelopmentLatest experimental prompts/models, frequent iterationRelaxed, but PII/secrets rules still enforced
StagingCandidate release, full golden-set eval required before promotionFull guardrail suite active, mirrors production
Production (canary)New version served to a small traffic percentage, shadow-comparedFull guardrails + heightened monitoring/alerting
Production (stable)Fully rolled out version, pinned model/prompt versionsFull guardrails, standard monitoring
Version everything that affects output: prompts, models, and retrieval config. A "prompt change" is a code change with the same blast-radius potential as a code deploy — treat prompt, model version, and retrieval-pipeline config changes with the same versioning, review, and staged-rollout discipline as application code, because they change behavior just as much.
20

Reference Architecture & Decision Matrix

// PUTTING IT ALL TOGETHER

Use this section as a quick-decision reference when scoping a new GenAI or agentic system — matching problem shape to the architecture patterns covered above.

Problem-to-Pattern Decision Matrix

If your problem is...Reach for...Section
Answers need to be grounded in a knowledge base that changes oftenRAG (advanced or agentic, depending on query complexity)§04
The model needs a consistent behavior/format that prompting can't nail downSFT / LoRA fine-tuning§05
Retrieval quality is the bottleneck, not generationHybrid retrieval + reranking, better chunking§04, §06
Cost is unsustainable at current volumeModel cascading + prompt caching§08
The task needs multiple sequential decisions with tool useReAct or Plan-and-Execute agent§11
Output quality needs an extra quality passReflection loop with a verifier§11
One agent can't cover the task's breadth or needs independent reviewOrchestrator-worker or implementer/verifier split§14
The system needs to run unattended for hours with checkpointsDurable workflow engine + graph orchestration§16
The system can take real-world actions (write, send, delete)Scoped tool permissions + HITL checkpoints + budgets§12, §17
You can't tell why a run failedFull trace logging + agent-specific metrics§18

Maturity Model for GenAI/Agentic Systems

Stage 01
Prototype
  • Single model call, naive RAG
  • No eval suite
  • Minimal guardrails
  • Manual testing only
Stage 02
Productionized
  • Advanced RAG, hybrid retrieval
  • Golden-set offline evals
  • Input/output guardrails live
  • Basic tracing and dashboards
Stage 03
Agentic
  • Tool-using agent loop
  • Verifier-gated completion
  • Budget limits and escalation
  • Full trace + agent metrics
Stage 04
Autonomous System
  • Multi-agent orchestration
  • Durable workflow execution
  • Distilled memory/skills layer
  • Continuous eval + auto-rollback
Advance identity-first, not automation-first. A Stage 2 system with excellent retrieval quality and solid guardrails delivers more real value than a Stage 4 multi-agent system with weak verification. Get grounding, evaluation, and safety right before adding autonomy — autonomy amplifies whatever quality level already exists underneath it, for better or worse.

Further Reading

📚
Companion handbooks in this series: Loop Engineering Handbook (autonomous agent loops, triggers, and verifiers in depth) · Transformers Handbook (model architecture fundamentals) · Deep Learning Handbook (pre-transformer foundations) — see the handbooks index for the full set.
Back to Handbooks