<?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: Sparsh Jain</title>
    <description>The latest articles on DEV Community by Sparsh Jain (@splintersword).</description>
    <link>https://dev.to/splintersword</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%2F3200544%2Fc814b736-3abf-4ca7-bc33-542d01ddf568.png</url>
      <title>DEV Community: Sparsh Jain</title>
      <link>https://dev.to/splintersword</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/splintersword"/>
    <language>en</language>
    <item>
      <title>I Built a RAG Search Engine from Scratch to Understand How Modern Search Actually Works</title>
      <dc:creator>Sparsh Jain</dc:creator>
      <pubDate>Thu, 26 Feb 2026 04:16:03 +0000</pubDate>
      <link>https://dev.to/splintersword/i-built-a-rag-search-engine-from-scratch-to-understand-how-modern-search-actually-works-16ng</link>
      <guid>https://dev.to/splintersword/i-built-a-rag-search-engine-from-scratch-to-understand-how-modern-search-actually-works-16ng</guid>
      <description>&lt;p&gt;Everyone is building RAG apps.&lt;/p&gt;

&lt;p&gt;But most tutorials skip the most important part — &lt;strong&gt;search quality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So instead of just plugging in a framework, I decided to build my own &lt;strong&gt;RAG Search Engine&lt;/strong&gt; from scratch to deeply understand how retrieval systems work under the hood.&lt;/p&gt;

&lt;p&gt;This project helped me explore the real mechanics behind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keyword search&lt;/li&gt;
&lt;li&gt;Semantic search&lt;/li&gt;
&lt;li&gt;Hybrid ranking&lt;/li&gt;
&lt;li&gt;Reranking models&lt;/li&gt;
&lt;li&gt;Evaluation metrics&lt;/li&gt;
&lt;li&gt;Multimodal retrieval&lt;/li&gt;
&lt;li&gt;Retrieval-Augmented Generation (RAG)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can watch the full breakdown here:&lt;br&gt;&lt;br&gt;
 &lt;strong&gt;YouTube Video:&lt;/strong&gt; [&lt;a href="https://www.youtube.com/watch?v=HEx0A5R-_Tc" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=HEx0A5R-_Tc&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;GitHub repository:&lt;br&gt;&lt;br&gt;
 &lt;strong&gt;Source Code:&lt;/strong&gt; [&lt;a href="https://github.com/SplinterSword/RAG-Search-Engine" rel="noopener noreferrer"&gt;https://github.com/SplinterSword/RAG-Search-Engine&lt;/a&gt;]&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Project Implements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Keyword Search (BM25)
&lt;/h3&gt;

&lt;p&gt;I implemented classical information retrieval techniques like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TF (Term Frequency)&lt;/li&gt;
&lt;li&gt;IDF (Inverse Document Frequency)&lt;/li&gt;
&lt;li&gt;BM25 scoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helped me understand why traditional keyword search is still extremely powerful in production systems.&lt;/p&gt;




&lt;h3&gt;
  
  
  Semantic Search (Embeddings + Vector Similarity)
&lt;/h3&gt;

&lt;p&gt;I added dense retrieval using embeddings and cosine similarity to capture meaning instead of exact keyword matches.&lt;/p&gt;

&lt;p&gt;This allows the system to handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Synonyms&lt;/li&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;Conceptual similarity&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Hybrid Search
&lt;/h3&gt;

&lt;p&gt;Instead of choosing between keyword or semantic search, I combined them using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Weighted fusion&lt;/li&gt;
&lt;li&gt;Reciprocal Rank Fusion (RRF)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is closer to how modern production search systems operate — combining precision and semantic understanding.&lt;/p&gt;




&lt;h3&gt;
  
  
  Reranking with Cross-Encoders
&lt;/h3&gt;

&lt;p&gt;After retrieving top results, I added a reranking stage to refine relevance.&lt;/p&gt;

&lt;p&gt;This significantly improved result quality by evaluating query-document pairs more deeply.&lt;/p&gt;




&lt;h3&gt;
  
  
  Evaluation (The Part Most People Skip)
&lt;/h3&gt;

&lt;p&gt;I didn’t just build the system — I measured it.&lt;/p&gt;

&lt;p&gt;I implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Precision&lt;/li&gt;
&lt;li&gt;Recall&lt;/li&gt;
&lt;li&gt;F1 Score&lt;/li&gt;
&lt;li&gt;Manual evaluation&lt;/li&gt;
&lt;li&gt;LLM-as-a-judge evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helped me understand how to properly assess retrieval performance.&lt;/p&gt;




&lt;h3&gt;
  
  
  Multimodal Search
&lt;/h3&gt;

&lt;p&gt;I also experimented with text + image retrieval using embedding-based similarity.&lt;/p&gt;




&lt;h3&gt;
  
  
  Retrieval-Augmented Generation (RAG)
&lt;/h3&gt;

&lt;p&gt;Finally, I connected the hybrid retrieval system to an LLM to generate grounded responses.&lt;/p&gt;

&lt;p&gt;This reinforced one important lesson:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Better retrieval &amp;gt; Bigger model.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Why I Built This
&lt;/h2&gt;

&lt;p&gt;Most RAG demos abstract away the hardest part — retrieval.&lt;/p&gt;

&lt;p&gt;I wanted to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How ranking algorithms work&lt;/li&gt;
&lt;li&gt;Why hybrid systems outperform pure approaches&lt;/li&gt;
&lt;li&gt;How reranking improves precision&lt;/li&gt;
&lt;li&gt;How evaluation should actually be done&lt;/li&gt;
&lt;li&gt;What tradeoffs exist in search system design&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project was about learning how modern search systems are engineered — not just calling an API.&lt;/p&gt;




&lt;p&gt;If you're interested in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search engines
&lt;/li&gt;
&lt;li&gt;Information retrieval
&lt;/li&gt;
&lt;li&gt;RAG systems
&lt;/li&gt;
&lt;li&gt;AI system design
&lt;/li&gt;
&lt;li&gt;Hybrid search architectures
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’d love to hear your thoughts.&lt;/p&gt;

&lt;p&gt;Let me know what you’d improve or explore next 👇&lt;/p&gt;

</description>
      <category>rag</category>
      <category>ai</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>THIS IS HOW REAL PASSWORD MANAGERS ACTUALLY WORK</title>
      <dc:creator>Sparsh Jain</dc:creator>
      <pubDate>Mon, 09 Feb 2026 12:00:39 +0000</pubDate>
      <link>https://dev.to/splintersword/this-is-how-real-password-managers-actually-work-46ib</link>
      <guid>https://dev.to/splintersword/this-is-how-real-password-managers-actually-work-46ib</guid>
      <description>&lt;p&gt;Most people use password managers every day.&lt;br&gt;&lt;br&gt;
Very few understand how they actually keep passwords secure.&lt;/p&gt;

&lt;p&gt;In this article, I break down how &lt;strong&gt;real, production-grade password managers work&lt;/strong&gt; — the same core ideas used by tools like &lt;strong&gt;1Password&lt;/strong&gt; or &lt;strong&gt;Bitwarden&lt;/strong&gt; — by walking through a project I built called &lt;strong&gt;Passwuts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;🎥 &lt;strong&gt;Full video walkthrough:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://youtu.be/G1m7K7ZG1M0" rel="noopener noreferrer"&gt;https://youtu.be/G1m7K7ZG1M0&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Built Passwuts
&lt;/h2&gt;

&lt;p&gt;Password reuse is one of the biggest security risks today.&lt;/p&gt;

&lt;p&gt;When a single website is breached, reused passwords expose users across &lt;em&gt;every&lt;/em&gt; service they use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Passwuts&lt;/strong&gt; solves this by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enforcing strong, unique passwords&lt;/li&gt;
&lt;li&gt;Using &lt;strong&gt;client-side encryption&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Ensuring the &lt;strong&gt;server never sees plaintext credentials&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the same security philosophy used by serious password managers.&lt;/p&gt;




&lt;h2&gt;
  
  
  High-Level Architecture (Zero-Knowledge Model)
&lt;/h2&gt;

&lt;p&gt;Passwuts follows a &lt;strong&gt;zero-knowledge, client-first encryption model&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔐 Master password &lt;strong&gt;never leaves the client&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🔑 Encryption keys are derived locally using &lt;strong&gt;PBKDF2&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🔒 Passwords are encrypted using &lt;strong&gt;AES-GCM&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🗄️ Server stores &lt;strong&gt;only ciphertext + IV&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if the backend is compromised, passwords remain safe.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Encryption Works (Step-by-Step)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;User creates a &lt;strong&gt;master password&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;A strong encryption key is derived using &lt;strong&gt;PBKDF2&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Inputs: master password + user UID (as salt)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Passwords are encrypted using &lt;strong&gt;AES-GCM&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Each encryption uses a &lt;strong&gt;random IV&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Only encrypted data is stored in Firestore&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At no point does plaintext leave the browser.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vault Verification (Without Storing Passwords)
&lt;/h2&gt;

&lt;p&gt;A common problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do you verify the master password without storing it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Passwuts uses a &lt;strong&gt;verifier pattern&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A known string (&lt;code&gt;"vault-check"&lt;/code&gt;) is encrypted&lt;/li&gt;
&lt;li&gt;Stored in Firestore as &lt;strong&gt;vault metadata&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;On unlock:

&lt;ul&gt;
&lt;li&gt;Client decrypts it locally&lt;/li&gt;
&lt;li&gt;If it decrypts correctly → password is valid&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;✅ Secure&lt;br&gt;&lt;br&gt;
✅ Zero-knowledge&lt;br&gt;&lt;br&gt;
✅ No password storage&lt;/p&gt;




&lt;h2&gt;
  
  
  Browser Extension Architecture
&lt;/h2&gt;

&lt;p&gt;The browser extension reuses the &lt;strong&gt;exact same crypto layer&lt;/strong&gt; as the web app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firebase authentication&lt;/li&gt;
&lt;li&gt;Shared internal crypto package (&lt;code&gt;@pm/crypto&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Client-side encryption only&lt;/li&gt;
&lt;li&gt;No secret logic in the backend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps behavior consistent across platforms.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Project Taught Me
&lt;/h2&gt;

&lt;p&gt;Building a password manager taught me some hard lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔍 Crypto failures usually come from &lt;strong&gt;misuse&lt;/strong&gt;, not math&lt;/li&gt;
&lt;li&gt;🔄 IV / nonce management is critical&lt;/li&gt;
&lt;li&gt;🧠 Security UX matters as much as cryptography&lt;/li&gt;
&lt;li&gt;🔐 Zero-knowledge systems require discipline everywhere&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Password managers are not magic.&lt;/p&gt;

&lt;p&gt;They are &lt;strong&gt;carefully engineered systems&lt;/strong&gt; built on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Key derivation&lt;/li&gt;
&lt;li&gt;Authenticated encryption&lt;/li&gt;
&lt;li&gt;Secure client-side architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding how they work makes you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A better engineer&lt;/li&gt;
&lt;li&gt;A safer user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you enjoyed this breakdown, watch the full video walkthrough 👇&lt;br&gt;&lt;br&gt;
🎥 &lt;a href="https://youtu.be/G1m7K7ZG1M0" rel="noopener noreferrer"&gt;https://youtu.be/G1m7K7ZG1M0&lt;/a&gt;&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>security</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Understanding Polyfills: Bridging the Gap in Modern and Old Web Browsers</title>
      <dc:creator>Sparsh Jain</dc:creator>
      <pubDate>Sun, 28 Sep 2025 12:05:36 +0000</pubDate>
      <link>https://dev.to/splintersword/understanding-polyfills-bridging-the-gap-in-modern-and-old-web-browsers-k04</link>
      <guid>https://dev.to/splintersword/understanding-polyfills-bridging-the-gap-in-modern-and-old-web-browsers-k04</guid>
      <description>&lt;p&gt;Modern web development is exciting. With JavaScript evolving rapidly and new web APIs emerging constantly, developers can build highly interactive and feature-rich applications. But here’s the challenge: &lt;strong&gt;not all browsers support these features natively&lt;/strong&gt;, especially older ones like Internet Explorer.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;polyfills&lt;/strong&gt; come in—a small piece of code that ensures your modern web features work across all browsers, bridging the gap between the old and the new.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a Polyfill?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;polyfill&lt;/strong&gt; is essentially a &lt;strong&gt;patch for missing features in older browsers&lt;/strong&gt;. It implements functionality that is present in modern browsers but absent in older ones.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Think of it like this: if modern browsers speak a new language, polyfills act as translators for older browsers, allowing them to understand and execute your code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Polyfills are crucial for &lt;strong&gt;cross-browser compatibility&lt;/strong&gt;. They let developers use modern JavaScript features without worrying that some users will see broken functionality.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Do We Need Polyfills?
&lt;/h2&gt;

&lt;p&gt;Even though modern browsers like Chrome, Firefox, Edge, and Safari update frequently, not all users keep their browsers updated. Some might still be using older versions or legacy browsers, which could break your website if you rely solely on modern APIs.&lt;/p&gt;

&lt;p&gt;Polyfills help:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ensure cross-browser compatibility&lt;/strong&gt;: Your application behaves consistently across different browsers and versions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable progressive enhancement&lt;/strong&gt;: You can use modern features while providing fallbacks for unsupported browsers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintain a smooth user experience&lt;/strong&gt;: Avoid runtime errors that could break your application for certain users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future-proof your code&lt;/strong&gt;: You can write modern code now without worrying about alienating users on older platforms.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Example Scenario: &lt;code&gt;Array.forEach()&lt;/code&gt; and Simulating Unsupported Browsers
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Array.prototype.forEach()&lt;/code&gt; method allows you to iterate over arrays conveniently:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&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="mi"&gt;2&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 2, 4, 6, 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Older browsers like Internet Explorer 8 &lt;strong&gt;do not support &lt;code&gt;forEach()&lt;/code&gt;&lt;/strong&gt;, which would break your code. To &lt;strong&gt;simulate an unsupported browser&lt;/strong&gt;, you can temporarily remove &lt;code&gt;forEach&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simulate missing forEach in old browsers&lt;/span&gt;
&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// This would throw an error in browsers that don't support it&lt;/span&gt;
&lt;span class="c1"&gt;// numbers.forEach(num =&amp;gt; console.log(num * 2));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Polyfill for &lt;code&gt;Array.forEach&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Polyfill for Array.forEach&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;thisArg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thisArg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Test after applying polyfill&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&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="mi"&gt;2&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 2, 4, 6, 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Full Demonstration Code
&lt;/h3&gt;

&lt;p&gt;Here’s the &lt;strong&gt;complete example combining all steps&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Step 1: Original array&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&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="mi"&gt;2&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Original forEach:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 2, 4, 6, 8&lt;/span&gt;

&lt;span class="c1"&gt;// Step 2: Simulate unsupported browser&lt;/span&gt;
&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Step 3: Uncommenting the following line would throw an error&lt;/span&gt;
&lt;span class="c1"&gt;// numbers.forEach(num =&amp;gt; console.log(num * 2));&lt;/span&gt;

&lt;span class="c1"&gt;// Step 4: Polyfill for Array.forEach&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;thisArg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thisArg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Step 5: Test after polyfill&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;After polyfill:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// Output: 2, 4, 6, 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Other Common Features Needing Polyfills
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Promise&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fetch()&lt;/code&gt; API&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Array.includes()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Object.assign()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;String.padStart()&lt;/code&gt; / &lt;code&gt;String.padEnd()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of writing these polyfills manually, developers often rely on libraries like &lt;strong&gt;core-js&lt;/strong&gt;, &lt;strong&gt;babel-polyfill&lt;/strong&gt;, or services like &lt;strong&gt;polyfill.io&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tools for Using Polyfills
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;core-js&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A modular library that implements &lt;strong&gt;ES6, ES7, and beyond features&lt;/strong&gt;. You can selectively import only what you need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;core-js/es/array/includes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/babel"&gt;@babel&lt;/a&gt;/preset-env&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Babel can automatically include necessary polyfills based on your target browsers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// babel.config.js&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;presets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@babel/preset-env&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;useBuiltIns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;entry&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;corejs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;strong&gt;polyfill.io&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A service that serves only the polyfills needed for the &lt;strong&gt;requesting browser&lt;/strong&gt;, minimizing bundle size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://polyfill.io/v3/polyfill.min.js?features=Array.prototype.forEach,Promise"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Best Practices for Using Polyfills
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Polyfill selectively&lt;/strong&gt;: Only include what is needed to reduce your bundle size.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature detection first&lt;/strong&gt;: Always check if a browser supports a feature before polyfilling it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encourage modern browsers&lt;/strong&gt;: While polyfills help, it’s better to prompt users to update their browsers for performance and security benefits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Combine with transpilers&lt;/strong&gt;: Tools like Babel can transform modern syntax while polyfills add missing runtime features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test across browsers&lt;/strong&gt;: Always test your application in the browsers you aim to support.&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;Polyfills are a &lt;strong&gt;bridge between modern web capabilities and older browser environments&lt;/strong&gt;. They let developers write modern, clean code without leaving behind users on outdated browsers.&lt;/p&gt;

&lt;p&gt;By understanding polyfills, using feature detection wisely, and combining them with tools like Babel or core-js, you can create &lt;strong&gt;robust, cross-browser applications&lt;/strong&gt; that work for everyone.&lt;/p&gt;

&lt;p&gt;Modern web development is about innovation, but accessibility matters too. &lt;strong&gt;Polyfills ensure no one is left behind.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The Googly way of Making AI Agents</title>
      <dc:creator>Sparsh Jain</dc:creator>
      <pubDate>Fri, 27 Jun 2025 12:06:31 +0000</pubDate>
      <link>https://dev.to/splintersword/the-googly-way-of-making-ai-agents-4g9l</link>
      <guid>https://dev.to/splintersword/the-googly-way-of-making-ai-agents-4g9l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I want to start by saying, this not a guide or post explaining how to use tools like &lt;a href="https://n8n.io/" rel="noopener noreferrer"&gt;n8n&lt;/a&gt; or &lt;a href="https://app.toolhouse.ai/" rel="noopener noreferrer"&gt;ToolHouse AI&lt;/a&gt; (By the way, already written a blog about how to use ToolHouse AI, you can read it by going &lt;a href="https://dev.to/splintersword/making-ai-agents-easy-17m7"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I wanted to write about how to make like a &lt;strong&gt;BIG BOI DEVELOPER&lt;/strong&gt; using python and real lines of code. Allowing you all to make your customise AI Agents easily for any app you desire. Who knows maybe you can create the next million dollar AI Agent startup.&lt;/p&gt;

&lt;p&gt;Now setup your local IDE with python and get ready to build your first AI Agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which Framework to choose
&lt;/h2&gt;

&lt;p&gt;Though there are many frameworks to build AI Agents like &lt;a href="https://www.langchain.com/" rel="noopener noreferrer"&gt;LangChain&lt;/a&gt;, &lt;a href="https://dev.toCrewAI"&gt;https://www.crewai.com/&lt;/a&gt;, etc, I recommend &lt;a href="https://google.github.io/adk-docs/" rel="noopener noreferrer"&gt;Google Agent Development Kit&lt;/a&gt; because first of all it is genuinely awesome and second of all it is by far the least complicated ,all the while being very powerful and providing all the necessary tools to build a &lt;strong&gt;Multi Agent Modal&lt;/strong&gt; from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Google ADK
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://google.github.io/adk-docs/" rel="noopener noreferrer"&gt;Google Agent Development Kit&lt;/a&gt; is is a flexible and modular framework for developing and deploying AI agents. While optimized for Gemini and the Google ecosystem, ADK is model-agnostic (fancy word for saying that it can use any agent like openAI,etc), deployment-agnostic, and is built for compatibility with other frameworks. ADK was designed to make agent development feel more like software development, to make it easier for developers to create, deploy, and orchestrate agentic architectures that range from simple tasks to complex workflows.&lt;/p&gt;

&lt;p&gt;It makes task so simple that it even has it's own function for starting a fastAPI server (which can be used as any other fastAPI server), handling all the complex session management, on its own so you can just focus on creating your app.&lt;/p&gt;

&lt;p&gt;It even has a built in Angular web application to test your AI Agents, where you can see what is the flows of actions taking place under the hood. You can even customize the UI to build your own custom made web app.&lt;/p&gt;

&lt;p&gt;You can all accomplish it by using just one package, &lt;strong&gt;Google ADK&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use Google ADK
&lt;/h2&gt;

&lt;p&gt;Now I will talk about how to use it :-&lt;/p&gt;

&lt;p&gt;First and most obvious is to download and install the python package, you can install it running this command :-&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Now before moving you need make sure that you have this exact structure in your directory if you don't want to deal with session management and creating a runner. You also need to have a &lt;strong&gt;root_agent&lt;/strong&gt; in every agent.py file. If you want full customizability in file structure you have create a your own session management and runner which not that hard either. I will link the docs at the end of this section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parent_folder/
    multi_tool_agent/ (Directory name = Name of the agent = App Name)
        __init__.py
        agent.py
        .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second setup your .env file in this format&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GOOGLE_GENAI_USE_VERTEXAI=FALSE
GOOGLE_API_KEY=PASTE_YOUR_ACTUAL_API_KEY_HERE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we get to the meet and potatoes of the code first open your &lt;strong&gt;init.py&lt;/strong&gt; file and paste this :-&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;.&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you are done with previous step, open the agent.py files(the file where the agents are defined) and paste this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;zoneinfo&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ZoneInfo&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.adk.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Retrieves the current weather report for a specified city.

    Args:
        city (str): The name of the city for which to retrieve the weather report.

    Returns:
        dict: status and result or error msg.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&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;new york&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&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;report&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The weather in New York is sunny with a temperature of 25 degrees&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; Celsius (77 degrees Fahrenheit).&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;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error_message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Weather information 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;city&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; is not available.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_current_time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Returns the current time in a specified city.

    Args:
        city (str): The name of the city for which to retrieve the current time.

    Returns:
        dict: status and result or error msg.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&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;new york&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;tz_identifier&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;America/New_York&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="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;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error_message&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sorry, I don&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t have timezone information for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="si"&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="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;tz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ZoneInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tz_identifier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tz&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="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;The current time in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d %H&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;Z&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;z&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="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&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;report&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;root_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;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;weather_time_agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-2.0-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&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;Agent to answer questions about the time and weather in a city.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;instruction&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;You are a helpful agent who can answer user questions about the time and weather in a city.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_current_time&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;and you are done with creating your AI Agent.&lt;/p&gt;

&lt;p&gt;Final step is testing which can be easily done by just navigating to the parent directory and just running this command :-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;adk web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which will open this UI in your library.&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%2Fhs9na63qdugvyzof2bi9.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%2Fhs9na63qdugvyzof2bi9.png" alt="ADK WEB UI" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can test the modal and see the workflow in this UI by giving it a prompt and using the &lt;strong&gt;Events&lt;/strong&gt; tab which looks like this :-&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%2Fsz3i5k6me5morgc8plic.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%2Fsz3i5k6me5morgc8plic.png" alt="ADK WEB Events Tab" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;Events&lt;/strong&gt; tab, you can also click the Trace button to see the trace logs for each event that shows the latency of each function calls:&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%2Fj011h8zyxx0oi08svn7h.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%2Fj011h8zyxx0oi08svn7h.png" alt="ADK WEB Trace tab" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking down the above code
&lt;/h2&gt;

&lt;p&gt;The code in agent.py (which is the main code) has several variables and functions, which contain the &lt;strong&gt;tools&lt;/strong&gt; used by the AI agents to complete the request and the &lt;strong&gt;Agent Definition&lt;/strong&gt;, I will break down these part one by one :-&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools&lt;/strong&gt; - Tools are the functions which the agent has access to accomplish tasks. These functions can be custom python functions or built in functions provided by google (which include google search, code runner, etc). If you want to build your custom tool (custom python function), It is important to keep one thing in mind.&lt;br&gt;
Write clear, descriptive, and accurate docstrings for your tools (python functions). This is essential for the LLM to use the tool correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Descriptive docstring
&lt;/span&gt;    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Retrieves the current weather report for a specified city.

    Args:
        city (str): The name of the city for which to retrieve the weather report.

    Returns:
        dict: status and result or error msg.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&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;new york&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&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;report&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The weather in New York is sunny with a temperature of 25 degrees&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; Celsius (77 degrees Fahrenheit).&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;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;error_message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Weather information 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;city&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; is not available.&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;&lt;strong&gt;Agent Definition&lt;/strong&gt; - This is the part which what your agent is and what does it / what is its role. This definition looks like this :-&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="n"&gt;root_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;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;NAME&lt;/span&gt; &lt;span class="n"&gt;OF&lt;/span&gt; &lt;span class="n"&gt;THE&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;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt; &lt;span class="n"&gt;LLM&lt;/span&gt; &lt;span class="n"&gt;MODAL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;DESCRIPTION&lt;/span&gt; &lt;span class="n"&gt;OF&lt;/span&gt; &lt;span class="n"&gt;THE&lt;/span&gt; &lt;span class="n"&gt;MODAL&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;instruction&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;INSTRUCTIONS&lt;/span&gt; &lt;span class="n"&gt;OF&lt;/span&gt; &lt;span class="n"&gt;THE&lt;/span&gt; &lt;span class="n"&gt;MODAL&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="n"&gt;WHAT&lt;/span&gt; &lt;span class="n"&gt;IT&lt;/span&gt; &lt;span class="n"&gt;DOES&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;TOOLS&lt;/span&gt; &lt;span class="n"&gt;ACCESSIBLE&lt;/span&gt; &lt;span class="n"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;THE&lt;/span&gt; &lt;span class="n"&gt;AGENT&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;Particularly &lt;strong&gt;Description&lt;/strong&gt; and &lt;strong&gt;Instructions&lt;/strong&gt; are important as descriptions tell other agents in a multi agent modal what this agent is so they can use it accordingly and instructions define the agent behavior, constraints and guardrails, etc.&lt;/p&gt;

&lt;p&gt;For deeper dive into these topics and if you want to learn about the &lt;strong&gt;Google ADK&lt;/strong&gt;, here are the &lt;a href="https://google.github.io/adk-docs/" rel="noopener noreferrer"&gt;docs&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Google ADK&lt;/strong&gt; is a powerful framework allowing you to build anything  from a simple single agent workflow to complex multi-agent modal, with much complications while providing all the flexibility that a developer would need. &lt;/p&gt;

&lt;p&gt;In fact here the multi agent modal I build for my personal project &lt;a href="https://edu-assistant.vercel.app/" rel="noopener noreferrer"&gt;EduAssistant&lt;/a&gt;(&lt;a href="https://github.com/SplinterSword/EduAssistant" rel="noopener noreferrer"&gt;Github&lt;/a&gt;), which is a ai tutor, making exam preparations easy. Go check it out. Now enough of shilling, here is the code :-&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;google.adk.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;

&lt;span class="n"&gt;quizzes_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;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;Quizzes_Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-2.0-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&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;This is an AI agent which is responsible for generating MCQ questions and answers from the content provided to it.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;instruction&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;You are the Quizzes Agent responsible for generating MCQ questions with 4 options and answers of the content provided to you by the Manager Agent. Also you are to return this output back to the manager agent.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;output_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quiz&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;summarizer_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;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;summarizer_agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-2.0-flash-exp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&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;This is an AI agent which is responsible for generating summaries of the content provided to it.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;instruction&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;You are a Summarizer Agent in an educational multi-agent system.

Your role:
- Create concise, accurate summaries of educational content
- Focus on key concepts, main ideas, and important details
- Maintain academic accuracy and clarity
- Structure summaries logically with clear headings when appropriate

When given content, analyze it thoroughly and provide a well-structured summary that captures the essential information in a clear, academic style.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;output_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;summary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;reference_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;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;Reference_Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-2.0-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&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;This is an AI agent which is responsible for giving relevant references or citations related to the content provided to it.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;instruction&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;You are a Reference Agent specialized in identifying the content and giving relavent citations, references, and source materials from educational content.

Your role:
- Provide all types of references relavant to the content including:
  * Academic citations (APA, MLA, Chicago, etc.)
  * URLs and web links
  * PDFs and other documents
  * Images and other media
  * Book titles and authors
  * Journal articles and papers
  * Document titles and section references
- Format extracted references clearly and organized
- Include page numbers, dates, and other citation details when available

Provide a comprehensive list of all references related to the content provided to you.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;output_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;references&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;flash_card_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;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;Flash_Card_Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-2.0-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&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;This is an AI agent which is responsible for generating flash cards from the content provided to it.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;instruction&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;You are a Flashcard Generation Agent that creates effective study flashcards from educational content.

Your role:
- Analyze content to identify key facts, concepts, and definitions
- Create clear question-answer pairs that test understanding
- Ensure questions are specific and answers are concise but complete
- Cover all important topics from the provided content

Create comprehensive flashcards that facilitate active recall and help students understand key concepts.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;output_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;flashcards&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;root_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;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;Manager_Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-2.0-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&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;This AI agent functions as an orchestrator and coordinator in a multi-agent system designed to answer queries based on domain-specific content provided to it. Its primary role is to manage the interactions between multiple specialized agents and ensure accurate, context-aware, and efficient responses to user queries.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;instruction&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;You are the Manager Agent for the EduAssistant multi-agent system.

Your role:
- Understand user requests and determine appropriate actions
- Coordinate with specialized agents when needed:
  * Use summarizer_agent for summarization requests
  * Use reference_agent for reference extraction requests  
  * Use flashcard_agent for flashcard generation requests
  * Use quizzes_agent for quizzes generation requests
- Provide comprehensive educational assistance
- Maintain academic accuracy and helpful tone
- Format responses appropriately based on user needs

Available agents:
- summarizer_agent: Creates summaries of educational content
- reference_agent: Extracts references and citations
- flashcard_agent: Generates study flashcards
- quizzes_agent: Generates quizzes from educational content

When users ask for specific functions, delegate to the appropriate agent and provide the results in a clear, helpful format asked by the user.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;sub_agents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;quizzes_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reference_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flash_card_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;summarizer_agent&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;only limitation which was able to find is that you can't use google's built in tools in sub-agents or with other sub agents. Also if you don't want handle session management but want to use the agent as a API call then you have to create a main.py in the parent directory and paste this :-&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;uvicorn&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;google.adk.cli.fast_api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_fast_api_app&lt;/span&gt;

&lt;span class="n"&gt;AGENT_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abspath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ALLOWED_ORIGINS&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;http://localhost&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;http://localhost:8080&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;*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;SERVE_WEB_INTERFACE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_fast_api_app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;agents_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AGENT_DIR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allow_origins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ALLOWED_ORIGINS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;web&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SERVE_WEB_INTERFACE&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;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;uvicorn&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;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&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;PORT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and start it by running a uvicorn run command, this way you can implement the &lt;strong&gt;CORS&lt;/strong&gt; policies preventing blocking of request.&lt;/p&gt;

&lt;p&gt;Now here you go, I have given you every thing to get started with building AI Agent with Google ADK, but it has many things which I didn't cover like sequencial, loop agents, etc, so I encourage you explore the &lt;a href="https://google.github.io/adk-docs/" rel="noopener noreferrer"&gt;Google ADK Docs&lt;/a&gt;. If you have any feedback regarding this post I would love to hear from you. Toodles.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>ai</category>
    </item>
    <item>
      <title>Making AI Agents Easy</title>
      <dc:creator>Sparsh Jain</dc:creator>
      <pubDate>Sun, 01 Jun 2025 10:55:04 +0000</pubDate>
      <link>https://dev.to/splintersword/making-ai-agents-easy-17m7</link>
      <guid>https://dev.to/splintersword/making-ai-agents-easy-17m7</guid>
      <description>&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%2Fu63u5tumrzo0ukr2htfi.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%2Fu63u5tumrzo0ukr2htfi.png" alt="Thumbnail" width="794" height="792"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everyone can agree that AI Agents are the next big thing the world development, It has huge potential not only just for developer but also for the everyday guy who is a teacher or a sales accountant,as it could literally automate things that us humans despise doing. But the problem is that non-coders can't take advantage of AI Agents, without learning how to code.&lt;/p&gt;

&lt;p&gt;Well no more, because I found a tool where anyone can make to powerful AI Agent to automate their workflow without writing a single line of code. Even developers who want an easy way to integrate AI Agents in there next project and don't want to learn how to code it, can use this tool, even I used it to integrate AI Agents in an existing project that I had.&lt;/p&gt;

&lt;h2&gt;
  
  
  Toolhouse AI
&lt;/h2&gt;

&lt;p&gt;Well enough beating around the bush, the tool I am talking about is Toolhouse AI.&lt;/p&gt;

&lt;p&gt;Toolhouse AI is a cloud-based platform designed to simplify the integration of AI Agents into applications powered by Large Language Models (LLMs). It offers developers and non-developers a streamlined approach to enhance AI capabilities with minimal or no code.&lt;/p&gt;

&lt;p&gt;You the best part is that they made their free tier so generous that 90% of the people are not going need more that this so for them it is essentially free.&lt;br&gt;
How to use it&lt;/p&gt;

&lt;p&gt;Now I am going to tell you how to use it. Are you excited, I know I am.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Log into toolhouse ai, like obviously what else did you expect the first step to be.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will greeted with this screen&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2F4755v707iyg0oimlrlqq.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%2F4755v707iyg0oimlrlqq.png" alt="Toolhouse1" width="800" height="493"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you have multiple option to explore multiple MCP severs and premade AI Agents you can go try these, if you want. I think they have good utility in everyday life.&lt;/p&gt;

&lt;p&gt;But to make you own you need to click on the create new agent button on the top right of the screen.&lt;br&gt;
You will taken to this page&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%2Ffzuu5o3sc2auit0n74mv.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%2Ffzuu5o3sc2auit0n74mv.png" alt="Toolhouse2" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now all you have to do is describe what you want the AI Agent to do do and voila you created your very own AI Agent. It is that easy.&lt;/p&gt;

&lt;p&gt;Here is an example agent for people who are looking for referrals and contacts for the company you want to work in.&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%2Fzrly6cnzqaukmwb3yuxl.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%2Fzrly6cnzqaukmwb3yuxl.png" alt="Toolhouse3" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Where I asked to find the linkedin and emails of Google HR and send it to my email.&lt;/p&gt;

&lt;p&gt;You can also use it as an API in your own project by using the API endpoint the provide here&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%2Fpm001zcqs3xhw8dxp6zv.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%2Fpm001zcqs3xhw8dxp6zv.png" alt="Toolhouse4" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can already guess how useful that can be.&lt;/p&gt;

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

&lt;p&gt;We all know that AI Agents is the future and rather than it being limited to people who know how to code, tool like Toolhouse AI give access of AI Agents to the general public which I think is really cool, I just wanted to shed some light on this product.&lt;/p&gt;

&lt;p&gt;If you have any feedback I would love to listen to it. Thanks for you time.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>powerfuldevs</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The Cheapest Way to Deploy Web Apps</title>
      <dc:creator>Sparsh Jain</dc:creator>
      <pubDate>Sat, 24 May 2025 13:37:37 +0000</pubDate>
      <link>https://dev.to/splintersword/the-cheapest-way-to-deploy-web-apps-p8f</link>
      <guid>https://dev.to/splintersword/the-cheapest-way-to-deploy-web-apps-p8f</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This month I got my first bill for my google cloud platform. When I saw the bill, my first thought was "well, I am screwed, aren't I". It was like 6000 rupees ($70). I am a college student and there is no way in hell I can afford that.&lt;/p&gt;

&lt;p&gt;So I did what any self respecting college student would do and decline all the payments and started fresh.&lt;/p&gt;

&lt;p&gt;Armed with my prior experience, I started my crusade to find the cheapest and the most effective way to deploy my apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which cloud platform to choose
&lt;/h2&gt;

&lt;p&gt;Choosing the appropriate cloud platform, is the most important decision one can make, I mean they are the ones making the bills at the end of the day which you have to pay. So it is essential that every developer does his in depth research about these platforms, before making a decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend&lt;/strong&gt; - I think &lt;strong&gt;&lt;a href="https://cloud.google.com/" rel="noopener noreferrer"&gt;Google Cloud Platform&lt;/a&gt;&lt;/strong&gt; is the best for beginners. It is cheap, not that complicated to use, has a very generous free tier, and most importantly &lt;strong&gt;it asks before it charges your charges your credit card&lt;/strong&gt;. Also while using it make sure that your storage and cloud run region are same and comes under the free tier of GCP, GCP charges extra for cross region transfer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend&lt;/strong&gt; - &lt;strong&gt;&lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;&lt;/strong&gt; is the best choice if your are using &lt;strong&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;NEXT.js&lt;/a&gt;&lt;/strong&gt; or any react app. One can deploy his/her frontend app easily in just 2 clicks with continuous deployment out of the box (any changes in main branch of github repo is automatically reflected there). Here is the fun part, you don't even need to enter your credit card details to get started, I know I haven't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Seperate Frontend and Backend deployment
&lt;/h2&gt;

&lt;p&gt;You must have noticed I choose different platforms for frontend and backend deployment. You might be wondering why do such a thing in the first place, isn't it better to have every thing on one place ??&lt;/p&gt;

&lt;p&gt;The reason I do it because first it makes my work much more &lt;strong&gt;manageable&lt;/strong&gt;, knowing that my frontend and backend seperated. But the more important reason is the specialized advantages that platform like &lt;strong&gt;Vercel&lt;/strong&gt; provide for heavier frontend deployment (like static-site optimization, CDNs, caching) which platforms like &lt;strong&gt;Google Cloud Platform&lt;/strong&gt; don't provide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Cloud Platform&lt;/strong&gt;, &lt;strong&gt;Heroku&lt;/strong&gt;, &lt;strong&gt;AWS&lt;/strong&gt; provide dynamic runtimes, scalability, database connection which are more tailored towards backend needs.&lt;/p&gt;

&lt;p&gt;Having frontend and backend deployed seperately means that you don't have to worry about potential problems that might occur when you try to scale either.&lt;/p&gt;

&lt;h2&gt;
  
  
  What programming language to choose
&lt;/h2&gt;

&lt;p&gt;I am of the belief that developers can choose whatever programming language to choose to build whatever they want. But sadly our world is not perfect and what language you choose will have a significant impact on your deployment cost, no matter what you which platform you decide to deploy on.&lt;/p&gt;

&lt;p&gt;Why you ask ??, I have two words for you &lt;strong&gt;Complied Size&lt;/strong&gt;. &lt;br&gt;
Languages such as &lt;strong&gt;Javascript&lt;/strong&gt; and &lt;strong&gt;Python&lt;/strong&gt; has huge complied size compare to something written in &lt;strong&gt;Go&lt;/strong&gt;, &lt;strong&gt;C++&lt;/strong&gt;, etc, because program return in Javascript and Python include all the dependencies in their complied size.&lt;/p&gt;

&lt;p&gt;Higher size means higher storing cost which leads to higher deployment cost and deployment time. It is as simple as that.&lt;/p&gt;

&lt;p&gt;If you want to save as money as you possibly can, My recommendation is that you write your frontend in &lt;strong&gt;Next.js&lt;/strong&gt; and for your backend use something like &lt;strong&gt;Go&lt;/strong&gt; cause it has very low compile size as compare to something like Javascript while being easier to write and learn compare to something like Rust or C++.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Correct way to build a Docker Image
&lt;/h2&gt;

&lt;p&gt;If you are using docker images for deployment (p.s. you should), I learned that there are many optimization you do reduce the size of your docker image from (and I am not kidding) 1.7gb to like 100mb, and best the part it is that it can be achieved you just changing just a few lines of code in your dockerfile. You can imagine how much cost can you save from doing this in the long run.&lt;/p&gt;

&lt;p&gt;Here is a step by step for how you can reduce the size :-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Choose a striped down base image, like &lt;strong&gt;python:3.10-alpine (60mb)&lt;/strong&gt; instead of using &lt;strong&gt;python:3.10 (900mb)&lt;/strong&gt; here is where you make the most significant reduction in size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do a Multistage Build of docker images. Multistage builds allow you to keep the build dependencies and debug tools like &lt;strong&gt;GCC&lt;/strong&gt; out of the final image which can significantly free up space.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure while building dependencies you use tags like &lt;strong&gt;--no-cache&lt;/strong&gt; so there is not cache generated and even if it is generated make sure to delete in that step only. it can save up to like ~100mb&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now I have an example of a bloated python docker image compare to an unbloated one and you can see the difference.&lt;/p&gt;

&lt;p&gt;This example created a docker image of 1.1gb&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM python:3.10

WORKDIR /app

COPY . /app

RUN pip install --no-cache-dir -r requirements.txt

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example created a docker image of 160mb&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ---------- Stage 1: Build dependencies ----------
FROM python:3.10-alpine AS builder

WORKDIR /app

# Add compiler tools for dependencies like numpy, psycopg2, etc.
RUN apk add --no-cache gcc musl-dev libffi-dev

COPY requirements.txt .

# Build all dependencies into .whl (wheel) files
RUN pip wheel --no-cache-dir --wheel-dir /wheels -r requirements.txt

# ---------- Stage 2: Final minimal image ----------
FROM python:3.10-alpine

WORKDIR /app

# Only runtime dependency
RUN apk add --no-cache libffi

# Copy built wheels from builder
COPY --from=builder /wheels /wheels
RUN pip install --no-cache-dir --no-index --find-links=/wheels /wheels/*

# Copy your application source code
COPY . .

EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Doing these steps can significantly reduce the cost of your deployment, but remember I have just scratched the surface of these kinds of optimization and I encourage to learn more tricks like these which and be used to save cost in deployment.&lt;/p&gt;

&lt;p&gt;If you have any questions or feedback, I would love to take it and connect with you guys.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
