<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gunasekaran</title>
    <description>The latest articles on DEV Community by Gunasekaran (@kalaiguna).</description>
    <link>https://dev.to/kalaiguna</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%2F674081%2F15906287-998d-4b00-9a03-14ce6dd94291.jpeg</url>
      <title>DEV Community: Gunasekaran</title>
      <link>https://dev.to/kalaiguna</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kalaiguna"/>
    <language>en</language>
    <item>
      <title>I built a Multi-Agent Support System in 5 Days (And Learned Why "God Agents" Don't Work)</title>
      <dc:creator>Gunasekaran</dc:creator>
      <pubDate>Thu, 11 Dec 2025 16:06:36 +0000</pubDate>
      <link>https://dev.to/kalaiguna/i-built-a-multi-agent-support-system-in-5-days-and-learned-why-god-agents-dont-work-4e06</link>
      <guid>https://dev.to/kalaiguna/i-built-a-multi-agent-support-system-in-5-days-and-learned-why-god-agents-dont-work-4e06</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-kaggle-ai-agents-2025-11-10"&gt;Google AI Agents Writing Challenge&lt;/a&gt;: Learning Reflections&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Aha" Moment
&lt;/h2&gt;

&lt;p&gt;I’ve been playing with LLMs for a while, mostly just prompting them to write code or answer questions. But I kept hitting a wall: the models were smart, but they were trapped in a text box. They couldn't &lt;em&gt;do&lt;/em&gt; anything.&lt;/p&gt;

&lt;p&gt;Last month, I joined the &lt;strong&gt;Google &amp;amp; Kaggle 5-Day AI Agents Intensive&lt;/strong&gt;, and it clicked. The future isn't just better chatbots; it's &lt;strong&gt;Agentic AI&lt;/strong&gt;—systems that can reason, use tools, and actually execute tasks.&lt;/p&gt;

&lt;p&gt;I wanted to prove this to myself, so for my capstone, I built &lt;strong&gt;&lt;a href="https://www.kaggle.com/competitions/agents-intensive-capstone-project/writeups/autosupport-intelligent-customer-agent" rel="noopener noreferrer"&gt;AutoSupport&lt;/a&gt;&lt;/strong&gt;—a system that doesn't just chat, but actually triages and attempts to resolve customer support tickets using a team of specialized agents. Here is how I built it and what I learned along the way.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Shift: From Monoliths to Teams
&lt;/h2&gt;

&lt;p&gt;The biggest takeaway from the course wasn't a specific line of code, but an architectural shift. In the beginning (Day 1), I was tempted to build one giant agent with a massive prompt to handle everything.&lt;/p&gt;

&lt;p&gt;By Day 2, I realized that fails. A "God Agent" gets confused. It hallucinates. It tries to fix billing issues with technical solutions.&lt;/p&gt;

&lt;p&gt;Instead, I adopted the &lt;strong&gt;Orchestrator Pattern&lt;/strong&gt;. Think of it like a real office: you don't have the receptionist fix the server. You have a receptionist (Triage Agent) who figures out what’s wrong and sends you to the IT Guy (Technical Agent) or the Accountant (Billing Agent).&lt;/p&gt;




&lt;h2&gt;
  
  
  Building "AutoSupport": My Capstone
&lt;/h2&gt;

&lt;p&gt;I decided to build a system that could ingest a raw customer complaint, figure out what it was actually about, and route it to a specialist.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Architecture
&lt;/h3&gt;

&lt;p&gt;I used the &lt;code&gt;google-adk&lt;/code&gt; library to structure my team. I needed four distinct roles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Triage Specialist:&lt;/strong&gt; The gatekeeper.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Billing Specialist:&lt;/strong&gt; Handles money, refunds, and subscriptions.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Technical Specialist:&lt;/strong&gt; Handles API errors and bugs.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Account Specialist:&lt;/strong&gt; Handles logins and passwords.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is the flow I designed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graph TD
    User[User Query] --&amp;gt; Orchestrator[Support Orchestrator]
    Orchestrator --&amp;gt; Triage[Triage Agent]
    Triage --&amp;gt; Router{Routing Logic}
    Router --&amp;gt;|Money Issue| Billing[Billing Specialist]
    Router --&amp;gt;|Bug/API| Tech[Technical Specialist]
    Router --&amp;gt;|Login| Account[Account Specialist]

    Billing --&amp;gt; Search[Google Search Tool]
    Tech --&amp;gt; Search

    Billing --&amp;gt; Response[Final Answer]
    Tech --&amp;gt; Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Code Logic&lt;/strong&gt;&lt;br&gt;
The most critical part wasn't the LLM itself, but the Python logic around it. In my SupportOrchestrator class, I didn't just trust the LLM to route things magically. I implemented a keyword-based routing layer to assist the decision-making.&lt;/p&gt;

&lt;p&gt;Here is a snippet from my actual code. I defined specific trigger words for each domain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def route_to_specialist(self, customer_message: str, triage_response: str):
    # ...setup...

    # I used strictly defined keywords to catch specific issues
    billing_keywords = ['billing', 'payment', 'refund', 'charge', 'invoice']
    technical_keywords = ['api', 'error', 'technical', 'bug', '401', '403']
    account_keywords = ['account', 'login', 'password', 'access', 'security']

    # Check if the message or the triage agent's thoughts contain these keywords
    if any(keyword in message_lower for keyword in billing_keywords):
        return "billing"
    elif any(keyword in message_lower for keyword in technical_keywords):
        return "technical"
    # ... logic continues ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This hybrid approach—using the LLM to understand the sentiment and Python to enforce the routing—made the system much more reliable than an LLM alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Happened (The Testing Phase)
&lt;/h2&gt;

&lt;p&gt;I ran the system through a few scenarios to see if it would actually work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test 1:&lt;/strong&gt; The API Error I fed it: "I'm getting 401 unauthorized errors on all my API calls." The Triage agent correctly flagged it as Technical. The router spun up the technical_specialist, which immediately offered troubleshooting steps for API keys and headers. It worked perfectly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test 2:&lt;/strong&gt; The Double Charge Input: "I was charged twice for my subscription." The system routed this to the Billing Specialist. What I liked was the tone shift—the billing agent was prompted to be empathetic ("I understand how frustrating it must be") while the technical agent was more direct.&lt;/p&gt;

&lt;p&gt;The "Gotcha" Moment It wasn't all smooth sailing. During my validation run, I noticed that a query about "logging in" initially risked being misrouted to technical support because it contained the word "error." This taught me that simple keyword matching has limits. In a V2, I’d probably implement a semantic router (using embeddings) rather than hard-coded lists.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Key Takeaways from the Course
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tools are everything:&lt;/strong&gt; An agent without tools is just a chatty encyclopedia. Giving my agents access to Google Search (Day 2 lab) completely changed the utility of the responses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State is hard:&lt;/strong&gt; Managing conversation history (Day 3) is tricky. You can't just dump the whole chat log into the context window or you'll burn through tokens. I learned about "Context Compaction"—summarizing the history to keep the agent focused.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evaluations save you:&lt;/strong&gt; You can't fix what you don't measure. The Day 4 labs on observability showed me that I need to log why an agent made a decision, not just the final output.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;This course laid the foundation. Next, I want to take &lt;strong&gt;AutoSupport&lt;/strong&gt; and deploy it using &lt;strong&gt;Vertex AI&lt;/strong&gt; so it’s not just running in a notebook. I also want to add a &lt;strong&gt;"Human in the Loop"&lt;/strong&gt; feature for when the confidence score is low—because sometimes, you really just need to talk to a person.&lt;/p&gt;

&lt;p&gt;Thanks to the Google and Kaggle team for this wonderful crash course on Agentic AI!&lt;/p&gt;

</description>
      <category>googleaichallenge</category>
      <category>ai</category>
      <category>agents</category>
      <category>devchallenge</category>
    </item>
  </channel>
</rss>
