<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: MUHAMMAD ABIODUN SULAIMAN</title>
    <description>The latest articles on DEV Community by MUHAMMAD ABIODUN SULAIMAN (@behordeun).</description>
    <link>https://dev.to/behordeun</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F363571%2Fcda34844-dd03-475b-bf38-c607738d4dbd.jpeg</url>
      <title>DEV Community: MUHAMMAD ABIODUN SULAIMAN</title>
      <link>https://dev.to/behordeun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/behordeun"/>
    <language>en</language>
    <item>
      <title>Engineering a Multi-Agent AI Platform — Part 1: Adaptive Depth</title>
      <dc:creator>MUHAMMAD ABIODUN SULAIMAN</dc:creator>
      <pubDate>Thu, 13 Aug 2026 19:32:27 +0000</pubDate>
      <link>https://dev.to/aws-builders/engineering-a-multi-agent-ai-platform-part-1-adaptive-depth-pll</link>
      <guid>https://dev.to/aws-builders/engineering-a-multi-agent-ai-platform-part-1-adaptive-depth-pll</guid>
      <description>&lt;p&gt;&lt;em&gt;This is Part 1 of a series on engineering AI systems that learn in production. This part covers the classification and strategy dispatch layer.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem nobody talks about
&lt;/h2&gt;

&lt;p&gt;Here's a question that keeps coming up in production AI systems: should your model think before it answers?&lt;/p&gt;

&lt;p&gt;Not philosophically. Mechanically. When a user asks "What's my account balance?", firing up a chain-of-thought reasoning engine with 16,000 thinking tokens is like hiring a PhD mathematician to count change. You burn compute, you add latency, and the answer isn't any better for it. But when someone asks "Compare the ROI of three deployment architectures under peak load, factoring in failure modes and regional latency differences," a zero-reasoning direct call produces garbage.&lt;/p&gt;

&lt;p&gt;Most platforms pick one approach and apply it everywhere. The expensive ones over-reason on simple queries, bleeding money on thinking tokens that produce nothing useful. The cheap ones under-reason on hard problems, producing responses that sound confident but miss the point entirely.&lt;/p&gt;

&lt;p&gt;Consider a platform where dozens of autonomous agents serve thousands of tenants across different industries. A scheduling agent handles "move my 3pm to Thursday" alongside an analytics agent wrestling with "why did churn spike in Q3 among enterprise accounts." These requests hit the same infrastructure, but they need radically different cognitive investment.&lt;/p&gt;

&lt;p&gt;The system we're building doesn't pick a single depth. It scores each request and routes it to the appropriate reasoning tier. And then, as we'll see in Parts 2 and 3, it learns from outcomes and human feedback to get better at that scoring over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three tiers of thinking
&lt;/h2&gt;

&lt;p&gt;Think of reasoning depth as a spectrum with three practical zones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 1: No intermediate reasoning (NONE)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The model receives the prompt and generates a response directly. No thinking tokens, no structured intermediate steps. Input goes in, output comes out. This is your workhorse for factual lookups, simple status checks, greetings, and FAQ-style questions. Latency sits around 200ms. Cost is minimal.&lt;/p&gt;

&lt;p&gt;When does this fail? When the question requires the model to hold multiple constraints in working memory simultaneously, or when the answer depends on comparing several options against each other. The model will produce something plausible-sounding, but it hasn't actually reasoned through the tradeoffs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 2: Lightweight structured reasoning (DRAFT)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here, the system injects a structured instruction into the prompt: "Before answering, write your reasoning inside &lt;code&gt;&amp;lt;draft&amp;gt;&lt;/code&gt; tags, limited to 512 tokens. Then provide your final answer inside &lt;code&gt;&amp;lt;answer&amp;gt;&lt;/code&gt; tags."&lt;/p&gt;

&lt;p&gt;The model gets a small scratchpad. It can organize its thoughts, check a few constraints, maybe outline a comparison. But the budget is tight. 512 tokens of reasoning is enough to decompose a moderately complex question into sub-parts and address each one, but not enough to explore rabbit holes or consider five alternative framings.&lt;/p&gt;

&lt;p&gt;The system parses the response, extracts what's between the &lt;code&gt;&amp;lt;answer&amp;gt;&lt;/code&gt; tags, discards the draft. The user never sees the intermediate reasoning unless the operator wants to inspect it for debugging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 3: Full chain-of-thought (FULL_COT)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This tier hands the problem to a model with native thinking-token support. Models like o3 or DeepSeek-R1 have a separate "thinking" channel where they can reason at length before producing a visible response. The system sets a &lt;code&gt;reasoning_effort&lt;/code&gt; parameter and allocates a thinking budget (more on budgets in a moment).&lt;/p&gt;

&lt;p&gt;The model can now spend thousands of tokens working through a problem. It can consider alternatives, backtrack when it hits a dead end, verify its own logic. For genuinely hard analytical questions, this produces qualitatively different answers than the other two tiers.&lt;/p&gt;

&lt;p&gt;The tradeoff is obvious: latency climbs to 2-5 seconds and token costs multiply. You don't want this running on "What time do you close?"&lt;/p&gt;

&lt;h2&gt;
  
  
  Scoring complexity
&lt;/h2&gt;

&lt;p&gt;So how does the system decide which tier to use? It runs the incoming request through a multi-signal classifier that produces a single score between 0 and 1.&lt;/p&gt;

&lt;p&gt;Five signals feed the score:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task type (weight: 0.30).&lt;/strong&gt; Is this a factual lookup? A comparison? An analysis? A debugging request? A creative task? The classifier maintains a taxonomy of task types with associated difficulty priors. A status check scores low. A multi-criteria comparison scores high.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ambiguity (weight: 0.20).&lt;/strong&gt; How many ways could this request be interpreted? "Tell me about performance" is ambiguous (performance of what? the system? the team? a specific metric?). "What was the p95 latency for the /checkout endpoint last Tuesday" is not. Ambiguity markers include vague pronouns, missing context, and underspecified scope.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Domain vocabulary density (weight: 0.20).&lt;/strong&gt; Requests loaded with specialized terminology signal that the answer needs domain expertise and careful reasoning. A message full of financial modeling terms or medical terminology likely needs deeper thinking than a conversational greeting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lexical complexity (weight: 0.15).&lt;/strong&gt; Sentence length, subordinate clause depth, vocabulary sophistication. A proxy for how much cognitive load the request itself carries. Not a perfect signal (a short request can demand complex reasoning), but a useful one in combination with the others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context dependency (weight: 0.15).&lt;/strong&gt; How much does the correct answer depend on prior conversation history, tenant-specific data, or cross-referencing multiple information sources? A standalone question scores lower than one that requires synthesizing three previous messages and two documents.&lt;/p&gt;

&lt;p&gt;The composite score:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C(x) = 0.30 · S_task(x) + 0.20 · S_amb(x) + 0.20 · S_dom(x) + 0.15 · S_lex(x) + 0.15 · S_ctx(x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each signal function &lt;code&gt;S(x)&lt;/code&gt; outputs a value in [0, 1]. The weighted sum produces the final complexity score &lt;code&gt;C(x)&lt;/code&gt;, also in [0, 1].&lt;/p&gt;

&lt;p&gt;The routing thresholds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;C(x) &amp;lt; 0.30&lt;/code&gt; → NONE (direct call, no reasoning)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0.30 ≤ C(x) &amp;lt; 0.65&lt;/code&gt; → DRAFT (lightweight scratchpad, 512-token cap)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;C(x) ≥ 0.65&lt;/code&gt; → FULL_COT (native thinking tokens with budget)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A concrete example makes this tangible. "What is my account balance?" scores roughly: task_type = 0.1 (factual lookup), ambiguity = 0.1 (clear intent), domain = 0.05 (no specialized vocabulary), lexical = 0.1 (short, simple), context = 0.2 (needs account data but straightforward). Composite: 0.30(0.1) + 0.20(0.1) + 0.20(0.05) + 0.15(0.1) + 0.15(0.2) = 0.03 + 0.02 + 0.01 + 0.015 + 0.03 = 0.105. NONE tier. Just answer it.&lt;/p&gt;

&lt;p&gt;Now try "Compare the ROI of three deployment architectures considering latency, cost, and failure modes under peak load." Task_type = 0.9 (multi-criteria analysis), ambiguity = 0.4 (what counts as "ROI" needs interpretation), domain = 0.8 (infrastructure terminology), lexical = 0.7 (complex sentence, multiple constraints), context = 0.6 (needs architecture details from prior context). Composite: 0.30(0.9) + 0.20(0.4) + 0.20(0.8) + 0.15(0.7) + 0.15(0.6) = 0.27 + 0.08 + 0.16 + 0.105 + 0.09 = 0.705. FULL_COT. This one needs to think.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters in multi-agent systems
&lt;/h2&gt;

&lt;p&gt;A single-agent chatbot can get away with a fixed reasoning depth. But multi-agent platforms have a topology that makes static approaches break down.&lt;/p&gt;

&lt;p&gt;Picture a supervisor agent that receives every inbound message. It classifies intent and routes to specialist agents: a scheduling agent, a billing agent, a technical support agent, an analytics agent. Each specialist handles a different slice of the problem space.&lt;/p&gt;

&lt;p&gt;Here's what's interesting: the same specialist agent might need different reasoning depths depending on the specific request. The billing agent handles "what's my next payment date?" (NONE) alongside "explain why my invoice increased 40% this month considering the three pricing tiers, the mid-cycle plan change, and the prorated adjustments" (FULL_COT).&lt;/p&gt;

&lt;p&gt;The reasoning strategy is selected per-request, not per-agent. The billing agent doesn't have a fixed reasoning depth. It gets classified fresh on every interaction based on what the user actually asked.&lt;/p&gt;

&lt;p&gt;It gets more layered when you have agent teams. A lead agent might decompose a complex request into subtasks, delegating each to a different specialist. One subtask might be simple data retrieval (NONE), another might require cross-referencing multiple sources (DRAFT), and a third might involve genuine analytical reasoning (FULL_COT). The system scores each subtask independently.&lt;/p&gt;

&lt;p&gt;This per-request granularity is what makes the whole thing tractable economically. If you set every agent to FULL_COT because some of their tasks are hard, you're paying ten times more for the easy ones. If you set them all to NONE because most tasks are easy, the hard ones produce bad answers and you lose user trust. Scoring at the request level means you pay for reasoning exactly where it creates value.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thinking budget
&lt;/h2&gt;

&lt;p&gt;Even within FULL_COT, not every hard problem deserves the maximum thinking allocation. A moderately complex question might need 4,096 thinking tokens to work through. A genuinely difficult analytical task might need 16,384. Allocating 32,000 thinking tokens to a question that only needs 4,000 wastes compute and sometimes degrades quality (the model can over-think, going in circles or second-guessing correct intermediate steps).&lt;/p&gt;

&lt;p&gt;The system maps complexity sub-ranges to budget tiers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple (below threshold): 0 tokens (NONE/DRAFT handle it)&lt;/li&gt;
&lt;li&gt;Moderate (0.65-0.80): 4,096 tokens&lt;/li&gt;
&lt;li&gt;Complex (0.80-1.0): 16,384 tokens&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Budget enforcement works as a state machine. When the model starts thinking, the state is ACTIVE. If the model reaches the budget limit, the state transitions to EXHAUSTED, and the system signals the model to wrap up its reasoning. A grace window of 512 tokens allows the model to reach a natural stopping point rather than being cut off mid-thought. After the grace window, the state transitions to TERMINATED and the model must produce its final answer from whatever reasoning it completed.&lt;/p&gt;

&lt;p&gt;This prevents runaway thinking. Without budget enforcement, a model given native thinking tokens can sometimes spend 20,000+ tokens reasoning in circles on a problem that doesn't benefit from it. The budget creates a ceiling without preventing deep reasoning when it's needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The diagram
&lt;/h2&gt;

&lt;p&gt;Here's the full request lifecycle through strategy selection:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1zyez9mbve302dygxw3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1zyez9mbve302dygxw3n.png" alt=" " width="800" height="782"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A request enters the complexity classifier, which evaluates five signal dimensions and produces a weighted score. The score crosses one of two thresholds (0.30 and 0.65), routing the request into one of three strategy lanes. Each lane uses a different mechanical approach to produce the final response: a simple pass-through call, a structured draft envelope with tag parsing, or a full thinking-token API with budget enforcement. All three converge on a response delivered to the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's missing
&lt;/h2&gt;

&lt;p&gt;The classifier works. It routes most requests to reasonable tiers. But it's a heuristic, and heuristics don't learn.&lt;/p&gt;

&lt;p&gt;If the system consistently under-reasons on a particular type of request for a specific agent, the classifier keeps making the same mistake. If tenant patterns shift (maybe a business changes industries and their support queries become more technical), the static weights don't adapt.&lt;/p&gt;

&lt;p&gt;What we actually want is a system that observes outcomes. Did the DRAFT strategy produce a good result for this context, or did it fall short? Was the FULL_COT response worth the extra latency and cost, or would DRAFT have been equally good?&lt;/p&gt;

&lt;p&gt;That's the reinforcement learning router, and it's the subject of Part 2. The core idea: maintain a probabilistic belief about how well each (model, strategy) pair performs in each context, sample from that belief to select an action, observe the outcome, and update the belief. A contextual bandit that learns the terrain.&lt;/p&gt;

&lt;p&gt;The classifier gives us a reasonable starting position. The bandit learns to do better.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Next in the series: Part 2 explores how Thompson Sampling learns optimal model+strategy routing from production outcomes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can follow me on &lt;a href="https://linkedin.com/in/muhammad-abiodun-sulaiman" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and &lt;a href="https://X.com/@Prince_Analyst" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; for more updates.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>systemdesign</category>
      <category>multiagentsystem</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Engineering a Multi-Agent AI Platform — Part 2: The Bandit</title>
      <dc:creator>MUHAMMAD ABIODUN SULAIMAN</dc:creator>
      <pubDate>Thu, 13 Aug 2026 19:24:44 +0000</pubDate>
      <link>https://dev.to/behordeun/engineering-a-multi-agent-ai-platform-part-2-the-bandit-5da</link>
      <guid>https://dev.to/behordeun/engineering-a-multi-agent-ai-platform-part-2-the-bandit-5da</guid>
      <description>&lt;p&gt;&lt;em&gt;This is Part 2 of a series on engineering AI systems that learn in production. Part 1 introduced the complexity classifier and three reasoning tiers. This part covers the reinforcement learning layer that replaces static thresholds with a contextual bandit that learns optimal (model, strategy) pairs from production outcomes.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The map is not the terrain
&lt;/h2&gt;

&lt;p&gt;Part 1 gave us a complexity classifier. It scores each request across five dimensions, maps that score to a reasoning tier, and dispatches accordingly. For a static system, it works reasonably well.&lt;/p&gt;

&lt;p&gt;But here's the thing about heuristic classifiers — they encode your assumptions at design time and then never update them. Those weights (0.30 for task type, 0.20 for ambiguity, and so on) were chosen based on intuition and early testing. They don't adapt when the system encounters patterns that violate those assumptions.&lt;/p&gt;

&lt;p&gt;Consider a technical support agent handling database troubleshooting. The classifier might score most requests as moderate complexity (DRAFT tier). But maybe for this specific agent dealing with this specific domain, DRAFT consistently produces responses that require operator correction. The classifier doesn't know that. It keeps routing to DRAFT because the input signals look moderate. The problem isn't the classification of the input. The problem is that input classification doesn't predict which strategy will produce a good outcome for this particular context.&lt;/p&gt;

&lt;p&gt;Think about the difference between a map and a navigator. The classifier is the map: static, useful for orientation, gives you a reasonable default route. What we need is a navigator that drives the actual roads, learns where the potholes are, and adjusts the route based on experience.&lt;/p&gt;

&lt;p&gt;That navigator is a contextual bandit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thompson Sampling in plain language
&lt;/h2&gt;

&lt;p&gt;Before the math, the intuition.&lt;/p&gt;

&lt;p&gt;You moved to a new city and you're trying to find the best lunch spot near your office. Nine restaurants to choose from (three cuisines times three price points, say). You don't know which one you'll like best. How do you figure it out?&lt;/p&gt;

&lt;p&gt;One approach: always go to whatever place seems best based on what you know so far. Problem is you'll settle on the first decent restaurant and never discover the amazing one two blocks further. You exploit what you know without exploring what you don't.&lt;/p&gt;

&lt;p&gt;Another approach: go to a random restaurant every day. Problem is you'll eat bad meals indefinitely because you never concentrate on the places that have proven good.&lt;/p&gt;

&lt;p&gt;Thompson Sampling does something more natural. You maintain a mental model of how good you think each restaurant is, but with uncertainty. For the place you've been to ten times and loved, you're pretty confident it's great. For the place you tried once and it was mediocre — you think it's probably mediocre but you're not sure. Maybe the chef was having a bad day.&lt;/p&gt;

&lt;p&gt;Each lunchtime, you mentally "sample" from your uncertainty about each restaurant. Sometimes that sample for the once-visited place comes out surprisingly high (your uncertainty is wide, so extreme values are possible). When that happens, you go try it again. Most of the time, your confident favorites produce the highest samples, so you go there. But occasionally, your uncertainty about less-explored options produces a high enough sample to trigger exploration.&lt;/p&gt;

&lt;p&gt;Over time, you visit everything enough to form confident beliefs. Restaurants you keep going back to are genuinely the best ones. You explored efficiently because you explored in proportion to your uncertainty, not randomly.&lt;/p&gt;

&lt;p&gt;That's Thompson Sampling. Now replace "restaurants" with "(model, strategy) pairs" and "how much you liked the meal" with "how good the AI response was, accounting for cost and latency."&lt;/p&gt;

&lt;h2&gt;
  
  
  The action space
&lt;/h2&gt;

&lt;p&gt;The bandit selects from the Cartesian product of available models and reasoning strategies.&lt;/p&gt;

&lt;p&gt;Say the system has access to three models (gpt-4o, o3, deepseek-r1) and three strategies (NONE, DRAFT, FULL_COT). That's nine possible arms:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Arm&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;gpt-4o&lt;/td&gt;
&lt;td&gt;NONE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;gpt-4o&lt;/td&gt;
&lt;td&gt;DRAFT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;gpt-4o&lt;/td&gt;
&lt;td&gt;FULL_COT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;o3&lt;/td&gt;
&lt;td&gt;NONE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;o3&lt;/td&gt;
&lt;td&gt;DRAFT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;o3&lt;/td&gt;
&lt;td&gt;FULL_COT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;deepseek-r1&lt;/td&gt;
&lt;td&gt;NONE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;deepseek-r1&lt;/td&gt;
&lt;td&gt;DRAFT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;deepseek-r1&lt;/td&gt;
&lt;td&gt;FULL_COT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Not all combinations make equal sense. You wouldn't typically run FULL_COT on a model without native thinking-token support. But the bandit can learn that. If arm 4 (o3 with no reasoning) consistently underperforms arm 6 (o3 with full reasoning), the posterior for arm 4 will shrink and it'll rarely get selected. You don't need to manually prune bad combinations — the learning handles it.&lt;/p&gt;

&lt;p&gt;Per-agent policies define which models and strategies are available. An agent optimized for cost might only have gpt-4o in its allowlist. An agent handling high-stakes analytical work might have all three models available. The bandit operates within whatever action space the policy permits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Context: the bandit isn't blind
&lt;/h2&gt;

&lt;p&gt;A plain multi-armed bandit treats every request the same. Pull the arm with the best track record, regardless of what the request looks like.&lt;/p&gt;

&lt;p&gt;That's too coarse. The optimal (model, strategy) pair for "summarize this email" is probably different from the optimal pair for "diagnose why our deployment is failing under load." We need the bandit to condition its selection on the request context.&lt;/p&gt;

&lt;p&gt;The system encodes each request into a context bucket — a composite key built from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Task complexity&lt;/strong&gt; (from the classifier): low / medium / high&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intent label&lt;/strong&gt;: the detected user intent (scheduling, billing, analysis, debugging, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conversation length bucket&lt;/strong&gt;: short (1-3 turns), medium (4-10), long (11+)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tenant plan tier&lt;/strong&gt;: free, professional, enterprise&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time bucket&lt;/strong&gt;: business hours, off-hours, weekend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full context key looks something like: &lt;code&gt;high | debugging | medium_conv | enterprise | business_hours&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Each unique context bucket gets its own set of Beta distributions, one per arm. So the system maintains separate beliefs about "how good is (gpt-4o, DRAFT) for high-complexity debugging requests from enterprise tenants during business hours" versus "how good is (gpt-4o, DRAFT) for low-complexity scheduling requests from free-tier tenants on weekends."&lt;/p&gt;

&lt;p&gt;Why buckets instead of continuous features? Three reasons.&lt;/p&gt;

&lt;p&gt;First, manageability: maintaining a Beta distribution per arm per context bucket works. Second, interpretability: an operator can look at the bucket &lt;code&gt;high | analysis | long_conv | enterprise | business_hours&lt;/code&gt; and understand exactly what context it represents. Third, cold-start sharing: a new agent handling similar request types can inherit priors from existing agents with the same context patterns, instead of starting from zero.&lt;/p&gt;

&lt;h2&gt;
  
  
  The selection algorithm
&lt;/h2&gt;

&lt;p&gt;Here's the core of Thompson Sampling with the Beta-Bernoulli model.&lt;/p&gt;

&lt;p&gt;Each arm &lt;code&gt;a_i&lt;/code&gt; in context bucket &lt;code&gt;b&lt;/code&gt; has parameters &lt;code&gt;(α_i, β_i)&lt;/code&gt; representing the system's belief about that arm's reward probability. Both start at &lt;code&gt;(1, 1)&lt;/code&gt;, which is a uniform prior. ("I know nothing. This arm could be anywhere from terrible to excellent.")&lt;/p&gt;

&lt;p&gt;When a request arrives with context bucket &lt;code&gt;b&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For each arm a_i in the agent's allowlist:
    Sample θ_i ~ Beta(α_i^b, β_i^b)

Select a* = argmax_i(θ_i)
Execute the request using (model, strategy) = a*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Sample from your current beliefs, pick whichever sample came out highest, use that arm. Arms you're uncertain about (low α + β, meaning wide distributions) will occasionally produce high samples and get explored. Arms you're confident about (high α + β, narrow distributions) will consistently produce samples near their true mean, so good arms get exploited.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The warm-up period.&lt;/strong&gt; When the system hasn't seen many requests for a given context, every arm has wide distributions and selection is nearly random. We define a warm-up threshold: if the selected arm has fewer than 50 observations in this context, the selection gets flagged as low-confidence. During warm-up (fewer than 50 total observations per arm in the context), exploration rate starts at 30%. With exploration active, the system bypasses Thompson Sampling entirely and selects a random arm uniformly. This guarantees that even arms the sampling might overlook get a fair number of trials early on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exploration decay.&lt;/strong&gt; That 30% exploration rate decays by 1% per week, settling at a 2% floor. Even in steady state, the system occasionally tries a random arm. This handles non-stationarity: if a model provider improves their API quality, or if token costs change, the system can discover that a previously inferior arm has become competitive.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reward signal
&lt;/h2&gt;

&lt;p&gt;After every request, the system observes three outcomes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Quality&lt;/strong&gt;: how good was the response? (Evaluated by automated quality metrics, sentence coherence scoring, factual grounding checks, or downstream task completion.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost&lt;/strong&gt;: how many tokens were consumed? (Translated to monetary cost using the model's pricing.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency&lt;/strong&gt;: how long did the user wait?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These three measurements get normalized and combined into a single scalar reward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R = w_q · Q_norm + w_c · (1 - C_norm) + w_l · (1 - L_norm)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default weights: &lt;code&gt;w_q = 0.5&lt;/code&gt;, &lt;code&gt;w_c = 0.3&lt;/code&gt;, &lt;code&gt;w_l = 0.2&lt;/code&gt;. Quality matters most, cost matters second, latency matters third. These weights are configurable per agent, so cost-sensitive deployments can raise &lt;code&gt;w_c&lt;/code&gt; and latency-sensitive ones can raise &lt;code&gt;w_l&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Normalization is relative. &lt;code&gt;Q_norm&lt;/code&gt;, &lt;code&gt;C_norm&lt;/code&gt;, and &lt;code&gt;L_norm&lt;/code&gt; are each scaled to [0, 1] based on the observed min/max across all arms in the model pool over a trailing 7-day window. If the cheapest model costs $0.001 per request and the most expensive costs $0.05, then a request costing $0.025 gets &lt;code&gt;C_norm = 0.49&lt;/code&gt;. Cost and latency are inverted (lower is better), which is why they appear as &lt;code&gt;(1 - C_norm)&lt;/code&gt; and &lt;code&gt;(1 - L_norm)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Edge case: when min equals max (no variance observed, maybe the system just started), the normalized value defaults to 0.5. System assumes middling performance until it has enough data to differentiate.&lt;/p&gt;

&lt;p&gt;A concrete example. An enterprise tenant asks a debugging question. The bandit selects (o3, FULL_COT). Response takes 3.2 seconds, costs $0.038, and scores 0.92 on quality evaluation. Over the trailing 7 days, quality ranges [0.6, 0.95], cost ranges [$0.001, $0.05], latency ranges [0.2s, 5.0s].&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Q_norm = (0.92 - 0.6) / (0.95 - 0.6) = 0.914&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C_norm = (0.038 - 0.001) / (0.05 - 0.001) = 0.755&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;L_norm = (3.2 - 0.2) / (5.0 - 0.2) = 0.625&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R = 0.5(0.914) + 0.3(1 - 0.755) + 0.2(1 - 0.625)
  = 0.457 + 0.074 + 0.075
  = 0.606
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A reward of 0.606. Decent but not outstanding. Quality was high, but cost and latency pulled it down. If a cheaper arm could have produced similar quality, the bandit will learn to prefer it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating beliefs
&lt;/h2&gt;

&lt;p&gt;After computing the reward, the system updates the Beta distribution for the arm that was selected, in the context bucket where it was selected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;α_new = α_old + R
β_new = β_old + (1 - R)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With our example reward of 0.606: if the arm previously had &lt;code&gt;α = 12.4, β = 8.2&lt;/code&gt;, it becomes &lt;code&gt;α = 13.006, β = 8.594&lt;/code&gt;. Distribution shifts slightly toward higher expected reward. Over hundreds of observations, the distribution narrows and the expected value converges on the arm's true performance in that context.&lt;/p&gt;

&lt;p&gt;Why does this work? Beta distribution's mean is &lt;code&gt;α / (α + β)&lt;/code&gt;. Adding &lt;code&gt;R&lt;/code&gt; to α and &lt;code&gt;(1 - R)&lt;/code&gt; to β pushes the mean toward &lt;code&gt;R&lt;/code&gt; while gradually reducing variance (as α + β grows, the distribution gets tighter). High rewards increase α faster, shifting the mean upward. Low rewards increase β faster, shifting the mean downward. Update is proportional to the reward magnitude, so a reward of 0.9 shifts the distribution more than a reward of 0.55.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Batch processing.&lt;/strong&gt; Rewards don't update the posterior immediately after each request. They accumulate in a Redis queue and get processed every 5 minutes. This is a pragmatic choice: it reduces database write pressure, allows the system to handle bursts without locking contention, and makes the update process idempotent (if a batch fails, it retries the same set of rewards).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persistence.&lt;/strong&gt; Every 15 minutes, current state of all Beta distributions gets persisted to PostgreSQL with a SHA-256 checksum. On startup, the system loads the latest valid checkpoint. If the checksum doesn't match (corrupted state from a partial write or a weird failure mode), the system falls back to &lt;code&gt;Beta(1, 1)&lt;/code&gt; priors (uniform, "I know nothing") and rebuilds from the last 7 days of routing decisions stored in the audit log.&lt;/p&gt;

&lt;p&gt;Worst-case data loss is 7 days of learning, not a catastrophic reset to zero knowledge. And because the system maintains the raw routing decisions alongside the computed posteriors, it can always reconstruct its beliefs from history.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes this work in practice
&lt;/h2&gt;

&lt;p&gt;A few design decisions that matter for production but don't show up in the math:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per-agent isolation.&lt;/strong&gt; Each agent has its own set of posteriors. The billing agent's beliefs about (gpt-4o, DRAFT) are completely separate from the analytics agent's beliefs about the same arm. What works for billing queries doesn't necessarily transfer to analytical queries, even in the same context bucket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Policy constraints.&lt;/strong&gt; Bandit can only select from the agent's configured allowlist. An enterprise-tier agent might have all nine arms available. A cost-constrained free-tier agent might only have three (gpt-4o with each strategy). The bandit optimizes within whatever boundaries the policy sets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The classifier as a prior.&lt;/strong&gt; The complexity classifier from Part 1 doesn't disappear. It provides the initial routing decision for new contexts where the bandit has insufficient data (the warm-up period). As the bandit accumulates observations, its learned posteriors gradually override the classifier's heuristic. In contexts where the bandit has 200+ observations per arm, the classifier's initial score barely influences the final selection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-stationarity handling.&lt;/strong&gt; Model providers change their APIs. Pricing shifts. Models get updated. The 2% exploration floor ensures the system can detect these changes, but slowly. For abrupt changes (a model provider announces a price cut), operators can manually reset the posteriors for affected arms, triggering a new warm-up period that quickly re-learns the new performance landscape.&lt;/p&gt;

&lt;h2&gt;
  
  
  The diagram
&lt;/h2&gt;

&lt;p&gt;Here's the full bandit decision loop:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5hi9copjiyml47a56wxd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5hi9copjiyml47a56wxd.jpeg" alt=" " width="376" height="1210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A request arrives with context features (complexity, intent, conversation depth, tenant tier, time). Context encoder maps these to a bucket string, which determines which set of Beta distributions to load, one per arm. System checks the exploration rate; if exploring, it picks a random arm. If exploiting, it samples from each arm's Beta distribution and picks the arm whose sample is highest. Selected arm executes, system observes quality/cost/latency, computes a normalized reward, enqueues it to Redis. Every 5 minutes a batch process applies the Bayesian update to the posterior. Loop closes. Next time this context appears, the distributions reflect what was learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's still missing
&lt;/h2&gt;

&lt;p&gt;The reward signal so far is fully automated. Quality is measured by an eval function. Cost and latency are measured by instrumentation. System learns from these numbers.&lt;/p&gt;

&lt;p&gt;But numbers miss something. An automated quality scorer might rate a response highly because it's coherent, grammatically correct, and addresses the topic. But the human reading it might find it unhelpful, off-target, or missing the point in a way that's hard for an automated metric to capture.&lt;/p&gt;

&lt;p&gt;What happens when an operator reads the response and corrects it? What happens when a customer gives a thumbs-down? What happens when a human takes over the conversation entirely because the agent's response was so inadequate that no correction could salvage it?&lt;/p&gt;

&lt;p&gt;These are human preference signals, and they carry information that automated metrics can't replicate. Part 3 covers how to collect them, how to convert them into reward adjustments, and how to feed them back into the bandit so that it learns not just from numbers but from human judgment.&lt;/p&gt;

&lt;p&gt;We'll also cover what happens when things go wrong at the infrastructure level: model timeouts, rate limits, budget exhaustion. System needs to degrade gracefully, and that graceful degradation is itself a learned behavior.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Next in the series: Part 3 explores how human preference signals enrich the learning loop, and how the system survives production failure modes.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>reinforcementlearning</category>
      <category>thompsonsampling</category>
      <category>systemdesign</category>
      <category>aiengineering</category>
    </item>
    <item>
      <title>System Design for Agentic AI Projects: What to Do, What Not to Do, and When</title>
      <dc:creator>MUHAMMAD ABIODUN SULAIMAN</dc:creator>
      <pubDate>Sat, 04 Oct 2025 17:43:58 +0000</pubDate>
      <link>https://dev.to/aws-builders/system-design-for-agentic-ai-projects-what-to-do-what-not-to-do-and-when-17kp</link>
      <guid>https://dev.to/aws-builders/system-design-for-agentic-ai-projects-what-to-do-what-not-to-do-and-when-17kp</guid>
      <description>&lt;p&gt;Agentic AI, where independent AI agents make complex decisions or orchestrate workflows, is revolutionizing business processes. Yet architecting such systems brings fresh design challenges and high stakes. Here are actionable principles, informed by real-world builds and strategic lessons, for designing robust, scalable Agentic AI solutions, complete with Python pseudocode examples to illustrate implementation patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to Do: Core System Design Principles Anchor to Business Value&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Start by defining explicit, measurable business outcomes for the AI system. Every agent’s function should map directly to a high-impact organizational goal. Avoid speculative builds; only add autonomy where it demonstrably amplifies value and innovation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BusinessAlignedAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;business_kpi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;success_threshold&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;business_kpi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;business_kpi&lt;/span&gt;  &lt;span class="c1"&gt;# e.g., "customer_satisfaction_score"
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;success_threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;success_threshold&lt;/span&gt;  &lt;span class="c1"&gt;# e.g., 0.85
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metrics_tracker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MetricsTracker&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task_input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Always measure business impact
&lt;/span&gt;        &lt;span class="n"&gt;kpi_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metrics_tracker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;measure_kpi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;business_kpi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;kpi_value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;success_threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;escalate_to_human&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kpi_value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use Clear Orchestration and Task Decomposition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Architect systems with a two-tier model: a primary (“supervisor”) agent that owns orchestration and specialized subagents that execute well-bounded, stateless tasks. Decompose complex operations either vertically (sequential dependency) or horizontally (parallel independence), based on the workflow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentOrchestrator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subagents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data_processor&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;DataProcessorAgent&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;validator&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ValidatorAgent&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;reporter&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ReporterAgent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_workflow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Sequential decomposition example
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data_analysis&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;raw_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subagents&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data_processor&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;validated_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subagents&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;validator&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subagents&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;reporter&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;generate_report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validated_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt;

        &lt;span class="c1"&gt;# Parallel decomposition example
&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;multi_source_research&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;parallel_tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split_into_parallel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;subtask&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parallel_tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_agent_for_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subtask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute_async&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subtask&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge_results&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Favor Statelessness and Modularity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design subagents as pure functions, with no internal state and no reliance on conversation history. This ensures predictable, parallel execution, easy troubleshooting, reproducible outputs, and streamlined caching. Isolate and test each module rigorously before integration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StatelessAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;
        &lt;span class="c1"&gt;# No conversation state stored here
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Pure function - same input always produces same output&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="c1"&gt;# Extract only necessary context
&lt;/span&gt;        &lt;span class="n"&gt;relevant_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extract_relevant_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Process without side effects
&lt;/span&gt;        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute_logic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;relevant_context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Return structured output with metadata
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;result&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;confidence&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calculate_confidence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;reasoning&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;explain_reasoning&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;metadata&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;processing_time&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_processing_time&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;tools_used&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_tools_used&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explicit Protocols and Structured Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All agent-to-agent communication should use strict, structured formats: specify objective, input data, expected output, constraints, and success criteria. Responses must report status, reason codes, results, and relevant metadata.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;enum&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Enum&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TaskStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;PENDING&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pending&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;IN_PROGRESS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;in_progress&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;COMPLETED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;completed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;FAILED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;failed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;ESCALATED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;escalated&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentTask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;objective&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;constraints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;expected_output_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;timeout_seconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;

&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TaskStatus&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;confidence_score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;reasoning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;error_details&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;next_actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CommunicationProtocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentTask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Send task to agent, return task_id&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AgentResponse&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Get agent response for task&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Integrate Monitoring, Observability, and Human Oversight Early&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From the outset, design dashboards and trace logs to capture every action, error, and decision path. Incorporate humans-in-the-loop to review high-stakes outcomes, intervene on edge cases, and absorb critical feedback for continual refinement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;opentelemetry&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;trace&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ObservableAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tracer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_tracer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent.&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metrics_collector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MetricsCollector&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_with_observability&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Create distributed trace
&lt;/span&gt;        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_as_current_span&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;_execute&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agent.name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;task.type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Log task start
&lt;/span&gt;                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Starting task: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objective&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="c1"&gt;# Execute task with monitoring
&lt;/span&gt;                &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;monitored_execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="c1"&gt;# Record success metrics
&lt;/span&gt;                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metrics_collector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;record_success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;task_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_time&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;total_seconds&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="n"&gt;confidence&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;confidence_score&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="c1"&gt;# Check if human oversight needed
&lt;/span&gt;                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;requires_human_review&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;escalate_to_human&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

            &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Record failure metrics
&lt;/span&gt;                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metrics_collector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;record_failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;task_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error.message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Task failed: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;raise&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;requires_human_review&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Determine if result needs human oversight&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;confidence_score&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; 
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high_stakes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt;
                &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;TaskStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ESCALATED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What Not to Do: Preventable Pitfalls Do Not Over-Engineer Hierarchies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;More than two levels of agent delegation often result in convoluted debugging, unclear accountability, and diminished returns. Resist deep trees of subagents; complexity compounds risk.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OverEngineeredSystem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# DON'T DO THIS
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Too many levels - hard to debug and maintain
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;level1_orchestrator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MainOrchestrator&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="nc"&gt;SubOrchestrator&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
                &lt;span class="nc"&gt;SpecializedAgent&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
                    &lt;span class="nc"&gt;MicroAgent&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;MicroAgent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;]),&lt;/span&gt;
                &lt;span class="nc"&gt;SpecializedAgent&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
                    &lt;span class="nc"&gt;MicroAgent&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;MicroAgent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# PREFER - Simple two-level hierarchy
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleSystem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# DO THIS INSTEAD
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orchestrator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MainOrchestrator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;processor&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ProcessorAgent&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;validator&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ValidatorAgent&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;reporter&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ReporterAgent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Avoid Context Creep and Unbounded State&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Do not simply pass all conversation history or business context to every agent. Instead, use the minimal, strictly relevant context needed for the immediate task.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContextManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;context_store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;context_filters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data_processor&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data_schema&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;processing_rules&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;validator&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;validation_rules&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;error_thresholds&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;reporter&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;report_template&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;audience_type&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_filtered_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return only relevant context for specific agent&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;full_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;context_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;

        &lt;span class="c1"&gt;# Filter to only relevant keys for this agent
&lt;/span&gt;        &lt;span class="n"&gt;relevant_keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;context_filters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
        &lt;span class="n"&gt;filtered_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;full_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
                          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;relevant_keys&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;# Add task-specific context
&lt;/span&gt;        &lt;span class="n"&gt;filtered_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_immediate_context&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;filtered_context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;When to Do What: Phased Execution Discovery &amp;amp; Design&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Interview stakeholders, clarify business KPIs, and identify the smallest, highest-value opportunity for autonomy. Map out explicit agent roles and approval boundaries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProjectDiscovery&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stakeholders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;business_requirements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent_specifications&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;conduct_stakeholder_interviews&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;stakeholder&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stakeholders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;requirements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;interview&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stakeholder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;business_requirements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;stakeholder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requirements&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;identify_automation_opportunities&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;opportunities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;business_requirements&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;processes&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_repetitive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; 
                &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_clear_success_criteria&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt;
                &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;risk_level&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;high&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;opportunities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Prioritize by value and feasibility
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opportunities&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                     &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;business_value&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;complexity_score&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Prototype &amp;amp; Evaluate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Build a minimal orchestration layer and 1–3 specialized subagents. Rigorously test each in isolation and as an integrated chain. Validate statelessness and boundary clarity with sample workflows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PrototypeValidator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_cases&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agents&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_cases&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;test_cases&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_isolation_tests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Test each agent individually&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;test_case&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_cases&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test_agent_isolation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_case&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;_isolation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_integration_tests&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Test agent interactions and workflows&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_cases&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;workflows&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test_workflow_integration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test_results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;workflow_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_statelessness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Ensure same input produces same output&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;test_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_test_input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;# Run same input multiple times
&lt;/span&gt;        &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

        &lt;span class="c1"&gt;# All results should be identical (stateless)
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Incremental Extension&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Expand agent count, memory, and privileges only after robust monitoring and human-in-the-loop review demonstrate sustained, safe performance. Each new extension must undergo regression and error-handling tests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SafeExpansionManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_system&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_system&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_system&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;safety_metrics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SafetyMetrics&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;approval_gate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ApprovalGate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;propose_expansion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_capability&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Check current system health
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;safety_metrics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_system_healthy&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Current system showing issues&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

        &lt;span class="c1"&gt;# Run safety analysis
&lt;/span&gt;        &lt;span class="n"&gt;risk_assessment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;analyze_expansion_risk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_capability&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;risk_assessment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;risk_level&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;medium&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Risk too high: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;risk_assessment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

        &lt;span class="c1"&gt;# Require human approval for expansion
&lt;/span&gt;        &lt;span class="n"&gt;approval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;approval_gate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request_approval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;expansion&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;new_capability&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;risk_assessment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;risk_assessment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;current_performance&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;safety_metrics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_performance_summary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;approval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ready for controlled rollout&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;controlled_rollout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_capability&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Gradual deployment with monitoring&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="c1"&gt;# Start with 5% of traffic
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy_to_percentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_capability&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Monitor for 24 hours
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;monitor_for_duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hours&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="c1"&gt;# Increase to 25%
&lt;/span&gt;            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy_to_percentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_capability&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="c1"&gt;# Continue gradual expansion...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What to Do When: Handling Change and Failure On System Drift or Error&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instantly trigger rollback, escalate to human review, and only proceed to retrain agents with the learnings post-mortem. Never ignore recurring anomalies, investigate, audit, and patch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ErrorRecoverySystem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error_detector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ErrorDetector&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rollback_manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RollbackManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;human_escalation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HumanEscalationSystem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;retry_policy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RetryPolicy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_system_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Immediate containment
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;severity&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;critical&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rollback_manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;immediate_rollback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;human_escalation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emergency_alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Retry with exponential backoff for transient errors
&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_transient&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retry_with_backoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;failed_operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Pattern analysis for recurring errors
&lt;/span&gt;        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error_detector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_recurring_pattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;escalate_for_investigation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Standard error recovery
&lt;/span&gt;        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;standard_recovery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retry_with_backoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Implement exponential backoff retry pattern&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;max_retries&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="c1"&gt;# Final attempt failed
&lt;/span&gt;                    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;human_escalation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;raise&lt;/span&gt;

                &lt;span class="c1"&gt;# Exponential backoff: 2^attempt seconds
&lt;/span&gt;                &lt;span class="n"&gt;wait_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt;
                &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wait_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;post_mortem_analysis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error_incident&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Analyze failures and improve system&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;analysis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;root_cause&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;analyze_root_cause&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error_incident&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;prevention_measures&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;identify_prevention_measures&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error_incident&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;system_improvements&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;suggest_improvements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error_incident&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;# Update agent training with lessons learned
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_agent_training&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;analysis&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;analysis&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Amidst New Constraints&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When regulations or requirements shift, update agent privileges, audit trails, and test compliance before resuming autonomous actions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ComplianceManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;regulation_tracker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RegulationTracker&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;audit_system&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AuditSystem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;constraint_engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ConstraintEngine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_regulatory_change&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_regulation&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Immediate system pause for critical changes
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;new_regulation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;impact_level&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;critical&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pause_autonomous_operations&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;# Update constraint engine
&lt;/span&gt;        &lt;span class="n"&gt;new_constraints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;regulation_tracker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;translate_to_constraints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_regulation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;constraint_engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update_constraints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_constraints&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Re-validate all agents against new constraints
&lt;/span&gt;        &lt;span class="n"&gt;validation_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate_agents_compliance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compliant&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;validation_results&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resume_operations_with_new_constraints&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remediate_non_compliant_agents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validation_results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;continuous_compliance_monitoring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Ongoing compliance checking&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;system_is_running&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;active_agents&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
                &lt;span class="n"&gt;compliance_check&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;audit_system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;check_compliance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;constraint_engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_constraints&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;compliance_check&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;passed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handle_compliance_violation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compliance_check&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compliance_check_interval&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For Coverage or Performance Gaps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Analyze dashboard metrics and user feedback, then upgrade agent skills or add specialized nodes incrementally, not en masse. Each new addition should prove its value through KPIs before full deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PerformanceOptimizer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metrics_analyzer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MetricsAnalyzer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;feedback_processor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FeedbackProcessor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;improvement_engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ImprovementEngine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;identify_performance_gaps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# Analyze quantitative metrics
&lt;/span&gt;        &lt;span class="n"&gt;performance_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metrics_analyzer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_performance_summary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;gaps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;performance_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_threshold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;gaps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PerformanceGap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_threshold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

        &lt;span class="c1"&gt;# Analyze qualitative feedback
&lt;/span&gt;        &lt;span class="n"&gt;user_feedback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;feedback_processor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;analyze_recent_feedback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;gaps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;feedback_processor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;identify_capability_gaps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_feedback&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gaps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;business_impact&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;implement_targeted_improvements&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;performance_gaps&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;gap&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;performance_gaps&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;  &lt;span class="c1"&gt;# Focus on top 3 gaps
&lt;/span&gt;            &lt;span class="n"&gt;improvement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;improvement_engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;design_improvement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# A/B test the improvement
&lt;/span&gt;            &lt;span class="n"&gt;test_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_ab_test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;improvement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;test_result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shows_improvement&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy_improvement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;improvement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;monitor_improvement_impact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;improvement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log_failed_improvement_attempt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;improvement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well-designed Agentic AI solutions are anchored by clear intent, strong modular boundaries, real-time observability, and phased expansion under active human guidance. The code examples above illustrate how these principles translate into practical implementation patterns that you can adapt for your specific use cases. Adhering to these principles avoids costly missteps and speeds the path from breakthrough to sustainable business impact.&lt;/p&gt;

&lt;p&gt;You can follow me on &lt;a href="https://linkedin.com/in/muhammad-abiodun-sulaiman" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and &lt;a href="https://twitter.com/@Prince_Analyst" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; for more updates.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>architecture</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>🎯 ML Done Right: Versioning Datasets and Models with DVC &amp; MLflow</title>
      <dc:creator>MUHAMMAD ABIODUN SULAIMAN</dc:creator>
      <pubDate>Sat, 01 Feb 2025 20:32:06 +0000</pubDate>
      <link>https://dev.to/aws-builders/ml-done-right-versioning-datasets-and-models-with-dvc-mlflow-4p3f</link>
      <guid>https://dev.to/aws-builders/ml-done-right-versioning-datasets-and-models-with-dvc-mlflow-4p3f</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Data versioning is a crucial aspect of Machine Learning (ML) workflows. It ensures that datasets are reproducible, traceable, and manageable throughout the ML lifecycle. Unlike traditional software development, where Git efficiently tracks code changes, ML workflows require specialized tools to version datasets, models, and metadata.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Two powerful tools for data versioning in ML pipelines are:&lt;/li&gt;
&lt;li&gt;DVC (Data Version Control): Designed to manage large datasets efficiently and integrates seamlessly with Git.&lt;/li&gt;
&lt;li&gt;MLflow: Focused on experiment tracking, model versioning, and lifecycle management.
In this article, we will explore how to set up DVC and MLflow for data versioning in a machine learning workflow using Python.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Do We Need Data Versioning?
&lt;/h2&gt;

&lt;p&gt;Before going into implementation, let’s first understand why data versioning is essential:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reproducibility → Ensures that ML models can be recreated using the exact dataset used during training.&lt;/li&gt;
&lt;li&gt;Collaboration → Enables teams to share and work on different versions of datasets.&lt;/li&gt;
&lt;li&gt;Traceability → Keeps track of dataset changes, helping to identify issues in models.&lt;/li&gt;
&lt;li&gt;Rollback &amp;amp; Experimentation → Facilitates easy rollback to previous dataset versions for comparison.&lt;/li&gt;
&lt;li&gt;Storage Efficiency → Avoids redundancy by tracking only changes in datasets instead of duplicating entire files.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1️⃣ Setting Up DVC for Data Versioning
&lt;/h2&gt;

&lt;p&gt;DVC is an open-source tool designed to &lt;strong&gt;handle large datasets&lt;/strong&gt; efficiently while integrating seamlessly with Git.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To install DVC, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install dvc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re using cloud storage (e.g., AWS S3, Google Drive, or Azure), install the appropriate extension:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install 'dvc[s3]'
pip install 'dvc[gdrive]'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Initialize DVC in a Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inside a &lt;strong&gt;Git-tracked&lt;/strong&gt; ML project, initialize DVC:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init
dvc init
git commit -m "Initialize DVC"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Adding and Versioning Data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Assume we have a dataset stored in data/:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dvc add data/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data.dvc → A metadata file that tracks the dataset version.&lt;/li&gt;
&lt;li&gt;Updates .gitignore to prevent large files from being committed to Git.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, commit these changes to Git:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add data.dvc .gitignore
git commit -m "Track dataset with DVC"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Remote Storage Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To store the dataset in &lt;strong&gt;cloud storage&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dvc remote add myremote s3://mybucket/path/
dvc push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This uploads the dataset to S3. Other options like Google Drive, Azure, and SSH are also supported.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Restoring Previous Versions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To retrieve a &lt;strong&gt;previous dataset version&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout &amp;lt;commit_id&amp;gt;
dvc pull
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures that data and models remain synchronized with the desired version.&lt;/p&gt;

&lt;h2&gt;
  
  
  2️⃣ Using MLflow for Data Tracking
&lt;/h2&gt;

&lt;p&gt;MLflow helps &lt;strong&gt;track datasets, experiments, and models&lt;/strong&gt; during development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install mlflow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Initializing MLflow Tracking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Start the MLflow tracking server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mlflow server --backend-store-uri sqlite:///mlflow.db --default-artifact-root ./mlruns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a local database (mlflow.db) to store ML experiments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Logging Dataset Versions with MLflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modify your Python script to &lt;strong&gt;track dataset versions&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mlflow
import mlflow.artifacts
import os

# Log dataset version
def log_dataset_version(dataset_path):
    with mlflow.start_run():
        mlflow.log_artifact(dataset_path, artifact_path="datasets")
        print("Dataset version logged in MLflow")

log_dataset_version("data/")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tracking Experiments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When training an ML model, &lt;strong&gt;log key parameters and metrics&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# Load dataset
data = load_iris()
X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.2, random_state=42)

# Train model
model = RandomForestClassifier(n_estimators=100)
model.fit(X_train, y_train)

# Evaluate model
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)

# Log model and metrics
with mlflow.start_run():
    mlflow.log_param("n_estimators", 100)
    mlflow.log_metric("accuracy", accuracy)
    mlflow.sklearn.log_model(model, "random_forest_model")

    print(f"Model logged with accuracy: {accuracy}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Retrieving Dataset Versions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To list previous dataset versions in MLflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mlflow artifacts list &amp;lt;run_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3️⃣ Combining DVC and MLflow for a Complete Workflow
&lt;/h2&gt;

&lt;p&gt;A best practice is to integrate DVC for dataset versioning and MLflow for experiment tracking.&lt;/p&gt;

&lt;p&gt;🔄 Workflow Summary&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Store dataset using DVC&lt;/strong&gt; → dvc add data/&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push dataset to remote storage&lt;/strong&gt; → dvc push&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track dataset version in MLflow&lt;/strong&gt; → mlflow.log_artifact("data/")&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Train ML models and log parameters in MLflow&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Retrieve dataset versions via DVC and experiments via MLflow.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;🛠️ Example: End-to-End Pipeline&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import dvc.api
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# Fetch dataset version from DVC
dataset_path = "data/"
dvc.api.get_url(dataset_path)

# Log dataset version in MLflow
mlflow.log_artifact(dataset_path, artifact_path="datasets")

# Load dataset
data = load_iris()
X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.2, random_state=42)

# Train model
model = RandomForestClassifier(n_estimators=100)
model.fit(X_train, y_train)

# Evaluate model
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)

# Log results in MLflow
with mlflow.start_run():
    mlflow.log_param("n_estimators", 100)
    mlflow.log_metric("accuracy", accuracy)
    mlflow.sklearn.log_model(model, "random_forest_model")

    print(f"Model logged with accuracy: {accuracy}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Data versioning is &lt;strong&gt;critical&lt;/strong&gt; for:&lt;br&gt;
✅ &lt;strong&gt;Reproducibility&lt;/strong&gt; → Ensure consistent ML results.&lt;br&gt;
✅ &lt;strong&gt;Collaboration&lt;/strong&gt; → Manage dataset changes efficiently.&lt;br&gt;
✅ &lt;strong&gt;Traceability&lt;/strong&gt; → Keep track of dataset &amp;amp; model versions.&lt;/p&gt;

&lt;p&gt;By integrating &lt;strong&gt;DVC&lt;/strong&gt; and &lt;strong&gt;MLflow&lt;/strong&gt;, you can create a &lt;strong&gt;scalable&lt;/strong&gt;, &lt;strong&gt;reproducible&lt;/strong&gt;, and &lt;strong&gt;traceable&lt;/strong&gt; ML pipeline.&lt;/p&gt;

&lt;p&gt;You can connect with me via &lt;a href="//mailto:abiodun.msulaiman@gmail.com"&gt;email&lt;/a&gt; or &lt;a href="https://linkedin.com/in/muhammad-abiodun-sulaiman" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or &lt;a href="https://medium.com/@behordeun" rel="noopener noreferrer"&gt;medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>datascience</category>
      <category>mlflow</category>
      <category>dataversioncontrol</category>
    </item>
    <item>
      <title>STREAMLINE YOUR CI/CD PIPELINE WITH GITHUB ACTIONS</title>
      <dc:creator>MUHAMMAD ABIODUN SULAIMAN</dc:creator>
      <pubDate>Fri, 12 Apr 2024 14:23:18 +0000</pubDate>
      <link>https://dev.to/aws-builders/automating-docker-deployment-security-and-efficiency-with-cicd-pipelines-using-github-actions-26i5</link>
      <guid>https://dev.to/aws-builders/automating-docker-deployment-security-and-efficiency-with-cicd-pipelines-using-github-actions-26i5</guid>
      <description>&lt;p&gt;In the current dynamic software development landscape, security and efficiency are critical. Companies and developers work hard to swiftly roll out apps while making sure they are safe from security flaws. This is where the industry-leading containerization technology Docker comes into play. By wrapping up applications in containers, Docker makes the deployment process simpler. However, if done manually, managing these containers, creating them, checking for vulnerabilities, and pushing them safely can be difficult and time-consuming. For this reason, it's critical to automate these procedures via a Continuous Integration/Continuous Deployment (CI/CD) pipeline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgsun030ewqt40ru4rv2x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgsun030ewqt40ru4rv2x.png" alt="Architectural Diagram of the CI/CD Pipeline Workflow" width="654" height="848"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Role of CI/CD in Modern Software Development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Software release process automation is the goal of Continuous Integration (CI) and Continuous Deployment (CD). Building software that is reliable, safe, and quickly deployable is the aim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continuous Integration:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CI involves merging all developers' working copies to a shared mainline several times a day. The main objectives of CI include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reducing bugs&lt;/strong&gt;: Automated testing in CI helps detect and fix bugs quickly, improves software quality, and reduces the time it takes to validate and release new software updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improving software quality&lt;/strong&gt;: Continuous integration leads to significantly reduced assumptions as integration issues are detected and fixed continuously.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Continuous Deployment:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CD extends CI by automatically deploying all code changes to a testing and/or production environment after the build stage. This means that on top of the automated testing, automated release processes further streamline the development lifecycle. Benefits of CD include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Faster time to market&lt;/strong&gt;: Accelerated release cycles ensure features reach production faster.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher release rates&lt;/strong&gt;: Frequent releases promote smaller, more manageable changes and less deployment risk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved customer satisfaction&lt;/strong&gt;: Continuous delivery of features addresses user feedback more promptly and enhances the user experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementing GitHub Actions for Docker Management
&lt;/h2&gt;

&lt;p&gt;From the first code change to the last production deployment, GitHub Actions is a CI/CD tool that streamlines the software process. Building processes that automatically create, test, and launch Docker containers is a requirement of using GitHub Actions for Docker administration.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Actions Workflow: The "Complete Docker Workflow"
&lt;/h3&gt;

&lt;p&gt;An extensive dissection of the "&lt;strong&gt;Complete Docker Workflow,” a&lt;/strong&gt; system for managing Docker deployments with GitHub Actions, is given in this section. There are multiple stages in this workflow, all designed to improve security and expedite procedures across the container management lifecycle.&lt;/p&gt;

&lt;h4&gt;
  
  
  Workflow Activation Triggers
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scheduled Runs&lt;/strong&gt;: Set to trigger daily at 16:21 UTC, this ensures regular updates and checks, keeping the application up to date with the latest base image vulnerabilities addressed.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    - cron: '21 16 * * *'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Push Events&lt;/strong&gt;: Activates on pushes to specific branches or tags (specified branch and semantic versioned tags). This ensures that all changes undergo rigorous testing and security checks before deployment.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;push:
    branches:
      - branch-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pull Requests&lt;/strong&gt;: Targets pull requests to the &lt;strong&gt;dev-2&lt;/strong&gt; branch, allowing for automated reviews and tests and ensuring that new code integrations meet quality standards before merging.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pull_request:
    branches:
      - branch-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Environment Configuration
&lt;/h3&gt;

&lt;p&gt;Using environment variables and secrets for configurations like Docker registry credentials secures sensitive information and streamlines the setup process across multiple environments or projects. &lt;strong&gt;docker.io&lt;/strong&gt; is specified as our REGISTRY in this instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;env:
  REGISTRY: ${{ secrets.REGISTRY }}
  IMAGE_NAME: ${{ secrets.DOCKER_USERNAME }}/${{ secrets.IMAGE_NAME }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Initial Setup and Configurations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Checkout Repository&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses GitHub's actions/&lt;a href="mailto:checkout@v3.5.2"&gt;checkout@v3.5.2&lt;/a&gt; to clone the repository, with a minimal fetch depth of 1 to speed up the checkout process.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Checkout repository
        uses: actions/checkout@v3.5.2
        with:
          fetch-depth: 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Install Cosign&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implements sigstore/&lt;a href="mailto:cosign-installer@v3.4.0"&gt;cosign-installer@v3.4.0&lt;/a&gt; to install Cosign, which is used later to sign Docker images.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Install Cosign
        uses: sigstore/cosign-installer@v3.4.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Set up QEMU&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Employs docker/&lt;a href="mailto:setup-qemu-action@v2.1.0"&gt;setup-qemu-action@v2.1.0&lt;/a&gt; to configure QEMU, facilitating the emulation of different architectures which is essential for cross-platform Docker builds.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Set up QEMU
        uses: docker/setup-qemu-action@v2.1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Set up Docker Buildx&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engages docker/&lt;a href="mailto:setup-buildx-action@v2.5.0"&gt;setup-buildx-action@v2.5.0&lt;/a&gt; to set up Docker Buildx, enhancing the ability to perform multi-platform builds directly from a single command.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2.5.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Log in to Docker Registry&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Utilizes docker/&lt;a href="mailto:login-action@v2.1.0"&gt;login-action@v2.1.0&lt;/a&gt; for logging into the Docker registry using credentials stored in GitHub secrets.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Log in to Docker Registry
        uses: docker/login-action@v2.1.0
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Extract Docker Metadata&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Activates docker/&lt;a href="mailto:metadata-action@v4.4.0"&gt;metadata-action@v4.4.0&lt;/a&gt; to generate and format Docker image metadata, such as tags, from the environment variables.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Extract Docker metadata
        id: meta
        uses: docker/metadata-action@v4.4.0
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Building and Pushing Images
&lt;/h3&gt;

&lt;p&gt;The procedure ensures interoperability across various hardware settings by supporting the development of images for many architectures using Docker Buildx and QEMU. Developers' work is made easier by automating the push to registries, freeing them up to concentrate on essential features rather than operational setups. Here, &lt;strong&gt;linux/amd64&lt;/strong&gt; is the chosen OS. Please be aware that you can use multiple operating systems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Build and Push container images
        uses: docker/build-push-action@v4.0.0
        with:
          platforms: linux/amd64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Security Scanning with Trivy
&lt;/h3&gt;

&lt;p&gt;Preventing potential security risks before they arise in production requires integrating Trivy scans to evaluate image vulnerabilities. This scan is essential for keeping a secure deployment as it looks for vulnerabilities at the OS and library levels. If there are multiple tags for the image, you can duplicate the below step and specify each of the tags.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Scan Docker image with Trivy (specifying a tag)
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:tag
          format: 'table'
          severity: 'CRITICAL,HIGH'
          vuln-type: 'os,library'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Digital Signing of Images with Cosign
&lt;/h3&gt;

&lt;p&gt;By confirming the source of the images and signing them using Cosign, GitHub's OIDC integration adds an extra degree of security to ensure that only validated images are released.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Sign the images with GitHub OIDC Token (Non-interactive)
        run: |
          IFS=',' read -ra ADDR &amp;lt;&amp;lt;&amp;lt; "${{ steps.meta.outputs.tags }}"
          for tag in "${ADDR[@]}"; do
            echo "Signing $tag"
            cosign sign --oidc-issuer=https://token.actions.githubusercontent.com --yes "$tag"
          done
        env:
          COSIGN_EXPERIMENTAL: "true"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Complete CI/CD Pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Complete Docker Workflow

on:
  schedule:
    - cron: '21 16 * * *'
  push:
    branches:
      - branch-name
    tags:
      - 'v*.*.*'
  pull_request:
    branches:
      - branch-name

env:
  REGISTRY: ${{ secrets.REGISTRY }}
  IMAGE_NAME: ${{ secrets.DOCKER_USERNAME }}/${{ secrets.IMAGE_NAME }}

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
      id-token: write # needed for signing the images with GitHub OIDC Token
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3.5.2
        with:
          fetch-depth: 1

      - name: Install Cosign
        uses: sigstore/cosign-installer@v3.4.0

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2.1.0

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2.5.0

      - name: Log in to Docker Registry
        uses: docker/login-action@v2.1.0
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Extract Docker metadata
        id: meta
        uses: docker/metadata-action@v4.4.0
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

      - name: Build and Push container images
        uses: docker/build-push-action@v4.0.0
        with:
          platforms: linux/amd64
          push: true
          tags: ${{ steps.meta.outputs.tags }}

      - name: Scan Docker image with Trivy (tag1)
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:tag1
          format: 'table'
          severity: 'CRITICAL,HIGH'
          vuln-type: 'os,library'

      - name: Scan Docker image with Trivy (tag2)
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:tag2
          format: 'table'
          severity: 'CRITICAL,HIGH'
          vuln-type: 'os,library'

      - name: Sign the images with GitHub OIDC Token (Non-interactive)
        run: |
          IFS=',' read -ra ADDR &amp;lt;&amp;lt;&amp;lt; "${{ steps.meta.outputs.tags }}"
          for tag in "${ADDR[@]}"; do
            echo "Signing $tag"
            cosign sign --oidc-issuer=https://token.actions.githubusercontent.com --yes "$tag"
          done
        env:
          COSIGN_EXPERIMENTAL: "true"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advantages over Traditional Methods
&lt;/h2&gt;

&lt;p&gt;There are several benefits to automating these procedures over more conventional manual ones.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduced Human Error&lt;/strong&gt;: Automating repetitive tasks lowers the possibility of human error, including deployment script misconfiguration or omission of stages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency and Reliability&lt;/strong&gt;: Automation guarantees consistency and repeatability by ensuring that each step is carried out in the same way. This makes the process of developing, testing, and deploying software dependable and predictable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: By methodically identifying and addressing security concerns, automated vulnerability scans considerably lower the risk of releasing vulnerable code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This pipeline comprehensively covers all aspects of Docker image management, from build to security checks to deployment, ensuring high standards of automation and security using GitHub Actions. This setup not only automates the build and deployment process but also incorporates critical security practices like scanning and signing images, pivotal for maintaining the integrity and trustworthiness of software in a CI/CD environment.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>cicd</category>
      <category>githubactions</category>
      <category>devops</category>
    </item>
    <item>
      <title>Guide to Resizing EC2 Instance Volume without Deleting the Instance</title>
      <dc:creator>MUHAMMAD ABIODUN SULAIMAN</dc:creator>
      <pubDate>Tue, 05 Dec 2023 13:51:24 +0000</pubDate>
      <link>https://dev.to/behordeun/guide-to-resizing-ec2-instance-volume-without-deleting-the-instance-1nd8</link>
      <guid>https://dev.to/behordeun/guide-to-resizing-ec2-instance-volume-without-deleting-the-instance-1nd8</guid>
      <description>&lt;p&gt;As engineers or developers who use AWS Cloud infrastructure, when we provision an EC2 instance, we often face the challenge of the instance storage getting exhausted while our deployment is midway. &lt;/p&gt;

&lt;p&gt;While starting out my career with AWS Cloud a couple of years ago, whenever I'm faced with this challenge, I find myself deleting the instance and provisioning a new instance with a higher volume size.&lt;/p&gt;

&lt;p&gt;Over the years, I found that I wasn't implementing the best practice. Rather, I was only meant to create a shell script that will increase the volume size to a size of my choice while restarting the instance to ensure that the partition takes up all the space it can. &lt;/p&gt;

&lt;p&gt;The script explained in part:&lt;/p&gt;

&lt;p&gt;A. Specify the desired volume size in GiB as a command line argument. If not specified, default to 20 GiB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SIZE=${1:-20}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;B. Get the ID of the environment host Amazon EC2 instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSTANCEID=$(curl http://169.254.169.254/latest/meta-data/instance-id)
REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/\(.*\)[a-z]/\1/')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;C. Get the ID of the Amazon EBS volume associated with the instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VOLUMEID=$(aws ec2 describe-instances \
  --instance-id $INSTANCEID \
  --query "Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId" \
  --output text \
  --region $REGION)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;D. Resize the EBS volume.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws ec2 modify-volume --volume-id $VOLUMEID --size $SIZE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E. Wait for the resize to finish.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;while [ \
  "$(aws ec2 describe-volumes-modifications \
    --volume-id $VOLUMEID \
    --filters Name=modification-state,Values="optimizing","completed" \
    --query "length(VolumesModifications)"\
    --output text)" != "1" ]; do
sleep 1
done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;F. Check if we're on an NVMe filesystem&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if [[ -e "/dev/xvda" &amp;amp;&amp;amp; $(readlink -f /dev/xvda) = "/dev/xvda" ]]
then
  # Rewrite the partition table to take up all the space it can.
  sudo growpart /dev/xvda 1

  # Expand the size of the file system.
  # Check if we're on AL2
  STR=$(cat /etc/os-release)
  SUB="VERSION_ID=\"2\""
  if [[ "$STR" == *"$SUB"* ]]
  then
    sudo xfs_growfs -d /
  else
    sudo resize2fs /dev/xvda1
  fi

else
  # Rewrite the partition table to take up all the space it can.
  sudo growpart /dev/nvme0n1 1

  # Expand the size of the file system.
  # Check if we're on AL2
  STR=$(cat /etc/os-release)
  SUB="VERSION_ID=\"2\""
  if [[ "$STR" == *"$SUB"* ]]
  then
    sudo xfs_growfs -d /
  else
    sudo resize2fs /dev/nvme0n1p1
  fi
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The complete script is below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

# Specify the desired volume size in GiB as a command line argument. If not specified, default to 20 GiB.
SIZE=${1:-20}

# Get the ID of the environment host Amazon EC2 instance.
INSTANCEID=$(curl http://169.254.169.254/latest/meta-data/instance-id)
REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/\(.*\)[a-z]/\1/')

# Get the ID of the Amazon EBS volume associated with the instance.
VOLUMEID=$(aws ec2 describe-instances \
  --instance-id $INSTANCEID \
  --query "Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.VolumeId" \
  --output text \
  --region $REGION)

# Resize the EBS volume.
aws ec2 modify-volume --volume-id $VOLUMEID --size $SIZE

# Wait for the resize to finish.
while [ \
  "$(aws ec2 describe-volumes-modifications \
    --volume-id $VOLUMEID \
    --filters Name=modification-state,Values="optimizing","completed" \
    --query "length(VolumesModifications)"\
    --output text)" != "1" ]; do
sleep 1
done

#Check if we're on an NVMe filesystem
if [[ -e "/dev/xvda" &amp;amp;&amp;amp; $(readlink -f /dev/xvda) = "/dev/xvda" ]]
then
  # Rewrite the partition table to take up all the space it can.
  sudo growpart /dev/xvda 1

  # Expand the size of the file system.
  # Check if we're on AL2
  STR=$(cat /etc/os-release)
  SUB="VERSION_ID=\"2\""
  if [[ "$STR" == *"$SUB"* ]]
  then
    sudo xfs_growfs -d /
  else
    sudo resize2fs /dev/xvda1
  fi

else
  # Rewrite the partition table to take up all the space it can.
  sudo growpart /dev/nvme0n1 1

  # Expand the size of the file system.
  # Check if we're on AL2
  STR=$(cat /etc/os-release)
  SUB="VERSION_ID=\"2\""
  if [[ "$STR" == *"$SUB"* ]]
  then
    sudo xfs_growfs -d /
  else
    sudo resize2fs /dev/nvme0n1p1
  fi
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can connect with me via &lt;a href="//mailto:%20abiodun.msulaiman@gmail.com"&gt;Email&lt;/a&gt; or &lt;a href="https://linkedin.com/in/muhammad-abiodun-sulaiman"&gt;LinkedIn&lt;/a&gt; or &lt;a href="https://medium.com/@behordeun"&gt;medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ec2</category>
      <category>devops</category>
      <category>bash</category>
      <category>automation</category>
    </item>
    <item>
      <title>Passing Credentials to Deployed Streamlit Apps using Streamlit Secrets</title>
      <dc:creator>MUHAMMAD ABIODUN SULAIMAN</dc:creator>
      <pubDate>Sat, 05 Nov 2022 16:32:52 +0000</pubDate>
      <link>https://dev.to/aws-builders/passing-credentials-to-deployed-streamlit-apps-using-streamlit-secrets-67l</link>
      <guid>https://dev.to/aws-builders/passing-credentials-to-deployed-streamlit-apps-using-streamlit-secrets-67l</guid>
      <description>&lt;p&gt;Often as programmers, we get to deal with credentials, for instance, when we need to connect to a database or ingest data from sources besides our local computers. Hence, it becomes imperative to find a way to securely pass the credentials such that they are not exposed in our code scripts.&lt;/p&gt;

&lt;p&gt;In this short article, I will explain how I used #StreamlitSecrets to resolve a problem with passing credentials to a #MachineLearning system I deployed to the web using #Streamlit. Before fixing the problem, the deployed app worked fine on my local computer while testing it because the credentials were passed to the ingestion pipeline using an environment variable file (.env); however, upon deploying to the web, the system failed to work due to unavailability of the credentials. Some steps in solving this problem include removing the environment variable file from &lt;strong&gt;gitignore&lt;/strong&gt;and creating a Python (.py) file; since the programming language I was working with was Python. Upon taking these steps, I could not push the local repository to the remote repository as &lt;strong&gt;pre-commit hook&lt;/strong&gt; detected that credentials had been exposed and did not allow the push. Hence, I finally had to use the #StreamlitSecrets file (secrets.toml) to pass the credentials while updating the credentials on the app settings section of the deployed streamlit app. The steps taken to achieve this are listed below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the directory &lt;strong&gt;.streamlit/&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create the secret file &lt;strong&gt;secrets.toml&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;In the created secret file, type in the credentials in the below format:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[db_credentials]
user = 'someuser'
password = 'somepassword'
host = 'somehost'
database = 'somedatabase'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PS: You can include other credentials as needed.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the python file, pass in the credentials with the following lines of code:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;host=st.secrets.db_credentials.host,
user=st.secrets.db_credentials.user,
password=st.secrets.db_credentials.password,
db=st.secrets.db_credentials.database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Navigate to the url link of the deployed app, open settings, and type in the provided credentials in &lt;strong&gt;.streamlit/secrets.toml&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe10ltzk97n8j8spy5121.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe10ltzk97n8j8spy5121.jpeg" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above steps ensure that your streamlit app works seamlessly on your local computer and the Streamlit deployed version.&lt;/p&gt;

&lt;p&gt;If you find the article helpful, kindly click the like button and comment.&lt;/p&gt;

&lt;p&gt;You can follow me on &lt;a href="https://www.linkedin.com/in/muhammad-abiodun-sulaiman" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; and &lt;a href="https://www.twitter.com/prince_Analyst" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; for more updates.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Automating AWS Infrastructure with Terraform</title>
      <dc:creator>MUHAMMAD ABIODUN SULAIMAN</dc:creator>
      <pubDate>Tue, 30 Aug 2022 16:30:41 +0000</pubDate>
      <link>https://dev.to/aws-builders/automating-aws-infrastructure-with-terraform-4291</link>
      <guid>https://dev.to/aws-builders/automating-aws-infrastructure-with-terraform-4291</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is Cloud Automation and Why is it Important in IT?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cloud automation broadly refers to the processes and tools used to provision and manage cloud computing workloads and infrastructure. These processes and tools aim to reduce or eliminate manual processes, saving costs and resources.&lt;/p&gt;

&lt;p&gt;With the increasing demand of serving a wider group of customers/clients and expanding the customer base, organizations need to consider the adoption of &lt;strong&gt;Cloud Automation&lt;/strong&gt; as it affords them the ability to scale efficiently. Several IT companies have adopted cloud automation to optimize their business resources while also staying on top of their games.&lt;br&gt;
Some of the reasons why companies will want to consider the adoption of cloud adoption are listed below&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It saves an IT team time and money;&lt;/li&gt;
&lt;li&gt;It is faster, more secure and more scalable than manually performing tasks;&lt;/li&gt;
&lt;li&gt;It leads to fewer errors, as organizations can construct more predictable and reliable workflows; and&lt;/li&gt;
&lt;li&gt;It contributes directly to better IT and corporate governance.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Next, we shall explore cloud automation tools which are categorized as:&lt;br&gt;
&lt;strong&gt;Cloud Providers (private and public):&lt;/strong&gt; These include:-&lt;/p&gt;

&lt;p&gt;i. &lt;strong&gt;AWS&lt;/strong&gt;: AWS Config, AWS CloudFormation, AWS EC2 Systems Manager;&lt;br&gt;
ii. &lt;strong&gt;Azure&lt;/strong&gt;: Microsoft Azure Resource Manager, Azure Automation;&lt;br&gt;
iii. &lt;strong&gt;Google&lt;/strong&gt;: Google Cloud Composer, Cloud Deployment Manager; and&lt;br&gt;
iv. &lt;strong&gt;IBM&lt;/strong&gt;: IBM Cloud Orchestrator.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Configuration Management tools&lt;/strong&gt;: Most of these tools allows for Infrastructure-as-a-service (IaaS) setup, and has the below as some of its examples:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;i. Red Hat Ansible,&lt;br&gt;
ii. Puppet Enterprise,&lt;br&gt;
iii. Chef Automate,&lt;br&gt;
iv. Salt/SaltStack, and&lt;br&gt;
v. HashiCorp Terraform&lt;/p&gt;

&lt;p&gt;Many multi-cloud management vendors incorporate automation capabilities into their tools. Some prominent ones are:&lt;/p&gt;

&lt;p&gt;i. VMware,&lt;br&gt;
ii. CloudBolt,&lt;br&gt;
iii. CloudSphere (Hypergrid),&lt;br&gt;
iv. Snow (Embotics),&lt;br&gt;
v. Morpheus Data,&lt;br&gt;
vi. Scalr, and&lt;br&gt;
vii. Flexera (RightScale).&lt;/p&gt;

&lt;p&gt;To read more about cloud automation, click &lt;a href="https://www.techtarget.com/searchcloudcomputing/definition/cloud-automation#:~:text=Cloud%20automation%20is%20a%20broad,public%20and%20hybrid%20cloud%20environments"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Having introduced us to the basics of cloud automation, its importance, and tools used for cloud automation. We shall employ some of the earlier mentioned cloud automation tools to build a project. We will use AWS, HashiCorp Terraform, and Microsoft Visual Studio Code (VSC) as our IDE.&lt;/p&gt;

&lt;p&gt;This project introduces beginners to Cloud Infrastructure Automation, with AWS as the cloud provider. A detailed explanation of the processes and resources created in this small project can be found &lt;a href="https://github.com/Behordeun/Automating-AWS-Infrastructure-with-Terraform"&gt;here&lt;/a&gt;. Simply follow the guides &lt;a href="https://github.com/Behordeun/Automating-AWS-Infrastructure-with-Terraform/blob/main/README.md"&gt;here&lt;/a&gt;, and you should be fine. Feel free to fork this repo, raise a pull request to contribute to this project, and raise an issue if you encounter any challenges&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lIZrrM13--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t4orajel386nozzws039.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lIZrrM13--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t4orajel386nozzws039.png" alt="A workflow of resources deployed via terraform" width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This project created nine resources/processes in our AWS instance right from terraform. These resources are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Virtual Private Cloud (VPC)&lt;/strong&gt;: A virtual private cloud (VPC) is a secure, isolated private cloud hosted within a public cloud. VPCs combines the scalability and convenience of public cloud computing with private cloud computing data isolation. Click here to read more about VPC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Internet Gateway&lt;/strong&gt;: An Internet gateway is a network "node" connecting two networks that use different protocols (rules) to communicate. In the most basic terms, an Internet gateway is where data stops on its way to or from other networks. &lt;a href="https://www.cloudflare.com/learning/cloud/what-is-a-virtual-private-cloud/"&gt;Click here to read more about internet gateway&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom Route Table&lt;/strong&gt;: A route table contains a set of rules, called routes, that are used to determine where network traffic from your subnet or gateway is directed. In a more explicit term, a route table tells network packets which way they need to go to get to their destination. &lt;a href="https://www.whatismypublicip.com/blog/what-is-an-internet-gateway/"&gt;Click here to read more about custom route table.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subnet: A subnet, or subnetwork, is a segmented piece of a more extensive network. More specifically, subnets are a logical partition of an IP network into multiple, smaller network segments. &lt;a href="https://www.techtarget.com/searchnetworking/definition/subnet"&gt;Click here to read more about subnets.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We associated the subnet created in step 4 with the route table created in step 3.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We created a Security Group to allow ports 22, 80, 443.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a network interface with an IP in the subnet created in step 4.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assigned an elastic IP to the network interface created in step 7&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created an Ubuntu server and installed/enabled apache2&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember to drop a comment and drop a like if you have benefitted from this article.&lt;/p&gt;

&lt;p&gt;You can connect with me via:&lt;br&gt;
Email: &lt;a href="//mailto:abiodun.msulaiman@gmail.com"&gt;abiodun.msulaiman@gmail.com&lt;/a&gt; or&lt;br&gt;
LinkedIn: &lt;a href="https://www.linkedin.com/in/muhammad-abiodun-sulaiman"&gt;Muhammad Abiodun Sulaiman&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>terraform</category>
      <category>devops</category>
      <category>github</category>
    </item>
  </channel>
</rss>
