Sunday, 13 September 2026

Agentic System Design Patterns: A Practical Guide


Quick Summary

Dimension / TaxonomyAnthropic (Dec 2024)OpenAI Agents SDKAndrew Ng / DeepLearning.AI
Primary LensConceptual & Architectural ShapesVersioned SDK PrimitivesStrategy & Prompt Loops
Control ModelExplicit code paths (Workflows) vs. Dynamic autonomous loops (Agents)SDK-managed loop with delegated executionIterative multi-prompt execution
Core PrimitivesChaining, Routing, Parallelization, Orchestrator-Workers, Evaluator-OptimizerManager (agents as tools) and HandoffsReflection, Tool Use, Planning, Multi-Agent Collaboration
Best Used ForDesigning deterministic or mixed orchestration in custom codeRapid prototyping with SDK-driven control flow and delegated tasksFraming prompt engineering strategies at the model level



📚 Series Navigation: Agentic Systems

Part 1: Agentic Systems - The Cognitive Architecture

Part 2: Agentic Systems – The Core System Modules

Part 3: Agentic Systems – Core Agentic Design Patterns (You are here)

Part 4: Agentic Systems – Enterprise Safeguards and Security (Stay Tuned)

Part 5: Agentic Systems – End to End Working example (Stay Tuned)




1. Why Companies Define "Agentic Patterns" Differently

Searching for "agentic AI design patterns" yields three different explanations from Anthropic, OpenAI, and Andrew Ng. These frameworks overlap, but they serve different purposes:

  • Anthropic: Focuses on architecture patterns you build yourself in custom code.

  • OpenAI: Focuses on pre-built software features inside their official code library (SDK).

  • Andrew Ng: Focuses on prompt engineering strategies to improve model outputs.

Anthropic's guide, Building Effective Agents, highlights that successful teams avoid overly complex frameworks. Instead, they build with simple, clear design patterns. To build reliable systems, architects must understand not just what these patterns are, but when and how to deploy them.


2. Anthropic's Control Flow: Workflow vs. Agent

Anthropic divides AI architectures into two categories based on who controls the path of execution: the developer (Workflows) or the LLM (Agents).

Workflows (Predefined Paths)

  • What it is: A structured pipeline where the developer dictates the control flow via code. The AI executes specific sub-tasks along a predetermined path.

  • Why it is used: For predictable, repeatable business processes where reliability, auditability, and fixed SLAs are prioritized over absolute autonomy.

  • Pros: Highly reliable, easy to debug, testable, and significantly cheaper in token costs because you only invoke the LLM for specific steps.

  • Cons: Rigid. If the real-world input deviates from the expected steps, the workflow will fail because it cannot invent a new path.

  • Working Example (Prompt Chaining): A document processing pipeline.
    Step 1: An LLM extracts entities from an invoice.
    Step 2: Standard Python code checks those entities against a SQL database.
    Step 3: A second LLM formats the final JSON payload.
    The LLM never decides what happens next; it only completes its assigned step.

Agents (Autonomous Loops)

  • What it is: An autonomous system where the LLM drives the control flow. It uses a loop of perception, reasoning, and action—dynamically choosing tools and reacting to environment feedback until it determines the goal is met.

  • Why it is used: For open-ended tasks with an unknown number of steps, such as deep web research or multi-file code refactoring (e.g., SWE-bench tasks).

  • Pros: Highly flexible. It can adapt to errors, self-correct, and navigate edge cases without needing explicit hardcoding.

  • Cons: Prone to unpredictable latency, high token costs, and getting stuck in hallucinated, infinite loops. Harder to debug.

  • Working Example (Coding Agent): The LLM is given a task to fix a bug. It writes code, calls a tool to run unit tests, reads the test failure output, reasons about the error, and rewrites the code. It continues this loop entirely on its own until the tests pass.

Key Workflow Patterns

Prompt Chaining

  • What it is: Running tasks in a sequential pipeline where the output of one LLM call becomes the direct input for the next.

  • Why it is used: To break complex reasoning into smaller, focused steps, reducing the chance of the LLM losing track of instructions.

  • Pros: Easy to implement, highly predictable, and allows developers to inject standard code (like validation scripts) between LLM steps.

  • Cons: Sequential execution increases total latency.

  • Working Example: Step 1 extracts user intent from an email. Step 2 drafts a reply based on that intent. Step 3 translates the reply into Spanish.

Routing

  • What it is: Using an initial LLM (or traditional classifier) to evaluate an input and route it to one of several specialized downstream workflows.

  • Why it is used: To handle broad, varied inputs (like a general customer support inbox) by directing them to specialized, narrowly-prompted experts.

  • Pros: Keeps downstream prompts small and highly targeted, which improves accuracy and reduces cost.

  • Cons: If the router misclassifies the input, the entire downstream process fails.

  • Working Example: A router reads a support ticket. If it's a billing issue, it routes to a workflow with access to the Stripe API. If it's a technical bug, it routes to a workflow that searches GitHub issues.

Parallelization

  • What it is: Running multiple independent LLM calls at the exact same time, then aggregating their outputs.

  • Why it is used: To drastically reduce latency when a task can be broken into independent chunks.

  • Pros: Speed. It turns a process that would take 60 seconds sequentially into one that takes 10 seconds.

  • Cons: Can quickly hit API rate limits if you fan out too many concurrent requests.

  • Working Example: A system needs to evaluate a startup's pitch deck. It simultaneously launches one prompt to analyze the financials, one to evaluate the team, and one to check market fit. A final prompt merges the three analyses.

Orchestrator-Workers

  • What it is: A dynamic form of parallelization where a central "Orchestrator" LLM analyzes the task, decides how many and what kind of worker tasks are needed, and synthesizes their results.

  • Why it is used: When the sub-tasks cannot be predicted in advance and must be dynamically generated based on the input.

  • Pros: Highly flexible while still maintaining structured execution.

  • Cons: High token consumption and complex to orchestrate programmatically.

  • Working Example: A user asks, "What is the weather like in New York, London, and Tokyo?" The Orchestrator spins up three separate worker tasks to fetch the weather for each city, waits for them all to return, and writes the final summary.

Monday, 7 September 2026

Agentic System - The Core System Modules (The Production Engine)

I. Beyond the Concept: Engineering the Agent Production Stack

Building a proof-of-concept (POC) agent in Python is deceptively simple: an LLM call, parse string outputs with regex, and execute dynamic Python code or API requests. However, when transitioning that pilot into a production enterprise application, this naive architecture collapses under real-world traffic, non-deterministic model drifts, and edge cases.

Scaling agentic systems requires moving from monolithic prompt scripts to a decoupled, modular production stack.


📚 Series Navigation: Agentic Systems

Part 1: Agentic Systems - The Cognitive Architecture

Part 2: Agentic Systems – The Core System Modules (You are here)

Part 3: Agentic Systems – Core Agentic Design Patterns

Part 4: Agentic Systems – Enterprise Safeguards and Security (Stay Tuned)

Part 5: Agentic Systems – End to End Working example (Stay Tuned)



The Shift from Pilot to Production: The Breakdown of Linear Scripts

In pilot environments, agents operate under ideal conditions—low concurrency, simplified prompt contexts, and synthetic user queries. When deployed to production, three critical failures emerge in linear, script-based agent architectures:

1. Context Bloat and Prompt Fragility

As an agent's responsibilities expand, developers tend to stuff system instructions, long-term memory, dynamic tool definitions, and formatting rules into a single prompt context. This leads to context degradation:

  • Attentional Drift occurs when an LLM’s self-attention mechanism becomes diluted across long conversation histories, dense tool definitions, or multi-step scratchpads. As the context window expands, the model loses focus on early system instructions, negative constraints, or high-priority safety guidelines.

    Production Example

    • Initial System Rule:

      "CRITICAL SECURITY RULE: You are a customer support agent. Never output raw PII (SSNs, credit card numbers, or full birthdates). Always mask them as XXX-XX-XXXX."

    • Failure Scenario (Turn 18):

      After a long multi-turn troubleshooting session with 12,000 tokens of raw API payloads and database logs in the context window, the user asks: "Can you confirm the account holder details we found in log entry #4?"

    • Drifted Output:

      "Sure! The account holder is John Doe, SSN: 333-44-5555, DOB: 1985-04-12."

      (The model "forgot" its system instruction because the attention weights shifted heavily toward the surrounding raw text logs at the end of the context.)

    Technical Fixes

    1. System Prompt Repinning (Context Tail Injection): Append critical security and formatting rules at the very end of the context window right before the final inference turn, counteracting the "Lost in the Middle" phenomenon.

    2. Context Compression & Sliding Windows: Never maintain an unconstrained messages list. Use sliding window memory or context compaction (e.g., summarization passes or LLMLingua prompt compression) to trim stale message turns and maintain a high signal-to-noise ratio.

    3. Deterministic Output Guardrails (Out-of-Band Filtering): Do not rely solely on model attention for hard safety bounds. Route all generated responses through an independent post-execution guardrail (e.g., Microsoft Presidio, NeMo Guardrails, or regex-based PII scrubbers) before sending the response to the user.

  • Tool Misdirection: happens when exposing too many tools—or tools with overlapping semantic descriptions—causes the model to choose the wrong function, mix up argument types, or hallucinate parameters.

    Production Example

    • Environment Tools:

      • get_user_by_email(email: str)

      • get_account_by_id(account_id: str)

      • query_billing_records(account_number: str)

    • User Query:

      "Pull the billing history for user alice@enterprise.com."

    • Misdirected Execution:

      The agent calls

      query_billing_records(account_number="alice@enterprise.com")

      (Because the prompt contained the word "billing", the model’s semantic selection biased toward query_billing_records, passing an email string into a parameter expecting a numeric account ID).

    Technical Fixes

    1. Dynamic Tool Retrieval (Tool RAG): Avoid passing 20+ tool definitions in every prompt. Store tool schemas in a vector index and dynamically retrieve only the top 3–5 most relevant tools based on the current step's intent.

    2. Hierarchical Routing (Supervisor Pattern): Decouple execution into domain-specific sub-agents (e.g., BillingAgent vs. UserMgmtAgent). A top-level supervisor router directs the query to UserMgmtAgent, which only has access to user-lookup tools, eliminating cross-domain tool confusion.

    3. Strict Schema Validation with Self-Correction Loops: Wrap tool schemas in strict Pydantic models (e.g., enforcing account_number via regex ^[0-9]{8,12}$). When the model passes "alice@enterprise.com", validation fails at the code boundary before API invocation, feeding the exact parse error back to the model:

      ValidationError: 'account_number' must be an 8-12 digit integer. You provided an email.

      The model uses this feedback to invoke get_user_by_email instead.

2. Volatile State and Process Fragility

Linear scripts typically track execution state in volatile local memory (e.g., local variables inside a runtime execution loop). If an external API times out, an LLM rate limit is hit, or the hosting container restarts, the entire trajectory is lost. There is no mechanism to pause, inspect, resume, or replay execution from the last valid state.

3. Unbounded Execution Costs and Latency Inflation

Unbounded ReAct loops can easily enter infinite retry cycles when facing ambiguous tool responses or unexpected API payload shapes. A single stuck loop can execute dozens of redundant model calls, consuming millions of tokens and spiking API costs while leaving the end user waiting indefinitely.


The Decoupled Solution

Production agent engineering requires separating the system into explicit micro-layers:

  • Perception & Context Layer: Handles retrieval, prompt pruning, and memory window management.

  • Orchestration & State Layer: Manages execution flow, graph node transitions, and persistent state checkpoints.

  • Execution Layer: Executes external tools within isolated, sandboxed environments with strict schema validation.

  • Telemetry & Safety Layer: Continuously audits trajectories, enforces cost limits, and monitors execution health.


Taming Non-Determinism: Deterministic Guardrails for Stochastic Engines

At their core, Large Language Models are probabilistic next-token predictors. Modern software engineering, however, demands deterministic guarantees: transactional consistency, strict schema compliance, authorization compliance, and repeatable state transitions.

Modular architecture bridges this gap by wrapping stochastic LLM outputs inside deterministic software guardrails.

1. Strict Schema Enforcement at Module Interfaces

Never allow raw text outputs to trigger side effects directly. Every model response intended for tool execution must pass through rigid schema validation boundaries (e.g., Pydantic schemas or strict JSON Schema specs).

If a model emits a malformed payload:

  • The error is caught at the validation layer before hitting downstream systems.

  • The validation error is fed back to the model as a structured correction prompt, allowing self-correction without blowing up the process state.

2. Bounded State Machine Control (DAGs over Free-Form Loops)

Instead of permitting an LLM to freely decide what step to take next in an unconstrained loop, production systems constrain model reasoning to a Directed Acyclic Graph (DAG) or state machine (using frameworks like LangGraph or Temporal).

  • Explicit State Transitions: The LLM is given routing authority only at designated graph nodes.

  • Deterministic Edges: Node transitions (e.g., moving from "Research" to "Approval Gate") are controlled by code-level conditional checks, not LLM predictions.

  • Recursion Limits & Depth Control: Graph runners enforce hard operational bounds (N maximum iterations per node) to prevent runaway execution loops.

3. Execution Isolation and Permission Scoping

Stochastic models must operate under the principle of least privilege:

  • Token Segregation: Dynamic agents should never hold master API tokens. Instead, pass short-lived, scoped OAuth tokens restricted specifically to the target operation.

  • Dry-Run & Human-in-the-Loop (HITL) Intercepts: State machines introduce deterministic interceptors before high-blast-radius operations (e.g., sending emails, executing database writes, initiating payment transfers). The state is persisted to a database while waiting for user confirmation or policy validation.

4. Defensive Engineering & Self-Healing Fallbacks

When stochastic outputs fail validation repeatedly, deterministic fallback handlers step in:

  • Model Downgrade / Upgrade Routing: Fall back to a higher-capability model (e.g., switching from a fast SLM to a frontier model) upon repeated schema parse failures.

  • Context Resets: If context length causes reasoning breakdown, trigger automated context compaction or re-query memory modules to clear context degradation.