{"id":5371,"date":"2026-04-03T13:12:37","date_gmt":"2026-04-03T13:12:37","guid":{"rendered":"https:\/\/www.genetechsolutions.com\/blog\/?p=5371"},"modified":"2026-04-03T14:54:47","modified_gmt":"2026-04-03T14:54:47","slug":"agentic-ai-chatbot-code","status":"publish","type":"post","link":"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/","title":{"rendered":"How We Built a Production-Ready Agentic AI Chatbot (With Real Code &amp; Architecture)"},"content":{"rendered":"\n<div class=\"gb-accordion\">\n<div class=\"gb-accordion__item gb-accordion__item-01887edd\">\n<div role=\"button\" tabindex=\"0\" class=\"gb-accordion__toggle gb-accordion__toggle-a6c44063\" id=\"gb-accordion-toggle-a6c44063\">\n<h4 class=\"wp-block-heading\">Summary: What You&#8217;ll Find Inside<\/h4>\n\n\n\n<span class=\"gb-accordion__toggle-icon gb-accordion__toggle-icon-b86c5154\"><span class=\"gb-accordion__toggle-icon-open\"><svg aria-hidden=\"true\" viewBox=\"0 0 256 256\"><rect width=\"256\" height=\"256\" fill=\"none\"><\/rect><polyline points=\"208 96 128 176 48 96\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"><\/polyline><\/svg><\/span><span class=\"gb-accordion__toggle-icon-close\"><svg aria-hidden=\"true\" viewBox=\"0 0 256 256\"><rect width=\"256\" height=\"256\" fill=\"none\"><\/rect><polyline points=\"48 160 128 80 208 160\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"><\/polyline><\/svg><\/span><\/span>\n<\/div>\n\n\n\n<div class=\"gb-accordion__content\" id=\"gb-accordion-content-2ae99acc\">\n<div class=\"gb-element-8e5799ae\">\n<p>We built a fully custom agentic AI chatbot for our own website and this post breaks down exactly how we did it. We cover why we chose ReAct architecture over simpler approaches, how we structured specialized domain tools instead of one bloated system prompt, and how dual-layer memory makes follow-up questions feel natural. We also walk through the guardrails keeping the bot on topic, the CRM integration that turns every conversation into a captured lead, and the observability setup that makes debugging straightforward. Real architectural decisions, real tradeoffs, and real production code throughout.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/How-We-Built-a-Production-Ready-Agentic-AI-Chatbot-1.jpg\"><img decoding=\"async\" width=\"1024\" height=\"537\" src=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/How-We-Built-a-Production-Ready-Agentic-AI-Chatbot-1-1024x537.jpg\" alt=\"Agentic AI Chatbot (With Real Code &amp; Architecture)\" class=\"wp-image-5372\" srcset=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/How-We-Built-a-Production-Ready-Agentic-AI-Chatbot-1-1024x537.jpg 1024w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/How-We-Built-a-Production-Ready-Agentic-AI-Chatbot-1-300x157.jpg 300w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/How-We-Built-a-Production-Ready-Agentic-AI-Chatbot-1-768x403.jpg 768w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/How-We-Built-a-Production-Ready-Agentic-AI-Chatbot-1-1536x806.jpg 1536w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/How-We-Built-a-Production-Ready-Agentic-AI-Chatbot-1-2048x1075.jpg 2048w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/How-We-Built-a-Production-Ready-Agentic-AI-Chatbot-1-500x262.jpg 500w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/#Introducing_The_Genetech_Solutions_Agentic_AI_Chatbot\" >Introducing: The Genetech Solutions Agentic AI Chatbot<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/#Now_What_Kind_of_AI_Agent_Is_This\" >Now: What Kind of AI Agent Is This?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/#What_Makes_a_Chatbot_%E2%80%98Agentic\" >What Makes a Chatbot &#8216;Agentic&#8217;?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/#Before_You_Write_a_Single_Line_of_Code\" >Before You Write a Single Line of Code<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/#1_Building_the_Agentic_AI_Chatbot_Workflow_Architecture\" >1. Building the Agentic AI Chatbot Workflow (Architecture)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/#2_Binding_the_ReAct_Agent_with_Specialized_Domain_Tools\" >2. Binding the ReAct Agent with Specialized Domain Tools<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/#3_Designing_the_Agentic_AI_Chatbot_Memory_System\" >3. Designing the Agentic AI Chatbot Memory System<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/#4_Building_Guardrails\" >4. Building Guardrails<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/#5_Testing_Monitoring_and_Observability\" >5. Testing, Monitoring, and Observability<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/#What_You_End_Up_With\" >What You End Up With<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/#Build_Yours_With_Us\" >Build Yours With Us<\/a><\/li><\/ul><\/nav><\/div>\n\n\n\n\n<p><\/p>\n\n\n\n<p><a href=\"https:\/\/www.genetechsolutions.com\/\">The chatbot sitting on the main page of Genetech Solutions website <\/a>is not a widget from a SaaS platform. It is not a scripted FAQ bot. It is a fully custom agentic AI system built by our own team, running in production, handling real queries from real visitors every day. It reasons. <strong>It routes. It remembers. And when the moment is right, it captures a lead and notifies the right person on our team within seconds.<\/strong><\/p>\n\n\n\n<p>Across this series, we have covered <a href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-for-business-leaders\/\">what agentic AI is<\/a> and why it matters for business leaders [link], <a href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-frameworks\/\">how to choose the right frameworks<\/a>, and the different types of agentic systems. This episode is where we get concrete. We are pulling back the curtain on our own chatbot \u2014 the decisions we made, the architecture we chose, the code we wrote, and what we would do differently if we were starting today.<\/p>\n\n\n\n<p>This is not a high-level overview. Throughout this breakdown, we will show you exactly how the system works including real architectural decisions, implementation patterns, and production code snippets from the chatbot running on our website today. If you are building something similar, you should be able to reuse parts of this directly.<\/p>\n\n\n\n<p>If you are a developer building something similar, the technical sections will give you a working reference. If you are a business or product leader trying to understand whether this kind of system makes sense for your organization, the earlier sections will tell you what questions to ask and why the answers matter.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Introducing_The_Genetech_Solutions_Agentic_AI_Chatbot\"><\/span><strong>Introducing: The Genetech Solutions Agentic AI Chatbot<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The Genetech Solutions website has a custom-built agentic AI chatbot that handles visitor queries, captures leads, and routes conversations to the right team \u2014 all without a human on standby.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>What it does<\/strong><\/h3>\n\n\n\n<p>At its core, the chatbot answers any question a visitor might have about Genetech \u2014 services, pricing, portfolio, team, industries, and contact information. But it goes well beyond a knowledge base. It actively guides visitors toward the next step: booking a consultation, connecting with the sales team, submitting a project brief, or reporting an issue.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>How it works<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image size-full video-border\"><a href=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/Video-1-2.gif\"><img decoding=\"async\" width=\"1366\" height=\"606\" src=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/Video-1-2.gif\" alt=\"Introducing Agentic AI Chatbot\" class=\"wp-image-5396\"\/><\/a><\/figure>\n\n\n\n<p>Video:<em> Introducing the agentic AI chatbot<\/em><\/p>\n\n\n\n<p>The chatbot operates on two tracks. For common queries and predictable journeys, it uses a button-based tree navigation \u2014 no LLM involved, which keeps responses instant and costs low. For open-ended, free-form questions, it fires the language model, which reasons across the conversation and routes to the appropriate response or action. Both tracks terminate at the same place: a form that captures structured data.<\/p>\n\n\n\n<p>Every conversation path ends in a form \u2014 lead generation, consultation scheduling, sales connection, or issue reporting. The forms are NLP-driven, meaning the agent extracts relevant information from the conversation before presenting them, so visitors are not repeating themselves.<\/p>\n\n\n\n<p>(screenmovie &#8211; product development get a quote)<\/p>\n\n\n\n<figure class=\"wp-block-image size-full video-border\"><a href=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/Untitled-design-2.gif\"><img decoding=\"async\" width=\"1366\" height=\"606\" src=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/Untitled-design-2.gif\" alt=\"Interacting with the Genetech agentic ai chatbot\" class=\"wp-image-5397\"\/><\/a><\/figure>\n\n\n\n<p>Video: <em>Interacting with the Genetech Solutions agentic AI chatbot<\/em><\/p>\n\n\n\n<p>Guardrails keep the LLM focused on Genetech. It will not invent services that do not exist, drift into off-topic territory, or produce responses that contradict what is on the website.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Personalized engagement<\/strong><\/h3>\n\n\n\n<p>Beyond the chat widget, the system includes behavior-triggered pop-ups. When a visitor reads a specific service page and scrolls past 60% or shows exit intent, a contextual prompt appears tied to exactly what they were reading \u2014 with two CTAs: connect with the sales team, or access a relevant resource like a checklist guide.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>CRM integration<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-4.png\"><img decoding=\"async\" width=\"1024\" height=\"468\" src=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-4-1024x468.png\" alt=\"Image: Every lead falls into the integrated company website CRM \" class=\"wp-image-5392\" srcset=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-4-1024x468.png 1024w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-4-300x137.png 300w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-4-768x351.png 768w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-4-500x228.png 500w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-4.png 1370w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p><em>Image: Every lead falls into the integrated company website CRM <\/em><\/p>\n\n\n\n<p>Every form submission flows into the Genetech CRM with the full conversation history attached. Leads, sales queries, consultation requests, and issues each land in separate tables so every team sees only what is relevant to them. The conversation transcript paired with the form entry means the sales team picks up a lead knowing exactly what the visitor was looking for, what questions they asked, and where the conversation went.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Who it is for<\/strong><\/h3>\n\n\n\n<p>Any visitor to the Genetech website \u2014 developers evaluating technical capabilities, founders comparing vendors, operations leads with specific questions, or businesses exploring AI and software services for the first time. The agentic AI chatbot meets each of them where they are.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Now_What_Kind_of_AI_Agent_Is_This\"><\/span><strong>Now: What Kind of AI Agent Is This?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Before we go into how we built it, it is worth being clear about what category of system this is \u2014 because not all agentic AI is built the same way, and the category you are building in determines most of your technical decisions.<\/p>\n\n\n\n<p>Agentic AI systems generally fall into six types:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Conversational AI Agents \u2014 chat-based systems that use an LLM to reason across multi-turn conversations, understand intent, and respond or act accordingly. This is what the Genetech agentic AI chatbot is.<\/li>\n\n\n\n<li>Task Automation Agents \u2014 systems that execute structured, multi-step workflows triggered by an event. Invoice processing, lead routing, employee onboarding.<\/li>\n\n\n\n<li>Multi-Agent Systems \u2014 teams of specialist agents coordinated by an orchestrator. Each agent handles a specific domain; the orchestrator manages the workflow.<\/li>\n\n\n\n<li>RAG-Based Knowledge Agents \u2014 agents connected to a vector database of proprietary documents. They retrieve relevant information before generating a response, grounding the LLM in your actual data.<\/li>\n\n\n\n<li>Code Agents \u2014 agents that write, execute, test, and debug code in a sandboxed environment. Used in software development and QA pipelines.<\/li>\n\n\n\n<li>Computer Use \/ Browser Agents \u2014 agents that interact with websites and applications the way a human does: clicking, navigating, filling forms. Used when no API exists.<\/li>\n<\/ul>\n\n\n\n<p>The Genetech chatbot is a conversational AI agent. Its primary mode of interaction is natural language. Its job is to understand what a visitor wants, route them through the right workflow, and capture structured data at the end. But it borrows from other types too \u2014 it uses task automation patterns for form routing and CRM writes, and RAG principles in how its tools are structured around curated knowledge bases.<\/p>\n\n\n\n<p>Understanding which type you are building is not an academic exercise. It tells you which framework to use, how to structure your memory system, what your testing approach should look like, and where the most likely failure points are. We are building a conversational agent, so everything that follows is shaped by that.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_Makes_a_Chatbot_%E2%80%98Agentic\"><\/span><strong>What Makes a Chatbot &#8216;Agentic&#8217;?<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>The word gets used loosely, so it is worth being precise. A traditional chatbot follows a script \u2014 if the user says X, respond with Y. It does not interpret. It does not adapt. It does not remember what you said two messages ago. It matches inputs to pre-written outputs.<\/p>\n\n\n\n<p>A conversational agentic AI chatbot works differently. At its core is an LLM acting as a reasoning engine. Instead of matching to a script, it reads the conversation, classifies what the user wants, selects the appropriate tool or response path, and generates an output tailored to that specific moment. When the next message arrives, it does the same thing again \u2014 but now with the full context of everything that came before.<\/p>\n\n\n\n<p>The three capabilities that define a genuinely agentic conversational system are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Reasoning across turns \u2014 the agent understands follow-up questions, pronoun references, and context shifts. &#8216;What is the pricing for that?&#8217; only makes sense if the agent remembers what &#8216;that&#8217; refers to.<\/li>\n\n\n\n<li>Dynamic tool selection \u2014 rather than a fixed pipeline, the agent decides in real time which capability to invoke based on what the user actually said.<\/li>\n\n\n\n<li>Goal-directed action \u2014 the agent is not just generating responses. It is working toward an outcome: in our case, capturing a qualified lead or booking a consultation.<\/li>\n<\/ul>\n\n\n\n<p>A chatbot that lacks any of these is not really an agent \u2014 it is a more sophisticated FAQ bot. The Genetech chatbot has all three. Here is how we built it.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Before_You_Write_a_Single_Line_of_Code\"><\/span><strong>Before You Write a Single Line of Code<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Every agentic AI project that struggles in production shares a common cause: the team started building before they finished thinking. The most valuable investment you can make before touching any framework is a clear, written answer to four questions.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>What is the specific problem this agentic AI chatbot is solving?<\/strong><\/h3>\n\n\n\n<p>Not &#8216;we want AI on our website.&#8217; Something specific: visitors are landing on our services pages and leaving without a conversion action, and we have no way to capture intent or route them appropriately at scale. The more precisely you can state the problem, the more clearly the solution reveals itself.<\/p>\n\n\n\n<p>For Genetech, the problem was conversion and intent segmentation. That single definition told us we needed lead capture forms, routing logic by service type, and a way to engage visitors before they left. Everything in the architecture traces back to that problem statement.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Who is going to use it, and what do they expect?<\/strong><\/h3>\n\n\n\n<p>A chatbot serving technical users can tolerate more friction than one serving business decision-makers who are evaluating vendors. The Genetech agentic AI chatbot serves a mixed audience \u2014 developers, founders, operations leads, marketers \u2014 and the interaction design reflects that. The button navigation handles users who want to move quickly without typing. The open query input is designed for users with specific questions. Both paths are necessary because the audience is not uniform.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>What data do you need to capture, and where does it need to go?<\/strong><\/h3>\n\n\n\n<p>Agentic chatbots are data pipelines as much as they are conversation interfaces. Define upfront what you need to collect \u2014 name, email, query type, service interest, issue description \u2014 and where each type of data needs to land. If you design conversation flows first and figure out the data destination later, you will build the wrong forms, in the wrong order, connected to nothing useful.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>How will you measure whether it is working?<\/strong><\/h3>\n\n\n\n<p>Conversion rate on leads captured. Time to first response for sales follow-up. Drop-off rate at each stage of the conversation flow. Define these before you deploy. Without baseline metrics, you cannot make the case that the system is working, and you cannot identify what to improve.<\/p>\n\n\n\n<p>With these four questions answered, the architecture choices become much cleaner. For Genetech, the answers pointed directly to a ReAct agent with specialized domain tools, dual-layer memory, and a CRM-connected form system. Here is how each of those pieces was built.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"1_Building_the_Agentic_AI_Chatbot_Workflow_Architecture\"><\/span><strong>1. Building the Agentic AI Chatbot Workflow (Architecture)<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1.1 Choosing the Right Architecture: Why ReAct?<\/strong><\/h3>\n\n\n\n<p>When building the Genetech agentci AI chatbot, we evaluated several agentic architectures \u2014 Chain-of-Thought prompting, simple tool-use pipelines, plan-and-execute agents, and routing-based multi-agent systems. Each has its place, but for a customer-facing chatbot that must answer diverse questions, collect leads, route to the right information, and handle follow-up context, we selected the ReAct (Reasoning + Acting) architecture.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><em>What is ReAct Architecture?<\/em><\/h4>\n\n\n\n<p>ReAct is an agent pattern that interleaves reasoning (Thought) with action (Act) in an iterative loop. Instead of executing a fixed pipeline, the LLM reasons about what to do next, calls a tool, observes the result, and reasons again \u2014 continuing this loop until it produces a final answer.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><em>Thought \u2192 Act \u2192 Observe \u2192 Thought \u2192 Act \u2192 Observe \u2192 &#8230; \u2192 Final Answer<\/em><em>This is fundamentally different from a static prompt pipeline. The agent dynamically decides which tools to invoke based on user intent, conversation history, and tool outputs.<\/em><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\"><em>Why Not the Alternatives?<\/em><\/h4>\n\n\n\n<p>Before settling on ReAct, we evaluated other approaches:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Simple Chain Prompting \u2014 a single LLM call with a large system prompt containing all company knowledge. The problem: massive context bloat, high token cost, no structured action capability.<\/li>\n\n\n\n<li>Plan-and-Execute \u2014 the agent plans all steps upfront, then executes. The problem: brittle for conversational flows where the user changes direction mid-conversation.<\/li>\n\n\n\n<li>Static Tool Routing \u2014 hardcoded rules to route queries to handlers. The problem: fails on nuanced or ambiguous queries and cannot handle follow-ups naturally.<\/li>\n\n\n\n<li>Multi-Agent Systems \u2014 multiple specialized agents coordinating. The problem: overkill complexity for a single-domain chatbot; harder to debug and maintain.<\/li>\n<\/ul>\n\n\n\n<p>ReAct solves all of these by giving the LLM full agency to reason about user intent and dynamically select the right tool \u2014 within a single, coherent reasoning loop.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><em>How the Main LLM Acts as a Query Router<\/em><\/h4>\n\n\n\n<p>In the Genetech agentic AI chatbot, GPT-4o serves as the central orchestrator. It receives every user message along with the conversation history and the full list of available tools. It then reads the user&#8217;s intent, reasons about which specialized tool can best answer, calls that tool with relevant parameters, observes the output, and formulates a final response. The LLM is not just a text generator \u2014 it is a dynamic query router that dispatches to specialized domain handlers.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1.2 ReAct Agent Flow Diagram<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image.png\"><img decoding=\"async\" width=\"363\" height=\"1024\" src=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-363x1024.png\" alt=\"Agentic AI Chatbot - Each iteration of the Reason \u2192 Act \u2192 Observe loop lets the agent adjust based on tool results\n\" class=\"wp-image-5377\" srcset=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-363x1024.png 363w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-106x300.png 106w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-544x1536.png 544w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image.png 567w\" sizes=\"(max-width: 363px) 100vw, 363px\" \/><\/a><\/figure>\n\n\n\n<p>Diagram:<em> Each iteration of the Reason \u2192 Act \u2192 Observe loop lets the agent adjust based on tool results<\/em><br><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1.3 Code Snippet: ReAct Agent Initialization in LangGraph<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># \u2500\u2500 ReAct Agent Initialization (app.py) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfrom langchain_openai import ChatOpenAI\nfrom langgraph.prebuilt import create_react_agent\nfrom langgraph.checkpoint.memory import MemorySaver\n\n# Short-Term Memory (STM) \u2014 persists conversation per session thread\ncheckpointer = MemorySaver()\n\n# LLM Orchestrator: GPT-4o as the central reasoning engine\nllm = ChatOpenAI(\n    model='gpt-4o',\n    temperature=0.0,  # Deterministic routing \u2014 no hallucination\n    max_tokens=500\n)\n\n# Register all specialized domain tools\ntools = &#091;\n    handle_greeting_feedbacks,   # Greetings &amp; casual messages\n    services_info,               # Knowledge: Genetech services\n    company_portfolio,           # Knowledge: Portfolio by domain\n    Company_Industries,          # Knowledge: Industries served\n    pricing_info,                # Knowledge: Pricing models\n    company_contact_info,        # Knowledge: Office locations\n    Awards,                      # Knowledge: Company awards\n    about_genetech,              # Knowledge: Company overview\n    show_lead_form,              # Action: Capture project lead\n    show_consultation_form,      # Action: Capture consultation\n    show_sales_form,             # Action: Connect to sales team\n    show_issue_form,             # Action: Report website issue\n    handle_irrelevant_queries,   # Guardrail: Out-of-scope filter\n    business_recommendations_solutions,\n    looking_job_opportunity,\n    client_reviews_and_ratings,\n    Podcast_Blogs,\n    Company_Founder_and_Teams,\n]\n\n# Create the ReAct Agent with LangGraph\nagent_executor = create_react_agent(\n    model=llm,\n    tools=tools,\n    checkpointer=checkpointer,  # Enables STM across turns\n    state_modifier=system_prompt  # Company context injected\n)\n\n# Invoke with per-session thread ID for isolated memory\nconfig = {'configurable': {'thread_id': thread_id}}\nresponse = agent_executor.invoke(\n    {'messages': &#091;HumanMessage(content=user_input)]},\n    config=config\n)<\/code><\/pre>\n\n\n\n<p>Code: <em>ReAct agent initialization \u2014 GPT-4o as the reasoning engine, all domain tools registered, MemorySaver for session persistence<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"2_Binding_the_ReAct_Agent_with_Specialized_Domain_Tools\"><\/span><strong>2. Binding the ReAct Agent with Specialized Domain Tools<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2.1 Why Specialized Tools Instead of One Big System Prompt?<\/strong><\/h3>\n\n\n\n<p>The most common mistake in building LLM-powered chatbots is loading everything into a single, monolithic system prompt. Imagine injecting all of Genetech&#8217;s service descriptions, pricing tables, portfolio links, industry data, contact information, awards, and CRM form logic into one giant context window. This creates two critical problems.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><em>Context Rot: As the context grows, the LLM&#8217;s attention degrades on earlier parts of the prompt. Important instructions get &#8216;forgotten&#8217; in long conversations.<\/em><em>Context Bloat: Each API call becomes expensive and slow because unnecessary tokens are processed on every single turn.<\/em><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The solution is specialization. Instead of one large context, we define compact, focused tools \u2014 each a domain expert with its own curated knowledge. The ReAct agent only loads what it needs for the current query. This is both cheaper and more accurate.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Reduced Token Cost \u2014 only the relevant tool&#8217;s knowledge is processed per query<\/li>\n\n\n\n<li>Higher Accuracy \u2014 each tool is optimized for its specific domain, no dilution<\/li>\n\n\n\n<li>Easier Maintenance \u2014 update a tool&#8217;s knowledge without touching the entire agent<\/li>\n\n\n\n<li>Better Testability \u2014 each tool can be unit-tested in isolation<\/li>\n\n\n\n<li>Cleaner Guardrails \u2014 out-of-scope queries are rejected by a dedicated tool<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2.2 Tool Categories in the Genetech Agentic AI Chatbot<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><em>A) Knowledge Base Tools<\/em><\/h4>\n\n\n\n<p>Knowledge tools provide domain-specific information by combining curated company data with LLM-powered natural language generation. Each tool maintains its own prompt template and knowledge base:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>services_info \u2014 deep knowledge of all 16+ Genetech services. Uses a dedicated services_data string and a PromptTemplate to generate context-aware responses.<\/li>\n\n\n\n<li>company_portfolio \u2014 validates whether Genetech offers a service or industry, then provides the appropriate portfolio link. Maintains a 66+ industry catalog.<\/li>\n\n\n\n<li>Company_Industries \u2014 industry-specific deep dives for Healthcare, Fintech, Logistics, Education, and Hospitality, plus portfolio links for 50+ additional verticals.<\/li>\n\n\n\n<li>pricing_info \u2014 handles all pricing queries: hourly (USD 50), dedicated resources (USD 2,500\u20134,000\/month), and project-based estimates. Includes objection handling.<\/li>\n\n\n\n<li>company_contact_info \u2014 contact details for 4 offices (2 Karachi, 1 Skardu, 1 Ann Arbor USA) with strict social media policy enforcement.<\/li>\n\n\n\n<li>about_genetech, Awards, Company_Founder_and_Teams, client_reviews_and_ratings, Podcast_Blogs, looking_job_opportunity \u2014 each serves a focused information domain.<\/li>\n\n\n\n<li>business_recommendations_solutions \u2014 maps user industry context to the most relevant Genetech services. Triggered when a user says &#8216;I am in healthcare, how can you help me?&#8217;<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><em>B) Action-Based Tools (CRM Integration)<\/em><\/h4>\n\n\n\n<p>Action tools trigger interactive forms that collect leads and save data directly into PostgreSQL CRM tables. These are the bridge between conversation and business value:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>show_lead_form \u2014 triggered when a user wants to hire Genetech for a software project. Returns &#8216;SHOW_LEAD_FORM&#8217; signal; the Flask backend detects this and renders the lead capture form. Data is saved to the leads table.<\/li>\n\n\n\n<li>show_consultation_form \u2014 captures consultation requests. Saved to the consultant table with session_id, name, email, and consultation type.<\/li>\n\n\n\n<li>show_sales_form \u2014 connects users with the sales team. Saves name, email, and reason_for_connecting to the sales table.<\/li>\n\n\n\n<li>show_issue_form \u2014 reports Genetech-specific issues. Saved to the issues table with issue_description.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><em>Every form submission is tracked with the user&#8217;s session_id, enabling full conversation-to-lead tracing. The ConversationTracker saves every user message, bot response, button click, and form submission \u2014 creating a complete client interaction audit trail for lead generation analytics.<\/em><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2.3 Tool Connection Diagram \u2014 ReAct Loop<\/strong><\/h3>\n\n\n\n<p>The following diagram shows how tools are dynamically selected inside the ReAct loop:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-1.png\"><img decoding=\"async\" width=\"1024\" height=\"393\" src=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-1024x393.png\" alt=\"Diagram: The LLM selects the appropriate tool dynamically \u2014 based on intent, not hardcoded rules\" class=\"wp-image-5378\" srcset=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-1024x393.png 1024w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-300x115.png 300w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-768x294.png 768w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-1-500x192.png 500w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-1.png 1427w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Diagram:<em> The LLM selects the appropriate tool dynamically \u2014 based on intent, not hardcoded rules<\/em><br><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2.4 Code Snippet: Tool Registration and Binding<\/strong><\/h3>\n\n\n\n<p>Each tool is defined using LangChain&#8217;s @tool decorator. Below are examples of both a Knowledge Base tool and an Action-based tool from the Genetech chatbot:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># \u2500\u2500 Knowledge Base Tool: services_info \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n@tool\ndef services_info(user_message: str = '') -&gt; str:\n    '''AI-Powered tool for Genetech service inquiries.\n    Handles: web development, mobile, AI, DevOps, cybersecurity queries.\n    '''\n    services_data = '''\n    1. Web Development: React, Node.js, Python \u2014 custom websites &amp; web apps\n    2. Mobile App Development: iOS, Android, Flutter \u2014 cross-platform solutions\n    3. AI Integration: ML, Chatbots, NLP, Computer Vision, Generative AI\n    4. Cybersecurity: Security audits, penetration testing, compliance\n    5. DevOps: CI\/CD, Docker, Kubernetes, infrastructure automation\n    ... (16+ services with detailed descriptions)\n    '''\n    prompt = PromptTemplate(\n        template='You are Genetech Solutions AI assistant... {services_data}... {user_message}',\n        input_variables=&#091;'user_message', 'services_data']\n    )\n    chain = prompt | llm\n    return chain.invoke({'user_message': user_message, 'services_data': services_data}).content\n\n# \u2500\u2500 Action-Based Tool: show_lead_form \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n@tool\ndef show_lead_form() -&gt; str:\n    '''Triggered when user wants to hire Genetech for software development.\n    Returns signal string that Flask backend intercepts to render the form UI.\n    '''\n    return 'SHOW_LEAD_FORM'  # Signal detected in process_user_message()\n\n# \u2500\u2500 Flask: Signal Detection and Form Routing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ndef process_user_message(user_input, client_session_id, thread_id):\n    config = {'configurable': {'thread_id': thread_id}}\n    response = agent_executor.invoke(\n        {'messages': &#091;HumanMessage(content=user_input)]},\n        config=config\n    )\n    for msg in reversed(response&#091;'messages']&#091;-3:]):\n        if type(msg).__name__ == 'ToolMessage':\n            if 'SHOW_LEAD_FORM' in msg.content:\n                return {'show_form': 'lead', 'response': ''}\n            elif 'SHOW_CONSULTATION_FORM' in msg.content:\n                return {'show_form': 'consultation', 'response': ''}\n    return {'show_form': None, 'response': agent_response}\n\n# \u2500\u2500 CRM: Lead saved to PostgreSQL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n@app.route('\/submit_lead_form', methods=&#091;'POST'])\ndef submit_lead_form():\n    cursor.execute('''\n        INSERT INTO leads (date, name, email, phone, status, session_id)\n        VALUES (%s, %s, %s, %s, %s, %s)\n    ''', (datetime.now(), name, email, phone, 'New Lead', session_id))\n    ConversationTracker.track_form_submit(session_id, 'lead', form_data)\n    send_form_notification_async('lead', form_data)  # Email alert<\/code><\/pre>\n\n\n\n<p>Code: <em>Knowledge tool using PromptTemplate + LLM chain; action tool returning a signal string; Flask signal detection and PostgreSQL CRM write<\/em><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"3_Designing_the_Agentic_AI_Chatbot_Memory_System\"><\/span><strong>3. Designing the Agentic AI Chatbot Memory System<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3.1 What Makes This a Real AI Agent?<\/strong><\/h3>\n\n\n\n<p>The difference between a simple chatbot and a true AI agent often comes down to one capability: memory. Without it, every message is a brand-new, isolated interaction. The agent cannot remember what was said two messages ago, cannot build on previous context, and cannot maintain the natural flow of a real conversation.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><em>Without memory, ask the chatbot &#8216;Tell me about your web development services&#8217; and then follow up with &#8216;What was the pricing for that?&#8217; \u2014 and it has no idea what &#8216;that&#8217; refers to. This breaks the user experience entirely and makes the chatbot feel robotic and unhelpful.<\/em><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>For the Genetech agentic AI chatbot to behave like a real intelligent assistant \u2014 understanding follow-ups, routing based on conversation context, and tracking leads across a session \u2014 memory is non-negotiable.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3.2 Short-Term Memory vs Long-Term Memory<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><em>Short-Term Memory (STM)<\/em><\/h4>\n\n\n\n<p>Stores the active conversation history within a single user session. Enables the agent to understand follow-up questions, pronoun references, and context switches. In LangGraph, this is implemented as an in-memory checkpointer keyed by a unique thread_id per session.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><em>Long-Term Memory (LTM)<\/em><\/h4>\n\n\n\n<p>Persists data across sessions and stores structured business data permanently. Does not expire when the session ends. In the Genetech chatbot, LTM is implemented as a PostgreSQL database that stores leads, consultations, issues, sales contacts, and complete conversation histories for analytics and follow-up.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3.3 Our Memory Implementation<\/strong><\/h3>\n\n\n\n<p>The Genetech chatbot implements both STM and LTM in a complementary architecture:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>STM via LangGraph MemorySaver: Each user gets a unique thread_id. MemorySaver persists all messages in-memory for that thread. When the agent is invoked with the same thread_id, it automatically receives the full conversation history \u2014 enabling natural follow-ups and context-aware routing.<\/li>\n\n\n\n<li>LTM via PostgreSQL CRM: Every form submission is saved permanently to PostgreSQL with the session_id as a foreign key. The ConversationTracker writes every user message, bot response, button click, and form submission to the conversation_history table.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><em>The combination of STM + LTM means: the chatbot remembers you within this conversation (STM), and Genetech&#8217;s sales team can see your full interaction history later (LTM). This is what transforms a chatbot into a lead generation engine.<\/em><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3.4 Memory System Diagram<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-2.png\"><img decoding=\"async\" width=\"1024\" height=\"448\" src=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-2-1024x448.png\" alt=\"Diagram: Agentic AI Chatbot - Short-term memory for live context. Long-term memory for everything that outlasts the session.\" class=\"wp-image-5379\" srcset=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-2-1024x448.png 1024w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-2-300x131.png 300w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-2-768x336.png 768w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-2-500x219.png 500w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-2.png 1423w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Diagram: <em>Short-term memory for live context. Long-term memory for everything that outlasts the session.<\/em><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3.5 Code Snippet: STM + LTM Integration<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># \u2500\u2500 SHORT-TERM MEMORY (STM): LangGraph MemorySaver \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfrom langgraph.checkpoint.memory import MemorySaver\n\ncheckpointer = MemorySaver()  # In-memory state store\nagent_executor = create_react_agent(\n    model=llm,\n    tools=tools,\n    checkpointer=checkpointer,  # STM enabled\n    state_modifier=system_prompt\n)\n\n# Each user session gets an isolated thread with unique ID\ndef get_or_create_thread_id(client_session_id):\n    return session_manager.get_or_create_session(client_session_id)\n\n# STM is automatically loaded when agent is invoked with same thread_id\nconfig = {'configurable': {'thread_id': thread_id}}\nresponse = agent_executor.invoke(\n    {'messages': &#091;HumanMessage(content=user_input)]},\n    config=config  # LangGraph restores full message history from MemorySaver\n)\n\n# \u2500\u2500 LONG-TERM MEMORY (LTM): PostgreSQL CRM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ncursor.execute('''\n    CREATE TABLE IF NOT EXISTS conversation_history (\n        id              SERIAL PRIMARY KEY,\n        session_id      VARCHAR(255) NOT NULL,\n        timestamp       TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n        message_type    VARCHAR(50) NOT NULL,  -- user_message | bot_response | button_click\n        user_message    TEXT,\n        bot_response    TEXT,\n        button_clicked  VARCHAR(255),\n        form_type       VARCHAR(50),\n        menu_action     VARCHAR(255)\n    )\n''')\n\nclass ConversationTracker:\n    @staticmethod\n    def track_user_message(session_id, user_message):\n        cursor.execute('''\n            INSERT INTO conversation_history\n            (session_id, timestamp, message_type, user_message)\n            VALUES (%s, %s, %s, %s)\n        ''', (session_id, datetime.now(), 'user_message', user_message))\n\n    @staticmethod\n    def track_form_submit(session_id, form_type, form_data):\n        cursor.execute('''\n            INSERT INTO conversation_history\n            (session_id, timestamp, message_type, form_type, user_message)\n            VALUES (%s, %s, %s, %s, %s)\n        ''', (session_id, datetime.now(), 'form_submit', form_type, str(form_data)))\n<\/code><\/pre>\n\n\n\n<p>Code: <em>MemorySaver for per-session STM; PostgreSQL schema and ConversationTracker for persistent LTM<\/em><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"4_Building_Guardrails\"><\/span><strong>4. Building Guardrails<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>4.1 What Are Guardrails?<\/strong><\/h3>\n\n\n\n<p>A guardrail is a safety boundary that defines the scope of your chatbot&#8217;s behavior. After you build powerful tools covering all business domains, you still face a fundamental challenge: users will ask things completely outside your chatbot&#8217;s purpose \u2014 the weather, how to fix their phone, cryptocurrency prices, general machine learning concepts. None of which the Genetech chatbot is designed to answer.<\/p>\n\n\n\n<p>Without guardrails, the LLM might hallucinate an answer, share incorrect information, or respond in ways that are off-brand and confusing. With guardrails, the chatbot politely redirects these queries while keeping the conversation on topic.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><em>Guardrails define the boundary between what the chatbot CAN do and what it SHOULD NOT do \u2014 and ensure both cases are handled gracefully and professionally.<\/em><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>4.2 Guardrails as a Tool in the Genetech Agentic AI Chatbot<\/strong><\/h3>\n\n\n\n<p>In the Genetech chatbot, guardrails are implemented as a specialized tool called handle_irrelevant_queries. This design means the guardrail participates in the same ReAct loop as all other tools \u2014 the LLM itself decides when a query is out of scope and routes it to the guardrail tool.<\/p>\n\n\n\n<p>The system prompt explicitly instructs the agent to classify every query before routing, and mandates use of the guardrail tool for anything not related to Genetech Solutions business:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>General knowledge questions \u2014 history, science, cooking<\/li>\n\n\n\n<li>Technical tutorials unrelated to our services \u2014 how to code, how ML works<\/li>\n\n\n\n<li>Hardware issues \u2014 phone repair, laptop problems<\/li>\n\n\n\n<li>Physical construction or non-software services<\/li>\n\n\n\n<li>Personal advice, health, or entertainment queries<\/li>\n<\/ul>\n\n\n\n<p>The guardrail tool generates a polite, professional response that acknowledges the query, explains the chatbot&#8217;s scope, and gently redirects toward Genetech&#8217;s actual services. For example: &#8216;I&#8217;m sorry, but I can only help with Genetech Solutions topics. Would you like to know about our AI solutions or web development services?&#8217;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>4.3 Guardrails Flow Diagram<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3.jpg\"><img decoding=\"async\" width=\"1024\" height=\"877\" src=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3-1024x877.jpg\" alt=\"Diagram: Agentic AI Chatbot - Out-of-scope queries are intercepted within the ReAct loop \u2014 the LLM routes to the guardrail tool before generating any response\" class=\"wp-image-5380\" srcset=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3-1024x877.jpg 1024w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3-300x257.jpg 300w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3-768x658.jpg 768w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3-1536x1315.jpg 1536w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3-350x300.jpg 350w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3.jpg 1600w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Diagram: <em>Out-of-scope queries are intercepted within the ReAct loop \u2014 the LLM routes to the guardrail tool before generating any response<\/em><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>4.4 Code Snippet: Guardrail Tool and System Prompt Enforcement<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># \u2500\u2500 Guardrail Tool: handle_irrelevant_queries \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n@tool\ndef handle_irrelevant_queries(user_message: str = '') -&gt; str:\n    '''\n    Guardrail: Handles ANY query NOT related to Genetech Solutions business.\n    Triggered by LLM when it determines the query is out of scope.\n    Returns polite, professional redirect response.\n\n    Examples of triggers:\n    - General knowledge: 'What is the capital of France?'\n    - Hardware: 'How do I fix my phone?'\n    - Non-tech: 'Can you build me a smart watch?'\n    - Personal advice: 'What are good meditation techniques?'\n    '''\n    irrelevant_prompt = PromptTemplate(\n        template='''You are Genetech Solutions AI assistant.\n        USER MESSAGE: {user_message}\n        RESPONSE PATTERNS:\n        1. Hardware issues \u2192 'I'm sorry, I can only help with Genetech Solutions\n           topics. For device issues, please consult the manufacturer.'\n        2. Non-software build requests \u2192 'Sorry, I only help with software and\n           AI solutions. Want to build a website or mobile app?'\n        3. General queries \u2192 Acknowledge, redirect to Genetech services.\n        Keep response to 1-2 sentences. End with service invitation.\n        ''',\n        input_variables=&#091;'user_message']\n    )\n    chain = irrelevant_prompt | llm\n    return chain.invoke({'user_message': user_message}).content\n\n# \u2500\u2500 System Prompt Guardrail Enforcement \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nsystem_prompt = '''\nCRITICAL QUERY VALIDATION \u2014 APPLY BEFORE EVERY RESPONSE:\n\nRELEVANT queries (use appropriate tools):\n- Services, portfolio, pricing, team, awards, contact info\n- Hiring, consultation, sales connection, issue reporting\n- Software\/web\/mobile\/AI\/cloud development inquiries\n\nIRRELEVANT queries (MUST use handle_irrelevant_queries tool):\n- General knowledge, tutorials, personal advice\n- Hardware issues, physical construction, non-tech services\n- ANY topic not involving Genetech Solutions business\n\nRULE: If query is about ANYTHING other than Genetech business,\ncall handle_irrelevant_queries tool IMMEDIATELY<\/code><\/pre>\n\n\n\n<p>Code: <em>Guardrail tool using PromptTemplate + LLM for professional redirects; system prompt enforcement ensuring consistent classification<\/em><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"5_Testing_Monitoring_and_Observability\"><\/span><strong>5. Testing, Monitoring, and Observability<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>5.1 Testing the Chatbot<\/strong><\/h3>\n\n\n\n<p>Testing an AI agent is fundamentally different from testing traditional software. You cannot write unit tests with exact expected outputs, because LLM responses are probabilistic and context-dependent. Instead, the recommended approach is to build a custom evaluation dataset and benchmark the agent against it.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><em>Building a Custom Evaluation Dataset<\/em><\/h4>\n\n\n\n<p>For the Genetech agentic AI chatbot, testing involves creating a dataset of representative question-answer pairs across all tool domains:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Knowledge queries \u2014 &#8216;What services does Genetech offer?&#8217; \u2192 Expected: mentions web, mobile, AI, DevOps, cybersecurity<\/li>\n\n\n\n<li>Action triggers \u2014 &#8216;I want to build a website&#8217; \u2192 Expected: SHOW_LEAD_FORM signal<\/li>\n\n\n\n<li>Guardrail cases \u2014 &#8216;What is the capital of France?&#8217; \u2192 Expected: polite redirect, no Genetech answer<\/li>\n\n\n\n<li>Context follow-ups \u2014 &#8216;Tell me about your web services&#8217; \u2192 &#8216;What is the pricing?&#8217; \u2192 Expected: web-relevant pricing<\/li>\n\n\n\n<li>Industry routing \u2014 &#8216;I am in healthcare, how can you help?&#8217; \u2192 Expected: healthcare-specific service recommendations<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><em>A well-tested agent should achieve &gt;90% correct tool routing on the evaluation dataset before going live. Periodic re-evaluation after adding new tools or modifying prompts ensures regression-free deployments.<\/em><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>5.2 Monitoring and Observability with LangSmith<\/strong><\/h3>\n\n\n\n<p>AI agents have a fundamental challenge: they are black boxes. When a user reports that the chatbot gave a wrong answer, how do you debug it? Was it a bad prompt? Wrong tool selected? Tool returned incorrect data? Without observability, you are guessing.<\/p>\n\n\n\n<p>LangSmith is the observability platform for LangChain and LangGraph applications. It solves the black-box problem by capturing complete execution traces for every agent invocation. A trace captures the user&#8217;s input message, the LLM&#8217;s reasoning at each ReAct step, every tool call and its output, the final response, and token usage, latency per step, and total cost.<\/p>\n\n\n\n<p>For the Genetech agentic AI chatbot, this means if a user asked about pricing and got the wrong answer, you can open LangSmith, find the trace, see exactly which tool was called, what it returned, and how the LLM synthesized the final response. Debugging becomes deterministic rather than guesswork.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>5.3 LangSmith Monitoring Diagram<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3.png\"><img decoding=\"async\" width=\"1024\" height=\"825\" src=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3-1024x825.png\" alt=\"Diagram: LangSmith captures every step of every agent invocation \u2014 making debugging deterministic\" class=\"wp-image-5381\" srcset=\"https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3-1024x825.png 1024w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3-300x242.png 300w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3-768x619.png 768w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3-372x300.png 372w, https:\/\/www.genetechsolutions.com\/blog\/wp-content\/uploads\/2026\/04\/image-3.png 1427w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Diagram: <em>LangSmith captures every step of every agent invocation \u2014 making debugging deterministic<\/em><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>5.4 Code Snippet: LangSmith Observability Setup<\/strong><\/h3>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># \u2500\u2500 LangSmith Observability Setup (app.py) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nimport os\nfrom dotenv import load_dotenv\nload_dotenv()\n\n# Enable LangSmith tracing\nos.environ&#091;'LANGCHAIN_API_KEY']    = os.getenv('LANGCHAIN_API_KEY')\nos.environ&#091;'LANGCHAIN_PROJECT']    = os.getenv('LANGCHAIN_PROJECT')  # e.g. 'genetech-chatbot'\nos.environ&#091;'LANGCHAIN_TRACING_V2'] = 'true'\n\n# Once enabled, EVERY agent.invoke() call is automatically traced\n# No other code changes needed \u2014 LangGraph handles instrumentation\n\n# \u2500\u2500 LangSmith Evaluation: Benchmark Against Custom Dataset \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfrom langsmith import Client\nfrom langsmith.evaluation import evaluate\n\nclient = Client()\ndataset = client.create_dataset('genetech-chatbot-evals')\n\nclient.create_examples(\n    inputs=&#091;\n        {'message': 'What web development services do you offer?'},\n        {'message': 'I want to build a mobile app'},\n        {'message': 'What is the capital of France?'},  # Guardrail test\n    ],\n    outputs=&#091;\n        {'expected_tool': 'services_info'},\n        {'expected_signal': 'SHOW_LEAD_FORM'},\n        {'expected_tool': 'handle_irrelevant_queries'},\n    ],\n    dataset_id=dataset.id\n)\n\nresults = evaluate(\n    lambda inputs: agent_executor.invoke({'messages': &#091;HumanMessage(content=inputs&#091;'message'])]}),\n    data=dataset.name,\n    evaluators=&#091;'tool_selection_accuracy', 'response_relevance'],\n    experiment_prefix='genetech-v1'\n)<\/code><\/pre>\n\n\n\n<p>Code: <em>Three environment variables enable full LangSmith tracing. Evaluation dataset benchmarks tool selection accuracy and response relevance.<\/em><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_You_End_Up_With\"><\/span><strong>What You End Up With<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Work through these five pieces \u2014 ReAct architecture, specialized domain tools, dual-layer memory, guardrails, and observability \u2014 and you end up with a system that is meaningfully different from a chatbot in the traditional sense. It reasons. It selects tools based on what the user actually said, not what you hardcoded it to do. It remembers the conversation across turns and stores every interaction permanently. It stays on topic when pushed off it. And when something breaks, you can trace exactly what happened and why.<\/p>\n\n\n\n<p>That is the Genetech chatbot. Every code snippet in this post is drawn from the actual implementation. Every architectural decision reflects a real tradeoff we made. The system is live at genetechsolutions.com, and if you want to understand what it feels like from the user side before you commit to building something like it, the fastest way is to open the chat widget on this page and try it with a real question.<\/p>\n\n\n\n<p>What you experience as a user \u2014 the way it handles ambiguity, the way it routes between knowledge queries and action triggers, the way it terminates in a form \u2014 is the system this post describes, running in real time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Build_Yours_With_Us\"><\/span><strong>Build Yours With Us<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>If you have worked through this post and have a use case forming in your head \u2014 a specific workflow, a conversion problem, a customer experience you want to improve \u2014 the next step is a conversation, not a commitment. We built this system for ourselves. We know what it takes to build one for a business with real requirements, real constraints, and real users.<\/p>\n\n\n\n<p>Use the chatbot on this page to start that conversation. It will route you to the right person. Or if you would rather go direct:<\/p>\n\n\n\n<p><strong>\u2192 <\/strong><a href=\"http:\/\/genetechsolutions.com\/contact\"><strong>genetechsolutions.com\/contact<\/strong> <\/a><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The chatbot sitting on the main page of Genetech Solutions website is not a widget from a SaaS platform. It is not a scripted FAQ bot. It is a fully custom agentic AI system built by our own team, running &hellip;<br \/> <a class=\"readmore\" href=\"https:\/\/www.genetechsolutions.com\/blog\/agentic-ai-chatbot-code\/\"> <span class=\"meta-nav\"><\/span><\/a><\/p>\n","protected":false},"author":27,"featured_media":5372,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[109],"tags":[],"class_list":["post-5371","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-emerging-tech"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.genetechsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/5371","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.genetechsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.genetechsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.genetechsolutions.com\/blog\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/www.genetechsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=5371"}],"version-history":[{"count":14,"href":"https:\/\/www.genetechsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/5371\/revisions"}],"predecessor-version":[{"id":5403,"href":"https:\/\/www.genetechsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/5371\/revisions\/5403"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.genetechsolutions.com\/blog\/wp-json\/wp\/v2\/media\/5372"}],"wp:attachment":[{"href":"https:\/\/www.genetechsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=5371"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.genetechsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=5371"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.genetechsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=5371"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}