<?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: Elizabeth Fuentes L</title>
    <description>The latest articles on Forem by Elizabeth Fuentes L (@elizabethfuentes12).</description>
    <link>https://forem.com/elizabethfuentes12</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%2F717518%2Fb550b165-b8b9-405d-acfb-e5dc846765b0.png</url>
      <title>Forem: Elizabeth Fuentes L</title>
      <link>https://forem.com/elizabethfuentes12</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/elizabethfuentes12"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Wed, 01 Apr 2026 19:54:27 +0000</pubDate>
      <link>https://forem.com/elizabethfuentes12/-jli</link>
      <guid>https://forem.com/elizabethfuentes12/-jli</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/ensamblador/facebook-messenger-to-amazon-connect-chat-5ccg" class="crayons-story__hidden-navigation-link"&gt;Facebook Messenger to Amazon Connect Chat&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/ensamblador" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F242047%2F4e391627-8eb1-4aa4-99ff-43f99f1296e8.jpg" alt="ensamblador profile" class="crayons-avatar__image" width="281" height="278"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/ensamblador" class="crayons-story__secondary fw-medium m:hidden"&gt;
              ensamblador
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                ensamblador
                
              
              &lt;div id="story-author-preview-content-3439628" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/ensamblador" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F242047%2F4e391627-8eb1-4aa4-99ff-43f99f1296e8.jpg" class="crayons-avatar__image" alt="" width="281" height="278"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;ensamblador&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/ensamblador/facebook-messenger-to-amazon-connect-chat-5ccg" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 1&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/ensamblador/facebook-messenger-to-amazon-connect-chat-5ccg" id="article-link-3439628"&gt;
          Facebook Messenger to Amazon Connect Chat
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/meta"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;meta&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/amazonconnect"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;amazonconnect&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cdk"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cdk&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/ensamblador/facebook-messenger-to-amazon-connect-chat-5ccg" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/ensamblador/facebook-messenger-to-amazon-connect-chat-5ccg#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            11 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Wed, 01 Apr 2026 15:21:03 +0000</pubDate>
      <link>https://forem.com/elizabethfuentes12/-1op7</link>
      <guid>https://forem.com/elizabethfuentes12/-1op7</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/ensamblador/respondiendo-dms-de-instagram-con-amazon-connect-chat-3kc" class="crayons-story__hidden-navigation-link"&gt;Respondiendo DMs de Instagram con Amazon Connect Chat&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/ensamblador" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F242047%2F4e391627-8eb1-4aa4-99ff-43f99f1296e8.jpg" alt="ensamblador profile" class="crayons-avatar__image" width="281" height="278"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/ensamblador" class="crayons-story__secondary fw-medium m:hidden"&gt;
              ensamblador
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                ensamblador
                
              
              &lt;div id="story-author-preview-content-3439504" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/ensamblador" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F242047%2F4e391627-8eb1-4aa4-99ff-43f99f1296e8.jpg" class="crayons-avatar__image" alt="" width="281" height="278"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;ensamblador&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/ensamblador/respondiendo-dms-de-instagram-con-amazon-connect-chat-3kc" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 1&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/ensamblador/respondiendo-dms-de-instagram-con-amazon-connect-chat-3kc" id="article-link-3439504"&gt;
          Respondiendo DMs de Instagram con Amazon Connect Chat
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/amazonconnect"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;amazonconnect&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/instagram"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;instagram&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/chat"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;chat&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/ensamblador/respondiendo-dms-de-instagram-con-amazon-connect-chat-3kc" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/ensamblador/respondiendo-dms-de-instagram-con-amazon-connect-chat-3kc#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            12 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Wed, 01 Apr 2026 05:22:55 +0000</pubDate>
      <link>https://forem.com/elizabethfuentes12/-oc6</link>
      <guid>https://forem.com/elizabethfuentes12/-oc6</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/aws/5-techniques-to-stop-ai-agent-hallucinations-in-production-oik" class="crayons-story__hidden-navigation-link"&gt;5 Techniques to Stop AI Agent Hallucinations in Production&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/aws"&gt;
            &lt;img alt="AWS logo" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1726%2F2a73f1e6-7995-4348-ae37-44b064274c59.png" class="crayons-logo__image" width="320" height="320"&gt;
          &lt;/a&gt;

          &lt;a href="/elizabethfuentes12" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717518%2Fb550b165-b8b9-405d-acfb-e5dc846765b0.png" alt="elizabethfuentes12 profile" class="crayons-avatar__image" width="420" height="420"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/elizabethfuentes12" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Elizabeth Fuentes L
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Elizabeth Fuentes L
                
              
              &lt;div id="story-author-preview-content-3433117" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/elizabethfuentes12" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717518%2Fb550b165-b8b9-405d-acfb-e5dc846765b0.png" class="crayons-avatar__image" alt="" width="420" height="420"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Elizabeth Fuentes L&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/aws" class="crayons-story__secondary fw-medium"&gt;AWS&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/aws/5-techniques-to-stop-ai-agent-hallucinations-in-production-oik" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 30&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/aws/5-techniques-to-stop-ai-agent-hallucinations-in-production-oik" id="article-link-3433117"&gt;
          5 Techniques to Stop AI Agent Hallucinations in Production
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/aws"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;aws&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/machinelearning"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;machinelearning&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/aws/5-techniques-to-stop-ai-agent-hallucinations-in-production-oik" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;26&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/aws/5-techniques-to-stop-ai-agent-hallucinations-in-production-oik#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            14 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Guardrails para Agentes de IA: Reglas Que los LLM No Pueden Evadir</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Tue, 31 Mar 2026 18:49:56 +0000</pubDate>
      <link>https://forem.com/aws-espanol/guardrails-para-agentes-de-ia-reglas-que-los-llm-no-pueden-evadir-5dmn</link>
      <guid>https://forem.com/aws-espanol/guardrails-para-agentes-de-ia-reglas-que-los-llm-no-pueden-evadir-5dmn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Los agentes de IA pueden alucinar el éxito de una operación incluso cuando violan reglas de negocio. Confirman reservas sin verificación de pago, aceptan parámetros inválidos como 15 huéspedes cuando el máximo es 10, o ignoran prerrequisitos obligatorios.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;El problema central: los agentes pueden confirmar reservas de hotel a pesar de que el pago nunca fue verificado, violar restricciones de capacidad, o saltarse pasos de validación obligatorios. &lt;strong&gt;El prompt engineering por sí solo no puede prevenir estos errores.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Este post demuestra cómo la &lt;strong&gt;validación neurosimbólica&lt;/strong&gt; — combinando razonamiento del LLM con reglas simbólicas deterministas aplicadas a nivel de framework — bloquea operaciones inválidas antes de que se ejecuten.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Esta demo utiliza Strands Agents. Patrones similares pueden aplicarse en LangGraph, AutoGen u otros frameworks de agentes.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Resumen de la Serie
&lt;/h2&gt;

&lt;p&gt;Esta es la Parte 3 de una serie sobre cómo detener las hallucinations en agentes de IA:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/rag-vs-graphrag-when-agents-hallucinate-answers-2mcb"&gt;RAG vs Graph-RAG&lt;/a&gt;&lt;/strong&gt; — Knowledge graphs para prevenir hallucinations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/reduce-agent-errors-and-token-costs-with-semantic-tool-selection-7mf"&gt;Semantic Tool Selection&lt;/a&gt;&lt;/strong&gt; — Filtrado de tools basado en vectores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Agent Guardrails&lt;/strong&gt; (este post) — Reglas simbólicas que los LLM no pueden evadir&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/runtime-guardrails-for-ai-agents-steer-dont-block-278n"&gt;Runtime Guardrails&lt;/a&gt;&lt;/strong&gt; — Redirigir en lugar de bloquear&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/how-to-stop-ai-agents-from-hallucinating-silently-with-multi-agent-validation-3f7e"&gt;Multi-Agent Validation&lt;/a&gt;&lt;/strong&gt; — Detección de hallucinations basada en equipos&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  El Problema: Los Prompts Son Sugerencias, No Restricciones
&lt;/h2&gt;

&lt;p&gt;La investigación de &lt;a href="https://arxiv.org/html/2510.16381v1" rel="noopener noreferrer"&gt;ATA: Autonomous Trustworthy Agents (2024)&lt;/a&gt; identifica tres patrones de hallucination:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Errores de parámetros:&lt;/strong&gt; El agent llama a &lt;code&gt;book_hotel(guests=15)&lt;/code&gt; a pesar de que el docstring indica un máximo de 10&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Errores de completitud:&lt;/strong&gt; El agent ejecuta reservas sin la verificación de pago requerida&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comportamiento de evasión de tools:&lt;/strong&gt; El agent confirma éxito sin llamar a los tools de validación obligatorios&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Causa raíz:&lt;/strong&gt; Los prompts son texto que el LLM interpreta. Las reglas de negocio embebidas en docstrings se convierten en sugerencias — el modelo decide si las sigue en cada llamada.&lt;/p&gt;




&lt;h2&gt;
  
  
  La Solución: Validación Neurosimbólica con Strands Hooks
&lt;/h2&gt;

&lt;p&gt;Los hooks a nivel de framework interceptan las llamadas a tools &lt;strong&gt;antes de la ejecución&lt;/strong&gt;. Usando &lt;code&gt;BeforeToolCallEvent&lt;/code&gt; en Strands Agents, puedes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validar reglas simbólicas de forma determinista&lt;/li&gt;
&lt;li&gt;Cancelar la ejecución del tool si alguna regla falla&lt;/li&gt;
&lt;li&gt;Enviar un mensaje de cancelación directamente al LLM (no puede ser anulado)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Diferencia arquitectónica clave:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prompts:&lt;/strong&gt; Entrada del LLM (interpretable, anulable)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hooks:&lt;/strong&gt; Interceptores del framework (deterministas, obligatorios)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Prerrequisitos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Experiencia con Python y uso de tools en agentes LLM&lt;/li&gt;
&lt;li&gt;Familiaridad con &lt;a href="https://strandsagents.com" rel="noopener noreferrer"&gt;Strands Agents&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/aws-samples/sample-why-agents-fail
&lt;span class="nb"&gt;cd &lt;/span&gt;stop-ai-agent-hallucinations/04-neurosymbolic-demo
uv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementación: Reglas, Hook y Dos Agentes
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Paso 1: Definir Reglas Simbólicas
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dataclasses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dataclass&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Callable&lt;/span&gt;

&lt;span class="nd"&gt;@dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Rule&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="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Callable&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="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="n"&gt;BOOKING_RULES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nc"&gt;Rule&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_guests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ctx&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;guests&lt;/span&gt;&lt;span class="sh"&gt;"&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="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Maximum 10 guests per booking&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nc"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;valid_dates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_in&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;lt;&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_out&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;Check-in must be before check-out&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;CONFIRMATION_RULES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nc"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment_before_confirm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ctx&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;payment_verified&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;Payment must be verified before confirmation&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Las reglas son funciones Python simples — deterministas, testeables y auditables de forma independiente a cualquier agent.&lt;/p&gt;


&lt;h3&gt;
  
  
  Paso 2: Crear el Hook de Validación
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.hooks&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HookProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HookRegistry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NeurosymbolicHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HookProvider&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;register_hooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HookRegistry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validate&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;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_use&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tool_name&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rules&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;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_build_context&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_use&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;passed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;violations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rules&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;context&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;passed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cancel_tool&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;BLOCKED: &lt;/span&gt;&lt;span class="si"&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="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Cuando se establece &lt;code&gt;event.cancel_tool&lt;/code&gt;, Strands reemplaza el resultado del tool con ese mensaje antes de que el LLM lo vea. &lt;strong&gt;El tool nunca se ejecuta.&lt;/strong&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Paso 3: Definir Tools Limpios
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;book_hotel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hotel&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;check_in&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;check_out&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;guests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="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;Book a hotel room.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&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;SUCCESS: Booked &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hotel&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;guests&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; guests, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;check_in&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;check_out&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;booking_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="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;Process payment for a booking.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&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;SUCCESS: Processed $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;booking_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;confirm_booking&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;booking_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="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;Confirm a booking.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&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;SUCCESS: Confirmed &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;booking_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Los tools contienen solo lógica de negocio — sin validación mezclada.&lt;/p&gt;


&lt;h3&gt;
  
  
  Paso 4: Crear Ambos Agentes
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="c1"&gt;# Using OpenAI-compatible interface via Strands SDK (not direct OpenAI usage)
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIModel&lt;/span&gt;

&lt;span class="n"&gt;MODEL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAIModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Baseline: no hook, no validation
&lt;/span&gt;&lt;span class="n"&gt;baseline_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&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="n"&gt;book_hotel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;process_payment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;confirm_booking&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Guarded: hook intercepts every tool call
&lt;/span&gt;&lt;span class="n"&gt;hook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NeurosymbolicHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STATE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;guarded_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&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="n"&gt;book_hotel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;process_payment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;confirm_booking&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;hooks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;hook&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Mismos tools, mismo modelo, mismos prompts.&lt;/strong&gt; La única diferencia: &lt;code&gt;hooks=[hook]&lt;/code&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Resultados de las Pruebas
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Prueba 1: Confirmar Reserva Sin Pago
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Consulta:&lt;/strong&gt; "Confirm booking BK001"&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Resultado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Baseline&lt;/td&gt;
&lt;td&gt;❌ Ejecuta — pago nunca verificado, docstring ignorado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guarded&lt;/td&gt;
&lt;td&gt;✅ Bloqueado — el hook evalúa &lt;code&gt;CONFIRMATION_RULES&lt;/code&gt;, encuentra &lt;code&gt;payment_verified=False&lt;/code&gt;, cancela&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;El LLM recibe: &lt;code&gt;BLOCKED: Payment must be verified before confirmation&lt;/code&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Prueba 2: Reservar Hotel Excediendo el Límite de Huéspedes
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Consulta:&lt;/strong&gt; "Book Grand Hotel for 15 people from 2026-03-20 to 2026-03-25"&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Resultado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Baseline&lt;/td&gt;
&lt;td&gt;❌ Ejecuta con 15 huéspedes — máximo en docstring ignorado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guarded&lt;/td&gt;
&lt;td&gt;✅ Bloqueado — &lt;code&gt;max_guests_check(15 &amp;lt;= 10)&lt;/code&gt; falla, ejecución cancelada&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;La validación ocurre &lt;strong&gt;antes de la ejecución&lt;/strong&gt; — no hay reserva que revertir.&lt;/p&gt;


&lt;h3&gt;
  
  
  Prueba 3: Reserva Válida
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Consulta:&lt;/strong&gt; "Book Grand Hotel for 5 guests from 2026-03-20 to 2026-03-25"&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Resultado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Baseline&lt;/td&gt;
&lt;td&gt;✅ Ejecuta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guarded&lt;/td&gt;
&lt;td&gt;✅ Ejecuta — todas las reglas pasan, el hook no agrega fricción&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Resumen de Escenarios
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Escenario&lt;/th&gt;
&lt;th&gt;Baseline&lt;/th&gt;
&lt;th&gt;Guarded&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Confirmar sin pago&lt;/td&gt;
&lt;td&gt;❌ Ejecuta — hallucination&lt;/td&gt;
&lt;td&gt;✅ Bloqueado antes de la ejecución&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reservar 15 huéspedes (máx. 10)&lt;/td&gt;
&lt;td&gt;❌ Ejecuta — regla violada&lt;/td&gt;
&lt;td&gt;✅ Bloqueado antes de la ejecución&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reserva válida (5 huéspedes)&lt;/td&gt;
&lt;td&gt;✅ Ejecuta&lt;/td&gt;
&lt;td&gt;✅ Ejecuta&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Punto Clave: Dónde Se Aplica la Validación
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Prompt Engineering (Insuficiente)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;system_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
IMPORTANT: Never confirm bookings without payment verification.
CRITICAL: Maximum 10 guests per booking.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;span class="c1"&gt;# The LLM reads this as context. It can hallucinate compliance.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;❌ El LLM decide si sigue estas instrucciones en cada llamada.&lt;/p&gt;
&lt;h3&gt;
  
  
  Aplicación Basada en Hooks (Suficiente)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;passed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;violations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rules&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;context&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;passed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cancel_tool&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;BLOCKED: &lt;/span&gt;&lt;span class="si"&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="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="c1"&gt;# Tool never executes. LLM receives the cancellation.
&lt;/span&gt;        &lt;span class="c1"&gt;# There is no path to override this.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;✅ El hook se ejecuta fuera del LLM. La decisión no depende del LLM.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diferencia arquitectónica:&lt;/strong&gt; Los prompts son entrada del LLM (interpretable). Los hooks son interceptores del framework (deterministas).&lt;/p&gt;


&lt;h2&gt;
  
  
  Consideraciones para Producción
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Ventajas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Restricciones verificables:&lt;/strong&gt; Las reglas son código, no instrucciones&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centralizadas:&lt;/strong&gt; Un solo hook valida todos los tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testeables de forma independiente:&lt;/strong&gt; Las reglas funcionan fuera de cualquier agent o contexto de LLM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auditables:&lt;/strong&gt; Las violaciones de reglas producen eventos explícitos con nombre del tool, parámetros y razón&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Desafíos
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Las reglas deben definirse explícitamente para cada operación protegida&lt;/li&gt;
&lt;li&gt;No maneja lógica difusa o probabilística — las reglas son booleanas&lt;/li&gt;
&lt;li&gt;Los casos límite requieren manejo explícito en las condiciones&lt;/li&gt;
&lt;li&gt;Las reglas necesitan mantenimiento a medida que evoluciona la lógica de negocio&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Mejores Prácticas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Define hooks para operaciones críticas: reservas, pagos, cancelaciones&lt;/li&gt;
&lt;li&gt;Registra todas las violaciones de reglas con nombre del tool, parámetros y razón&lt;/li&gt;
&lt;li&gt;Testea las reglas de forma independiente y exhaustiva&lt;/li&gt;
&lt;li&gt;Combina con semantic tool selection (Parte 2) y multi-agent validation (Parte 5) para protección en capas&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Siguiente Paso
&lt;/h2&gt;

&lt;p&gt;Los guardrails simbólicos bloquean violaciones de reglas a nivel de tool. Pero bloquear detiene el flujo de trabajo — el usuario debe intervenir.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/aws/runtime-guardrails-for-ai-agents-steer-dont-block-278n"&gt;Parte 4: Runtime Guardrails&lt;/a&gt;&lt;/strong&gt; muestra cómo Agent Control redirige a los agentes para que se autocorrijan en lugar de bloquearlos, completando flujos de trabajo sin intervención humana.&lt;/p&gt;


&lt;h2&gt;
  
  
  Conclusiones Clave
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Los prompts son sugerencias:&lt;/strong&gt; El LLM interpreta docstrings; puede alucinar cumplimiento con cualquier instrucción&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Los hooks son aplicación forzada:&lt;/strong&gt; &lt;code&gt;BeforeToolCallEvent&lt;/code&gt; intercepta antes de la ejecución a nivel de framework — el LLM no puede anular un tool cancelado&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Todas las operaciones inválidas bloqueadas:&lt;/strong&gt; Cero cambios en tools, cero cambios en prompts, un hook agregado&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separación limpia:&lt;/strong&gt; Los tools manejan operaciones; los hooks manejan la aplicación de restricciones&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auditable por diseño:&lt;/strong&gt; Las violaciones de reglas son condiciones Python explícitas — testeables, registrables, trazables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Un hook, todos los tools:&lt;/strong&gt; Un solo &lt;code&gt;NeurosymbolicHook&lt;/code&gt; valida cada llamada a tool de forma centralizada&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Ejecútalo Tú Mismo
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/aws-samples/sample-why-agents-fail
&lt;span class="nb"&gt;cd &lt;/span&gt;stop-ai-agent-hallucinations/04-neurosymbolic-demo
uv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
uv run test_neurosymbolic_hooks.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Puedes cambiar a cualquier proveedor soportado por Strands — consulta &lt;a href="https://strandsagents.com/docs/user-guide/concepts/model-providers/" rel="noopener noreferrer"&gt;Strands Model Providers&lt;/a&gt; para la configuración.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Investigación
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/html/2510.16381v1" rel="noopener noreferrer"&gt;ATA: Autonomous Trustworthy Agents (2024)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/pdf/2504.07640v1" rel="noopener noreferrer"&gt;Enhancing LLMs through Neuro-Symbolic Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.preprints.org/manuscript/202505.1955" rel="noopener noreferrer"&gt;Mitigating LLM Hallucinations: Meta-Analysis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Strands Agents
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://strandsagents.com/docs/user-guide/concepts/agents/hooks/" rel="noopener noreferrer"&gt;Strands Hooks Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://strandsagents.com/docs/user-guide/concepts/model-providers/" rel="noopener noreferrer"&gt;Strands Model Providers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Código
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/aws-samples/sample-why-agents-fail" rel="noopener noreferrer"&gt;Repositorio de Código&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Gracias!&lt;/p&gt;

&lt;p&gt;🇻🇪🇨🇱 &lt;a href="https://dev.to/elizabethfuentes12"&gt;Dev.to&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/lizfue/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;a href="https://github.com/elizabethfuentes12/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; &lt;a href="https://twitter.com/elizabethfue12" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://www.instagram.com/elifue.tech" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; &lt;a href="https://www.youtube.com/channel/UCr0Gnc-t30m4xyrvsQpNp2Q" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;&lt;br&gt;
&lt;a href="https://linktr.ee/elizabethfuentesleone" rel="noopener noreferrer"&gt;Linktr&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__717518"&gt;
    &lt;a href="/elizabethfuentes12" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717518%2Fb550b165-b8b9-405d-acfb-e5dc846765b0.png" alt="elizabethfuentes12 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/elizabethfuentes12"&gt;Elizabeth Fuentes L&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/elizabethfuentes12"&gt;I help developers build production-ready AI applications through hands-on tutorials and open-source projects.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>ai</category>
      <category>python</category>
      <category>agents</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>5 Techniques to Stop AI Agent Hallucinations in Production</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Mon, 30 Mar 2026 23:58:02 +0000</pubDate>
      <link>https://forem.com/aws/5-techniques-to-stop-ai-agent-hallucinations-in-production-oik</link>
      <guid>https://forem.com/aws/5-techniques-to-stop-ai-agent-hallucinations-in-production-oik</guid>
      <description>&lt;p&gt;&lt;strong&gt;AI agent hallucinations&lt;/strong&gt; occur when an LLM-powered agent fabricates data, selects the wrong tool, or ignores business rules during autonomous task execution. This post deploys 5 production-ready techniques to stop them — using managed hosting, serverless tools, database-driven guardrails, semantic tool routing, and a knowledge graph. Everything deploys as infrastructure as code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR — 5 techniques, one production stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Graph-RAG&lt;/strong&gt; on Neo4j AuraDB eliminates fabricated aggregations with Cypher queries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic tool routing&lt;/strong&gt; via AgentCore Gateway replaces custom FAISS indexes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-agent validation&lt;/strong&gt; on Lambda + DynamoDB catches errors single agents miss&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database-driven steering rules&lt;/strong&gt; update agent behavior without redeploying&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard hooks + soft steers&lt;/strong&gt; separate financial constraints from operational adjustments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every demo in this series on stopping AI agent hallucinations ran on a laptop. Hardcoded data, in-memory rules, a single user. The techniques worked, but the infrastructure did not scale. Moving to production means replacing local files with managed databases, in-process tools with serverless functions, and hardcoded rules with data you can update without redeploying.&lt;/p&gt;

&lt;p&gt;This post walks through a production hotel booking agent that applies every technique from the series. We use &lt;a href="https://strandsagents.com/" rel="noopener noreferrer"&gt;Strands Agents&lt;/a&gt; for its native support of &lt;a href="https://strandsagents.com/docs/user-guide/concepts/tools/" rel="noopener noreferrer"&gt;tool calling&lt;/a&gt;, &lt;a href="https://strandsagents.com/docs/user-guide/concepts/agents/hooks/" rel="noopener noreferrer"&gt;hooks&lt;/a&gt; for guardrail enforcement, and &lt;a href="https://strandsagents.com/docs/user-guide/concepts/tools/mcp-tools/" rel="noopener noreferrer"&gt;MCP (Model Context Protocol)&lt;/a&gt; integration for connecting to &lt;a href="https://aws.amazon.com/bedrock/agentcore/" rel="noopener noreferrer"&gt;Amazon Bedrock AgentCore&lt;/a&gt; Gateway. Similar patterns can be applied in LangGraph, AutoGen, CrewAI, or other agent frameworks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Complexity note:&lt;/strong&gt; This guide assumes familiarity with &lt;a href="https://aws.amazon.com/cdk/" rel="noopener noreferrer"&gt;AWS CDK&lt;/a&gt; and core AWS services (Lambda, DynamoDB, S3). New to CDK? Start with the &lt;a href="https://cdkworkshop.com/" rel="noopener noreferrer"&gt;CDK Workshop&lt;/a&gt; first.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Working code:&lt;/strong&gt; &lt;a href="https://github.com/elizabethfuentes12/why-agents-fail-sample-for-amazon-agentcore/tree/main/06-agentcore-production-demo" rel="noopener noreferrer"&gt;github.com/elizabethfuentes12/why-agents-fail-sample-for-amazon-agentcore&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;You need the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS account&lt;/strong&gt; with &lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html" rel="noopener noreferrer"&gt;CDK bootstrapped&lt;/a&gt; in your target region&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://aws.amazon.com/cli/" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt;&lt;/strong&gt; installed and configured&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://aws.amazon.com/cdk/" rel="noopener noreferrer"&gt;AWS CDK v2&lt;/a&gt;&lt;/strong&gt; (Cloud Development Kit) — infrastructure as code framework for deploying all resources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://python.org/downloads" rel="noopener noreferrer"&gt;Python 3.11+&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://docs.astral.sh/uv/" rel="noopener noreferrer"&gt;uv&lt;/a&gt;&lt;/strong&gt; package manager&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://platform.openai.com/api-keys" rel="noopener noreferrer"&gt;OpenAI API key&lt;/a&gt;&lt;/strong&gt; — the agent uses GPT-4o-mini as the LLM (Large Language Model) provider, swappable for &lt;a href="https://aws.amazon.com/bedrock/" rel="noopener noreferrer"&gt;Amazon Bedrock&lt;/a&gt; or other providers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://neo4j.com/cloud/aura-free/" rel="noopener noreferrer"&gt;Neo4j AuraDB Free&lt;/a&gt;&lt;/strong&gt; account — only if deploying GraphRAG (Stack 2)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Series Overview
&lt;/h2&gt;

&lt;p&gt;This is the final post in the series on stopping AI agent hallucinations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/rag-vs-graphrag-when-agents-hallucinate-answers-3chm"&gt;RAG vs Graph-RAG: When Agents Hallucinate Answers&lt;/a&gt;&lt;/strong&gt; — Knowledge graphs prevent hallucinated aggregations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/reduce-agent-errors-and-token-costs-with-semantic-tool-selection-1o04"&gt;Reduce Agent Errors and Token Costs with Semantic Tool Selection&lt;/a&gt;&lt;/strong&gt; — Vector filtering reduces wrong tool choices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/how-to-stop-ai-agents-from-hallucinating-silently-with-multi-agent-validation-1nkp"&gt;How to Stop AI Agents from Hallucinating Silently with Multi-Agent Validation&lt;/a&gt;&lt;/strong&gt; — Cross-validation catches errors single agents miss&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/ai-agent-guardrails-rules-that-llms-cannot-bypass-596d"&gt;AI Agent Guardrails: Rules That LLMs Cannot Bypass&lt;/a&gt;&lt;/strong&gt; — Symbolic rules enforced at the framework level&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/runtime-guardrails-for-ai-agents-steer-dont-block-36kd"&gt;Runtime Guardrails for AI Agents — Steer, Don't Block&lt;/a&gt;&lt;/strong&gt; — Agent self-corrects instead of failing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;From Demo to Production&lt;/strong&gt; (this post) — Deploy all techniques on AWS&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each post can be read independently. The &lt;a href="https://github.com/elizabethfuentes12/why-agents-fail-sample-for-amazon-agentcore" rel="noopener noreferrer"&gt;repository&lt;/a&gt; contains all demos with runnable code.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Does Each Anti-Hallucination Technique Map to Production?
&lt;/h2&gt;

&lt;p&gt;The table below shows what each demo built locally and what replaces it in production:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Technique&lt;/th&gt;
&lt;th&gt;Demo implementation&lt;/th&gt;
&lt;th&gt;Production replacement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Graph-RAG&lt;/strong&gt; (demo 01)&lt;/td&gt;
&lt;td&gt;Local Neo4j Desktop + manual APOC scripts&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://neo4j.com/cloud/aura-free/" rel="noopener noreferrer"&gt;Neo4j AuraDB Free&lt;/a&gt; + automated Lambda builder using &lt;a href="https://neo4j.com/docs/neo4j-graphrag-python/current/user_guide_kg_builder.html" rel="noopener noreferrer"&gt;SimpleKGPipeline&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Semantic tool selection&lt;/strong&gt; (demo 02)&lt;/td&gt;
&lt;td&gt;In-memory FAISS (Facebook AI Similarity Search) index rebuilt on every run&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://aws.amazon.com/bedrock/agentcore/" rel="noopener noreferrer"&gt;AgentCore Gateway&lt;/a&gt; with MCP semantic routing — no custom index needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Multi-agent validation&lt;/strong&gt; (demo 03)&lt;/td&gt;
&lt;td&gt;Hardcoded validator agents with in-memory state&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;validate_booking_rules&lt;/code&gt; Lambda backed by DynamoDB — same safety, lower latency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Neurosymbolic guardrails&lt;/strong&gt; (demo 04)&lt;/td&gt;
&lt;td&gt;Python hooks with hardcoded thresholds&lt;/td&gt;
&lt;td&gt;Steering rules in DynamoDB — change rules without redeploying&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Agent Control steering&lt;/strong&gt; (demo 05)&lt;/td&gt;
&lt;td&gt;Local Agent Control server with config files&lt;/td&gt;
&lt;td&gt;STEER messages stored in DynamoDB rules — agent self-corrects from database-driven guidance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The anti-hallucination techniques remain the same. The infrastructure becomes managed, scalable, and updatable without code changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Does the Production Architecture Look Like?
&lt;/h2&gt;

&lt;p&gt;The production architecture runs on &lt;a href="https://aws.amazon.com/bedrock/agentcore/" rel="noopener noreferrer"&gt;Amazon Bedrock AgentCore&lt;/a&gt;. Runtime hosts the agent code, and Gateway routes tool calls to &lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt; functions via MCP. Two independent &lt;a href="https://aws.amazon.com/cdk/" rel="noopener noreferrer"&gt;AWS CDK&lt;/a&gt; stacks deploy the full infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AgentCore Runtime&lt;/strong&gt; — Hosts and runs your agent code in a managed environment&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AgentCore Gateway&lt;/strong&gt; — MCP-based semantic tool routing that connects agents to serverless functions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft148lh3q3jsonzlso6ca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft148lh3q3jsonzlso6ca.png" alt="Production architecture: AgentCore Runtime connects to Gateway via MCP, which routes to Lambda tools backed by DynamoDB and Neo4j" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack 1 — &lt;code&gt;HotelBookingAgentStack&lt;/code&gt;&lt;/strong&gt; (deploy first, works on its own):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;3 &lt;a href="https://aws.amazon.com/dynamodb/" rel="noopener noreferrer"&gt;Amazon DynamoDB&lt;/a&gt; tables&lt;/td&gt;
&lt;td&gt;Hotels inventory, bookings, steering rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://aws.amazon.com/secrets-manager/" rel="noopener noreferrer"&gt;AWS Secrets Manager&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;OpenAI API key stored securely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AgentCore Runtime&lt;/td&gt;
&lt;td&gt;Managed agent hosting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AgentCore Gateway&lt;/td&gt;
&lt;td&gt;MCP semantic routing to Lambda tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7 &lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt; functions&lt;/td&gt;
&lt;td&gt;search, book, get_booking, process_payment, confirm, cancel, validate&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Stack 2 — &lt;code&gt;GraphRAGStack&lt;/code&gt;&lt;/strong&gt; (deploy when ready, adds FAQ capabilities):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://aws.amazon.com/s3/" rel="noopener noreferrer"&gt;Amazon S3&lt;/a&gt; bucket&lt;/td&gt;
&lt;td&gt;300 hotel FAQ documents auto-uploaded during deploy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda build_graph&lt;/td&gt;
&lt;td&gt;Builds knowledge graph from documents using &lt;a href="https://neo4j.com/docs/neo4j-graphrag-python/current/user_guide_kg_builder.html" rel="noopener noreferrer"&gt;SimpleKGPipeline&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda query_knowledge_graph&lt;/td&gt;
&lt;td&gt;Executes &lt;a href="https://neo4j.com/docs/cypher-manual/current/" rel="noopener noreferrer"&gt;Cypher&lt;/a&gt; queries against Neo4j AuraDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://neo4j.com/cloud/aura-free/" rel="noopener noreferrer"&gt;Neo4j AuraDB Free&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Managed graph database ($0/month free tier)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  How Do Steering Rules Work as Data Instead of Code?
&lt;/h2&gt;

&lt;p&gt;In demo 04, business rules were hardcoded in Python. Changing a threshold meant changing code and redeploying. In production, rules live in DynamoDB. Update a row and the agent's behavior changes immediately.&lt;/p&gt;

&lt;p&gt;Each rule has two messages: a &lt;code&gt;fail_message&lt;/code&gt; that describes the violation and a &lt;code&gt;steer_message&lt;/code&gt; that tells the agent how to self-correct:&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;"rule_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"max-guests"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"book"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"condition_field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"guests"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"operator"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"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;"threshold"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fail_message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Guest count exceeds maximum of 10"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"steer_message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Booking for 15 guests is not available, but you CAN book for up to 10. Adjust to 10 guests, proceed, and tell the user."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;The &lt;code&gt;validate_booking_rules&lt;/code&gt; tool reads rules from DynamoDB before every booking action. When a rule is violated, the agent receives the STEER guidance and self-corrects, completing the task instead of blocking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_booking_rules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;action&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;guests&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;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;check_in&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="n"&gt;check_out&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="n"&gt;booking_id&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="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;Validate business rules BEFORE executing a booking action.
    ALWAYS call this before book_hotel, confirm_booking, or cancel_booking.
    Rules are loaded from the SteeringRules database, changeable without redeploying.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;rules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;_get_rules_for_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# DynamoDB scan
&lt;/span&gt;    &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;_build_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;# Derive nights, days_until_checkin
&lt;/span&gt;    &lt;span class="n"&gt;violated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;_evaluate_rules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# Symbolic evaluation
&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;violated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&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;PASS: All &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;rules&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; rules passed for &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;. Proceed.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;lines&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;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;violated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;lines&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&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="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fail_message&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;  STEER: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;steer_message&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;FAIL: &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;violated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; rule(s) violated:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Changing a rule takes one command.&lt;/strong&gt; No redeploy, no PR, takes effect immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws dynamodb update-item &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--table-name&lt;/span&gt; HotelBookingAgentStack-SteeringRules &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--key&lt;/span&gt; &lt;span class="s1"&gt;'{"rule_id": {"S": "max-guests"}}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--update-expression&lt;/span&gt; &lt;span class="s2"&gt;"SET threshold = :t"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--expression-attribute-values&lt;/span&gt; &lt;span class="s1"&gt;'{":t": {"N": "8"}}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 6 steering rules deployed by default:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;What it catches&lt;/th&gt;
&lt;th&gt;How the agent self-corrects&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;max-guests&lt;/td&gt;
&lt;td&gt;book&lt;/td&gt;
&lt;td&gt;More than 10 guests&lt;/td&gt;
&lt;td&gt;Adjusts to 10, informs user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;valid-dates&lt;/td&gt;
&lt;td&gt;book&lt;/td&gt;
&lt;td&gt;Check-out before check-in&lt;/td&gt;
&lt;td&gt;Swaps dates, informs user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;advance-booking&lt;/td&gt;
&lt;td&gt;book&lt;/td&gt;
&lt;td&gt;Same-day booking&lt;/td&gt;
&lt;td&gt;Moves check-in to tomorrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;payment-before-confirm&lt;/td&gt;
&lt;td&gt;confirm&lt;/td&gt;
&lt;td&gt;Unpaid booking&lt;/td&gt;
&lt;td&gt;Processes payment first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cancellation-window&lt;/td&gt;
&lt;td&gt;cancel&lt;/td&gt;
&lt;td&gt;Less than 48h to check-in&lt;/td&gt;
&lt;td&gt;Suggests modification instead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;already-cancelled&lt;/td&gt;
&lt;td&gt;cancel&lt;/td&gt;
&lt;td&gt;Booking already cancelled&lt;/td&gt;
&lt;td&gt;Offers to create new booking&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  When Should You Block vs Steer?
&lt;/h2&gt;

&lt;p&gt;Not every rule should be steerable. Payment before confirmation is a financial integrity constraint: the LLM must never bypass it, regardless of how it interprets a STEER message. The production agent uses a two-layer approach:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 1 — Hard hooks (framework-level, cannot be bypassed):&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;from&lt;/span&gt; &lt;span class="n"&gt;strands.hooks.events&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.hooks.registry&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HookProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HookRegistry&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookingGuardrailsHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HookProvider&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Hard guardrails for financial and contractual constraints.
    The LLM cannot bypass these. They execute before the tool runs.
    &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;register_hooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HookRegistry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_validate&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;_validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_use&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;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_use&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;input&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;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;confirm&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;tool_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;booking&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_bookings&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;booking_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;params&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;booking_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="p"&gt;)}&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="n"&gt;booking&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;booking&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="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PAID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cancel_tool&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;BLOCKED: Payment must be processed before confirmation. &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ask the user if they want to proceed with payment.&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;strong&gt;Layer 2 — Soft steering (DynamoDB rules, agent self-corrects):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;validate_booking_rules&lt;/code&gt; tool shown above. Rules can be updated, disabled, or added without touching agent code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to decide which layer to use:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Mechanism&lt;/th&gt;
&lt;th&gt;When to use&lt;/th&gt;
&lt;th&gt;Can the LLM bypass it?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hard hook&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;event.cancel_tool&lt;/code&gt; blocks execution&lt;/td&gt;
&lt;td&gt;Financial, legal, compliance&lt;/td&gt;
&lt;td&gt;No — framework intercepts before the tool runs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Soft steer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;STEER message guides correction&lt;/td&gt;
&lt;td&gt;Capacity limits, date adjustments, preferences&lt;/td&gt;
&lt;td&gt;No bypass — but the agent adapts and completes the task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prompt rule&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;System prompt instruction&lt;/td&gt;
&lt;td&gt;Workflow order, communication style&lt;/td&gt;
&lt;td&gt;Yes — the LLM may ignore under ambiguous input&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Use hard hooks for rules where failure means financial or legal risk. Use soft steering for everything else. It reduces user friction without sacrificing safety.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Does the MCP Integration with AgentCore Gateway Work?
&lt;/h2&gt;

&lt;p&gt;The agent connects to &lt;a href="https://aws.amazon.com/bedrock/agentcore/" rel="noopener noreferrer"&gt;AgentCore Gateway&lt;/a&gt; via MCP at startup and discovers all available tools at runtime, with no hardcoded tool list needed. In demo 02, we built a custom FAISS index to pre-filter tools by semantic similarity. In production, the Gateway replaces that entirely, routing each tool call to the right Lambda function based on semantic matching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bedrock_agentcore&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BedrockAgentCoreApp&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.tools.mcp.mcp_client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;MCPClient&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.client.streamable_http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;streamablehttp_client&lt;/span&gt;

&lt;span class="c1"&gt;# Using OpenAI-compatible interface via Strands SDK (not direct OpenAI usage)
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIModel&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockAgentCoreApp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@app.entrypoint&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Entry point for AgentCore Runtime invocations.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAIModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;client_args&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;api_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;_openai_api_key&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;hooks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;BookingGuardrailsHook&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;

    &lt;span class="c1"&gt;# Gateway handles semantic tool routing via MCP
&lt;/span&gt;    &lt;span class="n"&gt;mcp_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MCPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;streamablehttp_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GATEWAY_URL&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;mcp_client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mcp_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list_tools_sync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SYSTEM_PROMPT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;hooks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payload&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;prompt&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="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&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 does not define tools inline. It connects to the Gateway, which discovers available Lambda functions and routes calls based on semantic matching. Adding a new tool (such as &lt;code&gt;query_knowledge_graph&lt;/code&gt;) means registering it in the Gateway. No agent code changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Does GraphRAG Work in Production?
&lt;/h2&gt;

&lt;p&gt;Demo 01 demonstrates that traditional RAG (Retrieval-Augmented Generation) hallucinates when answering aggregation queries. "How many hotels have a pool?" gets a guess instead of a count. Graph-RAG eliminates this by executing &lt;a href="https://neo4j.com/docs/cypher-manual/current/" rel="noopener noreferrer"&gt;Cypher&lt;/a&gt; queries on a knowledge graph that computes exact results.&lt;/p&gt;

&lt;p&gt;In production, the knowledge graph runs on &lt;a href="https://neo4j.com/cloud/aura-free/" rel="noopener noreferrer"&gt;Neo4j AuraDB Free&lt;/a&gt;, a managed graph database with a $0/month free tier (200K nodes, no credit card required). The build pipeline is fully automated:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;300 hotel FAQ documents&lt;/strong&gt; upload to S3 during &lt;code&gt;cdk deploy&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;build_graph Lambda&lt;/strong&gt; reads documents, calls OpenAI to extract entities and relationships via &lt;a href="https://neo4j.com/docs/neo4j-graphrag-python/current/user_guide_kg_builder.html" rel="noopener noreferrer"&gt;SimpleKGPipeline&lt;/a&gt;, and loads them into Neo4j AuraDB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;query_knowledge_graph Lambda&lt;/strong&gt; executes Cypher queries and returns structured results&lt;/li&gt;
&lt;li&gt;The query Lambda registers in &lt;strong&gt;AgentCore Gateway&lt;/strong&gt; — the agent discovers it via MCP&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Questions like "What amenities does the Grand Hotel have?" now traverse the graph (following connections between nodes) instead of guessing from text chunks.&lt;/p&gt;

&lt;p&gt;The CDK stack supports two build modes via &lt;code&gt;-c graph_mode=lite|full&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Build mode (&lt;code&gt;graph_mode&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Documents&lt;/th&gt;
&lt;th&gt;Build time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;lite&lt;/strong&gt; (default)&lt;/td&gt;
&lt;td&gt;Uploads a subset of docs, builds graph in a single Lambda&lt;/td&gt;
&lt;td&gt;30&lt;/td&gt;
&lt;td&gt;~15 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;full&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Uploads all docs, uses Step Functions to batch-process&lt;/td&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;~1-2 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cdk deploy GraphRAGStack                      &lt;span class="c"&gt;# lite mode (30 docs)&lt;/span&gt;
cdk deploy GraphRAGStack &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nv"&gt;graph_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;full   &lt;span class="c"&gt;# full mode (300 docs)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The booking agent works without GraphRAG. Deploy Stack 2 when hotel FAQ questions are frequent.&lt;/p&gt;




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

&lt;h3&gt;
  
  
  Step 1 — Clone and install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/elizabethfuentes12/why-agents-fail-sample-for-amazon-agentcore
&lt;span class="nb"&gt;cd &lt;/span&gt;why-agents-fail-sample-for-amazon-agentcore/06-agentcore-production-demo

uv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2 — Build and deploy
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./create_deployment_package.sh

&lt;span class="nb"&gt;cd &lt;/span&gt;cdk
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
cdk bootstrap   &lt;span class="c"&gt;# Only needed once per AWS account/region&lt;/span&gt;
cdk deploy HotelBookingAgentStack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3 — Store your OpenAI API key
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;a href="https://console.aws.amazon.com/secretsmanager/" rel="noopener noreferrer"&gt;AWS Secrets Manager Console&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Find &lt;code&gt;/HotelBookingAgentStack/openai-api-key&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set the secret value to your &lt;a href="https://platform.openai.com/api-keys" rel="noopener noreferrer"&gt;OpenAI API key&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 4 — Seed hotel data
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;span class="nv"&gt;AWS_DEFAULT_REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;us-east-1 uv run python seed_data.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5 — Test
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;test_agent_local.ipynb&lt;/code&gt; and run all cells. The notebook tests every anti-hallucination layer — see the Try It Yourself section for the full scenario list.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding GraphRAG (optional, separate stack)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Create a free Neo4j AuraDB instance at neo4j.com/cloud/aura-free&lt;/span&gt;
&lt;span class="c"&gt;# 2. Deploy the GraphRAG stack&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;cdk &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;INCLUDE_GRAPHRAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 cdk deploy GraphRAGStack

&lt;span class="c"&gt;# 3. Store Neo4j credentials in Secrets Manager (4 secrets)&lt;/span&gt;
&lt;span class="c"&gt;# 4. Build the knowledge graph&lt;/span&gt;
aws lambda invoke &lt;span class="nt"&gt;--function-name&lt;/span&gt; graphrag-build-graph &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 &lt;span class="nt"&gt;--cli-read-timeout&lt;/span&gt; 900 &lt;span class="se"&gt;\&lt;/span&gt;
    /tmp/build-graph-output.json

&lt;span class="c"&gt;# 5. Connect GraphRAG to the booking agent&lt;/span&gt;
cdk deploy HotelBookingAgentStack &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nv"&gt;graphrag_query_lambda_arn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;QueryLambdaArn from GraphRAGStack output&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;The repository includes &lt;a href="https://github.com/elizabethfuentes12/why-agents-fail-sample-for-amazon-agentcore/blob/main/06-agentcore-production-demo/test_agent_local.ipynb" rel="noopener noreferrer"&gt;&lt;code&gt;test_agent_local.ipynb&lt;/code&gt;&lt;/a&gt; — a notebook that tests every anti-hallucination layer against the deployed agent:&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;Scenario&lt;/th&gt;
&lt;th&gt;Technique (from series)&lt;/th&gt;
&lt;th&gt;What the agent does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Full booking flow&lt;/td&gt;
&lt;td&gt;All layers&lt;/td&gt;
&lt;td&gt;validate → book → pay → validate → confirm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;15 guests (max 10)&lt;/td&gt;
&lt;td&gt;Soft steering (demo 05)&lt;/td&gt;
&lt;td&gt;Self-corrects to 10, informs user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Confirm without payment&lt;/td&gt;
&lt;td&gt;Hard hook (demo 04)&lt;/td&gt;
&lt;td&gt;Blocks confirmation, asks to pay first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Sold-out hotel&lt;/td&gt;
&lt;td&gt;Grounded retrieval (demo 01)&lt;/td&gt;
&lt;td&gt;Returns "no rooms available" from DynamoDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;City with no hotels&lt;/td&gt;
&lt;td&gt;Grounded retrieval&lt;/td&gt;
&lt;td&gt;Returns "no hotels found", no fabrication&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Non-existent hotel&lt;/td&gt;
&lt;td&gt;Grounded retrieval&lt;/td&gt;
&lt;td&gt;Returns error, does not invent a hotel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Hotel amenities query&lt;/td&gt;
&lt;td&gt;Graph-RAG (demo 01)&lt;/td&gt;
&lt;td&gt;Cypher query returns real data from Neo4j&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;06-agentcore-production-demo
uv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
jupyter notebook test_agent_local.ipynb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run all cells top to bottom. The notebook reads the &lt;code&gt;AgentRuntimeArn&lt;/code&gt; from CloudFormation outputs automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Built-in Observability
&lt;/h2&gt;

&lt;p&gt;AgentCore provides &lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html" rel="noopener noreferrer"&gt;built-in observability&lt;/a&gt; when you include the OpenTelemetry dependencies in your agent package. Add &lt;code&gt;strands-agents[otel]&lt;/code&gt; and &lt;code&gt;aws-opentelemetry-distro&lt;/code&gt; to your agent's &lt;code&gt;requirements.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;strands-agents[openai,otel]&amp;gt;=1.27.0
aws-opentelemetry-distro&amp;gt;=0.7.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these dependencies, AgentCore automatically instruments Strands Agents — capturing invocation logs, tool call traces (which Lambda was called, input/output, latency), and error tracking (failed tool calls, guardrail blocks). You can monitor how the agent handles each anti-hallucination layer (steering, hooks, grounded retrieval) in &lt;a href="https://aws.amazon.com/cloudwatch/" rel="noopener noreferrer"&gt;Amazon CloudWatch&lt;/a&gt; without adding custom logging.&lt;/p&gt;

&lt;p&gt;See the &lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-get-started.html" rel="noopener noreferrer"&gt;observability getting started guide&lt;/a&gt; for details.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Fast Are the Anti-Hallucination Tools?
&lt;/h2&gt;

&lt;p&gt;Tool latency matters in production agents — every tool call adds to the end-to-end response time. If a&lt;br&gt;
  validation check takes 2 seconds, users notice. We benchmarked the deployed Lambda functions to measure real&lt;br&gt;
  execution duration (from CloudWatch REPORT lines, not CLI round-trip time).&lt;/p&gt;
&lt;h3&gt;
  
  
  DynamoDB-Backed Tools
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Cold Start&lt;/th&gt;
&lt;th&gt;Warm p50&lt;/th&gt;
&lt;th&gt;Warm p90&lt;/th&gt;
&lt;th&gt;Memory Used&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;validate_booking_rules&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~550–620 ms&lt;/td&gt;
&lt;td&gt;~25 ms&lt;/td&gt;
&lt;td&gt;~105 ms&lt;/td&gt;
&lt;td&gt;88 MB / 256 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;search_available_hotels&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~540–660 ms&lt;/td&gt;
&lt;td&gt;~16 ms&lt;/td&gt;
&lt;td&gt;~43 ms&lt;/td&gt;
&lt;td&gt;88 MB / 256 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The steering rules check (&lt;code&gt;validate_booking_rules&lt;/code&gt;) runs before every booking action. At &lt;strong&gt;~25 ms warm&lt;/strong&gt;, it adds negligible latency while preventing hallucinated bookings that violate business rules — a worthwhile trade-off vs. fixing bad bookings after the fact.&lt;/p&gt;
&lt;h3&gt;
  
  
  Neo4j AuraDB (GraphRAG)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Cold Start&lt;/th&gt;
&lt;th&gt;Warm p50&lt;/th&gt;
&lt;th&gt;Warm p90&lt;/th&gt;
&lt;th&gt;Memory Used&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;query_knowledge_graph&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~1.9–2.0 s&lt;/td&gt;
&lt;td&gt;~13 ms&lt;/td&gt;
&lt;td&gt;~75 ms&lt;/td&gt;
&lt;td&gt;122 MB / 256 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Neo4j AuraDB Free runs outside your VPC, but the &lt;a href="https://neo4j.com/docs/python-manual/current/" rel="noopener noreferrer"&gt;neo4j Python driver&lt;/a&gt; reuses TCP connections across warm invocations. After the first call resolves credentials from Secrets Manager and establishes the connection, subsequent Cypher queries execute in &lt;strong&gt;11–30 ms&lt;/strong&gt; — comparable to DynamoDB.&lt;/p&gt;
&lt;h3&gt;
  
  
  DynamoDB vs Neo4j AuraDB: Side by Side
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;DynamoDB (steering rules)&lt;/th&gt;
&lt;th&gt;Neo4j AuraDB (knowledge graph)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Warm p50&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~16–25 ms&lt;/td&gt;
&lt;td&gt;~13 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Warm p90&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~43–105 ms&lt;/td&gt;
&lt;td&gt;~75 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cold start&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~550–660 ms&lt;/td&gt;
&lt;td&gt;~1.9–2.0 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Driver reuse&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;boto3 (local)&lt;/td&gt;
&lt;td&gt;neo4j driver (TCP keepalive)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both backends deliver sub-100 ms warm latency, which means tool calls add minimal overhead to the agent's end-to-end response time. The cold start difference (~600 ms vs ~2 s) is only relevant for the first invocation after an idle period.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Benchmark methodology:&lt;/strong&gt; 10 consecutive invocations per function using &lt;code&gt;aws lambda invoke&lt;/code&gt; against the deployed stack in &lt;code&gt;us-east-1&lt;/code&gt;. Duration values extracted from CloudWatch Lambda REPORT log lines. Cold start = Init Duration + Duration. Warm = Duration only (no Init).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  5 Lessons from Moving Anti-Hallucination Techniques to Production
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Separate hard blocks from soft steers.&lt;/strong&gt; Payment-before-confirmation is a hard block: the agent cannot work around it. Guest count limits are a soft steer where the agent adjusts and completes the task. Mixing them in the same mechanism (all hooks or all prompts) either blocks too much or steers too little.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Store rules in a database, not in code.&lt;/strong&gt; Business rules change more frequently than agent code. When the maximum guest count changes from 10 to 8, an operations team should update a DynamoDB item, not open a pull request and wait for CI/CD.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Deploy stacks independently.&lt;/strong&gt; The booking agent works without GraphRAG. Independent stacks mean you can ship the core agent quickly and add capabilities when the use case demands it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Test locally against the same data.&lt;/strong&gt; The &lt;code&gt;test_agent_local.ipynb&lt;/code&gt; notebook calls the same DynamoDB tables as production. Run all 7 test scenarios locally before deploying to AgentCore. The behavior is identical.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Keep tools as pure CRUD (Create, Read, Update, Delete).&lt;/strong&gt; Lambda functions do one thing: read or write data. All business rule enforcement happens in the guardrail layers (hooks and validate tool). This keeps tools reusable and guardrails centralized.&lt;/p&gt;


&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hard hooks block&lt;/strong&gt; what the LLM must never bypass (financial, legal, compliance constraints)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Soft steering corrects&lt;/strong&gt; what the agent can adapt (capacity, dates, preferences) — reducing user friction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB steering rules&lt;/strong&gt; let operations teams change agent behavior without code deploys&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AgentCore Gateway&lt;/strong&gt; replaces custom tool-selection indexes with managed MCP-based semantic routing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graph-RAG on Neo4j AuraDB&lt;/strong&gt; eliminates fabricated aggregations by computing exact results with Cypher queries&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Clean Up
&lt;/h2&gt;

&lt;p&gt;To avoid ongoing charges:&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="nb"&gt;cd &lt;/span&gt;cdk
cdk destroy HotelBookingAgentStack
&lt;span class="nv"&gt;INCLUDE_GRAPHRAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 cdk destroy GraphRAGStack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is Amazon Bedrock AgentCore?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/bedrock/agentcore/" rel="noopener noreferrer"&gt;Amazon Bedrock AgentCore&lt;/a&gt; is a managed service for deploying and running AI agents. It provides two components: Runtime (hosts agent code) and Gateway (MCP-based tool routing that connects agents to serverless functions). AgentCore handles scaling, networking, and credential management so you do not need to build that infrastructure yourself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use Amazon Bedrock models instead of OpenAI?
&lt;/h3&gt;

&lt;p&gt;Yes. The agent supports any provider compatible with Strands Agents, including &lt;a href="https://aws.amazon.com/bedrock/" rel="noopener noreferrer"&gt;Amazon Bedrock&lt;/a&gt;, Anthropic, or Ollama. Change the model in &lt;code&gt;booking_agent.py&lt;/code&gt;. The anti-hallucination techniques work independently of the LLM provider.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between hard hooks and soft steering?
&lt;/h3&gt;

&lt;p&gt;Hard hooks use &lt;code&gt;event.cancel_tool&lt;/code&gt; to block tool execution at the framework level. The LLM cannot bypass them. Soft steering returns a STEER message that instructs the agent how to self-correct: the agent adjusts parameters and completes the task. Use hard hooks for financial and compliance rules. Use soft steering for operational rules where the agent can adapt.&lt;/p&gt;

&lt;h3&gt;
  
  
  How much does this architecture cost?
&lt;/h3&gt;

&lt;p&gt;All AWS services used (DynamoDB on-demand, Lambda, Secrets Manager) are eligible for the &lt;a href="https://aws.amazon.com/free/" rel="noopener noreferrer"&gt;AWS Free Tier&lt;/a&gt;. Neo4j AuraDB Free has a $0/month tier. For current pricing details, see the &lt;a href="https://aws.amazon.com/pricing/" rel="noopener noreferrer"&gt;AWS Pricing&lt;/a&gt; page. For a demo or low-traffic deployment, total infrastructure cost is minimal, excluding LLM API costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need GraphRAG for the agent to work?
&lt;/h3&gt;

&lt;p&gt;No. Stack 1 (&lt;code&gt;HotelBookingAgentStack&lt;/code&gt;) deploys a fully functional booking agent with search, booking, payment, and validation tools. GraphRAG (Stack 2) adds hotel FAQ capabilities. Deploy it when you need answers about amenities, policies, and services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I apply these patterns with other agent frameworks?
&lt;/h3&gt;

&lt;p&gt;Yes. The guardrail patterns (database-driven rules, hard hooks, and soft steering) are framework-agnostic. Strands provides native hook and MCP support, but LangGraph, AutoGen, and CrewAI offer similar extension points for tool interception and pre-validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does the agent discover tools via MCP at runtime?
&lt;/h3&gt;

&lt;p&gt;The agent connects to AgentCore Gateway using &lt;code&gt;MCPClient&lt;/code&gt; from Strands. On startup, it calls &lt;code&gt;list_tools_sync()&lt;/code&gt; to discover all available Lambda tools registered in the Gateway. When the agent needs a tool, the Gateway routes the call based on semantic matching. There is no hardcoded tool list in the agent code. Adding a new tool means registering it in the Gateway; the agent discovers it automatically on the next invocation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Research Background
&lt;/h2&gt;

&lt;p&gt;The techniques in this series are grounded in recent research on AI agent reliability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://arxiv.org/pdf/2503.13514" rel="noopener noreferrer"&gt;RAG-KG-IL: Multi-Agent Hybrid Framework for Reducing Hallucinations&lt;/a&gt; — Knowledge graphs reduce hallucinations compared to standalone LLMs&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://arxiv.org/abs/2601.05214" rel="noopener noreferrer"&gt;Internal Representations as Indicators of Hallucinations in Agent Tool Selection&lt;/a&gt; — Tool selection errors increase with tool count; semantic routing mitigates this&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://arxiv.org/pdf/2510.19507" rel="noopener noreferrer"&gt;Teaming LLMs to Detect and Mitigate Hallucinations&lt;/a&gt; — Multi-agent validation detects errors that single agents miss&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://arxiv.org/pdf/2509.09360" rel="noopener noreferrer"&gt;MetaRAG: Metamorphic Testing for Hallucination Detection&lt;/a&gt; — Hallucinations are inherent to LLMs without structured grounding&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;The complete code — CDK stacks, Lambda tools, agent runtime, steering rules, test notebook, and 300 hotel FAQ documents — is in the &lt;a href="https://github.com/elizabethfuentes12/why-agents-fail-sample-for-amazon-agentcore/tree/main/06-agentcore-production-demo" rel="noopener noreferrer"&gt;repository&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Gracias!&lt;/p&gt;

&lt;p&gt;🇻🇪🇨🇱 &lt;a href="https://dev.to/elizabethfuentes12"&gt;Dev.to&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/lizfue/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;a href="https://github.com/elizabethfuentes12/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; &lt;a href="https://twitter.com/elizabethfue12" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://www.instagram.com/elifue.tech" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; &lt;a href="https://www.youtube.com/channel/UCr0Gnc-t30m4xyrvsQpNp2Q" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aws</category>
      <category>python</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Tue, 24 Mar 2026 20:09:02 +0000</pubDate>
      <link>https://forem.com/elizabethfuentes12/-4ih1</link>
      <guid>https://forem.com/elizabethfuentes12/-4ih1</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/aws/escala-inteligente-con-microservicios-serverless-3lbe" class="crayons-story__hidden-navigation-link"&gt;Escala Inteligente con Microservicios Serverless&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/aws"&gt;
            &lt;img alt="AWS logo" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1726%2F2a73f1e6-7995-4348-ae37-44b064274c59.png" class="crayons-logo__image" width="320" height="320"&gt;
          &lt;/a&gt;

          &lt;a href="/hsaenzg" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F852908%2Fa3a10986-307b-4a35-8adf-eeb9a583e6a9.jpg" alt="hsaenzg profile" class="crayons-avatar__image" width="800" height="1066"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/hsaenzg" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Hazel Saenz
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Hazel Saenz
                
              
              &lt;div id="story-author-preview-content-3396326" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/hsaenzg" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F852908%2Fa3a10986-307b-4a35-8adf-eeb9a583e6a9.jpg" class="crayons-avatar__image" alt="" width="800" height="1066"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Hazel Saenz&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/aws" class="crayons-story__secondary fw-medium"&gt;AWS&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/aws/escala-inteligente-con-microservicios-serverless-3lbe" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 24&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/aws/escala-inteligente-con-microservicios-serverless-3lbe" id="article-link-3396326"&gt;
          Escala Inteligente con Microservicios Serverless
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/serverless"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;serverless&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/microservices"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;microservices&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/architecture"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;architecture&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/aws"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;aws&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/aws/escala-inteligente-con-microservicios-serverless-3lbe" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/aws/escala-inteligente-con-microservicios-serverless-3lbe#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            8 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>serverless</category>
      <category>microservices</category>
      <category>architecture</category>
      <category>aws</category>
    </item>
    <item>
      <title>Why AI Agents Fail: 3 Failure Modes That Cost You Tokens and Time</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Tue, 24 Mar 2026 02:14:33 +0000</pubDate>
      <link>https://forem.com/aws/why-ai-agents-fail-3-failure-modes-that-cost-you-tokens-and-time-1flb</link>
      <guid>https://forem.com/aws/why-ai-agents-fail-3-failure-modes-that-cost-you-tokens-and-time-1flb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;AI agents don't fail like traditional software — they don't crash with a stack trace. They fail silently: returning incomplete answers, freezing on slow APIs, or burning tokens calling the same tool over and over. The agent appears to work, but the output is wrong, late, or expensive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This series covers the three most common failure modes with research-backed solutions. Each technique has a runnable demo that measures the before/after difference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Working code:&lt;/strong&gt; &lt;a href="https://github.com/aws-samples/sample-why-agents-fail/tree/main/stop-ai-agents-wasting-tokens" rel="noopener noreferrer"&gt;github.com/aws-samples/sample-why-agents-fail&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The demos use &lt;a href="https://strandsagents.com" rel="noopener noreferrer"&gt;Strands Agents&lt;/a&gt; with &lt;a href="https://platform.openai.com/" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt; (GPT-4o-mini). The patterns are framework-agnostic — they apply to &lt;a href="https://langchain-ai.github.io/langgraph/" rel="noopener noreferrer"&gt;LangGraph&lt;/a&gt;, &lt;a href="https://github.com/microsoft/autogen" rel="noopener noreferrer"&gt;AutoGen&lt;/a&gt;, &lt;a href="https://github.com/crewAIInc/crewAI" rel="noopener noreferrer"&gt;CrewAI&lt;/a&gt;, or any framework that supports tool calling and lifecycle hooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  This Series: 3 Essential Fixes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Context Window Overflow&lt;/strong&gt; — Memory Pointer Pattern for large data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Tools That Never Respond&lt;/strong&gt; — Async handleId pattern for slow external APIs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Agent Reasoning Loops&lt;/strong&gt; — DebounceHook + clear tool states to block repeated calls&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What Happens When Tool Outputs Overflow the Context Window?
&lt;/h2&gt;

&lt;p&gt;Context window overflow occurs when a tool returns more data than the LLM can process — server logs, database results, or file contents that exceed the token limit. The agent does not crash with an error. It silently degrades: truncating data, losing context, or producing incomplete answers.&lt;/p&gt;

&lt;p&gt;Research from &lt;a href="https://arxiv.org/html/2511.22729v1" rel="noopener noreferrer"&gt;IBM&lt;/a&gt; quantifies this: a Materials Science workflow consumed &lt;strong&gt;20M tokens and failed&lt;/strong&gt;. The same workflow with memory pointers used &lt;strong&gt;1,234 tokens and succeeded&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz197w37u0rmuq1w3y3n9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz197w37u0rmuq1w3y3n9.jpg" alt="Comparison of an AI agent without Memory Pointer Pattern versus with it, showing how large data stays outside the context window"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix — Memory Pointer Pattern:&lt;/strong&gt; Store large data in &lt;code&gt;agent.state&lt;/code&gt;, return a short pointer to the context. The next tool resolves the pointer to access the full data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ToolContext&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_application_logs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_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_context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ToolContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hours&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;24&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;Fetch logs. Stores large data as pointer to avoid context overflow.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_logs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Could be 200KB+
&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="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logs&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;20_000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;pointer&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;logs-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;app_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;tool_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&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;Data stored as pointer &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pointer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;. Use analyze tools to query it.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&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;logs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;analyze_error_patterns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_pointer&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_context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ToolContext&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;Analyze errors — resolves pointer from agent.state.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tool_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_pointer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;if&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;level&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;ERROR&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Found &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;errors&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; errors across &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="nf"&gt;set&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;service&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;e&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; services&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The LLM never sees the 200KB — it only sees &lt;code&gt;"Data stored as pointer 'logs-payment-service'"&lt;/code&gt; (52 bytes).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why &lt;a href="https://strandsagents.com" rel="noopener noreferrer"&gt;Strands Agents&lt;/a&gt;?&lt;/strong&gt; The &lt;a href="https://strandsagents.com/docs/user-guide/concepts/tools/custom-tools/" rel="noopener noreferrer"&gt;&lt;code&gt;ToolContext&lt;/code&gt;&lt;/a&gt; API provides &lt;code&gt;agent.state&lt;/code&gt; as a native key-value store scoped to each agent — no global dictionaries, no external infrastructure. For multi-agent workflows, &lt;a href="https://strandsagents.com/docs/user-guide/concepts/multi-agent/multi-agent-patterns/" rel="noopener noreferrer"&gt;&lt;code&gt;invocation_state&lt;/code&gt;&lt;/a&gt; shares data across agents in a &lt;a href="https://strandsagents.com/docs/user-guide/concepts/multi-agent/swarm/" rel="noopener noreferrer"&gt;Swarm&lt;/a&gt; with the same API.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Without pointers&lt;/th&gt;
&lt;th&gt;With Memory Pointers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Data in context&lt;/td&gt;
&lt;td&gt;214KB (full logs)&lt;/td&gt;
&lt;td&gt;52 bytes (pointer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent behavior&lt;/td&gt;
&lt;td&gt;Truncates or fails&lt;/td&gt;
&lt;td&gt;Processes all data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Errors detected&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0vsn5ydchfhy6lu831d0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0vsn5ydchfhy6lu831d0.png" alt="Bar chart showing token usage across context management strategies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full demo:&lt;/strong&gt; &lt;a href="https://github.com/aws-samples/sample-why-agents-fail/tree/main/stop-ai-agents-wasting-tokens/01-context-overflow-demo" rel="noopener noreferrer"&gt;01-context-overflow-demo&lt;/a&gt; — single-agent and multi-agent (Swarm) implementations with notebooks.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Do AI Agents Freeze When Calling External APIs?
&lt;/h2&gt;

&lt;p&gt;AI agents freeze when MCP tools call slow or unresponsive external APIs. The agent blocks on the tool call, the user sees no progress, and after 7 seconds many implementations return a &lt;a href="https://community.openai.com/t/call-remote-mcp-server-tool-timed-out-resulting-in-error-424/1364167" rel="noopener noreferrer"&gt;424 error&lt;/a&gt;. &lt;a href="https://strandsagents.com/docs/user-guide/concepts/tools/mcp-tools/" rel="noopener noreferrer"&gt;MCP (Model Context Protocol)&lt;/a&gt; enables agents to call external tools, but does not handle timeout or retry by default.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frlvwpo26agw84bvi620c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frlvwpo26agw84bvi620c.jpg" alt="Synchronous MCP tool call showing agent blocked while waiting for slow API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix — Async handleId pattern:&lt;/strong&gt; The tool returns immediately with a job ID. The agent polls a separate &lt;code&gt;check_status&lt;/code&gt; tool:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.server.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="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;timeout-demo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;JOBS&lt;/span&gt; &lt;span class="o"&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;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start_long_job&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;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;Return handle immediately — prevents timeout.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;job_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uuid4&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="n"&gt;JOBS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;job_id&lt;/span&gt;&lt;span class="p"&gt;]&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;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;processing&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="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;_process_job&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job_id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# Background work
&lt;/span&gt;    &lt;span class="k"&gt;return&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;Job started. Handle: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;job_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Use check_job_status to poll.&lt;/span&gt;&lt;span class="sh"&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;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_job_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="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;Poll job status — returns &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;processing&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;completed&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; with result.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JOBS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job_id&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;job&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&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;FAILED: Job &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;job_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&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;job&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="nf"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;()&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;job&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;result&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;Still processing...&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Response time&lt;/th&gt;
&lt;th&gt;UX&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fast API (1s)&lt;/td&gt;
&lt;td&gt;3s total&lt;/td&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Slow API (15s)&lt;/td&gt;
&lt;td&gt;18s blocked&lt;/td&gt;
&lt;td&gt;Agent frozen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failing API&lt;/td&gt;
&lt;td&gt;424 error after 7s&lt;/td&gt;
&lt;td&gt;Agent crashes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Async handleId&lt;/td&gt;
&lt;td&gt;~4s (immediate + poll)&lt;/td&gt;
&lt;td&gt;Agent responsive&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1ef742j0hk1dcvuna54.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1ef742j0hk1dcvuna54.jpg" alt="Timeline visualization showing four MCP response patterns"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why &lt;a href="https://strandsagents.com" rel="noopener noreferrer"&gt;Strands Agents&lt;/a&gt;?&lt;/strong&gt; The &lt;a href="https://strandsagents.com/docs/user-guide/concepts/tools/mcp-tools/" rel="noopener noreferrer"&gt;&lt;code&gt;MCPClient&lt;/code&gt;&lt;/a&gt; connects to any MCP server with one line. The agent discovers tools at runtime via &lt;code&gt;list_tools_sync()&lt;/code&gt; — no hardcoded tool list. When the MCP server implements the async pattern, the agent automatically polls without extra orchestration code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full demo:&lt;/strong&gt; &lt;a href="https://github.com/aws-samples/sample-why-agents-fail/tree/main/stop-ai-agents-wasting-tokens/02-mcp-timeout-demo" rel="noopener noreferrer"&gt;02-mcp-timeout-demo&lt;/a&gt; — local MCP server with all 4 scenarios and notebook.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Do AI Agents Repeat the Same Tool Call?
&lt;/h2&gt;

&lt;p&gt;AI agent reasoning loops happen when the agent calls the same tool repeatedly with identical parameters, making no progress. The root cause is ambiguous tool feedback — responses like "more results may be available" make the agent think another call will produce better results. &lt;a href="https://the-decoder.com/language-models-can-overthink-and-get-stuck-in-endless-thought-loops/" rel="noopener noreferrer"&gt;Research shows&lt;/a&gt; agents can loop hundreds of times without delivering an answer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F76bs0qj49uby5z0t06np.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F76bs0qj49uby5z0t06np.jpg" alt="Diagram showing how ambiguous tool feedback causes loops versus how clear states and DebounceHook prevent them"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix 1 — Clear terminal states:&lt;/strong&gt; Tools return explicit &lt;code&gt;SUCCESS&lt;/code&gt; or &lt;code&gt;FAILED&lt;/code&gt; instead of ambiguous messages:&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;# Ambiguous (causes loops)
&lt;/span&gt;&lt;span class="k"&gt;return&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;Found flights: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. More results may be available.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Clear (agent stops)
&lt;/span&gt;&lt;span class="k"&gt;return&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;SUCCESS: Booked flight &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;conf_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;passenger&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Confirmation sent.&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;Fix 2 — DebounceHook:&lt;/strong&gt; Detect and block duplicate tool calls at the framework level:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.hooks.registry&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HookProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HookRegistry&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.hooks.events&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DebounceHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HookProvider&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Block duplicate tool calls in a sliding window.&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;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;window_size&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;window_size&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;register_hooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HookRegistry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;check_duplicate&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;check_duplicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_use&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;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="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_use&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;input&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;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&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="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cancel_tool&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;BLOCKED: Duplicate call to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_use&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="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_history&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;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_history&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window_size&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;Tool calls&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ambiguous feedback (baseline)&lt;/td&gt;
&lt;td&gt;14 calls&lt;/td&gt;
&lt;td&gt;No definitive answer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DebounceHook&lt;/td&gt;
&lt;td&gt;12 calls (2 blocked)&lt;/td&gt;
&lt;td&gt;Completes with blocks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clear SUCCESS states&lt;/td&gt;
&lt;td&gt;2 calls&lt;/td&gt;
&lt;td&gt;Immediate completion&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwgxbs8mu8tl83f1s9s2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwgxbs8mu8tl83f1s9s2.png" alt="Bar chart showing tool calls across different strategies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why &lt;a href="https://strandsagents.com" rel="noopener noreferrer"&gt;Strands Agents&lt;/a&gt;?&lt;/strong&gt; The &lt;a href="https://strandsagents.com/docs/user-guide/concepts/agents/hooks/" rel="noopener noreferrer"&gt;&lt;code&gt;HookProvider&lt;/code&gt;&lt;/a&gt; API intercepts tool calls via &lt;code&gt;BeforeToolCallEvent&lt;/code&gt; before they execute. Setting &lt;code&gt;event.cancel_tool&lt;/code&gt; blocks execution at the framework level — the LLM cannot bypass it. This makes hooks composable: stack DebounceHook, LimitToolCounts, and custom validators on the same agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full demo:&lt;/strong&gt; &lt;a href="https://github.com/aws-samples/sample-why-agents-fail/tree/main/stop-ai-agents-wasting-tokens/03-reasoning-loops-demo" rel="noopener noreferrer"&gt;03-reasoning-loops-demo&lt;/a&gt; — all 4 scenarios with hooks and notebook.&lt;/p&gt;


&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;You need &lt;a href="https://python.org/downloads" rel="noopener noreferrer"&gt;Python 3.9+&lt;/a&gt;, &lt;a href="https://docs.astral.sh/uv/" rel="noopener noreferrer"&gt;uv&lt;/a&gt; (a fast Python package manager), and an &lt;a href="https://platform.openai.com/api-keys" rel="noopener noreferrer"&gt;OpenAI API key&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/aws-samples/sample-why-agents-fail
&lt;span class="nb"&gt;cd &lt;/span&gt;sample-why-agents-fail/stop-ai-agents-wasting-tokens

&lt;span class="c"&gt;# Pick any demo&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;01-context-overflow-demo   &lt;span class="c"&gt;# or 02-mcp-timeout-demo, 03-reasoning-loops-demo&lt;/span&gt;
uv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-key-here"&lt;/span&gt;

uv run python test_&lt;span class="k"&gt;*&lt;/span&gt;.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Each demo is self-contained with its own dependencies, test script, and &lt;a href="https://jupyter.org/" rel="noopener noreferrer"&gt;Jupyter&lt;/a&gt; notebook.&lt;/p&gt;


&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;
&lt;h3&gt;
  
  
  What are the most common AI agent failure modes?
&lt;/h3&gt;

&lt;p&gt;The three most common failure modes are context window overflow (tool returns more data than the LLM can process), MCP tool timeouts (external APIs block the agent indefinitely), and reasoning loops (agent repeats the same tool call without progress). Each failure mode causes token waste and degrades response quality.&lt;/p&gt;
&lt;h3&gt;
  
  
  How do I reduce AI agent token costs?
&lt;/h3&gt;

&lt;p&gt;The two most effective techniques are memory pointers and clear tool states. The Memory Pointer Pattern stores large tool outputs in external state and passes short references to the LLM context — reducing token usage from 200KB+ to under 100 bytes per tool call. Clear terminal states (&lt;code&gt;SUCCESS&lt;/code&gt;/&lt;code&gt;FAILED&lt;/code&gt;) in tool responses prevent the agent from retrying completed operations, which can reduce tool calls from 14 to 2.&lt;/p&gt;
&lt;h3&gt;
  
  
  Can I use these patterns with frameworks other than Strands Agents?
&lt;/h3&gt;

&lt;p&gt;Yes. The Memory Pointer Pattern works with any framework that supports tool context (passing state between tools). The async handleId pattern is an MCP server design pattern — it works with any MCP-compatible agent. DebounceHook requires lifecycle hooks, which are available in &lt;a href="https://langchain-ai.github.io/langgraph/" rel="noopener noreferrer"&gt;LangGraph&lt;/a&gt;, &lt;a href="https://github.com/microsoft/autogen" rel="noopener noreferrer"&gt;AutoGen&lt;/a&gt;, and &lt;a href="https://github.com/crewAIInc/crewAI" rel="noopener noreferrer"&gt;CrewAI&lt;/a&gt; with different APIs.&lt;/p&gt;


&lt;h2&gt;
  
  
  References
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Research
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://arxiv.org/html/2511.22729v1" rel="noopener noreferrer"&gt;Solving Context Window Overflow in AI Agents&lt;/a&gt; — IBM Research, Nov 2025&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://arxiv.org/pdf/2412.05449" rel="noopener noreferrer"&gt;Towards Effective GenAI Multi-Agent Collaboration&lt;/a&gt; — Amazon, Dec 2024&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://octopus.com/blog/mcp-timeout-retry" rel="noopener noreferrer"&gt;Resilient AI Agents With MCP&lt;/a&gt; — Octopus, May 2025&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://the-decoder.com/language-models-can-overthink-and-get-stuck-in-endless-thought-loops/" rel="noopener noreferrer"&gt;Language models can overthink&lt;/a&gt; — The Decoder, Jan 2025&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://strandsagents.com/docs/user-guide/concepts/agents/state/" rel="noopener noreferrer"&gt;Strands Agent State&lt;/a&gt; — ToolContext and agent.state&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://strandsagents.com/docs/user-guide/concepts/tools/mcp-tools/" rel="noopener noreferrer"&gt;Strands MCP Tools&lt;/a&gt; — Connect any MCP server&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://strandsagents.com/docs/user-guide/concepts/agents/hooks/" rel="noopener noreferrer"&gt;Strands Hooks&lt;/a&gt; — Lifecycle events and tool cancellation&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Which failure mode have you hit in your agents? Share in the comments.&lt;/p&gt;



&lt;p&gt;Gracias!&lt;/p&gt;

&lt;p&gt;🇻🇪🇨🇱 &lt;a href="https://dev.to/elizabethfuentes12"&gt;Dev.to&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/lizfue/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;a href="https://github.com/elizabethfuentes12/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; &lt;a href="https://twitter.com/elizabethfue12" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://www.instagram.com/elifue.tech" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; &lt;a href="https://www.youtube.com/channel/UCr0Gnc-t30m4xyrvsQpNp2Q" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;&lt;br&gt;
&lt;a href="https://linktr.ee/elizabethfuentesleone" rel="noopener noreferrer"&gt;Linktr&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag__user ltag__user__id__717518"&gt;
    &lt;a href="/elizabethfuentes12" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717518%2Fb550b165-b8b9-405d-acfb-e5dc846765b0.png" alt="elizabethfuentes12 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/elizabethfuentes12"&gt;Elizabeth Fuentes L&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/elizabethfuentes12"&gt;I help developers build production-ready AI applications through hands-on tutorials and open-source projects.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>ai</category>
      <category>python</category>
      <category>agents</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Reduce errores y costos de tokens en agentes con seleccion semantica de herramientas</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Mon, 23 Mar 2026 16:25:05 +0000</pubDate>
      <link>https://forem.com/aws-espanol/reduce-errores-y-costos-de-tokens-en-agentes-con-seleccion-semantica-de-herramientas-12o5</link>
      <guid>https://forem.com/aws-espanol/reduce-errores-y-costos-de-tokens-en-agentes-con-seleccion-semantica-de-herramientas-12o5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cuando los agentes de IA tienen muchas herramientas similares, a menudo seleccionan la incorrecta y consumen tokens excesivos al procesar todas las descripciones de herramientas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este articulo demuestra como la seleccion semantica de herramientas filtra tools antes del procesamiento del agente, mejorando la precision y reduciendo costos de tokens. La demostracion utiliza Strands Agents y FAISS para filtrar 29 herramientas y quedarse con las 3 mas relevantes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Esta demo utiliza Strands Agents. Patrones similares se pueden aplicar en LangGraph, AutoGen u otros frameworks de agentes.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Vision general de la serie
&lt;/h2&gt;

&lt;p&gt;Esta es la Parte 2 de una serie sobre como detener las hallucinations en agentes de IA:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws-espanol/rag-vs-graphrag-cuando-los-agentes-alucinan-respuestas-1mlj"&gt;RAG vs Graph-RAG&lt;/a&gt;&lt;/strong&gt; — Knowledge graphs para prevenir hallucinations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seleccion semantica de herramientas&lt;/strong&gt; (este articulo) — Filtrado de tools basado en vectores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/how-to-stop-ai-agents-from-hallucinating-silently-with-multi-agent-validation-3f7e"&gt;Validacion multi-agente&lt;/a&gt;&lt;/strong&gt; — Deteccion de hallucinations basada en equipos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/ai-agent-guardrails-rules-that-llms-cannot-bypass-596d"&gt;AI Agent Guardrails&lt;/a&gt;&lt;/strong&gt; — Aplicacion de razonamiento simbolico&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/aws/runtime-guardrails-for-ai-agents-steer-dont-block-278n"&gt;Runtime Guardrails&lt;/a&gt;&lt;/strong&gt; — Controles autocorrectivos&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Configuracion
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/aws-samples/sample-why-agents-fail
&lt;span class="nb"&gt;cd &lt;/span&gt;stop-ai-agent-hallucinations/02-semantic-tools-demo
uv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  El problema dual: errores + desperdicio de tokens
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Escenario del problema
&lt;/h3&gt;

&lt;p&gt;Un agente de viajes con 29 herramientas similares (&lt;code&gt;search_hotels&lt;/code&gt;, &lt;code&gt;search_flights&lt;/code&gt;, &lt;code&gt;search_hotel_reviews&lt;/code&gt;, etc.) recibe la consulta: "How much does Hotel Marriott cost?"&lt;/p&gt;

&lt;p&gt;El agente puede seleccionar &lt;code&gt;get_hotel_details()&lt;/code&gt; en lugar de &lt;code&gt;get_hotel_pricing()&lt;/code&gt; — una seleccion incorrecta de tool. Este error consume 4,500 tokens procesando las descripciones de las 29 herramientas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Causas raiz
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Nombres de herramientas similares causan confusion&lt;/li&gt;
&lt;li&gt;Las herramientas genericas se usan en exceso&lt;/li&gt;
&lt;li&gt;Mas herramientas aumentan la probabilidad de hallucination&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Contexto de investigacion
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Las hallucinations en la seleccion de herramientas aumentan con la cantidad de tools. Sistemas en produccion reportan una reduccion del 89% en tokens con seleccion semantica de herramientas."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  La solucion: seleccion semantica de herramientas con FAISS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Modos de falla de agentes a escala
&lt;/h3&gt;

&lt;p&gt;La investigacion identifica cinco modos criticos de falla:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Errores de seleccion de funcion&lt;/strong&gt; — Llamar a tools inexistentes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Errores de parametros&lt;/strong&gt; — Argumentos mal formados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Errores de completitud&lt;/strong&gt; — Parametros requeridos faltantes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comportamiento de bypass de tools&lt;/strong&gt; — Generar respuestas en lugar de llamar herramientas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desbordamiento de contexto&lt;/strong&gt; — Desperdicio de tokens al procesar todas las descripciones&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Analisis costo-beneficio
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Cada llamada al LLM envia las descripciones de las 29 herramientas&lt;/li&gt;
&lt;li&gt;En un flujo de 50 pasos: 29 tools x 50 llamadas&lt;/li&gt;
&lt;li&gt;Genera un desperdicio significativo de tokens y retrasos en el procesamiento&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;La investigacion muestra hasta un 86.4% de precision previniendo hallucinations en la seleccion de herramientas en sistemas de produccion.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Demostracion: tres enfoques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prueba 1: Enfoque tradicional (las 29 herramientas)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="c1"&gt;# Using OpenAI-compatible interface via Strands SDK (not direct OpenAI usage)
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIModel&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;enhanced_tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ALL_TOOLS&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TESTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ALL_TOOLS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PROMPT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;run_and_capture_with_tokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Resultado&lt;/strong&gt;: ~1,557 tokens promedio por consulta con precision variable.&lt;/p&gt;




&lt;h3&gt;
  
  
  Prueba 2: Enfoque semantico (top-3 herramientas filtradas)
&lt;/h3&gt;

&lt;p&gt;El agente recibe unicamente las 3 herramientas mas relevantes por consulta.&lt;/p&gt;

&lt;h4&gt;
  
  
  Construccion del indice FAISS
&lt;/h4&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;faiss&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sentence_transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&lt;/span&gt;

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SentenceTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;all-MiniLM-L6-v2&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;build_index&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="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Build FAISS index from tool docstrings&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;texts&lt;/span&gt; &lt;span class="o"&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="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__doc__&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;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;faiss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IndexFlatL2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&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="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;float32&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;index&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_tools&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;top_k&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="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Find most relevant tools using FAISS&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;emb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&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="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;emb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;float32&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;top_k&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="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;indices&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;El modelo all-MiniLM-L6-v2 es ligero (22M parametros, 384 dimensiones), optimizado para similitud semantica y funciona de manera eficiente en CPUs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Filtrado en tiempo de ejecucion
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="c1"&gt;# Using OpenAI-compatible interface via Strands SDK (not direct OpenAI usage)
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIModel&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TESTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search_tools&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="n"&gt;top_k&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="n"&gt;selected_names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PROMPT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;run_and_capture_with_tokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Resultado&lt;/strong&gt;: ~275 tokens promedio por consulta — una reduccion desde 1,557 tokens.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dato clave: el agente nunca procesa las otras 26 herramientas. Estas tools permanecen en el sistema pero nunca entran en la ventana de contexto del agente.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Prueba 3: Semantico + memoria (agente unico)
&lt;/h3&gt;

&lt;p&gt;Para conversaciones multi-turno en produccion, manteniendo la memoria mientras se intercambian herramientas dinamicamente.&lt;/p&gt;

&lt;h4&gt;
  
  
  Intercambio dinamico de herramientas
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;swap_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_tools&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Swap tools in a live agent without losing conversation memory.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;reg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_registry&lt;/span&gt;
    &lt;span class="n"&gt;reg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;reg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dynamic_tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&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;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;new_tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;reg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Implementacion completa
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="c1"&gt;# Using OpenAI-compatible interface via Strands SDK (not direct OpenAI usage)
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.models.openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAIModel&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;enhanced_tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ALL_TOOLS&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;build_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;search_tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;swap_tools&lt;/span&gt;

&lt;span class="n"&gt;initial_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TESTS&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;top_k&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="n"&gt;memory_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;initial_tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PROMPT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MODEL&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;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TESTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search_tools&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="n"&gt;top_k&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="nf"&gt;swap_tools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memory_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;selected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;run_and_capture_with_tokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memory_agent&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Resultado&lt;/strong&gt;: Mas tokens que el enfoque solo semantico (debido al contexto acumulado), pero significativamente menos comparado con el metodo tradicional, manteniendo el historial completo de la conversacion.&lt;/p&gt;

&lt;h4&gt;
  
  
  Por que funciona
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Strands llama a &lt;code&gt;tool_registry.get_all_tools_config()&lt;/code&gt; en cada ciclo del event loop, detectando automaticamente los cambios en tiempo de ejecucion.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Ventajas&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cero perdida de conversacion: &lt;code&gt;agent.messages&lt;/code&gt; se preserva entre intercambios de tools&lt;/li&gt;
&lt;li&gt;No requiere recrear el agente&lt;/li&gt;
&lt;li&gt;Flexibilidad en tiempo de ejecucion para necesidades dinamicas de herramientas&lt;/li&gt;
&lt;li&gt;Listo para produccion en conversaciones largas&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Contexto de investigacion y rendimiento en el mundo real
&lt;/h2&gt;

&lt;p&gt;La demo controlada logro precision perfecta en 13 consultas. Sin embargo, los sistemas de produccion reales con cientos de herramientas y consultas ambiguas muestran resultados diferentes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"La investigacion muestra que en sistemas de produccion con cientos de herramientas, la seleccion semantica de tools alcanza hasta un 86.4% de precision en la deteccion y prevencion de hallucinations en la seleccion de herramientas."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esto reduce significativamente los errores comparado con los enfoques tradicionales (que caen por debajo del 50% de precision con mas de 100 tools), pero sigue siendo un desafio en dominios con semantica de herramientas superpuesta.&lt;/p&gt;




&lt;h2&gt;
  
  
  Siguiente paso
&lt;/h2&gt;

&lt;p&gt;La seleccion semantica de herramientas reduce los errores de seleccion de tools y los costos de tokens. Sin embargo, los agentes aun pueden generar hallucinations sobre el &lt;strong&gt;exito de operaciones&lt;/strong&gt; (por ejemplo, confirmar reservaciones sin procesar pagos o ignorar reglas de negocio).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parte 3: Validacion multi-agente&lt;/strong&gt; demuestra como equipos especializados de agentes (Executor -&amp;gt; Validator -&amp;gt; Critic) detectan hallucinations antes de que lleguen a los usuarios.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Esta capacidad esta disponible de forma nativa a traves de &lt;a href="https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway.html" rel="noopener noreferrer"&gt;Amazon Bedrock Agentcore Gateway&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Puntos clave
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Problema dual&lt;/strong&gt;: Errores en la seleccion de herramientas Y desperdicio de tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduccion significativa de errores&lt;/strong&gt;: Menos herramientas = menos selecciones incorrectas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;89% de ahorro en tokens&lt;/strong&gt;: Reduciendo de 29 a 3 herramientas por llamada&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implementacion sencilla&lt;/strong&gt;: ~20 lineas de codigo con FAISS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integracion con Strands&lt;/strong&gt;: El decorador &lt;code&gt;@tool&lt;/code&gt; y la carga dinamica permiten el filtrado semantico con intercambio de herramientas en tiempo de ejecucion&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Ejecutalo tu mismo
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/aws-samples/sample-why-agents-fail
&lt;span class="nb"&gt;cd &lt;/span&gt;stop-ai-agent-hallucinations/02-semantic-tools-demo
uv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
uv run test_semantic_tool_selection.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Puedes cambiar a cualquier proveedor soportado por Strands — consulta &lt;a href="https://strandsagents.com/latest/documentation/docs/user-guide/concepts/model-providers/" rel="noopener noreferrer"&gt;Strands Model Providers&lt;/a&gt; para la configuracion.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Investigacion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/pdf/2601.05214" rel="noopener noreferrer"&gt;Internal Representations as Indicators of Hallucinations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://arxiv.org/html/2511.22729v1" rel="noopener noreferrer"&gt;Solving Context Window Overflow&lt;/a&gt; — Reduccion de tokens 7x&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.rconnect.tech/blog/semantic-tool-selection-guide" rel="noopener noreferrer"&gt;Semantic Tool Selection in Practice&lt;/a&gt; — Reduccion del 89%&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Strands Agents
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://strandsagents.com" rel="noopener noreferrer"&gt;Strands Agents Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://strandsagents.com/latest/documentation/docs/examples/python/meta_tooling/" rel="noopener noreferrer"&gt;Strands Meta-Tooling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://strandsagents.com/latest/documentation/docs/user-guide/concepts/model-providers/" rel="noopener noreferrer"&gt;Strands Model Providers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Codigo
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/aws-samples/sample-why-agents-fail" rel="noopener noreferrer"&gt;Repositorio de codigo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Gracias!&lt;/p&gt;

&lt;p&gt;🇻🇪🇨🇱 &lt;a href="https://dev.to/elizabethfuentes12"&gt;Dev.to&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/lizfue/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;a href="https://github.com/elizabethfuentes12/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; &lt;a href="https://twitter.com/elizabethfue12" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://www.instagram.com/elifue.tech" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; &lt;a href="https://www.youtube.com/channel/UCr0Gnc-t30m4xyrvsQpNp2Q" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>agents</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Sat, 21 Mar 2026 15:03:44 +0000</pubDate>
      <link>https://forem.com/elizabethfuentes12/-33p8</link>
      <guid>https://forem.com/elizabethfuentes12/-33p8</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/aws-espanol/deten-las-hallucinations-de-ai-agents-4-tecnicas-esenciales-3kcl" class="crayons-story__hidden-navigation-link"&gt;Detén las Hallucinations en Agentes de IA: 4 Técnicas Esenciales&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/aws-espanol"&gt;
            &lt;img alt="AWS Español logo" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F7402%2F04f86f58-db61-410f-8eda-06b0c052f17f.jpeg" class="crayons-logo__image" width="600" height="600"&gt;
          &lt;/a&gt;

          &lt;a href="/elizabethfuentes12" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717518%2Fb550b165-b8b9-405d-acfb-e5dc846765b0.png" alt="elizabethfuentes12 profile" class="crayons-avatar__image" width="420" height="420"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/elizabethfuentes12" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Elizabeth Fuentes L
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Elizabeth Fuentes L
                
              
              &lt;div id="story-author-preview-content-3365188" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/elizabethfuentes12" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717518%2Fb550b165-b8b9-405d-acfb-e5dc846765b0.png" class="crayons-avatar__image" alt="" width="420" height="420"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Elizabeth Fuentes L&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/aws-espanol" class="crayons-story__secondary fw-medium"&gt;AWS Español&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/aws-espanol/deten-las-hallucinations-de-ai-agents-4-tecnicas-esenciales-3kcl" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Mar 18&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/aws-espanol/deten-las-hallucinations-de-ai-agents-4-tecnicas-esenciales-3kcl" id="article-link-3365188"&gt;
          Detén las Hallucinations en Agentes de IA: 4 Técnicas Esenciales
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/agents"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;agents&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/aws-espanol/deten-las-hallucinations-de-ai-agents-4-tecnicas-esenciales-3kcl" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;11&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/aws-espanol/deten-las-hallucinations-de-ai-agents-4-tecnicas-esenciales-3kcl#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>agents</category>
      <category>ai</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Wed, 18 Mar 2026 01:08:21 +0000</pubDate>
      <link>https://forem.com/elizabethfuentes12/-3e60</link>
      <guid>https://forem.com/elizabethfuentes12/-3e60</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/aws" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__org__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1726%2F1f5cc5bc-5f61-428d-9d35-ba0c39f8af2d.png" alt="AWS" width="500" height="500"&gt;
      &lt;div class="ltag__link__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F852908%2Fa3a10986-307b-4a35-8adf-eeb9a583e6a9.jpg" alt="" width="800" height="1066"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/aws/cold-starts-en-aws-lambda-que-son-por-que-ocurren-y-como-solucionarlos-13no" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Cold Starts en AWS Lambda: Qué son, por qué ocurren y cómo solucionarlos&lt;/h2&gt;
      &lt;h3&gt;Hazel Saenz for AWS ・ Mar 16&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#lambda&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#performance&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#español&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#aws&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>lambda</category>
      <category>performance</category>
      <category>español</category>
      <category>aws</category>
    </item>
    <item>
      <title>RAG vs GraphRAG: Cuando los Agentes Alucinan Respuestas</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Wed, 18 Mar 2026 01:05:06 +0000</pubDate>
      <link>https://forem.com/aws-espanol/rag-vs-graphrag-cuando-los-agentes-alucinan-respuestas-1mlj</link>
      <guid>https://forem.com/aws-espanol/rag-vs-graphrag-cuando-los-agentes-alucinan-respuestas-1mlj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Un agent que alucina durante la ejecucion es catastrofico: podria fabricar parametros de API, inventar confirmaciones de exito tras fallos, o ejecutar acciones basadas en creencias falsas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este articulo explora como el Retrieval-Augmented Generation (RAG) tradicional provoca que los AI agents alucinen estadisticas y agregaciones, en contraste con GraphRAG usando knowledge graphs de Neo4j. Demostramos las diferencias a traves de un agent de reservas de viajes que compara RAG (FAISS) frente a GraphRAG sobre 300 documentos FAQ de hoteles.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Esta demo utiliza Strands Agents. Patrones similares se pueden aplicar en LangGraph, AutoGen u otros frameworks de agents.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Vision General de la Serie
&lt;/h2&gt;

&lt;p&gt;Esta es la Parte 1 de una serie sobre como detener las hallucinations en AI agents:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;RAG vs Graph-RAG&lt;/strong&gt; (este articulo) — Los knowledge graphs previenen agregaciones alucinadas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic Tool Selection&lt;/strong&gt; — El filtrado vectorial reduce las elecciones incorrectas de tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Agent Validation&lt;/strong&gt; — Los swarms detectan hallucinations antes de que lleguen a los usuarios&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Agent Guardrails&lt;/strong&gt; — Reglas simbolicas que el LLM no puede eludir&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime Guardrails&lt;/strong&gt; — Dirigir en lugar de bloquear&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  El Problema: Tres Tipos de Hallucinations en RAG
&lt;/h2&gt;

&lt;p&gt;La investigacion (&lt;a href="https://arxiv.org/pdf/2509.09360" rel="noopener noreferrer"&gt;MetaRAG: Metamorphic Testing for Hallucination Detection&lt;/a&gt;) identifica tres tipos de hallucination en sistemas RAG:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Estadisticas fabricadas&lt;/strong&gt; — Los sistemas RAG producen numeros estimados en lugar de valores calculados. El LLM adivina agregaciones a partir de unos pocos documentos recuperados en vez de calcularlas sobre el conjunto completo de datos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recuperacion incompleta&lt;/strong&gt; — La busqueda vectorial recupera los top-k fragmentos mas similares, pero los datos necesarios para una respuesta pueden estar dispersos en muchos documentos. El LLM llena los vacios con fabricaciones que suenan plausibles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fabricacion fuera de dominio&lt;/strong&gt; — Cuando no existen datos relevantes, RAG devuelve los resultados de apariencia mas similar de todos modos. El LLM trata estas coincidencias parciales como contexto valido y fabrica una respuesta con confianza.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  La Solucion: GraphRAG con Knowledge Graphs
&lt;/h2&gt;

&lt;p&gt;Los knowledge graphs resuelven estos problemas a nivel arquitectonico:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Las agregaciones&lt;/strong&gt; son calculadas por el motor de base de datos (AVG, COUNT, SUM) — no adivinadas por el LLM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Las relaciones&lt;/strong&gt; son aristas explicitas en el grafo — no inferidas por similitud de texto&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Los datos faltantes&lt;/strong&gt; devuelven resultados vacios — el LLM recibe "no se encontraron resultados" en lugar de coincidencias parciales de las cuales alucinar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La diferencia clave: RAG siempre devuelve algo. GraphRAG devuelve resultados vacios cuando los datos no existen.&lt;/p&gt;




&lt;h2&gt;
  
  
  Requisitos Previos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.9+&lt;/li&gt;
&lt;li&gt;Neo4j ejecutandose localmente con el plugin APOC&lt;/li&gt;
&lt;li&gt;Clave de API de OpenAI (o cualquier proveedor de modelos compatible con Strands)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/aws-samples/sample-why-agents-fail
&lt;span class="nb"&gt;cd &lt;/span&gt;stop-ai-agent-hallucinations/01-faq-graphrag-demo
uv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Implementacion
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Agent 1: RAG Tradicional (FAISS)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_faqs&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="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;Search hotel FAQs using vector similarity.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;query_embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embed_model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&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="n"&gt;distances&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;float32&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="k"&gt;return&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="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&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="mi"&gt;500&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;idx&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;indices&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="n"&gt;rag_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&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="n"&gt;search_faqs&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El agent RAG recupera los 3 documentos mas similares y permite que el LLM los resuma. No puede agregar sobre el conjunto completo de datos, recorrer relaciones ni reconocer cuando los datos estan ausentes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agent 2: GraphRAG (Neo4j + Cypher)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query_knowledge_graph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cypher_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="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Execute a Cypher query against the hotel knowledge graph.

    Node labels: Hotel, Room, Amenity, Policy, Service
    Relationships: (Hotel)-[:HAS_ROOM]-&amp;gt;(Room), (Hotel)-[:OFFERS_AMENITY]-&amp;gt;(Amenity),
                   (Hotel)-[:HAS_POLICY]-&amp;gt;(Policy), (Hotel)-[:PROVIDES_SERVICE]-&amp;gt;(Service)

    Properties:
    - Hotel: name, location, rating, price_range
    - Room: type, capacity, price_per_night
    - Amenity: name, category
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&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;session&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;span class="n"&gt;cypher_query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;records&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;No results found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;return&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;Found &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;records&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; results:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&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="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;records&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;graph_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&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="n"&gt;query_knowledge_graph&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El schema en el docstring habilita Text2Cypher — el LLM genera consultas Cypher precisas en lugar de adivinar a partir de fragmentos de texto.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resultados: 4 Escenarios de Prueba
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prueba 1: Agregacion — "What is the average hotel rating in Paris?"
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Enfoque&lt;/th&gt;
&lt;th&gt;Resultado&lt;/th&gt;
&lt;th&gt;Por que&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RAG&lt;/td&gt;
&lt;td&gt;4.7 (de solo 2 documentos)&lt;/td&gt;
&lt;td&gt;Recupero 2 documentos similares y promedio esas calificaciones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GraphRAG&lt;/td&gt;
&lt;td&gt;4.7 (a nivel de base de datos) ✅&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;MATCH (h:Hotel {location:'Paris'}) RETURN avg(h.rating)&lt;/code&gt; — calculado sobre todos los hoteles&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;RAG tuvo suerte aqui — mismo numero, pero de 2 documentos en vez del conjunto completo de datos. Con datos diferentes, esto divergiria.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prueba 2: Conteo — "How many hotels have a swimming pool?"
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Enfoque&lt;/th&gt;
&lt;th&gt;Resultado&lt;/th&gt;
&lt;th&gt;Por que&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RAG&lt;/td&gt;
&lt;td&gt;"No tengo los datos" ❌&lt;/td&gt;
&lt;td&gt;Los 3 documentos principales no mencionaban piscinas; no pudo contar entre 300 documentos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GraphRAG&lt;/td&gt;
&lt;td&gt;"133 hoteles" ✅&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MATCH (h)-[:OFFERS_AMENITY]-&amp;gt;(a {name:'pool'}) RETURN count(h)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Prueba 3: Multi-hop — "What room types does the highest-rated hotel offer?"
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Enfoque&lt;/th&gt;
&lt;th&gt;Resultado&lt;/th&gt;
&lt;th&gt;Por que&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RAG&lt;/td&gt;
&lt;td&gt;Incompleto ⚠️&lt;/td&gt;
&lt;td&gt;Encontro informacion del hotel pero no pudo recorrer hasta los datos de habitaciones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GraphRAG&lt;/td&gt;
&lt;td&gt;Completo con datos de habitaciones ✅&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MATCH (h:Hotel) WITH h ORDER BY h.rating DESC LIMIT 1 MATCH (h)-[:HAS_ROOM]-&amp;gt;(r) RETURN r&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Prueba 4: Fuera de dominio — "Find hotels in Antarctica"
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Enfoque&lt;/th&gt;
&lt;th&gt;Resultado&lt;/th&gt;
&lt;th&gt;Por que&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RAG&lt;/td&gt;
&lt;td&gt;Fabrico "Estaciones de Investigacion" como hoteles ❌&lt;/td&gt;
&lt;td&gt;Devolvio documentos de apariencia similar sobre alojamiento en clima frio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GraphRAG&lt;/td&gt;
&lt;td&gt;"No se encontraron hoteles" ✅&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;MATCH (h:Hotel {location:'Antarctica'}) RETURN h&lt;/code&gt; — resultado vacio&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Cuando Usar Cada Enfoque
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criterio&lt;/th&gt;
&lt;th&gt;RAG&lt;/th&gt;
&lt;th&gt;GraphRAG&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Estructura de datos&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Texto no estructurado, documentos&lt;/td&gt;
&lt;td&gt;Estructurado, con relaciones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tipo de consulta&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Similitud semantica, busqueda difusa&lt;/td&gt;
&lt;td&gt;Agregaciones precisas, recorridos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Datos faltantes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Devuelve resultados similares (riesgo de hallucination)&lt;/td&gt;
&lt;td&gt;Devuelve vacio (fallo honesto)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complejidad de configuracion&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Menor (embeddings + vector store)&lt;/td&gt;
&lt;td&gt;Mayor (knowledge graph + schema)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ideal para&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Busqueda de contenido, Q&amp;amp;A sobre documentos&lt;/td&gt;
&lt;td&gt;Analitica, razonamiento multi-hop, verificacion&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Conclusiones Clave
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;RAG siempre devuelve algo — incluso cuando los datos no existen, creando oportunidades de hallucination&lt;/li&gt;
&lt;li&gt;GraphRAG devuelve resultados vacios cuando los datos estan ausentes — forzando respuestas honestas de "No lo se"&lt;/li&gt;
&lt;li&gt;Las agregaciones deben ser calculadas por la base de datos, no adivinadas por el LLM&lt;/li&gt;
&lt;li&gt;El schema en el docstring del tool habilita Text2Cypher — consultas precisas en lugar de similitud de texto&lt;/li&gt;
&lt;li&gt;Ambos enfoques tienen su lugar — usa RAG para busqueda semantica, GraphRAG para recuperacion precisa de datos&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Siguiente Paso
&lt;/h2&gt;

&lt;p&gt;GraphRAG previene estadisticas y agregaciones alucinadas. Pero los agents aun pueden seleccionar el tool incorrecto o desperdiciar tokens procesando descripciones de tools irrelevantes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/aws/reduce-agent-errors-and-token-costs-with-semantic-tool-selection-7mf"&gt;Parte 2: Semantic Tool Selection&lt;/a&gt; muestra como el filtrado vectorial reduce los errores de seleccion de tools y los costos de tokens.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pruebalo Tu Mismo
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/aws-samples/sample-why-agents-fail
&lt;span class="nb"&gt;cd &lt;/span&gt;stop-ai-agent-hallucinations/01-faq-graphrag-demo
uv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; uv pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;span class="c"&gt;# Start Neo4j with APOC plugin first&lt;/span&gt;
uv run test_graphrag_hallucinations.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Puedes cambiar a cualquier proveedor compatible con Strands — consulta &lt;a href="https://strandsagents.com/latest/documentation/docs/user-guide/concepts/model-providers/" rel="noopener noreferrer"&gt;Strands Model Providers&lt;/a&gt; para la configuracion.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Investigacion
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/pdf/2509.09360" rel="noopener noreferrer"&gt;MetaRAG: Metamorphic Testing for Hallucination Detection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/pdf/2503.13514" rel="noopener noreferrer"&gt;RAG-KG-IL: Multi-Agent Hybrid Framework&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Strands Agents
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://strandsagents.com" rel="noopener noreferrer"&gt;Strands Agents Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://strandsagents.com/latest/documentation/docs/user-guide/concepts/model-providers/" rel="noopener noreferrer"&gt;Strands Model Providers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Codigo
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/aws-samples/sample-why-agents-fail" rel="noopener noreferrer"&gt;Repositorio de Codigo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Gracias!&lt;/p&gt;

&lt;p&gt;🇻🇪🇨🇱 &lt;a href="https://dev.to/elizabethfuentes12"&gt;Dev.to&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/lizfue/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;a href="https://github.com/elizabethfuentes12/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; &lt;a href="https://twitter.com/elizabethfue12" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://www.instagram.com/elifue.tech" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; &lt;a href="https://www.youtube.com/channel/UCr0Gnc-t30m4xyrvsQpNp2Q" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>agents</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Detén las Hallucinations en Agentes de IA: 4 Técnicas Esenciales</title>
      <dc:creator>Elizabeth Fuentes L</dc:creator>
      <pubDate>Wed, 18 Mar 2026 00:13:33 +0000</pubDate>
      <link>https://forem.com/aws-espanol/deten-las-hallucinations-de-ai-agents-4-tecnicas-esenciales-3kcl</link>
      <guid>https://forem.com/aws-espanol/deten-las-hallucinations-de-ai-agents-4-tecnicas-esenciales-3kcl</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;4 técnicas para detener las hallucinations en AI agents: Graph-RAG para recuperación precisa de datos, selección semántica de tools para elegir la herramienta correcta, guardrails neurosimbólicos para aplicar reglas de negocio, y validación multi-agent para detección de errores.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Objetivos de Aprendizaje
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cómo Graph-RAG previene hallucinations estadísticas con datos estructurados&lt;/li&gt;
&lt;li&gt;Por qué la selección semántica de tools mejora la precisión y reduce costos de tokens&lt;/li&gt;
&lt;li&gt;Cómo los guardrails neurosimbólicos con Strands Agents bloquean operaciones inválidas&lt;/li&gt;
&lt;li&gt;Cómo la validación multi-agent detecta hallucinations antes de que lleguen a los usuarios&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Esta demo utiliza Strands Agents. Patrones similares pueden aplicarse en LangGraph, AutoGen u otros frameworks de agents.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Repositorio y Prerequisitos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Clonar:&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;git clone https://github.com/aws-samples/sample-why-agents-fail
&lt;span class="nb"&gt;cd &lt;/span&gt;stop-ai-agent-hallucinations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Requisitos:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.9+&lt;/li&gt;
&lt;li&gt;Acceso a un LLM (Amazon Bedrock, OpenAI, Anthropic u Ollama)&lt;/li&gt;
&lt;li&gt;Credenciales de AWS configuradas (si se usa Bedrock)&lt;/li&gt;
&lt;li&gt;Comprensión básica de AI agents y tool calling&lt;/li&gt;
&lt;li&gt;Bibliotecas clave: Strands Agents, Neo4j, FAISS, SentenceTransformers&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Técnica 1: Graph-RAG para Recuperación Precisa de Datos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problema:&lt;/strong&gt; El RAG tradicional recupera fragmentos de texto en lugar de ejecutar cálculos, lo que produce tres tipos de hallucination:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Estadísticas fabricadas a partir de agregaciones adivinadas&lt;/li&gt;
&lt;li&gt;Recuperación incompleta cuando los datos están dispersos&lt;/li&gt;
&lt;li&gt;Fabricación fuera de dominio cuando no existen datos relevantes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Solución:&lt;/strong&gt; Los knowledge graphs proporcionan datos estructurados y verificables, donde las agregaciones son calculadas por la base de datos en lugar de ser adivinadas por los LLMs.&lt;/p&gt;
&lt;h3&gt;
  
  
  Código de Comparación
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;

&lt;span class="c1"&gt;# RAG Agent — vector similarity search
&lt;/span&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_faqs&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="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;Search hotel FAQs using vector similarity.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;query_embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embed_model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&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="n"&gt;distances&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;astype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;float32&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="k"&gt;return&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="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&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="mi"&gt;500&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;idx&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;indices&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="c1"&gt;# Graph-RAG Agent — Cypher queries on knowledge graph
&lt;/span&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query_knowledge_graph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cypher_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="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Execute a Cypher query against the hotel knowledge graph.
    Node labels: Hotel, Room, Amenity, Policy, Service
    Relationships: (Hotel)-[:HAS_ROOM]-&amp;gt;(Room), (Hotel)-[:OFFERS_AMENITY]-&amp;gt;(Amenity)
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&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;session&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;span class="n"&gt;cypher_query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;records&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;No results found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;return&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;Found &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;records&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; results:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&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="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;records&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;rag_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&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="n"&gt;search_faqs&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;graph_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&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="n"&gt;query_knowledge_graph&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Resultados de la Demo
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tipo de Consulta&lt;/th&gt;
&lt;th&gt;RAG&lt;/th&gt;
&lt;th&gt;Graph-RAG&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Agregación&lt;/strong&gt;: "¿Calificación promedio en París?"&lt;/td&gt;
&lt;td&gt;⚠️ Calcula solo con 2 documentos&lt;/td&gt;
&lt;td&gt;✅ AVG() nativo sobre todos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Conteo&lt;/strong&gt;: "¿Hoteles con piscina?"&lt;/td&gt;
&lt;td&gt;❌ "No tengo los datos"&lt;/td&gt;
&lt;td&gt;✅ Preciso: 133&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Multi-hop&lt;/strong&gt;: "¿Tipos de habitación del mejor hotel?"&lt;/td&gt;
&lt;td&gt;❌ No puede recorrer relaciones&lt;/td&gt;
&lt;td&gt;✅ Recorrido Hotel → Room&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Fuera de dominio&lt;/strong&gt;: "Hoteles en la Antártida"&lt;/td&gt;
&lt;td&gt;❌ Fabrica respuestas&lt;/td&gt;
&lt;td&gt;✅ Honesto: "No hay hoteles"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Hallazgo Clave:&lt;/strong&gt; Graph-RAG reduce las hallucinations porque devuelve resultados vacíos en lugar de respuestas fabricadas cuando los datos no están disponibles.&lt;/p&gt;


&lt;h2&gt;
  
  
  Técnica 2: Selección Semántica de Tools para Elegir la Herramienta Correcta
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problema:&lt;/strong&gt; "Las hallucinations en tool-calling aumentan con la cantidad de tools." Cuando los agents tienen muchas tools similares, exhiben errores de selección de función, errores de idoneidad, errores de parámetros, errores de completitud y comportamiento de evasión de tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problema Dual:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Riesgo de hallucination: Más tools = más selecciones inapropiadas&lt;/li&gt;
&lt;li&gt;❌ Desperdicio de tokens: 31 tools ≈ 4,500 tokens por consulta&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Solución: Filtrado Semántico de Tools
&lt;/h3&gt;

&lt;p&gt;Filtra las tools &lt;em&gt;antes&lt;/em&gt; de que el agent las vea usando similitud vectorial.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sentence_transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;faiss&lt;/span&gt;

&lt;span class="c1"&gt;# Build index once
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SentenceTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;all-MiniLM-L6-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;tool_embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&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="n"&gt;description&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ALL_TOOLS&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;faiss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IndexFlatL2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;384&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tool_embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Filter per query
&lt;/span&gt;&lt;span class="n"&gt;query_embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&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="n"&gt;distances&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;k&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="n"&gt;relevant_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ALL_TOOLS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;indices&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Intercambio Dinámico de Tools con Strands Agents
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;

&lt;span class="c1"&gt;# Create agent once
&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&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="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Swap tools per query without losing conversation history
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;relevant_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search_tools&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="n"&gt;top_k&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="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&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;tool&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;relevant_tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register_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="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;agent&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="c1"&gt;# agent.messages preserved
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Resultados en 29 Consultas de Viaje
&lt;/h3&gt;

&lt;p&gt;Las pruebas muestran mejoras significativas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;86.4% de reducción en errores de selección de tools&lt;/li&gt;
&lt;li&gt;89% de reducción en costos de tokens&lt;/li&gt;
&lt;li&gt;Precisión mantenida con menos tools visibles&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Técnica 3: Guardrails Neurosimbólicos para AI Agents
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problema:&lt;/strong&gt; Investigaciones demuestran que los agents generan hallucinations cuando las reglas de negocio se expresan únicamente en prompts de lenguaje natural. El prompt engineering no puede aplicar restricciones porque los prompts son sugerencias, no reglas ejecutables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solución:&lt;/strong&gt; Usar hooks de Strands Agents para interceptar llamadas a tools antes de su ejecución y aplicar reglas simbólicas a nivel del framework.&lt;/p&gt;
&lt;h3&gt;
  
  
  Implementación
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.hooks&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HookProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HookRegistry&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;

&lt;span class="c1"&gt;# Define symbolic rules
&lt;/span&gt;&lt;span class="n"&gt;BOOKING_RULES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nc"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_guests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ctx&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;guests&lt;/span&gt;&lt;span class="sh"&gt;"&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="o"&gt;&amp;lt;=&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;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Maximum 10 guests per booking&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="c1"&gt;# Create validation hook
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NeurosymbolicHook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HookProvider&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;register_hooks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HookRegistry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validate&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;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BeforeToolCallEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;ctx&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;guests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_use&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="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;guests&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;passed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;violations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BOOKING_RULES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&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;passed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cancel_tool&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;BLOCKED: &lt;/span&gt;&lt;span class="si"&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="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;violations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Clean tool (no validation logic)
&lt;/span&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;book_hotel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hotel&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;guests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="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;Book a hotel room.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&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;SUCCESS: Booked &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;hotel&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;guests&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; guests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Attach hook to agent
&lt;/span&gt;&lt;span class="n"&gt;hook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NeurosymbolicHook&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&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="n"&gt;book_hotel&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;hooks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;hook&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Test
&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Book hotel for 15 guests&lt;/span&gt;&lt;span class="sh"&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;agent&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="c1"&gt;# ✅ Hook blocks before tool executes
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Por Qué los Hooks de Strands Destacan
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API sencilla:&lt;/strong&gt; Implementar HookProvider y registrar callbacks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validación centralizada:&lt;/strong&gt; Un solo hook valida todas las tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools limpias:&lt;/strong&gt; Sin lógica de validación mezclada con lógica de negocio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tipado seguro:&lt;/strong&gt; Objetos de eventos fuertemente tipados&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;El LLM no puede evadir:&lt;/strong&gt; Las reglas se aplican antes de la ejecución de la tool&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Efectividad
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Escenario&lt;/th&gt;
&lt;th&gt;Prompt Engineering&lt;/th&gt;
&lt;th&gt;Neurosimbólico con Hooks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Parámetros Inválidos&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Acepta&lt;/td&gt;
&lt;td&gt;✅ Bloquea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prerequisitos Faltantes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;⚠️ A veces detecta&lt;/td&gt;
&lt;td&gt;✅ Siempre bloquea&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Evasión de Reglas&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Posible&lt;/td&gt;
&lt;td&gt;✅ Imposible&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Técnica 4: Validación Multi-Agent para Detección de Errores
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Problema:&lt;/strong&gt; Los agents individuales operan en aislamiento. Cuando generan hallucinations, no existe un mecanismo para detectar errores antes de que lleguen a los usuarios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solución:&lt;/strong&gt; Múltiples agents especializados se validan mutuamente mediante debate estructurado, utilizando Strands Swarm para transferencias autónomas con contexto compartido.&lt;/p&gt;
&lt;h3&gt;
  
  
  Implementación
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;strands.multiagent&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Swarm&lt;/span&gt;

&lt;span class="c1"&gt;# Define specialized agents
&lt;/span&gt;&lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;executor&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="n"&gt;ALL_TOOLS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Execute requests, then hand off to validator&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;validator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;validator&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Check for hallucinations. Say VALID or HALLUCINATION&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;critic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;critic&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_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Final review. Say APPROVED or REJECTED&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create swarm - agents hand off autonomously
&lt;/span&gt;&lt;span class="n"&gt;swarm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Swarm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;critic&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;entry_point&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_handoffs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&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;swarm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Book grand_hotel for John&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;h3&gt;
  
  
  Comparación de Rendimiento
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Enfoque&lt;/th&gt;
&lt;th&gt;Detección de Hallucinations&lt;/th&gt;
&lt;th&gt;Precisión&lt;/th&gt;
&lt;th&gt;Latencia&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent Individual&lt;/td&gt;
&lt;td&gt;❌ Ninguna&lt;/td&gt;
&lt;td&gt;⚠️ Fabrica&lt;/td&gt;
&lt;td&gt;✅ Rápido&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-Agent&lt;/td&gt;
&lt;td&gt;✅ Detecta errores&lt;/td&gt;
&lt;td&gt;✅ Valida&lt;/td&gt;
&lt;td&gt;⚠️ Más lento&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo:&lt;/strong&gt; Cuando el executor intenta reservar "the_ritz_paris" (no existe), el validator detecta el hotel inválido y el critic devuelve FAILED en lugar de fabricar una alternativa.&lt;/p&gt;


&lt;h2&gt;
  
  
  Combinando Técnicas para Producción
&lt;/h2&gt;

&lt;p&gt;Estas técnicas se complementan entre sí:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Graph-RAG&lt;/strong&gt; asegura la precisión de los datos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selección semántica de tools&lt;/strong&gt; reduce errores de tools y costos de tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reglas neurosimbólicas&lt;/strong&gt; aplican restricciones de negocio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validación multi-agent&lt;/strong&gt; detecta las hallucinations restantes&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Por Qué Strands Agents Python SDK
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Gestión dinámica de tools sin perder el estado de la conversación&lt;/li&gt;
&lt;li&gt;Multi-agent nativo con Swarm manejando transferencias&lt;/li&gt;
&lt;li&gt;Validación a nivel de tool ejecutándose antes de que el LLM vea los resultados&lt;/li&gt;
&lt;li&gt;Flexibilidad de modelos (Bedrock, OpenAI, Anthropic, Ollama)&lt;/li&gt;
&lt;li&gt;Listo para producción en despliegues AWS&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Conclusiones Clave
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Las hallucinations son inevitables — enfócate en detección y mitigación, no en eliminación&lt;/li&gt;
&lt;li&gt;Graph-RAG para precisión cuando necesitas cálculos exactos o relaciones&lt;/li&gt;
&lt;li&gt;Filtrado semántico esencial con más de 10 tools similares&lt;/li&gt;
&lt;li&gt;Las reglas simbólicas aplican cumplimiento de negocio donde el prompt engineering falla&lt;/li&gt;
&lt;li&gt;La validación multi-agent detecta errores que los agents individuales no captan&lt;/li&gt;
&lt;li&gt;Strands Agents permite despliegues en producción con tools dinámicas y soporte nativo multi-agent&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Referencias
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/pdf/2509.09360" rel="noopener noreferrer"&gt;MetaRAG: Metamorphic Testing for Hallucination Detection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/abs/2601.05214" rel="noopener noreferrer"&gt;Internal Representations as Indicators of Hallucinations in Agent Tool Selection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/pdf/2510.19507" rel="noopener noreferrer"&gt;Teaming LLMs to Detect and Mitigate Hallucinations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arxiv.org/pdf/2503.13514" rel="noopener noreferrer"&gt;RAG-KG-IL: Multi-Agent Hybrid Framework&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://strandsagents.com" rel="noopener noreferrer"&gt;Strands Agents Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Gracias!&lt;/p&gt;

&lt;p&gt;🇻🇪🇨🇱 &lt;a href="https://dev.to/elizabethfuentes12"&gt;Dev.to&lt;/a&gt; &lt;a href="https://www.linkedin.com/in/lizfue/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; &lt;a href="https://github.com/elizabethfuentes12/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; &lt;a href="https://twitter.com/elizabethfue12" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; &lt;a href="https://www.instagram.com/elifue.tech" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; &lt;a href="https://www.youtube.com/channel/UCr0Gnc-t30m4xyrvsQpNp2Q" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;&lt;br&gt;
&lt;a href="https://linktr.ee/elizabethfuentesleone" rel="noopener noreferrer"&gt;Linktr&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__717518"&gt;
    &lt;a href="/elizabethfuentes12" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717518%2Fb550b165-b8b9-405d-acfb-e5dc846765b0.png" alt="elizabethfuentes12 image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/elizabethfuentes12"&gt;Elizabeth Fuentes L&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/elizabethfuentes12"&gt;I help developers build production-ready AI applications through hands-on tutorials and open-source projects.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;





</description>
      <category>agents</category>
      <category>ai</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
