<?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>Forem: Aj</title>
    <description>The latest articles on Forem by Aj (@ajbuilds).</description>
    <link>https://forem.com/ajbuilds</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3825798%2F0d0f60ca-1b4d-4a45-bebb-8a365c4c2c97.png</url>
      <title>Forem: Aj</title>
      <link>https://forem.com/ajbuilds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ajbuilds"/>
    <language>en</language>
    <item>
      <title>AWS EBS explained: volume types, snapshots, and when NOT to use it</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Fri, 10 Apr 2026 13:29:43 +0000</pubDate>
      <link>https://forem.com/ajbuilds/aws-ebs-explained-volume-types-snapshots-and-when-not-to-use-it-1hp3</link>
      <guid>https://forem.com/ajbuilds/aws-ebs-explained-volume-types-snapshots-and-when-not-to-use-it-1hp3</guid>
      <description>&lt;p&gt;Most AWS tutorials treat EBS like it's just a cloud hard drive you attach to EC2. Plug it in, store your files, done.&lt;/p&gt;

&lt;p&gt;That mental model is why developers end up with the wrong volume type for their workload, surprise bills from forgotten snapshots, and architecture decisions that are hard to reverse six months later.&lt;/p&gt;

&lt;p&gt;This is the guide that actually explains how EBS works — the volume types, when to use each, when to use something else entirely, and what the common expensive mistakes look like.&lt;/p&gt;




&lt;h2&gt;
  
  
  What AWS EBS actually is
&lt;/h2&gt;

&lt;p&gt;EBS (Elastic Block Store) is &lt;strong&gt;persistent block storage&lt;/strong&gt; for EC2 instances. The two words that matter: &lt;em&gt;persistent&lt;/em&gt; and &lt;em&gt;block&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persistent&lt;/strong&gt; means your data survives instance stop and termination. This is different from instance store (ephemeral storage that disappears when the instance stops). If you stop an EC2 instance and start it again tomorrow, EBS data is still there. Instance store data is gone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Block storage&lt;/strong&gt; means the OS sees it as a raw disk — a device like &lt;code&gt;/dev/xvda&lt;/code&gt; or &lt;code&gt;/dev/nvme0n1&lt;/code&gt;. You format it with a filesystem (ext4, xfs), mount it, and use it like any disk. This is different from S3 (object storage, accessed via API) or EFS (file storage, accessed via NFS protocol).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The key operational fact:&lt;/strong&gt; Each EBS volume lives in one Availability Zone and can only be attached to instances in the same AZ. If your instance is in &lt;code&gt;us-east-1a&lt;/code&gt;, your EBS volume must also be in &lt;code&gt;us-east-1a&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  EBS volume types: which one do you actually need?
&lt;/h2&gt;

&lt;p&gt;AWS offers six EBS volume types. Most workloads need one of two. Here is the complete breakdown:&lt;/p&gt;

&lt;h3&gt;
  
  
  gp3 — General Purpose SSD (the default, and usually the right choice)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IOPS:&lt;/strong&gt; 3,000 baseline, up to 16,000 provisioned independently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throughput:&lt;/strong&gt; 125 MB/s baseline, up to 1,000 MB/s independently&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; ~$0.08/GB-month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use for:&lt;/strong&gt; Boot volumes, development environments, small to medium databases, web servers, almost everything&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important upgrade from gp2: on gp3, IOPS and throughput are &lt;strong&gt;independent&lt;/strong&gt; of storage size. On gp2, you got 3 IOPS per GB (so a 100GB volume had 300 IOPS). On gp3, you always get 3,000 IOPS regardless of size, and you can add more without buying more storage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you have gp2 volumes today, migrate them to gp3.&lt;/strong&gt; Same performance, 20% cheaper.&lt;/p&gt;

&lt;h3&gt;
  
  
  gp2 — General Purpose SSD (legacy, stop using this)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IOPS:&lt;/strong&gt; 3 IOPS/GB, minimum 100, maximum 16,000&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; ~$0.10/GB-month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use for:&lt;/strong&gt; Nothing new. Migrate existing gp2 to gp3.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  io2 Block Express — Provisioned IOPS SSD (when you need extreme performance)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IOPS:&lt;/strong&gt; Up to 256,000&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throughput:&lt;/strong&gt; Up to 4,000 MB/s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; ~$0.125/GB-month + $0.065/provisioned IOPS-month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use for:&lt;/strong&gt; Large critical databases (Oracle, SQL Server, SAP HANA), workloads requiring sub-millisecond latency with consistent performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;io2 Block Express is expensive. A 1TB io2 volume with 32,000 IOPS costs roughly $180/month vs $80/month for the same size gp3. The performance difference is real — if your database latency is the bottleneck, io2 is worth it. If it's not your bottleneck, it's waste.&lt;/p&gt;

&lt;h3&gt;
  
  
  io1 — Provisioned IOPS SSD (legacy io2, skip this)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use io2 instead. Better durability (99.999% vs 99.8%), same price or cheaper per IOPS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  st1 — Throughput Optimized HDD (big sequential reads)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Throughput:&lt;/strong&gt; Up to 500 MB/s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IOPS:&lt;/strong&gt; Low (not the right metric for HDDs)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; ~$0.045/GB-month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use for:&lt;/strong&gt; Big data, data warehouses, log processing — workloads that read/write large files sequentially&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cannot be used as boot volume&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;st1 is significantly cheaper than SSDs. If your workload reads Kafka log files, Hadoop data, or large sequential datasets where throughput matters but IOPS don't, st1 saves significant money.&lt;/p&gt;

&lt;h3&gt;
  
  
  sc1 — Cold HDD (infrequently accessed archives)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Throughput:&lt;/strong&gt; Up to 250 MB/s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; ~$0.015/GB-month (cheapest EBS option)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use for:&lt;/strong&gt; Infrequently accessed data that still needs block storage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cannot be used as boot volume&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;sc1 is basically archival storage. If you're storing data you access rarely and can tolerate slow access, sc1 is the cheapest block storage available on AWS.&lt;/p&gt;




&lt;h2&gt;
  
  
  The decision framework
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is this a boot volume?
  → Yes: gp3 (required — st1/sc1 can't boot)

Does your workload need &amp;gt;16,000 IOPS or consistent sub-ms latency?
  → Yes: io2 Block Express
  → No: Continue

Is your workload sequential large reads/writes (logs, Hadoop, analytics)?
  → Yes: st1 (throughput optimized)

Is the data infrequently accessed?
  → Yes: sc1 (cheapest)

Everything else: gp3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nine out of ten workloads should be on gp3. The other one is a large database that needs io2.&lt;/p&gt;




&lt;h2&gt;
  
  
  EBS vs EFS vs S3: choosing the right storage
&lt;/h2&gt;

&lt;p&gt;This is where most architecture decisions go wrong. Block, file, and object storage serve fundamentally different purposes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;EBS&lt;/th&gt;
&lt;th&gt;EFS&lt;/th&gt;
&lt;th&gt;S3&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Storage type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Block&lt;/td&gt;
&lt;td&gt;File (NFS)&lt;/td&gt;
&lt;td&gt;Object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Access pattern&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single EC2 instance&lt;/td&gt;
&lt;td&gt;Multiple EC2 instances&lt;/td&gt;
&lt;td&gt;Any client via API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Protocol&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;OS disk (mounted)&lt;/td&gt;
&lt;td&gt;NFS&lt;/td&gt;
&lt;td&gt;HTTP REST API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Persistence&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Until deleted&lt;/td&gt;
&lt;td&gt;Until deleted&lt;/td&gt;
&lt;td&gt;Until deleted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sub-millisecond&lt;/td&gt;
&lt;td&gt;Low milliseconds&lt;/td&gt;
&lt;td&gt;Milliseconds to seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Availability Zone&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single AZ&lt;/td&gt;
&lt;td&gt;Multi-AZ&lt;/td&gt;
&lt;td&gt;Global&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Price (storage)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;From $0.015/GB&lt;/td&gt;
&lt;td&gt;From $0.30/GB&lt;/td&gt;
&lt;td&gt;From $0.023/GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Databases, boot volumes&lt;/td&gt;
&lt;td&gt;Shared file systems, CMS&lt;/td&gt;
&lt;td&gt;Media, backups, static assets&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Use EBS when:&lt;/strong&gt; You need a disk that one EC2 instance treats as its own — databases, application servers, boot volumes, anything requiring filesystem-level access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use EFS when:&lt;/strong&gt; Multiple EC2 instances need to read/write the same files simultaneously — shared CMS uploads, distributed application configs, dev environments shared across instances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use S3 when:&lt;/strong&gt; You're storing objects via API — static website assets, images, videos, backups, data lake files, anything accessed via URL or SDK rather than a mounted filesystem.&lt;/p&gt;

&lt;p&gt;The most common wrong decision: using EBS for something that should be S3 (backups, logs, static files). S3 is cheaper, more durable (99.999999999%), and globally accessible. EBS is more expensive, tied to one AZ, and appropriate only when your application needs a real disk.&lt;/p&gt;




&lt;h2&gt;
  
  
  Snapshots: what they are and how to not forget them
&lt;/h2&gt;

&lt;p&gt;An EBS snapshot is a point-in-time backup of a volume stored in S3. Snapshots are incremental — the first one copies everything, subsequent ones only copy what changed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a snapshot:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 create-snapshot &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--volume-id&lt;/span&gt; vol-0123456789abcdef0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"Production DB backup &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y-%m-%d&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Restore a volume from snapshot:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 create-volume &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--snapshot-id&lt;/span&gt; snap-0123456789abcdef0 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--availability-zone&lt;/span&gt; us-east-1a &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--volume-type&lt;/span&gt; gp3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The expensive mistake:&lt;/strong&gt; Creating snapshots and never deleting old ones. Snapshots cost $0.05/GB-month for the data stored. A 500GB production database with daily snapshots and no retention policy generates 500GB × 30 days × $0.05 = $750/month in snapshot storage — more than the EC2 instance itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set a lifecycle policy immediately:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a Data Lifecycle Manager policy&lt;/span&gt;
aws dlm create-lifecycle-policy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"Daily snapshots, keep 7 days"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--state&lt;/span&gt; ENABLED &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--execution-role-arn&lt;/span&gt; arn:aws:iam::123456789012:role/AWSDataLifecycleManagerDefaultRole &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--policy-details&lt;/span&gt; &lt;span class="s1"&gt;'{
    "PolicyType": "EBS_SNAPSHOT_MANAGEMENT",
    "ResourceTypes": ["VOLUME"],
    "TargetTags": [{"Key": "Backup", "Value": "daily"}],
    "Schedules": [{
      "Name": "Daily",
      "CreateRule": {"Interval": 24, "IntervalUnit": "HOURS", "Times": ["03:00"]},
      "RetainRule": {"Count": 7},
      "CopyTags": true
    }]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tag your volumes with &lt;code&gt;Backup: daily&lt;/code&gt;, and this policy automatically creates and expires snapshots. No manual management, no forgotten snapshots accumulating cost.&lt;/p&gt;




&lt;h2&gt;
  
  
  EBS encryption with KMS
&lt;/h2&gt;

&lt;p&gt;Encrypt EBS volumes using AWS KMS. Two ways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Enable default encryption for all new volumes (recommended — set this once):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 enable-ebs-encryption-by-default &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running this, every new EBS volume in &lt;code&gt;us-east-1&lt;/code&gt; is automatically encrypted using your default KMS key. No per-volume configuration needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Encrypt a specific volume:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 create-volume &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--availability-zone&lt;/span&gt; us-east-1a &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--size&lt;/span&gt; 100 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--volume-type&lt;/span&gt; gp3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--encrypted&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--kms-key-id&lt;/span&gt; arn:aws:kms:us-east-1:123456789012:key/your-key-id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Encryption adds zero latency overhead. There is no reason not to encrypt. Enable default encryption by default in every region you use.&lt;/p&gt;




&lt;h2&gt;
  
  
  EBS cost optimization: where teams overpay
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Unattached volumes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you terminate an EC2 instance, the root EBS volume is deleted (by default). But additional data volumes are not. They keep charging until explicitly deleted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find all unattached volumes&lt;/span&gt;
aws ec2 describe-volumes &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;status,Values&lt;span class="o"&gt;=&lt;/span&gt;available &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Volumes[*].[VolumeId,Size,VolumeType,CreateTime]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this monthly. Delete volumes you don't need. An unused 100GB gp3 volume is $8/month, quietly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. gp2 volumes that haven't been migrated to gp3&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find all gp2 volumes&lt;/span&gt;
aws ec2 describe-volumes &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;volume-type,Values&lt;span class="o"&gt;=&lt;/span&gt;gp2 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Volumes[*].[VolumeId,Size]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Migrate each to gp3 for an instant 20% cost reduction with no performance loss.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Over-provisioned io2 volumes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;io2 charges per provisioned IOPS regardless of usage. If you provisioned 16,000 IOPS but your CloudWatch &lt;code&gt;VolumeReadOps&lt;/code&gt; and &lt;code&gt;VolumeWriteOps&lt;/code&gt; show average usage of 2,000 IOPS, you're paying for 14,000 idle IOPS.&lt;/p&gt;

&lt;p&gt;Check your EBS volume metrics in CloudWatch. Right-size io2 to match actual usage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Snapshots with no retention policy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use Data Lifecycle Manager (shown above). One-time setup, saves money indefinitely.&lt;/p&gt;




&lt;h2&gt;
  
  
  EC2 instance store vs EBS: the critical difference
&lt;/h2&gt;

&lt;p&gt;Instance store is temporary storage physically attached to the EC2 host. It is &lt;strong&gt;not&lt;/strong&gt; EBS. Key differences:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;EBS&lt;/th&gt;
&lt;th&gt;Instance Store&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Persistence&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Survives stop/start/reboot&lt;/td&gt;
&lt;td&gt;Gone on stop, termination, failure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Speed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very fast (NVMe gp3/io2)&lt;/td&gt;
&lt;td&gt;Fastest (direct physical attach)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Charged separately&lt;/td&gt;
&lt;td&gt;Included in instance price&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Size&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Any size up to 64TB&lt;/td&gt;
&lt;td&gt;Fixed to instance type&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Instance store is appropriate for: cache data you can regenerate, Hadoop temporary files, database buffer pools that can be rebuilt. Never use instance store for data you cannot regenerate from another source.&lt;/p&gt;

&lt;p&gt;If your EC2 instance is stopped for any reason — scheduled maintenance, capacity issue, failure — instance store data is gone with no recovery path.&lt;/p&gt;




&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I attach one EBS volume to multiple EC2 instances?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;io1 and io2 volumes support Multi-Attach, allowing up to 16 instances in the same AZ to attach the same volume simultaneously. This requires careful application-level coordination to prevent data corruption — your application must handle concurrent writes. gp2 and gp3 do not support Multi-Attach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens to my EBS volume if the EC2 instance fails?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The EBS volume is unaffected. You can detach it and attach it to a new instance. This is one of EBS's core advantages over instance store.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I move an EBS volume to a different Availability Zone?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not directly. Create a snapshot, then create a new volume from that snapshot in the target AZ. The snapshot → new volume path is the standard way to move EBS storage across AZs or regions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does EBS cost?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;gp3: $0.08/GB-month. io2: $0.125/GB-month + $0.065/provisioned IOPS-month. st1: $0.045/GB-month. sc1: $0.015/GB-month. Snapshots: $0.05/GB-month for changed data stored.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is EBS encrypted at rest by default?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not by default, but you can enable account-level default encryption with one command (&lt;code&gt;aws ec2 enable-ebs-encryption-by-default&lt;/code&gt;). After that, every new volume is encrypted automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practice this in a real AWS environment
&lt;/h2&gt;

&lt;p&gt;Understanding EBS volume types is one thing. Knowing which type your workload actually needs — and what happens when you get it wrong — requires working with real volumes, real IOPS metrics, and real cost dashboards.&lt;/p&gt;

&lt;p&gt;The Core AWS Foundations track on Cloud Edventures includes hands-on labs covering EBS volume creation, snapshot lifecycle management, KMS encryption, and cost optimization — in isolated real AWS sandboxes with automated validation. No AWS account needed.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://cloudedventures.com/labs/track/aws-cloud-foundations" rel="noopener noreferrer"&gt;cloudedventures.com/labs/track/aws-cloud-foundations&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What EBS scenario are you trying to solve? Drop a comment.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I built an MCP server on AWS Bedrock in 30 minutes. Here's the exact code.</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Thu, 09 Apr 2026 11:13:10 +0000</pubDate>
      <link>https://forem.com/ajbuilds/i-built-an-mcp-server-on-aws-bedrock-in-30-minutes-heres-the-exact-code-2e32</link>
      <guid>https://forem.com/ajbuilds/i-built-an-mcp-server-on-aws-bedrock-in-30-minutes-heres-the-exact-code-2e32</guid>
      <description>&lt;p&gt;MCP (Model Context Protocol) is the most important AI infrastructure pattern of 2026. Anthropic built it, the Linux Foundation now owns it, and AWS just made it a first-class citizen in Bedrock AgentCore.&lt;/p&gt;

&lt;p&gt;97 million SDK downloads. 13,000+ servers built by the community. And as of this month, AWS is deploying them as managed services inside your existing cloud infrastructure.&lt;/p&gt;

&lt;p&gt;This is the tutorial I wish existed when I started. Not theory. Actual working code that deploys a real MCP server connected to AWS services in under 30 minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  What MCP Actually Is (In One Paragraph)
&lt;/h2&gt;

&lt;p&gt;MCP is the protocol that lets AI agents use external tools reliably. Without it, your agent either hardcodes tool integrations (brittle, unmaintainable) or hallucinates function calls that don't exist.&lt;/p&gt;

&lt;p&gt;With MCP, you define tools once as a server. Any agent — Claude, Cursor, your own custom Bedrock agent — can discover and use those tools via a standardized interface. Think USB-C for AI tools. Build once, plug in anywhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Agent (Claude / Bedrock)
        ↓
   MCP Client (asks: what tools are available?)
        ↓
   MCP Server (returns: tool schemas + executes calls)
        ↓
   Your actual APIs, databases, AWS services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What We're Building
&lt;/h2&gt;

&lt;p&gt;A working MCP server that exposes two AWS tools:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;query_dynamodb&lt;/code&gt;&lt;/strong&gt; — lets Claude query a DynamoDB table using natural language&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;get_s3_summary&lt;/code&gt;&lt;/strong&gt; — lets Claude list and summarize files in an S3 bucket&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then we'll connect it to a Bedrock agent and watch Claude use both tools autonomously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites:&lt;/strong&gt; Python 3.11+, AWS credentials configured, boto3 installed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 — Install the MCP SDK
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;mcp boto3 fastmcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;FastMCP is the Python framework that makes building MCP servers significantly less painful than raw MCP. It handles the protocol layer so you write tools, not JSON-RPC boilerplate.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 — Build the MCP Server
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;aws_mcp_server.py&lt;/code&gt;:&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;boto3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastmcp&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastMCP&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize FastMCP server
&lt;/span&gt;&lt;span class="n"&gt;mcp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastMCP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS Tools Server&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# AWS clients
&lt;/span&gt;&lt;span class="n"&gt;dynamodb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dynamodb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;s3_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="nd"&gt;@mcp.tool&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;query_dynamodb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table_name&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;key_name&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;key_value&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="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;
    Query a DynamoDB table by primary key.
    Use this when the user wants to look up specific records from a database.

    Args:
        table_name: The DynamoDB table to query
        key_name: The primary key attribute name
        key_value: The value to look up
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dynamodb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_item&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="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;key_value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Item&lt;/span&gt;&lt;span class="sh"&gt;"&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;item&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;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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;message&lt;/span&gt;&lt;span class="sh"&gt;"&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;No record found for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key_value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;table_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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;found&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;table&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;record&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&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;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&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="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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;table&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;


&lt;span class="nd"&gt;@mcp.tool&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_s3_summary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bucket_name&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;prefix&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="sh"&gt;""&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;
    List and summarize files in an S3 bucket.
    Use this when the user asks about files, documents, or data stored in S3.

    Args:
        bucket_name: The S3 bucket to inspect
        prefix: Optional folder prefix to filter results (e.g., &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;reports/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; or &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data/2026/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;paginator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_paginator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;list_objects_v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;pages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;paginator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bucket_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;Prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;PaginationConfig&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;MaxItems&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="n"&gt;total_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;pages&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;obj&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;page&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Contents&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="n"&gt;files&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Key&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;size_kb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Size&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="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;last_modified&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LastModified&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
                &lt;span class="n"&gt;total_size&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Size&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="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bucket&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bucket_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prefix&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prefix&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;(root)&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;file_count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total_size_kb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_size&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;files&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;  &lt;span class="c1"&gt;# Return first 20 for context window efficiency
&lt;/span&gt;            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;note&lt;/span&gt;&lt;span class="sh"&gt;"&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;Showing &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; of &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; files&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&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;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&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="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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bucket&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bucket_name&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;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Run as stdio MCP server (for local testing with Claude Desktop / Claude Code)
&lt;/span&gt;    &lt;span class="n"&gt;mcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;@mcp.tool()&lt;/code&gt; decorator does the heavy lifting — it generates the JSON schema from your Python type hints and docstring. Claude uses the docstring to decide &lt;strong&gt;when&lt;/strong&gt; to call each tool. Write it from Claude's perspective: "Use this when the user wants to..."&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Test Locally With Claude Code
&lt;/h2&gt;

&lt;p&gt;Before deploying to Bedrock, test the MCP server locally. Add it to your Claude Code MCP config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add to Claude Code's MCP servers&lt;/span&gt;
claude mcp add aws-tools &lt;span class="nt"&gt;--&lt;/span&gt; python /path/to/aws_mcp_server.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Claude Code, then ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How many files are in my logs-bucket-prod S3 bucket?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see Claude invoke &lt;code&gt;get_s3_summary&lt;/code&gt; automatically. If it works locally, it'll work on Bedrock.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 — Deploy to Bedrock AgentCore Runtime
&lt;/h2&gt;

&lt;p&gt;AWS Bedrock AgentCore Runtime lets you deploy MCP servers as managed services — serverless, auto-scaling, with session isolation handled for you. This is the new way to run MCP in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4a — Create a Dockerfile&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.11-slim&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-cache-dir&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; aws_mcp_server.py .&lt;/span&gt;

&lt;span class="c"&gt;# AgentCore expects MCP servers to run on port 8080&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;

&lt;span class="c"&gt;# Run as HTTP MCP server for AgentCore&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "aws_mcp_server.py", "--transport", "http", "--port", "8080"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;requirements.txt&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;fastmcp&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;=0.9.0&lt;/span&gt;
&lt;span class="py"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;=1.35.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4b — Push to ECR&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create ECR repo&lt;/span&gt;
aws ecr create-repository &lt;span class="nt"&gt;--repository-name&lt;/span&gt; aws-tools-mcp-server

&lt;span class="c"&gt;# Get ECR login&lt;/span&gt;
aws ecr get-login-password &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 | &lt;span class="se"&gt;\&lt;/span&gt;
  docker login &lt;span class="nt"&gt;--username&lt;/span&gt; AWS &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--password-stdin&lt;/span&gt; 123456789.dkr.ecr.us-east-1.amazonaws.com

&lt;span class="c"&gt;# Build and push&lt;/span&gt;
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; aws-tools-mcp-server &lt;span class="nb"&gt;.&lt;/span&gt;
docker tag aws-tools-mcp-server:latest &lt;span class="se"&gt;\&lt;/span&gt;
  123456789.dkr.ecr.us-east-1.amazonaws.com/aws-tools-mcp-server:latest
docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/aws-tools-mcp-server:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4c — Deploy to AgentCore Runtime&lt;/strong&gt;&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;boto3&lt;/span&gt;

&lt;span class="n"&gt;agentcore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock-agentcore&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agentcore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_agent_runtime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;agentRuntimeName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aws-tools-mcp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;agentRuntimeArtifact&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;containerConfiguration&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;containerUri&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;123456789.dkr.ecr.us-east-1.amazonaws.com/aws-tools-mcp-server:latest&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="n"&gt;networkConfiguration&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;networkMode&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;PUBLIC&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AgentCore Runtime ARN:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agentRuntimeArn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Endpoint:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;agentRuntimeEndpoint&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AgentCore handles: session isolation (each user gets their own MCP session in a dedicated microVM), automatic scaling, authentication, and 8-hour maximum session support for long-running operations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 — Connect to a Bedrock Agent
&lt;/h2&gt;

&lt;p&gt;Now wire the deployed MCP server into a Bedrock agent:&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;boto3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;bedrock_runtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock-runtime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Your MCP server endpoint from Step 4c
&lt;/span&gt;&lt;span class="n"&gt;MCP_ENDPOINT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://your-agentcore-endpoint.bedrock-agentcore.us-east-1.amazonaws.com&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;run_agent_with_mcp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_message&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="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;
    Bedrock agent that uses your deployed MCP server as its tool provider.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&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;role&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;user&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;content&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;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_message&lt;/span&gt;&lt;span class="p"&gt;}]}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;system&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;text&lt;/span&gt;&lt;span class="sh"&gt;"&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;You are an AWS assistant with access to DynamoDB and S3 tools.
        Use your tools to answer questions about the user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s AWS data.
        Always use tools to get real data — never guess or make up values.
        MCP Server: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;MCP_ENDPOINT&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;# Tool config pointing to your MCP server
&lt;/span&gt;    &lt;span class="n"&gt;tool_config&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;tools&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;toolSpec&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;name&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;query_dynamodb&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;description&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;Query a DynamoDB table by primary key&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;inputSchema&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;json&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;type&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;object&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;properties&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;table_name&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;type&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;string&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;key_name&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;type&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;string&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;key_value&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;type&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;string&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;required&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;table_name&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;key_name&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;key_value&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="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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolSpec&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;name&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;get_s3_summary&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;description&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;List and summarize files in an S3 bucket&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;inputSchema&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;json&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;type&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;object&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;properties&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;bucket_name&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;type&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;string&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;prefix&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;type&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;string&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;required&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;bucket_name&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="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;# Agentic loop
&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;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock_runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;converse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-3-sonnet-20240229-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;toolConfig&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tool_config&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;stop_reason&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stopReason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&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;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;messages&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;output&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;stop_reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_turn&lt;/span&gt;&lt;span class="sh"&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;block&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&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;block&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;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;stop_reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tool_use&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;tool_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;block&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUse&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;

                &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUse&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="n"&gt;tool_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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;tool_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

                &lt;span class="c1"&gt;# Route to correct tool
&lt;/span&gt;                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tool_name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query_dynamodb&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="nf"&gt;query_dynamodb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;tool_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;tool_name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_s3_summary&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="nf"&gt;get_s3_summary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;tool_input&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unknown tool: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool_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;tool_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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolResult&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;toolUseId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUseId&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;content&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;text&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="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;

            &lt;span class="n"&gt;messages&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&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;user&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool_results&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Agent reached iteration limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


&lt;span class="c1"&gt;# Test it
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;run_agent_with_mcp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How many files are in my data-lake-prod bucket? &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;And look up user ID &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;user_123&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; in my Users table.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Three Things That Break MCP in Production
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1 — Vague tool descriptions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Claude decides which tool to call based entirely on the &lt;code&gt;description&lt;/code&gt; field. If your description is vague, Claude either skips the tool or calls it when it shouldn't.&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="c1"&gt;# Weak — Claude might not call this when it should
&lt;/span&gt;&lt;span class="nd"&gt;@mcp.tool&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_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&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;key&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="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;Get data from a table.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="c1"&gt;# Strong — Claude knows exactly when to use this
&lt;/span&gt;&lt;span class="nd"&gt;@mcp.tool&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;query_dynamodb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table_name&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;key_name&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;key_value&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="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;
    Query a DynamoDB table by primary key.
    Use this when the user wants to look up specific records,
    find customer data, retrieve order information, or access
    any structured data stored in DynamoDB.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2 — Returning too much data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MCP tool results flow back into the agent's context window. A tool that returns 10,000 rows from DynamoDB will burn your context window in one call.&lt;/p&gt;

&lt;p&gt;Always limit your returns: paginate aggressively, return summaries not raw dumps, use &lt;code&gt;limit&lt;/code&gt; parameters in every database query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3 — Not handling tool failures&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your tool raises an exception, the entire agentic loop breaks. Every tool should return structured JSON even on failure:&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;try&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="nf"&gt;do_the_thing&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;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&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="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;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&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;error&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tool&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;tool_name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent can read the error message and respond gracefully. An uncaught exception just crashes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stateful MCP: AWS's New Feature (March 2026)
&lt;/h2&gt;

&lt;p&gt;AWS just shipped stateful MCP server support in AgentCore Runtime. This is significant.&lt;/p&gt;

&lt;p&gt;Previously, each MCP call was stateless — the server had no memory between tool invocations. Now, each user session gets a &lt;strong&gt;dedicated microVM&lt;/strong&gt; with session context preserved using an &lt;code&gt;Mcp-Session-Id&lt;/code&gt; header.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Elicitation&lt;/strong&gt; — the server can ask the user follow-up questions mid-tool execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sampling&lt;/strong&gt; — the server can request Claude to generate content as part of a tool's operation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progress notifications&lt;/strong&gt; — real-time updates for long-running operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For long-running tasks (ML training jobs, large data exports, multi-hour simulations), this changes the architecture completely. The server can now maintain state across a multi-hour operation without requiring the agent session to stay open.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to Build Next
&lt;/h2&gt;

&lt;p&gt;With this foundation working, the natural next steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add more AWS tools&lt;/strong&gt; — CloudWatch metrics querier, RDS query executor, Lambda invoker, Step Functions status checker. Each becomes a tool your agent can use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add Bedrock Guardrails&lt;/strong&gt; — wrap your MCP server with content filtering and PII detection that operates outside the agent's reasoning loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-agent coordination&lt;/strong&gt; — one coordinator agent that routes requests to specialist subagents, each with their own focused MCP server and tool set.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AgentCore Gateway&lt;/strong&gt; — instead of embedding tool schemas in your agent, register your MCP server with AgentCore Gateway and let multiple agents discover the same tools via a central registry.&lt;/p&gt;




&lt;p&gt;The full production version of this architecture — agentic loops, multi-agent systems, MCP server builds, Bedrock Guardrails, CloudWatch observability — is covered hands-on in the CCA-001: Claude Certified Architect track. Real Bedrock sandboxes, automated validation, no AWS account needed.&lt;/p&gt;

&lt;p&gt;If you want to build the architecture in this article in a real environment without worrying about AWS billing, that's the path.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://cloudedventures.com/labs/track/claude-certified-architect-cca-001" rel="noopener noreferrer"&gt;cloudedventures.com/labs/track/claude-certified-architect-cca-001&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What are you building with MCP? Drop a comment — especially if you hit a specific architecture problem I can help with.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Claude Code Power User Guide: /ghost, OODA, L99, KAIROS and Every Hidden Feature From the Source Code Leak</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Wed, 08 Apr 2026 18:09:35 +0000</pubDate>
      <link>https://forem.com/ajbuilds/claude-code-power-user-guide-ghost-ooda-l99-kairos-and-every-hidden-feature-from-the-source-57jg</link>
      <guid>https://forem.com/ajbuilds/claude-code-power-user-guide-ghost-ooda-l99-kairos-and-every-hidden-feature-from-the-source-57jg</guid>
      <description>&lt;p&gt;If you're using Claude Code the same way you use ChatGPT — typing conversational prompts and hoping for the best — you're leaving 80% of its power on the table.&lt;/p&gt;

&lt;p&gt;I've been deep in Claude Code for 90+ days building a production AWS learning platform. What I've learned: the difference between average and power-user results comes down to &lt;strong&gt;knowing what's under the hood&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The March 2026 source code leak gave us that knowledge. Here's the complete, tested guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Got Leaked (Quick Summary)
&lt;/h2&gt;

&lt;p&gt;On March 31, 2026, Anthropic published Claude Code version 2.1.88 to npm with a &lt;code&gt;.map&lt;/code&gt; source file included by accident. 512,000 lines of TypeScript. 1,900 files. 44 feature flags. The complete system prompt. Everything.&lt;/p&gt;

&lt;p&gt;The key takeaways for power users:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Claude Code has &lt;strong&gt;40+ built-in tools&lt;/strong&gt; — most people use 3-4&lt;/li&gt;
&lt;li&gt;The system prompt &lt;strong&gt;explicitly tells Claude to be direct&lt;/strong&gt; — conversational prompts work against this&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallel tool execution&lt;/strong&gt; is built-in but only triggers with properly structured prompts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLAUDE.md&lt;/strong&gt; is a first-class feature that loads automatically every session&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;20+ unreleased features&lt;/strong&gt; are built and tested but flagged off in public builds&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's turn each of these into actionable techniques.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Prompt Frameworks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/ghost&lt;/code&gt; — Kill the AI Voice
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;/ghost&lt;/code&gt; when Claude Code's output will be read by humans (docs, READMEs, PR descriptions, emails).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Without /ghost&lt;/span&gt;
/ghost rewrite this README to sound like a senior engineer wrote it, not an AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output drops the hedging ("It's worth noting that..."), the filler ("In order to..."), and the corporate tone. You get clean, direct prose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use:&lt;/strong&gt; Documentation, blog posts, commit messages, Slack messages, code comments.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;OODA&lt;/code&gt; — Force a Decision
&lt;/h3&gt;

&lt;p&gt;OODA (Observe-Orient-Decide-Act) is a military decision framework. In Claude Code, it prevents the "here are the pros and cons" non-answer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;OODA: Our API currently uses REST. We&lt;span class="s1"&gt;'re adding real-time features. 
Should we add WebSockets, use SSE, or switch to GraphQL subscriptions? 
We have 3 engineers and ship weekly.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude will &lt;strong&gt;observe&lt;/strong&gt; your constraints, &lt;strong&gt;orient&lt;/strong&gt; around your team size and shipping cadence, &lt;strong&gt;decide&lt;/strong&gt; on one approach, and &lt;strong&gt;act&lt;/strong&gt; by providing the implementation plan.&lt;/p&gt;

&lt;p&gt;No more "it depends." You get a decision with reasoning.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;L99&lt;/code&gt; — Expert Depth
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;L99: Design a DynamoDB single-table schema &lt;span class="k"&gt;for &lt;/span&gt;a multi-tenant SaaS 
with per-tenant billing, usage metering, and team permissions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without L99, you get a tutorial answer. With L99, you get GSI overloading patterns, composite sort keys for time-series queries, TTL-based cleanup strategies, and the exact access patterns with their key conditions.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;SCAFFOLD&lt;/code&gt; — Full Project Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;SCAFFOLD: Production Next.js 15 app
- Prisma + PostgreSQL
- NextAuth with GitHub + Google
- Tailwind CSS
- Vitest + Playwright
- GitHub Actions CI/CD
- Vercel deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude generates the full directory structure, all config files, and boilerplate before touching business logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;PERSONA&lt;/code&gt; — Domain Expert Mode
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PERSONA: Senior AWS Solutions Architect with 10 years experience. 
Review this CloudFormation template &lt;span class="k"&gt;for &lt;/span&gt;production readiness.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This frames Claude's entire response through that expertise lens.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. System Prompt Insights You Can Exploit
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Be Terse
&lt;/h3&gt;

&lt;p&gt;The system prompt tells Claude Code to be direct. Mirror that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ❌ This triggers verbose mode&lt;/span&gt;
&lt;span class="s2"&gt;"Hey Claude, could you take a look at this function and let me know 
if there's anything that might be improved? Thanks!"&lt;/span&gt;

&lt;span class="c"&gt;# ✅ This gets the system prompt working for you&lt;/span&gt;
&lt;span class="s2"&gt;"What's wrong with this function? Fix it."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Parallel Execution
&lt;/h3&gt;

&lt;p&gt;Claude Code can run tools simultaneously, but only when you make independence explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ❌ Sequential — Claude plays it safe&lt;/span&gt;
&lt;span class="s2"&gt;"Check the frontend components and then run the API tests"&lt;/span&gt;

&lt;span class="c"&gt;# ✅ Parallel — both fire at once  &lt;/span&gt;
&lt;span class="s2"&gt;"Two independent tasks:
1. Audit src/components/ for React anti-patterns
2. Run and fix failing tests in src/api/__tests__/"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On large codebases, this cuts response time significantly.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Bash Tool is King
&lt;/h3&gt;

&lt;p&gt;The leaked tool definitions show &lt;code&gt;bash&lt;/code&gt; is Claude Code's most capable tool. It can install packages, run tests, check git status, read files, and execute arbitrary commands.&lt;/p&gt;

&lt;p&gt;Power users lean into this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="s2"&gt;"Run the test suite. If anything fails, read the failing test file, 
understand what it expects, then fix the source code. Repeat until green."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates an autonomous debugging loop.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. CLAUDE.md — Your Project's AI Memory
&lt;/h2&gt;

&lt;p&gt;The source confirms CLAUDE.md is loaded automatically. Here's a battle-tested template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Project: [Name]&lt;/span&gt;

&lt;span class="gu"&gt;## Stack&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [Framework] + [Database] + [Deploy target]
&lt;span class="p"&gt;-&lt;/span&gt; Key deps: [list the non-obvious ones]

&lt;span class="gu"&gt;## Architecture Decisions&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [Decision 1]: [Why]
&lt;span class="p"&gt;-&lt;/span&gt; [Decision 2]: [Why]

&lt;span class="gu"&gt;## Code Conventions  &lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; [Pattern]: [Where to use]
&lt;span class="p"&gt;-&lt;/span&gt; [Anti-pattern]: [What to avoid]

&lt;span class="gu"&gt;## Current Context&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Working on: [Current feature/sprint]
&lt;span class="p"&gt;-&lt;/span&gt; Recent changes: [What changed this week]
&lt;span class="p"&gt;-&lt;/span&gt; Known issues: [Active bugs]

&lt;span class="gu"&gt;## Testing&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Framework: [Vitest/Jest/Playwright]
&lt;span class="p"&gt;-&lt;/span&gt; Run: [exact command]
&lt;span class="p"&gt;-&lt;/span&gt; Coverage: [current %]

&lt;span class="gu"&gt;## Deploy&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Staging: [command]
&lt;span class="p"&gt;-&lt;/span&gt; Production: [command + checklist]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This replaces 10 minutes of context-setting at the start of every session.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Unreleased Features (From the Leak)
&lt;/h2&gt;

&lt;p&gt;These are built, tested, and hidden behind compile-time flags:&lt;/p&gt;

&lt;h3&gt;
  
  
  KAIROS — Background Agent Mode
&lt;/h3&gt;

&lt;p&gt;Referenced 150+ times in the source. An autonomous daemon that runs memory consolidation while you're idle. It can plan tasks, execute them in the background, and surface results when you return. Think: "Fix all the lint warnings while I'm at lunch."&lt;/p&gt;

&lt;h3&gt;
  
  
  BUDDY — AI Coding Companion
&lt;/h3&gt;

&lt;p&gt;A Tamagotchi-style pet that lives in your terminal. Species deterministically generated from your userId hash (salt: &lt;code&gt;friend-2026-401&lt;/code&gt;). Cosmetic hats. Speech bubbles. Claude generates its name and "soul description" on first hatch.&lt;/p&gt;

&lt;p&gt;Leaked internal notes suggest an April 1-7 teaser with full launch in May 2026. The &lt;code&gt;/buddy&lt;/code&gt; command did activate on April 1 as predicted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Voice Mode
&lt;/h3&gt;

&lt;p&gt;Talk to Claude Code. Useful for pair programming. In the source but not shipped.&lt;/p&gt;

&lt;h3&gt;
  
  
  ULTRAPLAN
&lt;/h3&gt;

&lt;p&gt;Extended planning mode with multi-step task decomposition.&lt;/p&gt;

&lt;h3&gt;
  
  
  Undercover Mode
&lt;/h3&gt;

&lt;p&gt;Details sparse, but it's referenced in the feature flags.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. My Daily Workflow
&lt;/h2&gt;

&lt;p&gt;After 90 days, here's my exact process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Morning:
  claude --resume          # pick up where I left off
  /init                    # if new project, generate CLAUDE.md

Planning:
  Shift+Tab → plan mode    # architecture first
  OODA for decisions       # no "it depends"
  L99 for deep dives       # principal-engineer answers

Building:
  Parallel task prompts    # 2x speed on independent work
  SCAFFOLD for new modules # structure before code
  Autonomous bash loops    # "fix until green"

Shipping:
  /ghost for PR descriptions
  /ghost for changelog entries
  Review with PERSONA: "Senior reviewer focused on security"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Hands-On Practice
&lt;/h2&gt;

&lt;p&gt;If you want to practice these techniques with real AWS infrastructure, I've been building &lt;a href="https://cloudedventures.com" rel="noopener noreferrer"&gt;Cloud Edventures&lt;/a&gt; — guided missions in sandbox environments with automated validation. The AI Navigator path specifically covers Claude + Bedrock integration where you'll use a lot of these patterns.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/ghost&lt;/code&gt; and &lt;code&gt;OODA&lt;/code&gt; frameworks work in any AI tool though — start there.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Your Power-User Trick?
&lt;/h2&gt;

&lt;p&gt;I'm collecting Claude Code techniques for a follow-up post. If you've found something that changed your workflow, drop it in the comments.&lt;/p&gt;

&lt;p&gt;The gap between "using Claude Code" and "being a Claude Code power user" is wider than most people think. These frameworks close it.&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>ai</category>
      <category>productivity</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Why creating an AWS account is harder than it should be — especially in India</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Tue, 07 Apr 2026 11:57:19 +0000</pubDate>
      <link>https://forem.com/ajbuilds/why-creating-an-aws-account-is-harder-than-it-should-be-especially-in-india-4e2e</link>
      <guid>https://forem.com/ajbuilds/why-creating-an-aws-account-is-harder-than-it-should-be-especially-in-india-4e2e</guid>
      <description>&lt;p&gt;You decided to learn AWS. You went to aws.amazon.com, clicked "Create a Free Account," and ran straight into a wall.&lt;/p&gt;

&lt;p&gt;Credit card required. Phone verification that never calls back. A mysterious ₹2 charge on your card. Documents that don't match. An account suspended before you ever deployed anything.&lt;/p&gt;

&lt;p&gt;This is one of the most complained-about onboarding experiences in cloud computing — and if you are in India, there is an entire extra layer of complexity that most guides completely skip.&lt;/p&gt;

&lt;p&gt;Here's everything AWS requires, why each hurdle exists, what breaks, and how to get past all of it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What AWS Requires Globally
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. A unique email address
&lt;/h3&gt;

&lt;p&gt;Cannot be tied to an existing Amazon account. If you shop on Amazon.in, that email is already taken. Use a different one.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. A valid payment method
&lt;/h3&gt;

&lt;p&gt;AWS requires a credit or debit card even for the free tier — used for identity verification and fraud prevention.&lt;/p&gt;

&lt;p&gt;What happens: AWS places a &lt;strong&gt;$1 USD temporary authorization hold&lt;/strong&gt; (or ₹2 for AISPL accounts in India). This is not a charge. It disappears in 3-5 business days. Your bank may show it as a pending transaction — this is normal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cards that work:&lt;/strong&gt; Visa or Mastercard credit/debit cards enabled for international online transactions, American Express.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cards that commonly fail:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prepaid or gift cards&lt;/li&gt;
&lt;li&gt;Cards not enabled for international transactions&lt;/li&gt;
&lt;li&gt;Cards with strict fraud settings blocking new merchant authorizations&lt;/li&gt;
&lt;li&gt;Cards with zero balance (can't hold even a small authorization)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Fix for card declines:&lt;/strong&gt; Call your bank, say "I'm making a ₹2 authorization attempt from Amazon Web Services, please whitelist this merchant." This resolves most card issues in 5 minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Phone verification
&lt;/h3&gt;

&lt;p&gt;AWS calls or texts your number with a PIN.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Numbers that fail:&lt;/strong&gt; VoIP numbers (Google Voice, Skype, most internet calling apps), numbers blocked for international calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If the call doesn't come:&lt;/strong&gt; Switch from voice to SMS, wait 10 minutes between attempts. Too many failed attempts locks you out — contact AWS Support to reset.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Account activation (up to 24 hours)
&lt;/h3&gt;

&lt;p&gt;Usually 15-60 minutes in practice. Some services like Bedrock stay locked until full activation — wait and retry before contacting support.&lt;/p&gt;




&lt;h2&gt;
  
  
  The India-Specific Layer: AISPL + KYC Documents
&lt;/h2&gt;

&lt;p&gt;This is where Indian users hit a completely different set of walls that global guides never cover.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is AISPL?
&lt;/h3&gt;

&lt;p&gt;When you create an AWS account with an Indian address, you are contracting with &lt;strong&gt;AISPL — Amazon Internet Services Private Limited&lt;/strong&gt;, not AWS Inc. globally. AISPL is AWS's local Indian legal entity and your billing, verification, and payment rules are all different.&lt;/p&gt;

&lt;p&gt;The ₹2 temporary hold (instead of $1) comes from AISPL. Your invoices are in INR. RBI payment regulations apply to your account.&lt;/p&gt;

&lt;h3&gt;
  
  
  KYC Document Verification in India
&lt;/h3&gt;

&lt;p&gt;At some point after account creation — either immediately or when AWS flags your account for identity verification — you will be asked to submit a government-issued ID document.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documents AWS India (AISPL) accepts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ PAN Card&lt;/li&gt;
&lt;li&gt;✅ Voter ID (EPIC Card)&lt;/li&gt;
&lt;li&gt;✅ Driving License&lt;/li&gt;
&lt;li&gt;✅ Passport&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What AWS India does NOT currently accept:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Aadhaar card alone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This surprises many Indian developers because Aadhaar is widely accepted for financial KYC across banks, telecom, and fintech platforms in India. But AWS's verification system does not list Aadhaar as a selectable document type. If Aadhaar is the only government ID you have, you need to contact AWS Support directly and explain your situation — there is no standard workaround through the normal interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Aadhaar is not enough for AWS (the practical reason):&lt;/strong&gt; AWS uses the PAN/Voter ID/Passport/Driving License for identity linkage in ways that Aadhaar's current integration doesn't support in their system. It's a platform limitation, not a legal one — Aadhaar is a perfectly valid government ID under Indian law, just not yet integrated into AWS's verification flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  The PAN Card + Aadhaar Linkage (Important from 2025)
&lt;/h3&gt;

&lt;p&gt;From July 2025, applying for a new PAN card requires Aadhaar authentication, and existing PAN cards must be linked to Aadhaar. If your PAN is not linked to your Aadhaar, it became inoperative from January 2026 — which would also make it invalid for AWS verification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before using your PAN for AWS verification:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm your PAN is active at incometax.gov.in&lt;/li&gt;
&lt;li&gt;Confirm PAN-Aadhaar linking is complete&lt;/li&gt;
&lt;li&gt;An inoperative PAN will fail AWS verification even though the number itself is valid&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  RBI Payment Regulations Affecting AISPL Accounts
&lt;/h3&gt;

&lt;p&gt;The Reserve Bank of India regulates how payment data can be stored, which creates friction for Indian AWS users that global accounts don't experience.&lt;/p&gt;

&lt;p&gt;Key things to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Marketplace contract products can no longer use stored credit/debit cards for AISPL accounts due to RBI regulations — you need to manually enter card details or switch to Pay By Invoice&lt;/li&gt;
&lt;li&gt;For pay-as-you-go Marketplace products, you must manually input card details for each payment&lt;/li&gt;
&lt;li&gt;If you use AWS for business and volume is significant, switching to &lt;strong&gt;Pay By Invoice&lt;/strong&gt; is smoother than repeated manual card entry&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Billing Anxiety Problem (India-Specific Too)
&lt;/h2&gt;

&lt;p&gt;Even after successfully getting through all the above, there is a second wall: billing anxiety.&lt;/p&gt;

&lt;p&gt;You are finally in the AWS console. Ready to practice Lambda, S3, or Bedrock. And then you pause.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What if I forget to stop this instance? What if I accidentally go over free tier? What if I get a ₹5,000 bill next month?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is rational. AWS billing is opaque, and horror stories are real — developers leaving an EC2 instance running over a long weekend, data transfer costs from misconfigured S3 buckets, NAT Gateways charging quietly in the background.&lt;/p&gt;

&lt;p&gt;For Indian developers, the anxiety is often sharper. Currency conversion means a $50 bill is ₹4,000+. The free tier limits are the same globally but the consequences of mistakes feel more significant.&lt;/p&gt;

&lt;p&gt;The result: most developers watch tutorials instead of building. They read documentation instead of deploying. When interviews arrive, they can describe AWS services but can't walk through something they actually built.&lt;/p&gt;




&lt;h2&gt;
  
  
  Three Options for Hands-On Practice
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Option 1 — Your own AWS account with guardrails&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a billing budget alert at ₹400/month immediately after account setup. Use IAM users (never root) for daily practice. Stick to free tier services and instance types. Stop all resources at end of every session.&lt;/p&gt;

&lt;p&gt;The anxiety doesn't disappear but a billing alert means the worst case is an email warning before ₹400 is spent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2 — AWS Educate / AWS Academy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For students and educators, AWS Educate provides sandbox credits. Good if you qualify — the limitation is expiry dates and service restrictions that make comprehensive practice harder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 3 — Pre-built isolated sandbox environments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The option that removes both the account setup friction and the billing anxiety completely: practicing in real AWS environments where someone else handles the account, compliance, and resource cleanup.&lt;/p&gt;

&lt;p&gt;Cloud Edventures runs exactly this model. Real AWS sandboxes — actual Lambda functions, actual S3 buckets, actual IAM roles, actual Bedrock environments — without needing to go through AISPL verification, PAN card submission, RBI-compliant payment setup, or any of the above. The billing isolation is handled at the platform level.&lt;/p&gt;

&lt;p&gt;Built specifically for developers who want to build real cloud skills without the account setup friction — which is a genuine problem in India that most global platforms don't address.&lt;/p&gt;

&lt;p&gt;No AWS account needed. No ₹2 holds. No KYC document submission. No billing surprises.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://cloudedventures.com" rel="noopener noreferrer"&gt;cloudedventures.com&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  India AWS Account Checklist
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before you start:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unique email not tied to Amazon.in account&lt;/li&gt;
&lt;li&gt;Active PAN card linked to Aadhaar (verify at incometax.gov.in)&lt;/li&gt;
&lt;li&gt;Debit/credit card enabled for international transactions&lt;/li&gt;
&lt;li&gt;Call your bank to whitelist ₹2 authorization from Amazon Internet Services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;During setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose SMS over voice for phone verification (more reliable)&lt;/li&gt;
&lt;li&gt;Have your PAN Card, Voter ID, Driving License, or Passport ready for KYC&lt;/li&gt;
&lt;li&gt;If asked for identity verification, Aadhaar alone won't work — use PAN or Passport&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After account is active:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set billing alert at ₹400/month immediately&lt;/li&gt;
&lt;li&gt;Enable MFA on root account&lt;/li&gt;
&lt;li&gt;Create IAM user — practice as IAM, not root&lt;/li&gt;
&lt;li&gt;Check AISPL payment settings if using AWS Marketplace&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If stuck:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Support → Account and Billing → Activation category (free support)&lt;/li&gt;
&lt;li&gt;Only have Aadhaar and no other ID? Contact AWS Support directly — explain and request manual review&lt;/li&gt;
&lt;li&gt;Card issues → bank whitelist of "Amazon Internet Services Private Limited" usually fixes it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Stuck on a specific step? Drop it in the comments — especially if you hit an India-specific issue.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Cloud engineer in 2026: the honest roadmap that actually gets you hired</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Mon, 06 Apr 2026 12:46:16 +0000</pubDate>
      <link>https://forem.com/ajbuilds/cloud-engineer-in-2026-the-honest-roadmap-that-actually-gets-you-hired-f5d</link>
      <guid>https://forem.com/ajbuilds/cloud-engineer-in-2026-the-honest-roadmap-that-actually-gets-you-hired-f5d</guid>
      <description>&lt;p&gt;Most cloud engineer roadmaps give you a list of services to learn and certifications to collect.&lt;/p&gt;

&lt;p&gt;What actually gets you hired is different. Here is that roadmap.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the job actually requires
&lt;/h2&gt;

&lt;p&gt;Cloud engineers design, build, and maintain cloud infrastructure. On any given week that means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing Terraform or CloudFormation to provision infrastructure as code&lt;/li&gt;
&lt;li&gt;Building CI/CD pipelines that deploy code automatically&lt;/li&gt;
&lt;li&gt;Setting up monitoring so teams know when things break before users do&lt;/li&gt;
&lt;li&gt;Debugging why a Lambda function is timing out or two services can not communicate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common thread: building systems that run reliably without you watching. That requires hands-on experience with real AWS — not just knowing what the services are.&lt;/p&gt;




&lt;h2&gt;
  
  
  The real skill stack (in priority order)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Linux fundamentals — do not skip this
&lt;/h3&gt;

&lt;p&gt;Every cloud environment runs Linux. If you cannot navigate a file system, read logs, manage permissions, and write shell scripts, you will struggle with everything else.&lt;/p&gt;

&lt;p&gt;Start here before AWS. One week of real Linux practice saves months of confusion later.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Networking basics
&lt;/h3&gt;

&lt;p&gt;VPCs, subnets, security groups, route tables, NAT gateways. You do not need to be a network engineer. You need to understand how data flows between services and why a connection might fail.&lt;/p&gt;

&lt;p&gt;The most common junior cloud engineer interview failure: they can configure services but cannot debug why two services cannot communicate. Networking is usually the answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Core AWS services — hands-on, not watched
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Compute:&lt;/strong&gt; Lambda and EC2. Build a Lambda function that does something real — reads from S3, writes to DynamoDB, calls an external API. Understand when to use each.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Storage:&lt;/strong&gt; S3 for files, DynamoDB for NoSQL, RDS for relational. Know how IAM roles grant access between them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Networking:&lt;/strong&gt; VPC setup, security groups, Application Load Balancers. Deploy something behind a load balancer with proper security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitoring:&lt;/strong&gt; CloudWatch dashboards and alarms. Know how to detect problems before users report them.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Infrastructure as Code
&lt;/h3&gt;

&lt;p&gt;Terraform is the industry standard. CloudFormation is AWS-native. Know at least one deeply.&lt;/p&gt;

&lt;p&gt;The goal is understanding why IaC matters: every manual console click is a change that cannot be tracked, reviewed, or reproduced. Good cloud engineers automate everything.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. CI/CD pipelines
&lt;/h3&gt;

&lt;p&gt;GitHub Actions, AWS CodePipeline, or Jenkins. Build a pipeline that automatically tests and deploys code when you push to a branch. Table stakes for any cloud role.&lt;/p&gt;




&lt;h2&gt;
  
  
  The certification question (honest answer)
&lt;/h2&gt;

&lt;p&gt;AWS Solutions Architect Associate (SAA-C03) is worth getting. It validates broad AWS knowledge and passes ATS filters.&lt;/p&gt;

&lt;p&gt;Cloud Practitioner is useful for complete beginners but provides weak signal to hiring managers.&lt;/p&gt;

&lt;p&gt;The honest truth: a certification without projects is weak evidence. A portfolio without a cert gets ignored by automated screening. You need both — but projects matter more in the interview room.&lt;/p&gt;




&lt;h2&gt;
  
  
  The three portfolio projects that get interviews
&lt;/h2&gt;

&lt;p&gt;Build these. They cover the full cloud engineer skill stack and give you specific things to discuss in technical interviews.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project 1: Serverless REST API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lambda + API Gateway + DynamoDB + IAM + CloudWatch. Build a working API that does something real — a URL shortener, a task manager, a simple inventory system. Use IAM least privilege. Add monitoring.&lt;/p&gt;

&lt;p&gt;Demonstrates: Lambda, API Gateway, DynamoDB, IAM, CloudWatch, serverless architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project 2: Infrastructure as Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reproduce Project 1 entirely with Terraform or CloudFormation. No console clicks. Everything version-controlled in GitHub, deployable with one command.&lt;/p&gt;

&lt;p&gt;Demonstrates: IaC, version control, infrastructure design, reproducibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project 3: CI/CD pipeline&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add GitHub Actions that automatically runs tests and deploys infrastructure on push to main. Include staging with a manual approval gate before production.&lt;/p&gt;

&lt;p&gt;Demonstrates: CI/CD, environment management, deployment automation, testing.&lt;/p&gt;

&lt;p&gt;These three projects together cover everything a cloud engineer job description asks for.&lt;/p&gt;




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

&lt;p&gt;Most people hit the same wall: practicing on real AWS costs money and one mistake causes a surprise bill. That anxiety makes people hesitant to experiment freely.&lt;/p&gt;

&lt;p&gt;Hesitant experimentation does not build intuition. Cloud engineers develop intuition by breaking things and fixing them.&lt;/p&gt;

&lt;p&gt;The solution is isolated sandbox environments. Cloud Edventures provides real AWS environments for hands-on labs — Lambda, S3, IAM, DynamoDB, CloudFormation, CodePipeline, Auto Scaling, Terraform, GitHub Actions OIDC — with automated validation and no billing risk. The Core AWS Foundations track goes from your first Lambda function through event-driven architectures and Step Functions.&lt;/p&gt;

&lt;p&gt;Start free at &lt;a href="https://www.cloudedventures.com/labs/track/aws-cloud-foundations" rel="noopener noreferrer"&gt;cloudedventures.com/labs/track/aws-cloud-foundations&lt;/a&gt; — no AWS account needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  The timeline that works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Weeks 1–2:&lt;/strong&gt; Linux + basic networking. Do not skip.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weeks 3–6:&lt;/strong&gt; Core AWS hands-on. Build things, do not just read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weeks 7–10:&lt;/strong&gt; SAA-C03 study alongside building. When you read about a service, deploy it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weeks 11–14:&lt;/strong&gt; Terraform + CI/CD. Build the three portfolio projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Week 15+:&lt;/strong&gt; Apply. Document projects in GitHub with READMEs and architecture diagrams.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3–4 months of focused hands-on work. Not 6 months of course watching.&lt;/p&gt;




&lt;h2&gt;
  
  
  The one thing that separates hires from rejections
&lt;/h2&gt;

&lt;p&gt;"I know AWS" does not get you hired.&lt;/p&gt;

&lt;p&gt;"I built a serverless event processing pipeline using Lambda, SQS, and DynamoDB with CloudWatch monitoring and Terraform IaC" does.&lt;/p&gt;

&lt;p&gt;Build specific things. Document them specifically. Talk about them specifically.&lt;/p&gt;

&lt;p&gt;The certification proves you studied. The portfolio proves you can build.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What part of the cloud engineer roadmap are you working on right now? Drop it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>career</category>
      <category>devops</category>
    </item>
    <item>
      <title>AWS Bedrock in 2026: what it actually is and how to build your first AI agent on it</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Sun, 05 Apr 2026 16:47:42 +0000</pubDate>
      <link>https://forem.com/ajbuilds/aws-bedrock-in-2026-what-it-actually-is-and-how-to-build-your-first-ai-agent-on-it-gf8</link>
      <guid>https://forem.com/ajbuilds/aws-bedrock-in-2026-what-it-actually-is-and-how-to-build-your-first-ai-agent-on-it-gf8</guid>
      <description>&lt;p&gt;Most AWS Bedrock content is either marketing copy or academic papers. Neither is useful if you're trying to actually build something.&lt;/p&gt;

&lt;p&gt;This is the architecture, the real code patterns, and the things that actually trip people up in production.&lt;/p&gt;




&lt;h2&gt;
  
  
  What AWS Bedrock actually is
&lt;/h2&gt;

&lt;p&gt;AWS Bedrock is Amazon's managed AI inference platform. It gives you API access to foundation models — Claude, Llama, Titan, Mistral — without managing the infrastructure those models run on.&lt;/p&gt;

&lt;p&gt;The reason it's become the foundation of most enterprise AI deployments is simple: it sits inside your existing AWS infrastructure. Your IAM roles, VPCs, CloudWatch, Lambda functions — they all work with Bedrock the same way they work with S3 or DynamoDB.&lt;/p&gt;

&lt;p&gt;Four primitives make it powerful beyond raw model access:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge Bases&lt;/strong&gt; — managed RAG. Connect an S3 bucket of documents, Bedrock handles embedding, vector storage, and retrieval automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agents&lt;/strong&gt; — managed agentic orchestration. Define tools (Lambda functions) the model can call, Bedrock manages conversation history and the agentic loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guardrails&lt;/strong&gt; — content filtering, PII detection, topic restrictions at the platform level, not in your application code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt Management&lt;/strong&gt; — versioned, managed prompts. Test variants, roll back bad changes, maintain consistency across environments.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The core pattern: how a Bedrock agent works
&lt;/h2&gt;

&lt;p&gt;Every Bedrock agent follows the same underlying pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User sends message
    ↓
Model receives message + tool definitions + conversation history
    ↓
Model returns: stopReason = "tool_use" OR "end_turn"
    ↓
If tool_use: execute the Lambda, append result, loop again
If end_turn: return response to user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model does not execute tools — it &lt;em&gt;requests&lt;/em&gt; them. Your code executes them and feeds the result back.&lt;/p&gt;

&lt;p&gt;Here is the full implementation:&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;boto3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock-runtime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&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="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;toolSpec&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;name&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;get_s3_file_list&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;description&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;List files in an S3 bucket. Use when the user asks about files or data stored in S3.&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;inputSchema&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;json&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;type&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;object&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;properties&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;bucket_name&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;type&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;string&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;description&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;The S3 bucket name to list&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;prefix&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;type&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;string&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;description&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;Optional prefix to filter results&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;required&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;bucket_name&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="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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_name&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;tool_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tool_name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_s3_file_list&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list_objects_v2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tool_input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bucket_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;Prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tool_input&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prefix&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="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Key&lt;/span&gt;&lt;span class="sh"&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;obj&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Contents&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;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;files&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;files&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;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unknown tool: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool_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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_bedrock_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_message&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="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;messages&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;role&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;user&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;content&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;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_message&lt;/span&gt;&lt;span class="p"&gt;}]}]&lt;/span&gt;
    &lt;span class="n"&gt;system&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;text&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;You are an AWS assistant. Use tools to get real data rather than guessing.&lt;/span&gt;&lt;span class="sh"&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;_&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;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;converse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-3-sonnet-20240229-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;toolConfig&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;tools&lt;/span&gt;&lt;span class="sh"&gt;"&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="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;stop_reason&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stopReason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&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;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;messages&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;output&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;stop_reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_turn&lt;/span&gt;&lt;span class="sh"&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;block&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&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;block&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;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;stop_reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tool_use&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;tool_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;block&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUse&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUse&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="nf"&gt;execute_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                &lt;span class="n"&gt;tool_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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolResult&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;toolUseId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUseId&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;content&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;text&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="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="n"&gt;messages&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&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;user&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool_results&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Agent reached iteration limit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;run_bedrock_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;How many files are in my data-lake-prod bucket?&lt;/span&gt;&lt;span class="sh"&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;code&gt;stopReason&lt;/code&gt; is your only control signal. &lt;code&gt;"tool_use"&lt;/code&gt; means keep looping. &lt;code&gt;"end_turn"&lt;/code&gt; means stop. Everything else is implementation detail.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Bedrock adds over raw API access
&lt;/h2&gt;

&lt;p&gt;If you are already calling Claude's API directly, three things matter in production:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IAM-native access control&lt;/strong&gt; — Use IAM roles instead of API keys. No secrets to rotate, no credential leaks. Your Lambda gets a role, that role gets a Bedrock policy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Built-in observability&lt;/strong&gt; — Every Bedrock call shows up in CloudWatch automatically. Latency, token usage, error rates, throttling — zero instrumentation required from you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VPC isolation&lt;/strong&gt; — Model calls can run inside your VPC. For healthcare, finance, or regulated workloads this is the difference between a viable architecture and a compliance non-starter.&lt;/p&gt;




&lt;h2&gt;
  
  
  The three bugs that break Bedrock agents in production
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bug 1 — Checking content type instead of stopReason
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This breaks silently on complex tasks
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&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;message&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&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="c1"&gt;# Agent stops before the tool ever runs
&lt;/span&gt;
&lt;span class="c1"&gt;# This is correct
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stopReason&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_turn&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude returns explanatory text &lt;em&gt;alongside&lt;/em&gt; &lt;code&gt;tool_use&lt;/code&gt; blocks. If you check content type to detect completion, you terminate the loop before the tool executes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bug 2 — Missing assistant message before tool results
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Missing a critical step
&lt;/span&gt;&lt;span class="n"&gt;messages&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;tool_result_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Correct — append assistant response first, then the tool result
&lt;/span&gt;&lt;span class="n"&gt;messages&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;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;               &lt;span class="c1"&gt;# The assistant's tool_use request
&lt;/span&gt;&lt;span class="n"&gt;messages&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;tool_result_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Then the result
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without the assistant message in history, the model cannot connect the tool result back to its own request. You get confused or looping responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bug 3 — Using the iteration cap as your primary stop
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;for _ in range(10)&lt;/code&gt; is a safety net against runaway loops — not your stopping condition. &lt;code&gt;stopReason&lt;/code&gt; is how the model signals it is finished. Cap is a ceiling, not a controller.&lt;/p&gt;




&lt;h2&gt;
  
  
  What comes next after the basics
&lt;/h2&gt;

&lt;p&gt;Once the core loop works, the natural Bedrock progression is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge Bases&lt;/strong&gt; — connect documents, let the model ground answers in your actual data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bedrock Guardrails&lt;/strong&gt; — content filters and PII detection the model cannot be prompted around&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-agent coordination&lt;/strong&gt; — coordinator agent delegating to specialist subagents via tool calls, each with an isolated context window&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch observability&lt;/strong&gt; — latency distribution, token cost, tool call frequency, error rates per agent&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Getting hands-on
&lt;/h2&gt;

&lt;p&gt;Understanding the architecture is step one. Building intuition for what breaks in production — failed tools, bad tool inputs, sessions that run longer than expected — requires actually running the system.&lt;/p&gt;

&lt;p&gt;If you want to work through these patterns in a real AWS Bedrock sandbox — agentic loops, tool sequencing, Guardrails, CloudWatch dashboards — Cloud Edventures has a hands-on track covering exactly this. The CCA-001: Claude Certified Architect track runs in isolated AWS sandboxes with automated validation. No AWS account needed.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.cloudedventures.com/labs/track/claude-certified-architect-cca-001" rel="noopener noreferrer"&gt;cloudedventures.com/labs/track/claude-certified-architect-cca-001&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What is the most confusing part of Bedrock for you? Drop a comment — happy to go deeper on any section.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>ai</category>
      <category>cloud</category>
    </item>
    <item>
      <title>5 tools that turn Claude Code from good to unstoppable (exact install commands)</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Thu, 26 Mar 2026 11:17:03 +0000</pubDate>
      <link>https://forem.com/ajbuilds/5-tools-that-turn-claude-code-from-good-to-unstoppable-exact-install-commands-3p3j</link>
      <guid>https://forem.com/ajbuilds/5-tools-that-turn-claude-code-from-good-to-unstoppable-exact-install-commands-3p3j</guid>
      <description>&lt;p&gt;Most developers use Claude Code the same way they used Stack Overflow. Ask a question, get an answer, move on.&lt;/p&gt;

&lt;p&gt;The developers shipping fastest in 2026 use a specific stack around it. Five tools. Each one fixes a specific failure mode. Here they are with exact install commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three things that break Claude Code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Context rot&lt;/strong&gt; — Quality drops at ~50% context usage, not at the limit. Most developers don't notice until Claude writes duplicate code it wrote 20 messages ago.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hallucinated APIs&lt;/strong&gt; — Training data is 6–12 months behind. Claude confidently suggests functions that were renamed, deprecated, or never existed in your version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No planning phase&lt;/strong&gt; — Claude dives into code on your first vague prompt. No spec. No architecture. Three hours later you're rewriting everything.&lt;/p&gt;

&lt;p&gt;Each tool below attacks one of these.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tool 1 — cc-statusline
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fixes:&lt;/strong&gt; Context rot — you can't manage what you can't see&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx cc-statusline@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adds a status bar to your terminal showing model, context%, session cost, and git branch in real time.&lt;/p&gt;

&lt;p&gt;Configure your lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Line 1: model | context% | session_cost | session_clock  
Line 2: git_branch | git_worktree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The rule:&lt;/strong&gt; When context hits 50%, stop and &lt;code&gt;/clear&lt;/code&gt;. Don't use &lt;code&gt;/compact&lt;/code&gt; — it's lossy compression that keeps context poisoning. &lt;code&gt;/clear&lt;/code&gt; reloads your CLAUDE.md and starts completely fresh with zero information loss.&lt;/p&gt;

&lt;p&gt;Built-in alternative: type &lt;code&gt;/statusline&lt;/code&gt; directly in Claude Code and it generates a script for you.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tool 2 — Superpowers plugin
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fixes:&lt;/strong&gt; Vague prompts → vague code. No planning phase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stats:&lt;/strong&gt; 99,000+ GitHub stars. Official Anthropic marketplace.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/plugin marketplace add obra/superpowers-marketplace
/plugin &lt;span class="nb"&gt;install &lt;/span&gt;superpowers@superpowers-marketplace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart. Skills activate automatically — no manual triggers needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The three-step workflow it enforces:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Brainstorm&lt;/strong&gt; — Claude asks clarifying questions, proposes 2–3 approaches, produces a design doc you approve. Code doesn't start until you sign off.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write Plan&lt;/strong&gt; — Breaks your spec into 2–5 minute tasks with exact file paths and complete code. A proper plan is 300–500 lines. Not a vague outline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Execute Plan&lt;/strong&gt; — Dispatches subagents, each in their own isolated context window. Main instance only gets small update summaries. Context never bloats.&lt;/p&gt;

&lt;p&gt;This is spec-driven development. The biggest tech companies use it. Now you can with two install commands.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tool 3 — Context7 MCP
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fixes:&lt;/strong&gt; Hallucinated APIs from stale training data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add context7 &lt;span class="nt"&gt;--&lt;/span&gt; npx &lt;span class="nt"&gt;-y&lt;/span&gt; @upstash/context7-mcp@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or add to &lt;code&gt;~/.claude/mcp.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"context7"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@upstash/context7-mcp@latest"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How to use:&lt;/strong&gt; Append "use context7" to any library-related prompt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build a Next.js 15 server component that fetches from Supabase. use context7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Context7 fetches current documentation from the official source and injects it before Claude generates code. Claude then uses actual APIs instead of guessing from 12-month-old training data.&lt;/p&gt;

&lt;p&gt;Works with React, Next.js, Supabase, Tailwind, Prisma, and thousands of other libraries.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tool 4 — Warp terminal
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fixes:&lt;/strong&gt; Claude is a black box — you can't see what it's building while it builds&lt;/p&gt;

&lt;p&gt;Free at warp.dev (macOS and Linux)&lt;/p&gt;

&lt;p&gt;Three features that matter:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side panel&lt;/strong&gt; — Open your file tree alongside Claude. Review generated code as it's written, not after.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Split terminals (Cmd+D)&lt;/strong&gt; — Run multiple Claude Code instances in parallel. One building, one reviewing, one testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tabs (Ctrl+T)&lt;/strong&gt; — Multiple projects open simultaneously without losing session state.&lt;/p&gt;

&lt;p&gt;Core habit: keep your file tree open in the side panel while Claude executes a plan. Review each file as it's generated. Catch bad decisions before they compound.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tool 5 — Sequential Thinking MCP
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fixes:&lt;/strong&gt; Claude jumping to solutions before reasoning through the problem&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tell Claude: "Please install the sequential thinking MCP server"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude finds the package, installs it, and configures everything. Restart when done.&lt;/p&gt;

&lt;p&gt;Forces chain-of-thought reasoning before Claude produces an answer. Pairs especially well with Superpowers brainstorming — design doc quality improves noticeably.&lt;/p&gt;

&lt;p&gt;Use for: architecture decisions, complex debugging, designing systems that will be hard to change later.&lt;/p&gt;

&lt;p&gt;Skip for: simple tasks, variable renames, quick fixes. Adds latency and tokens — match it to the complexity.&lt;/p&gt;




&lt;h2&gt;
  
  
  The full stack in action
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Open Warp → start Claude Code
2. Status bar shows context% (cc-statusline)
3. Describe the feature
4. Superpowers brainstorm activates automatically
5. Claude reasons through approaches (sequential thinking)
6. Mention a library → Context7 fetches live docs
7. Approve spec → Superpowers writes detailed plan
8. Review plan in Warp side panel
9. Execute → subagents build in isolated context windows
10. Context% stays low (subagents handle heavy lifting)
11. Main context hits 50% → /clear and reload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Production-quality code. No hallucinated APIs. Documented plan you can review and hand off.&lt;/p&gt;




&lt;h2&gt;
  
  
  Install priority if you have 10 minutes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;cc-statusline&lt;/strong&gt; — visibility first, 2 min&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context7&lt;/strong&gt; — eliminates the most common failure mode, 2 min&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Superpowers&lt;/strong&gt; — biggest quality improvement, 3 min&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Warp&lt;/strong&gt; — quality of life, 5 min&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sequential Thinking&lt;/strong&gt; — just ask Claude, 1 min&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;For hands-on labs building the agentic patterns these tools enable — coordinator-subagent systems, MCP servers, production Claude/Bedrock architectures — &lt;strong&gt;Cloud Edventures CCA-001 track&lt;/strong&gt;, 22 labs, real AWS sandboxes.&lt;/p&gt;

&lt;p&gt;Search: &lt;strong&gt;Cloud Edventures CCA-001&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Which tool made the biggest difference in your setup? Drop a comment.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>productivity</category>
      <category>devtools</category>
      <category>ai</category>
    </item>
    <item>
      <title>Your CLAUDE.md is probably broken — 5 silent failure patterns and how to fix them</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Wed, 25 Mar 2026 18:27:00 +0000</pubDate>
      <link>https://forem.com/ajbuilds/your-claudemd-is-probably-broken-5-silent-failure-patterns-and-how-to-fix-them-1abn</link>
      <guid>https://forem.com/ajbuilds/your-claudemd-is-probably-broken-5-silent-failure-patterns-and-how-to-fix-them-1abn</guid>
      <description>&lt;p&gt;CLAUDE.md is the most important file in your Claude Code setup. It's also the easiest to get silently wrong.&lt;/p&gt;

&lt;p&gt;Here's the uncomfortable truth: Claude actively filters what it follows from your CLAUDE.md — it doesn't treat everything as a permanent command. Most production CLAUDE.md files are broken and developers don't know it.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Claude has an instruction budget of ~100–150 slots after its own system prompt&lt;/li&gt;
&lt;li&gt;Files over 60 lines cause Claude to silently ignore rules mid-session&lt;/li&gt;
&lt;li&gt;"Never do X" rules without alternatives cause Claude to freeze and ask permission&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@file&lt;/code&gt; embeds burn context on every session — reference instead&lt;/li&gt;
&lt;li&gt;CLAUDE.md is advisory (80% compliance) — hooks are deterministic (100%)&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Claude Code injects a system reminder above your instructions: &lt;em&gt;"This context may or may not be relevant to your tasks."&lt;/em&gt; Claude actively decides which rules to follow per turn.&lt;/p&gt;

&lt;p&gt;Frontier models follow roughly 150–200 instructions before compliance drops. Claude Code's own system prompt uses ~50 of those slots. That leaves you about 100–150 slots.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If your CLAUDE.md has 60+ rules, Claude is silently ignoring some. You just don't know which ones.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Failure 1 — The kitchen sink file
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# TOO LONG — Claude starts ignoring rules mid-session&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Use TypeScript strict mode
&lt;span class="p"&gt;-&lt;/span&gt; Prefer functional components  
&lt;span class="p"&gt;-&lt;/span&gt; Use arrow functions
&lt;span class="p"&gt;-&lt;/span&gt; Destructure props
&lt;span class="p"&gt;-&lt;/span&gt; Use const over let
&lt;span class="p"&gt;-&lt;/span&gt; Avoid any type
&lt;span class="p"&gt;-&lt;/span&gt; Use interface over type
&lt;span class="p"&gt;-&lt;/span&gt; Always handle errors
&lt;span class="p"&gt;-&lt;/span&gt; Use async/await not .then()
&lt;span class="p"&gt;-&lt;/span&gt; Add JSDoc to public functions
... (30 more rules)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When context fills, Claude weights early rules heavily and discards later ones. The rules you care most about are usually at the bottom.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Keep it under 60 lines. For each rule ask: &lt;em&gt;"Would removing this cause Claude to make a mistake?"&lt;/em&gt; If not, cut it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Failure 2 — Prohibitions without alternatives
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# BAD — Claude freezes every time&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Never use console.log
&lt;span class="p"&gt;-&lt;/span&gt; Never use var
&lt;span class="p"&gt;-&lt;/span&gt; Never commit to main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# GOOD — Claude has a path forward&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Never use console.log; use src/utils/logger.ts
&lt;span class="p"&gt;-&lt;/span&gt; Never use var; use const, or let for reassigned variables
&lt;span class="p"&gt;-&lt;/span&gt; Never commit to main; create feature/description branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every "never" needs an "instead, do this." Without it, Claude pauses and asks permission every time it hits the rule, breaking flow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Failure 3 — &lt;a class="mentioned-user" href="https://dev.to/file"&gt;@file&lt;/a&gt; embeds killing your context
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# BAD — embeds entire files on every session start&lt;/span&gt;
@src/utils/api-client.ts
@docs/architecture.md
@docs/design-system.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# GOOD — reference, don't embed&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; For API patterns, see src/utils/api-client.ts
&lt;span class="p"&gt;-&lt;/span&gt; For architecture decisions, see docs/architecture.md
&lt;span class="p"&gt;-&lt;/span&gt; For design system, see docs/design-system.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;@file&lt;/code&gt; embeds the full file content into every conversation. A 500-line architecture doc loaded every session burns context before you've typed a word.&lt;/p&gt;




&lt;h2&gt;
  
  
  Failure 4 — Missing bash commands
&lt;/h2&gt;

&lt;p&gt;The most commonly skipped section. The most valuable one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Commands&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Build: npm run build
&lt;span class="p"&gt;-&lt;/span&gt; Test (single file): npm run test -- --testPathPattern=
&lt;span class="p"&gt;-&lt;/span&gt; Type check: npm run typecheck
&lt;span class="p"&gt;-&lt;/span&gt; Lint + fix: npm run lint:fix
&lt;span class="p"&gt;-&lt;/span&gt; Dev: npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things matter here: the single-test command (Claude should never run your full suite for one file), typecheck (Claude should run this after every change), and your deployment scripts (Claude cannot guess them).&lt;/p&gt;




&lt;h2&gt;
  
  
  Failure 5 — Sprint context in a permanent file
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# BAD — this gets forgotten when context rotates&lt;/span&gt;
&lt;span class="gu"&gt;## Current Sprint&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Working on payment flow redesign
&lt;span class="p"&gt;-&lt;/span&gt; UserCard component is being deprecated
&lt;span class="p"&gt;-&lt;/span&gt; Don't touch legacy auth module this sprint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CLAUDE.md loads every session. Sprint context belongs in &lt;code&gt;dev-docs/current-sprint.md&lt;/code&gt;, loaded explicitly when needed.&lt;/p&gt;

&lt;p&gt;CLAUDE.md is for permanent project truth. Current state goes in session-specific files.&lt;/p&gt;




&lt;h2&gt;
  
  
  What a production CLAUDE.md actually looks like
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Project: [Name]&lt;/span&gt;
[One sentence. What it does.]

&lt;span class="gu"&gt;## Commands&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Build: npm run build
&lt;span class="p"&gt;-&lt;/span&gt; Test (single): npm run test -- --testPathPattern=
&lt;span class="p"&gt;-&lt;/span&gt; Type check: npm run typecheck
&lt;span class="p"&gt;-&lt;/span&gt; Lint: npm run lint:fix
&lt;span class="p"&gt;-&lt;/span&gt; Dev: npm run dev

&lt;span class="gu"&gt;## Stack&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; TypeScript strict mode
&lt;span class="p"&gt;-&lt;/span&gt; React 18 hooks only — no class components
&lt;span class="p"&gt;-&lt;/span&gt; Tailwind — no custom CSS unless unavoidable
&lt;span class="p"&gt;-&lt;/span&gt; Zustand for state — see src/stores/

&lt;span class="gu"&gt;## Rules&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; ES modules only — never require()
&lt;span class="p"&gt;-&lt;/span&gt; Always handle errors explicitly — no silent catches
&lt;span class="p"&gt;-&lt;/span&gt; Never use console.log; use src/utils/logger.ts instead
&lt;span class="p"&gt;-&lt;/span&gt; No implicit any, no type assertions without explanatory comment

&lt;span class="gu"&gt;## Architecture&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; API calls only through src/queries/ — never direct fetch in components
&lt;span class="p"&gt;-&lt;/span&gt; Shared utilities in src/utils/
&lt;span class="p"&gt;-&lt;/span&gt; Colocate tests with components

&lt;span class="gu"&gt;## What Claude gets wrong here&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Adds index.ts barrel exports — don't, breaks tree shaking
&lt;span class="p"&gt;-&lt;/span&gt; Forgets typecheck after changes — always run npm run typecheck
&lt;span class="p"&gt;-&lt;/span&gt; Uses default exports — always use named exports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice: no sprint info, no &lt;code&gt;@file&lt;/code&gt; embeds, no prohibitions without alternatives, no style rules that don't affect correctness.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 5-minute diagnostic
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Tinkleberry test&lt;/strong&gt;&lt;br&gt;
Add one line: &lt;code&gt;Always address me as "Chief."&lt;/code&gt; Have a 10+ message session on a real task. If Claude stops using "Chief" mid-session, your file is too long and rules are being lost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The direct question test&lt;/strong&gt;&lt;br&gt;
Ask Claude: &lt;em&gt;"What are the rules in CLAUDE.md about error handling?"&lt;/em&gt; If Claude can't recite them accurately, they're too buried, too ambiguous, or too many.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The repeated mistake test&lt;/strong&gt;&lt;br&gt;
If Claude makes the same mistake twice despite a rule against it, that rule needs one of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shorter and clearer wording&lt;/li&gt;
&lt;li&gt;An "instead, do this" alternative&lt;/li&gt;
&lt;li&gt;To be a hook instead of a rule&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  CLAUDE.md vs hooks — the most important distinction
&lt;/h2&gt;

&lt;p&gt;CLAUDE.md is advisory — Claude follows it ~80% of the time.&lt;br&gt;
Hooks are deterministic — 100% every time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.claude/settings.json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;—&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;things&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;MUST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;happen&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"PostToolUse"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Edit|Write"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run lint:fix"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If something must happen without exception — formatting, linting, security checks — make it a hook. CLAUDE.md is for guidance. Hooks are for guarantees.&lt;/p&gt;




&lt;h2&gt;
  
  
  The three-layer system
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLAUDE.md  → permanent project rules    (always loads, max 60 lines)
Skills     → domain knowledge           (loads on demand, no session cost)
Hooks      → non-negotiable actions     (deterministic, not advisory)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most developers only use CLAUDE.md. The developers getting the best results from Claude Code use all three.&lt;/p&gt;




&lt;p&gt;For hands-on labs building production CLAUDE.md hierarchies, slash command registries, and CI/CD integration with Claude Code — &lt;strong&gt;Cloud Edventures CCA-001 track&lt;/strong&gt;, 22 labs, real AWS sandboxes.&lt;/p&gt;

&lt;p&gt;Search: &lt;strong&gt;Cloud Edventures CCA-001&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What does Claude keep ignoring in your CLAUDE.md? Drop a comment — I'll diagnose which failure pattern it is.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>productivity</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Why your RAG system fails in production — and the agentic loop fix</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Tue, 24 Mar 2026 17:54:18 +0000</pubDate>
      <link>https://forem.com/ajbuilds/why-your-rag-system-fails-in-production-and-the-agentic-loop-fix-1knj</link>
      <guid>https://forem.com/ajbuilds/why-your-rag-system-fails-in-production-and-the-agentic-loop-fix-1knj</guid>
      <description>&lt;p&gt;Your RAG demo worked perfectly. Then real users arrived and it started giving confidently wrong answers.&lt;/p&gt;

&lt;p&gt;This is the most common production AI failure in 2026. And it's not a chunking problem or an embedding problem. It's an architectural one.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Standard RAG is a one-shot pipeline with no decision point between retrieval and generation&lt;/li&gt;
&lt;li&gt;When retrieval is weak, the LLM hallucinates confidently using bad context&lt;/li&gt;
&lt;li&gt;Agentic RAG adds a control loop: retrieve → evaluate → retry or proceed&lt;/li&gt;
&lt;li&gt;The evaluation step is the entire value add — use a cheap fast model for it&lt;/li&gt;
&lt;li&gt;2–4x token cost vs single-pass — worth it when wrong answers have real consequences&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What standard RAG actually does
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User query
    ↓
Embed → search vector DB → retrieve top-K chunks
    ↓
Inject chunks into LLM context
    ↓
Generate answer
    ↓
Return to user (no checkpoint, no second chance)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works fine for simple direct questions. Breaks silently on ambiguous, multi-hop, or cross-source queries. The LLM has no way to signal "my context was bad" — it just generates something plausible-sounding and wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  The agentic RAG pattern
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User query
    ↓
Agent decides which source to query
    ↓
Retrieve chunks
    ↓
┌─── DECISION POINT ──────────────────┐
│  Evaluate: is this sufficient?       │
│  → SUFFICIENT: generate answer       │
│  → RETRY: rewrite query, search again│
│  → ESCALATE: cannot answer reliably  │
└─────────────────────────────────────┘
    ↓
Generate grounded answer with citations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The decision point between retrieval and generation is the entire architectural difference. Something now asks "was this retrieval good enough?" before the LLM generates.&lt;/p&gt;




&lt;h2&gt;
  
  
  Complete implementation on AWS Bedrock
&lt;/h2&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;boto3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock-runtime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;retrieval_tools&lt;/span&gt; &lt;span class="o"&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;toolSpec&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;name&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;search_knowledge_base&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;description&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;Search the primary knowledge base for relevant information.
            Use this first for any factual question.
            Returns chunks with relevance scores.&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;inputSchema&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;json&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;type&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;object&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;properties&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;query&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;type&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;string&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;max_results&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;type&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;integer&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;required&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;query&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="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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolSpec&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;name&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;evaluate_retrieval_quality&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;description&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;Evaluate whether retrieved chunks are sufficient to answer the question.
            Use after every retrieval. Returns SUFFICIENT, RETRY, or ESCALATE.&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;inputSchema&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;json&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;type&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;object&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;properties&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;original_query&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;type&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;string&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;retrieved_chunks&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;type&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;string&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;required&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;original_query&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;retrieved_chunks&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="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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_knowledge_base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&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;max_results&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;3&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;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Replace with your actual vector DB call (Pinecone, pgvector, Bedrock KB)
&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;chunks&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="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&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;Retrieved chunk for: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.87&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;text&lt;/span&gt;&lt;span class="sh"&gt;"&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;Second chunk for: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.72&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;evaluate_retrieval_quality&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original_query&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;retrieved_chunks&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="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    Use a cheap fast model to evaluate — save expensive model for generation.
    This is the decision point that makes the loop work.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;eval_prompt&lt;/span&gt; &lt;span class="o"&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;Evaluate if the retrieved content is sufficient to answer the question.

Question: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;original_query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
Retrieved: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;retrieved_chunks&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Respond with exactly: VERDICT|reasoning|suggested_query_if_retry
VERDICT must be: SUFFICIENT, RETRY, or ESCALATE&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;converse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-3-haiku-20240307-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Cheap model for evaluation
&lt;/span&gt;        &lt;span class="n"&gt;messages&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;role&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;user&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;content&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;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;eval_prompt&lt;/span&gt;&lt;span class="p"&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;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&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;message&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;parts&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="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&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;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;verdict&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parts&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="nf"&gt;strip&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;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;strip&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;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;else&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;suggested_query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;strip&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;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&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;tool_router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_name&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;tool_input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tool_name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search_knowledge_base&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="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;search_knowledge_base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;tool_input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;tool_input&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_results&lt;/span&gt;&lt;span class="sh"&gt;"&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="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;tool_name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;evaluate_retrieval_quality&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="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;evaluate_retrieval_quality&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;tool_input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;original_query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;tool_input&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;retrieved_chunks&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;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unknown tool: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tool_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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_agentic_rag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_query&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="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;system&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;You are a precise Q&amp;amp;A agent.

Process:
1. Search knowledge base
2. Evaluate retrieval quality — ALWAYS do this before generating
3. RETRY if evaluation says so (max 3 retries)
4. ESCALATE if cannot find sufficient information
5. Generate grounded answer with citations only if SUFFICIENT

Never generate before evaluating. Cite sources in your answer.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="n"&gt;messages&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;role&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;user&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;content&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;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_query&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;8&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# Safety cap
&lt;/span&gt;        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;converse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-3-sonnet-20240229-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;system&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;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
            &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;toolConfig&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;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;retrieval_tools&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;stop_reason&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stopReason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&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;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;messages&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;output&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;stop_reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_turn&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="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&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;stop_reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tool_use&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;tool_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;block&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUse&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;
                &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUse&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="nf"&gt;tool_router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                &lt;span class="n"&gt;tool_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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolResult&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;toolUseId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUseId&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;content&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;text&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="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;})&lt;/span&gt;
            &lt;span class="n"&gt;messages&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&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;user&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool_results&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Max iterations — could not generate reliable answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;run_agentic_rag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;How does our refund policy work for enterprise customers upgrading mid-cycle?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Three things that make this work
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The evaluation tool is the entire value add&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;evaluate_retrieval_quality&lt;/code&gt; uses Haiku (fast, cheap) to judge relevance before the main model generates. That decision point is where quality improvement comes from. Don't use your expensive model for this step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tool descriptions are your routing logic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Write them as instructions: "Use this first for any factual question" — not labels like "knowledge base search". The agent routes entirely based on these descriptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The system prompt is your quality contract&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Never generate before evaluating" is the single most important instruction. Without it the agent sometimes skips evaluation and hallucinates from bad context.&lt;/p&gt;




&lt;h2&gt;
  
  
  When to use each pattern
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Use when&lt;/th&gt;
&lt;th&gt;Token cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Standard RAG&lt;/td&gt;
&lt;td&gt;Simple single-hop Q&amp;amp;A, latency-sensitive&lt;/td&gt;
&lt;td&gt;1x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agentic RAG&lt;/td&gt;
&lt;td&gt;Ambiguous queries, multi-hop, quality matters&lt;/td&gt;
&lt;td&gt;2–4x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Agentic RAG costs more per query. Worth it when wrong answers have real consequences. Overkill for simple doc lookups.&lt;/p&gt;




&lt;h2&gt;
  
  
  Production tips
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Log every iteration.&lt;/strong&gt; Which queries needed retries, and why, reveals exactly where your knowledge base has gaps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cap at 5–6 iterations.&lt;/strong&gt; Queries needing more are usually unanswerable from your KB and should escalate instead of burning tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Latency is now a distribution.&lt;/strong&gt; Some queries resolve in one pass (fast). Some need three (slower). Monitor p95, not average.&lt;/p&gt;




&lt;p&gt;For hands-on labs building a full RAG system with Bedrock Knowledge Bases in a real AWS sandbox — &lt;strong&gt;Cloud Edventures CCA-001 track&lt;/strong&gt;, 22 labs, no AWS account needed.&lt;/p&gt;

&lt;p&gt;Search: &lt;strong&gt;Cloud Edventures CCA-001&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Where does your RAG system break down most in production? Drop a comment.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>python</category>
      <category>ai</category>
      <category>aws</category>
    </item>
    <item>
      <title>The coordinator-subagent pattern: the foundation every Claude multi-agent system is built on</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Mon, 23 Mar 2026 12:49:43 +0000</pubDate>
      <link>https://forem.com/ajbuilds/the-coordinator-subagent-pattern-the-foundation-every-claude-multi-agent-system-is-built-on-17o6</link>
      <guid>https://forem.com/ajbuilds/the-coordinator-subagent-pattern-the-foundation-every-claude-multi-agent-system-is-built-on-17o6</guid>
      <description>&lt;p&gt;Agent Teams landed in Claude Opus 4.6. Everyone's excited. But before you touch experimental features, understand the foundational pattern everything is built on.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Coordinator receives task, delegates to specialists via tool calls&lt;/li&gt;
&lt;li&gt;Each subagent gets its own isolated context window and system prompt&lt;/li&gt;
&lt;li&gt;Subagents &lt;strong&gt;cannot&lt;/strong&gt; talk to each other — everything routes through coordinator&lt;/li&gt;
&lt;li&gt;Same &lt;code&gt;stopReason&lt;/code&gt; loop as single-agent, tool calls just dispatch to separate API calls&lt;/li&gt;
&lt;li&gt;3–4x token cost vs single agent — only use when specialist quality justifies it&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Pattern 1 — Coordinator-subagent (pure API)
&lt;/h2&gt;

&lt;p&gt;The flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Request
     ↓
Coordinator Agent  ←── stopReason: tool_use
     ↓
  Route to specialist
     ↓
┌──────────────────────────────────┐
│ research_agent │ writer_agent    │  ← Each: isolated context,
│ reviewer_agent │ any_specialist  │    own system prompt, own tools
└──────────────────────────────────┘
     ↓
Tool result back to coordinator
     ↓
stopReason: end_turn → return answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the full working implementation:&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;boto3&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock-runtime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;subagent_tools&lt;/span&gt; &lt;span class="o"&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;toolSpec&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;name&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;research_agent&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;description&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;Research specialist. Use for finding and analyzing information.&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;inputSchema&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;json&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;type&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;object&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;properties&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;task&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;type&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;string&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;required&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;task&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="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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolSpec&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;name&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;writer_agent&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;description&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;Writing specialist. Always pass research as context.&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;inputSchema&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;json&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;type&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;object&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;properties&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;task&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;type&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;string&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;context&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;type&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;string&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;required&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;task&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;context&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="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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_subagent&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="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="n"&gt;kwargs&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="n"&gt;prompts&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;research_agent&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;You are a research specialist. Be factual and concise.&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;writer_agent&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;You are a writing specialist. Use only facts from the context provided.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&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;k&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="si"&gt;}&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;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;kwargs&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="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;converse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-3-sonnet-20240229-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;system&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;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompts&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;messages&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;role&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;user&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;content&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;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;content&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;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&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;message&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&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_coordinator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&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="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;messages&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;role&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;user&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;content&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;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;}]}]&lt;/span&gt;
    &lt;span class="n"&gt;system&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;text&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;Coordinate specialists. Research first, then write.&lt;/span&gt;&lt;span class="sh"&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;_&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;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# Safety cap
&lt;/span&gt;        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;converse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-3-sonnet-20240229-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;toolConfig&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;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;subagent_tools&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&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;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;messages&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;output&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;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stopReason&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_turn&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="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="n"&gt;tool_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;block&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUse&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;
            &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUse&lt;/span&gt;&lt;span class="sh"&gt;"&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;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;research_agent&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="nf"&gt;run_subagent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;research_agent&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="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&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;task&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;writer_agent&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="nf"&gt;run_subagent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;writer_agent&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;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="n"&gt;tool_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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolResult&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;toolUseId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUseId&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;content&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;text&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="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="n"&gt;messages&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&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;user&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool_results&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Safety cap reached&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;run_coordinator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write a post about why hands-on labs beat certifications alone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Pattern 2 — Claude Code subagents
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claude Code Session
      ↓
Main agent → Task tool → specialist-1  (isolated context)
           → Task tool → specialist-2  (isolated context)
           → Task tool → specialist-3  (isolated context)
      ↓
All report back to main agent only — no sideways talk
      ↓
Main agent synthesizes output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same one-way reporting as Pattern 1, but running inside Claude Code via the Task tool. Use for local dev workflows — security reviews, test runs, documentation. Stable and production-ready today.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pattern 3 — Agent Teams (experimental)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Team lead
   ↙         ↓         ↘
Researcher ⟺ Writer ⟺ Reviewer
   ↘         ↓         ↙
Team lead synthesizes

⟺ = direct peer-to-peer communication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key difference: teammates message each other directly without going through the lead. Requires &lt;code&gt;CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1&lt;/code&gt;. Known issues with session resumption and shutdown. Keep off production.&lt;/p&gt;




&lt;h2&gt;
  
  
  Three patterns compared
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Peer talk&lt;/th&gt;
&lt;th&gt;Production&lt;/th&gt;
&lt;th&gt;Token cost&lt;/th&gt;
&lt;th&gt;Use when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Coordinator-subagent (API)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;3–4x&lt;/td&gt;
&lt;td&gt;Production API agents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code subagents&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;3–4x&lt;/td&gt;
&lt;td&gt;Local dev workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent Teams&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;⚠️ Experimental&lt;/td&gt;
&lt;td&gt;3–4x+&lt;/td&gt;
&lt;td&gt;Peers need mid-task sharing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The critical mistake
&lt;/h2&gt;

&lt;p&gt;Subagents share nothing. If your writer needs the research output, you must pass it explicitly.&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="c1"&gt;# WRONG — writer has zero context
&lt;/span&gt;&lt;span class="n"&gt;research&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;run_subagent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;research_agent&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="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;research Lambda limits&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;run_subagent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;writer_agent&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="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;write about Lambda&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# RIGHT — explicitly pass context through coordinator
&lt;/span&gt;&lt;span class="n"&gt;research&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;run_subagent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;research_agent&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="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;research Lambda limits&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;run_subagent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;writer_agent&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="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;write about Lambda&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;research&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isolation is the feature, not the bug. Design for it explicitly.&lt;/p&gt;




&lt;h2&gt;
  
  
  What comes next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Retry logic&lt;/strong&gt; — coordinator decides whether to retry a failed subagent or escalate to a human&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallel subagents&lt;/strong&gt; — multiple tool calls in one response run simultaneously, cutting latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decision routing&lt;/strong&gt; — confidence scores from one subagent pick the next specialist&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Build it hands-on
&lt;/h2&gt;

&lt;p&gt;For hands-on labs covering the full multi-agent coordinator pattern in real AWS Bedrock sandboxes — &lt;strong&gt;Cloud Edventures CCA-001 track&lt;/strong&gt;, 22 labs, automated validation, no AWS account needed.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.cloudedventures.com/labs/track/claude-certified-architect-cca-001" rel="noopener noreferrer"&gt;cloudedventures.com/labs/track/claude-certified-architect-cca-001&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Are you building production API agents or Claude Code workflows? Drop a comment.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>python</category>
      <category>ai</category>
      <category>aws</category>
    </item>
    <item>
      <title>Claude's agentic loop explained: stopReason, tool_use, and the pattern behind every AI agent</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Fri, 20 Mar 2026 18:49:16 +0000</pubDate>
      <link>https://forem.com/ajbuilds/claudes-agentic-loop-explained-stopreason-tooluse-and-the-pattern-behind-every-ai-agent-2l61</link>
      <guid>https://forem.com/ajbuilds/claudes-agentic-loop-explained-stopreason-tooluse-and-the-pattern-behind-every-ai-agent-2l61</guid>
      <description>&lt;p&gt;If you've tried building an AI agent with Claude and Bedrock, you've hit &lt;code&gt;stopReason&lt;/code&gt;. Maybe you ignored it, maybe you cargo-culted the pattern from a tutorial. Either way — here's what's actually happening and why it matters for production systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;stopReason: "tool_use"&lt;/code&gt; → execute the tool, append result, loop again&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stopReason: "end_turn"&lt;/code&gt; → agent is done, return the response&lt;/li&gt;
&lt;li&gt;Always append the assistant message &lt;strong&gt;before&lt;/strong&gt; tool results&lt;/li&gt;
&lt;li&gt;Never use text content checks as your stop condition&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why this pattern exists
&lt;/h2&gt;

&lt;p&gt;Claude on Bedrock doesn't magically "know" to use tools. You have to implement the loop that lets it. The model's job is to reason about your task and signal what it needs — your code's job is to listen to that signal and respond correctly.&lt;/p&gt;

&lt;p&gt;The signal is &lt;code&gt;stopReason&lt;/code&gt;. Everything else follows from there.&lt;/p&gt;




&lt;h2&gt;
  
  
  The loop, step by step
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Send message + tool definitions to Claude
2. Read stopReason from response
3a. If "tool_use"  → run the tool → append result → go to step 1
3b. If "end_turn"  → return the final response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Here's the full working implementation:&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;boto3&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock-runtime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us-east-1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Define your tools
&lt;/span&gt;&lt;span class="n"&gt;tools&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;toolSpec&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;name&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;get_order_status&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;description&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;Look up the status of a customer order by order ID&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;inputSchema&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;json&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;type&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;object&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;properties&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;order_id&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;type&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;string&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;required&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;order_id&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="p"&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;run_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool_input&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;tool_name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_order_status&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="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&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;shipped&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;eta&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;2 days&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="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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown tool&lt;/span&gt;&lt;span class="sh"&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_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_message&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;messages&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;role&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;user&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;content&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;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_message&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;20&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# Safety cap — not your primary stop mechanism
&lt;/span&gt;        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;converse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-3-sonnet-20240229-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;toolConfig&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;tools&lt;/span&gt;&lt;span class="sh"&gt;"&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="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;stop_reason&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stopReason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;output_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&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;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="c1"&gt;# Step 1: Always append Claude's response first
&lt;/span&gt;        &lt;span class="n"&gt;messages&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;output_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Step 2: Check stopReason — not content type
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;stop_reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_turn&lt;/span&gt;&lt;span class="sh"&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;block&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;output_message&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&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;block&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;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;stop_reason&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tool_use&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;tool_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;block&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;output_message&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUse&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;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUse&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="nf"&gt;run_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                    &lt;span class="n"&gt;tool_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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolResult&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;toolUseId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toolUseId&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;content&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;json&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="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;})&lt;/span&gt;

            &lt;span class="c1"&gt;# Step 3: Append tool results and loop
&lt;/span&gt;            &lt;span class="n"&gt;messages&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&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;user&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tool_results&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Safety cap reached&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;run_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;What&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s the status of order ORD-12345?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The three bugs that will waste your afternoon
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bug 1 — Missing assistant message append
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# What most tutorials show (broken)
&lt;/span&gt;&lt;span class="n"&gt;messages&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;tool_results_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# What you actually need
&lt;/span&gt;&lt;span class="n"&gt;messages&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;output_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# Claude's response FIRST
&lt;/span&gt;&lt;span class="n"&gt;messages&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;tool_results_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Then your tool results
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude needs to see its own previous response to connect tool results back to the tool call it made. Skip this and you'll get confused responses or infinite loops.&lt;/p&gt;




&lt;h3&gt;
  
  
  Bug 2 — Content type check as stop condition
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Breaks silently on complex tasks
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&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;message&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;content&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&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="n"&gt;response&lt;/span&gt;  &lt;span class="c1"&gt;# WRONG
&lt;/span&gt;
&lt;span class="c1"&gt;# Correct
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stopReason&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;end_turn&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="n"&gt;response&lt;/span&gt;  &lt;span class="c1"&gt;# RIGHT
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude can return &lt;code&gt;{"type": "text", ...}&lt;/code&gt; blocks &lt;em&gt;alongside&lt;/em&gt; &lt;code&gt;tool_use&lt;/code&gt; blocks. A message like "I'll look that up now" followed by a tool call has text in position &lt;code&gt;[0]&lt;/code&gt; — your agent terminates before the tool ever runs.&lt;/p&gt;




&lt;h3&gt;
  
  
  Bug 3 — Iteration cap as primary stop
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This is a safety net, not a strategy
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&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;10&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;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;  &lt;span class="c1"&gt;# Wrong use of cap
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caps prevent runaway agents. They don't signal completion. A task that genuinely needs 12 iterations gets cut off at 10. A task that finishes in 3 wastes 7 loops. The model signals completion via &lt;code&gt;stopReason&lt;/code&gt; — listen to it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where this goes next
&lt;/h2&gt;

&lt;p&gt;Master the core loop and these patterns become straightforward:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-step tool sequencing&lt;/strong&gt; — Claude chains multiple tool calls across iterations, reasoning about each result before deciding the next action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-agent systems&lt;/strong&gt; — coordinator agents treat subagents as tools. Same &lt;code&gt;tool_use&lt;/code&gt; / &lt;code&gt;end_turn&lt;/code&gt; cycle, one level up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Human escalation&lt;/strong&gt; — on low-confidence results, append a special &lt;code&gt;toolResult&lt;/code&gt; that prompts Claude to request human input instead of proceeding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error propagation&lt;/strong&gt; — structured error responses in tool results let Claude decide whether to retry, use a fallback tool, or surface the failure cleanly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Want to build this in a real AWS Bedrock sandbox?
&lt;/h2&gt;

&lt;p&gt;This is Mission 1 of the &lt;strong&gt;CCA-001: Claude Certified Architect&lt;/strong&gt; track — 22 labs covering agentic loops, MCP servers, multi-agent systems, Bedrock Guardrails, CI/CD with Claude Code, and observability dashboards. Real AWS sandbox, automated validation, no account setup needed.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.cloudedventures.com/labs/bedrock-agentic-loop-stopreason" rel="noopener noreferrer"&gt;cloudedventures.com/labs/bedrock-agentic-loop-stopreason&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also join &lt;strong&gt;r/ClaudeCertifications&lt;/strong&gt; on Reddit — building a community for Claude and Bedrock practitioners.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Drop a comment if anything's unclear — what part of the loop trips you up most?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>aws</category>
      <category>python</category>
      <category>ai</category>
    </item>
    <item>
      <title>Claude Certified Architect (CCA-001): The First Hands-On AI Certification That Actually Matters</title>
      <dc:creator>Aj</dc:creator>
      <pubDate>Thu, 19 Mar 2026 20:19:57 +0000</pubDate>
      <link>https://forem.com/ajbuilds/claude-certified-architect-cca-001-the-first-hands-on-ai-certification-that-actually-matters-3l41</link>
      <guid>https://forem.com/ajbuilds/claude-certified-architect-cca-001-the-first-hands-on-ai-certification-that-actually-matters-3l41</guid>
      <description>&lt;p&gt;There's a new certification making waves in the AI engineering space, and it's not from AWS, Google, or Microsoft.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Claude Certified Architect (CCA-001)&lt;/strong&gt; is the first certification focused entirely on building production-grade AI systems with Anthropic's Claude — and unlike most AI certifications, it's 100% hands-on. No multiple choice. No memorizing API parameters. You either build working agentic systems or you don't pass.&lt;/p&gt;

&lt;p&gt;Here's why that matters, and why AI engineers should pay attention.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI Certification Problem
&lt;/h2&gt;

&lt;p&gt;Let's be real: most AI certifications are glorified reading comprehension tests. You memorize which model has which context window, learn the difference between fine-tuning and RAG, and select the right answer from four options.&lt;/p&gt;

&lt;p&gt;Then you get to an actual job and realize none of that prepared you to build a multi-agent system that handles failures gracefully, or to design tool-calling patterns that don't hallucinate, or to implement guardrails that actually work in production.&lt;/p&gt;

&lt;p&gt;The gap between "I know what agentic AI is" and "I can build reliable agentic AI systems" is enormous. That's the gap CCA-001 is designed to close.&lt;/p&gt;

&lt;h2&gt;
  
  
  What CCA-001 Actually Covers
&lt;/h2&gt;

&lt;p&gt;The certification spans 5 domains, 22 hands-on missions, and roughly 40 hours of work in real AWS Bedrock sandbox environments. Here's what you're building:&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain 1: Agentic Architecture
&lt;/h3&gt;

&lt;p&gt;This isn't theory. You're designing and deploying complete agentic systems — agents that can reason, use tools, and maintain context across complex multi-step tasks. You learn how to structure CLAUDE.md hierarchies, build plan-execute pipelines, and handle the messy reality of agents that don't always do what you expect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain 2: Tool Design &amp;amp; Integration
&lt;/h3&gt;

&lt;p&gt;Every useful AI agent needs tools. You'll build custom tool schemas, implement function calling patterns, and learn why most tool designs fail in production (hint: it's usually the schema descriptions, not the code).&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain 3: Prompt Engineering at Scale
&lt;/h3&gt;

&lt;p&gt;Not "write a better prompt" basics. This covers system prompt architecture for complex applications, dynamic prompt composition, and the engineering patterns that make prompts maintainable across a team — not just one developer's magic strings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain 4: Reliability &amp;amp; Guardrails
&lt;/h3&gt;

&lt;p&gt;The domain that separates demo projects from production systems. You'll implement retry strategies, circuit breakers, output validation, content filtering, and the observability patterns you need to trust an AI system with real users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain 5: Multi-Agent Systems
&lt;/h3&gt;

&lt;p&gt;The most advanced domain. Building systems where multiple AI agents coordinate, share context, handle handoffs, and recover from failures. This is where most teams struggle, and it's where the certification gets genuinely hard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Employers Care About This
&lt;/h2&gt;

&lt;p&gt;Three trends are converging that make CCA-001 uniquely valuable right now:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Claude is dominating the enterprise AI stack.&lt;/strong&gt; Anthropic's models are increasingly the default choice for companies building AI applications. AWS Bedrock makes Claude accessible at enterprise scale, and companies need engineers who know how to build with it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. "AI Engineer" is the fastest-growing role.&lt;/strong&gt; Every job board shows it — companies are hiring specifically for people who can build AI-powered applications, not just data scientists who train models. CCA-001 maps directly to what these roles require.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Agentic AI is the current frontier.&lt;/strong&gt; The shift from simple chatbots to autonomous agents that can reason, use tools, and complete complex tasks is happening now. Most engineers are still figuring out the basics. A certification that proves you can build reliable agentic systems is a genuine differentiator.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hands-On Difference
&lt;/h2&gt;

&lt;p&gt;Here's what makes CCA-001 fundamentally different from other certifications:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every mission runs in a real AWS Bedrock sandbox.&lt;/strong&gt; You're not answering questions about Bedrock — you're deploying actual agents, calling real Claude APIs, and building infrastructure that gets automatically validated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automated validation checks your work.&lt;/strong&gt; You can't fake it. The system verifies that your agent actually works, your tools return correct responses, your guardrails catch what they should, and your multi-agent system handles failures properly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You build a verified portfolio.&lt;/strong&gt; Every completed mission becomes a portfolio piece with proof of completion. When you tell an interviewer "I built a multi-agent system with tool calling and guardrails," you can show them the verified project, not just talk about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Should Get Certified
&lt;/h2&gt;

&lt;p&gt;CCA-001 makes the most sense if you're:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;backend or full-stack engineer&lt;/strong&gt; adding AI capabilities to your skill set&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;cloud engineer&lt;/strong&gt; who wants to specialize in AI infrastructure&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;AI/ML engineer&lt;/strong&gt; who works with LLMs and wants formal proof of agentic architecture skills&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;solutions architect&lt;/strong&gt; designing AI systems for enterprise clients&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;career changer&lt;/strong&gt; targeting the AI engineering role specifically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're still learning basic cloud concepts, get comfortable with AWS first (the Cloud Explorer and Automation Captain paths are good starting points), then come back to CCA-001.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Prepare
&lt;/h2&gt;

&lt;p&gt;The certification is designed to be self-contained — each mission builds on the previous one. But you'll get more out of it if you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic AWS experience (Lambda, API Gateway, IAM)&lt;/li&gt;
&lt;li&gt;Familiarity with at least one programming language (Python recommended)&lt;/li&gt;
&lt;li&gt;General understanding of what LLMs are and how they work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't need prior experience with Claude specifically or with building AI agents. The certification teaches those skills through the missions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 22-Mission Path
&lt;/h2&gt;

&lt;p&gt;The missions follow a progressive structure:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Navigator's Compass&lt;/strong&gt; (4 missions) — Start with CLAUDE.md configuration, slash commands, plan-execute pipelines, and CI/CD integration for AI systems.&lt;/p&gt;

&lt;p&gt;Then you work through each domain with increasingly complex projects, culminating in multi-agent orchestration systems that mirror what companies are actually building in production.&lt;/p&gt;

&lt;p&gt;Each mission takes between 60-120 minutes, and you're working in isolated Bedrock sandboxes the entire time. No risk of runaway API costs, no configuration headaches — just building.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;The AI job market in 2026 is flooded with people who "know about" AI. What's scarce is engineers who can prove they've built reliable, production-grade AI systems.&lt;/p&gt;

&lt;p&gt;CCA-001 is the first certification I've seen that actually tests this. It's not easy — 40 hours of hands-on work is a real commitment. But that difficulty is exactly what makes it valuable. A certification that's hard to get is a certification worth having.&lt;/p&gt;

&lt;p&gt;If you're serious about AI engineering, this is worth your time.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I built &lt;a href="https://www.cloudedventures.com" rel="noopener noreferrer"&gt;Cloud Edventures&lt;/a&gt; specifically to provide hands-on sandbox environments for certifications like this. The CCA-001 path gives you all 22 missions with real Bedrock sandboxes and automated validation. You can &lt;a href="https://www.cloudedventures.com/labs/track/claude-certified-architect-cca-001" rel="noopener noreferrer"&gt;start the Claude Architect path here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Already working on AI certifications? What's your experience been? I'd love to hear in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aws</category>
      <category>claude</category>
      <category>career</category>
    </item>
  </channel>
</rss>
