<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Mohit's Personal Blog]]></title><description><![CDATA[Mohit's Personal Blog]]></description><link>https://mohittilwani.xyz</link><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Apr 2026 13:44:40 GMT</lastBuildDate><atom:link href="https://mohittilwani.xyz/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[AI Jargons]]></title><description><![CDATA[LLM (Large Language Model)
LLM is a sophisticated mathematical function that predicts the next word in the sequence. So if you ask LLM to complete the sentence “The capital of France is ___“, it will ]]></description><link>https://mohittilwani.xyz/ai-jargons</link><guid isPermaLink="true">https://mohittilwani.xyz/ai-jargons</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[Mohit Tilwani]]></dc:creator><pubDate>Wed, 18 Mar 2026 08:00:00 GMT</pubDate><content:encoded><![CDATA[<h2>LLM (Large Language Model)</h2>
<p>LLM is a sophisticated mathematical function that <strong>predicts the next word</strong> in the sequence. So if you ask LLM to complete the sentence “The capital of France is ___“, it will try to predict the next word based on knowledge it is trained upon. For more comprehensible overview of the LLM, please watch this amazing <a href="https://www.youtube.com/watch?v=LPZh9BOjkQs">video</a> from 3Blue1Brown</p>
<p>There are two types of LLMs:</p>
<h3>Autoregressive Language Model</h3>
<p>An autoregressive language model is trained to predict the next token in a sequence, <strong>using only the preceding tokens.</strong></p>
<p>Think of it like writing a sentence word by word, where you can only see what you've already written - never what comes next. Each prediction depends solely on the past.</p>
<h3>Masked Language Model</h3>
<p>A masked language model is trained to predict missing tokens anywhere in a sequence, <strong>using the context from both before and after the missing tokens.</strong></p>
<p>Think of it like a fill-in-the-blank test where you can read the entire sentence before answering:</p>
<pre><code class="language-plaintext">Input: "The [MASK] sat on the mat"
Model sees: words before AND after the blank
Prediction: "cat" (using context from both sides)
</code></pre>
<h2>Tokens</h2>
<p>A token is a fundamental unit of a text. A token is often a word or even part of a word. For example, the sentence <em>"I love cats"</em> has three tokens: <strong>"I"</strong>, <strong>"love"</strong>, and <strong>"cats"</strong>. Sometimes, it can go even smaller. If you have a complicated word like <em>"Flibbertigibbet"</em>, it will get split into six tokens like <strong>"Fl"</strong>, <strong>"ib"</strong>, <strong>"bert", “ig”, “ib” and “keit”</strong></p>
<p>Whether a word splits into multiple tokens or not comes down to the vocabulary of the respective LLM. The process of <strong>breaking</strong> the original text into tokens is called tokenization. You can play around on how OpenAI tokenize on their <a href="https://platform.openai.com/tokenizer">website</a>. GPT-4o vocabulary size is 199,997.</p>
<h2>Prompt</h2>
<p>It’s just a fancy way of saying <em>“what you tell the computer to do.”</em> For example, when you ask ChatGPT, “Write an email to my manager that I am quitting“, you’re basically prompting ChatGPT.</p>
<p>To receive high quality response from LLMs, there are many techniques that AI researchers have came up with. Check out this <a href="https://www.promptingguide.ai/">website</a> to learn more about prompt engineering.</p>
<h2>LMM (Large Multimodal Model)</h2>
<p>A Large Multimodal Model is an advanced AI model that can process and understand multiple types of data, such as text, images, audio, and video. Unlike traditional Large Language Models (LLMs) that focus primarily on text, LMMs handle diverse data forms for a holistic interpretation. Examples include GPT-4o and Google Gemini, which can respond to both text and images.</p>
<h2>Inference</h2>
<p>Inference is the process of a LLM drawing conclusion (generating response) based on the data it was trained upon. So basically inference is an AI model in action.</p>
<p>Think of it like studying vs taking the exam. During training, the model reads billions of documents and learns patterns. During inference, it applies that knowledge to answer your specific question.</p>
<h2>Fine tuning</h2>
<p>Fine tuning is a technique where a pre-trained AI model is further trained on a smaller, specialized dataset to adapt for a specific task, like coding. It leverages existing knowledge, enhancing performance without extensive retraining, which is useful when data is limited.</p>
<p>Think of it like hiring a smart generalist and then training them on your company's specific processes. They already know how to think and communicate - you're just teaching them your particular way of doing things.</p>
<h2>RAG</h2>
<p>Retrieval Augmented Generation (RAG) is a smart technology that helps LLM provide more accurate and relevant answers by combining two key steps: searching for information and then generating a response. Think of RAG like a super-smart librarian who doesn't just recall information from memory, but actively searches through a vast library to find the most relevant sources before crafting an answer.</p>
<p><strong>The RAG Process:</strong></p>
<p><strong>Retrieval</strong>: Imagine you ask a question. LLM first searches through a large database to find the most relevant information related to your query. This is similar to a librarian pulling out the most relevant books from shelves.</p>
<p><strong>Augmentation</strong>: The LLM then takes those retrieved documents and summarizes or enhances the key information, making it more digestible. It’s like the librarian highlighting the most important passages in those books.</p>
<p><strong>Generation</strong>: Finally, the LLM uses this retrieved and augmented information to craft a precise, contextually accurate response. This means the answer is not just pulled from the LLM’s original training, but grounded in up-to-date and specific information.</p>
<p>The big advantage of RAG is that it helps solve a common problem with LLM called <strong>hallucination</strong> - where LLM might confidently provide incorrect information. By retrieving and using real, current information, RAG makes AI responses more reliable and accurate.</p>
<h2>Tools</h2>
<p>Tools are functions or APIs that agents use to interact with the environment, access information, or perform tasks, like web search or database queries, extending their capabilities beyond pre-trained knowledge.</p>
<h2><strong>Parameters/Weights</strong></h2>
<p>Parameters (also called weights) are the numbers inside an AI model that determine how it processes information. When you hear "GPT-4 has 1.8 trillion parameters" or "Llama 3 is a 70B model," these numbers refer to how many adjustable values the model contains.</p>
<p>Think of parameters like the settings on a massive mixing board in a recording studio. Each knob affects how the final sound comes out. During training, the AI adjusts millions or billions of these "knobs" until it produces good outputs. More parameters generally means the model can capture more nuanced patterns, but also requires more computing power to run.</p>
<img src="https://cdn.hashnode.com/uploads/covers/679511833322eabaf4b6d4d7/92891f5d-f454-40f1-b555-b90d9485b777.png" alt="" style="display:block;margin:0 auto" />

<p>The relationship isn't linear though. A well-trained 8B model can outperform a poorly-trained 70B model. Quality of training data and techniques matter as much as raw size.</p>
<h2>Context Window</h2>
<p>The context window is the maximum amount of text an AI model can process at once. It's measured in tokens. If a model has a 128K context window, it can "see" roughly 100,000 words simultaneously.</p>
<p>Imagine reading a book, but you can only remember the last 50 pages. That's essentially what a limited context window does to an AI. Anything beyond that window effectively doesn't exist for the model.</p>
<p>Context windows have grown dramatically:</p>
<p>GPT-3 (2020): 4K tokens<br />GPT-4 (2023): 128K tokens<br />Claude 3 (2024): 200K tokens<br />Gemini 1.5 (2024): 1M+ tokens</p>
<p>Larger context windows enable use cases like analyzing entire codebases, summarizing long documents, or maintaining coherent conversations over extended sessions. The tradeoff is that longer contexts require more compute and can increase latency.</p>
<h2>Agentic AI</h2>
<p>Agentic AI refers to AI systems that can autonomously plan, reason, and take actions to accomplish goals, rather than just responding to single prompts. Instead of asking "write me an email," you might tell an agent "research competitors, draft a market analysis, and schedule a meeting with the team to discuss findings."</p>
<p>The key capabilities that make AI "agentic":</p>
<p>• <strong>Planning</strong>: Breaking down complex tasks into steps<br />• <strong>Tool Use</strong>: Calling APIs, searching the web, executing code<br />• <strong>Memory</strong>: Remembering context across interactions<br />• <strong>Reasoning</strong>: Deciding what to do next based on results<br />• <strong>Autonomy</strong>: Operating with minimal human intervention</p>
<p>A simple chatbot answers questions. An agent books your flight, checks your calendar for conflicts, sends confirmation to your team, and adds the trip to your expense tracker.</p>
<h2>MCP (Model Context Protocol)</h2>
<p>MCP is an open standard created by Anthropic that defines how AI models connect to external tools, data sources, and services. Think of it as USB-C for AI. Before USB-C, every device had its own charger. MCP aims to solve the same fragmentation problem for AI integrations.</p>
<p>Without MCP, connecting an AI to your calendar, database, or code editor requires custom integration work for each combination. With MCP, a tool built once works with any MCP-compatible AI system.</p>
<p>The protocol defines three core primitives:</p>
<p>• Tools: Functions the AI can call (e.g., send_email, search_database)<br />• Resources: Data the AI can access (e.g., files, documents)<br />• Prompts: Reusable templates for common tasks</p>
<p>Example: An MCP server for Notion exposes tools like "create_page" and "search_notes." Any MCP-compatible AI (Claude, GPT, local models) can then interact with Notion without needing Notion-specific code.</p>
<h2>Skills</h2>
<p>Skills are packaged capabilities that extend what an AI agent can do. A skill typically includes instructions, tools, and templates that enable the agent to perform a specific task well.</p>
<p>Think of skills like apps on your phone. Your phone's base OS can do a lot, but you install apps (skills) for specific tasks: photography, banking, navigation. Similarly, a base AI model can chat, but skills let it do specialized work like "analyze SEO," "generate images," or "manage your calendar."</p>
<p>A skill usually contains:</p>
<p>• <strong>Instructions</strong>: How to approach the task (prompts, best practices)<br />• <strong>Tools</strong>: APIs or functions needed (e.g., image generation API)<br />• <strong>Templates</strong>: Reusable formats for outputs<br />• <strong>Context</strong>: Domain knowledge relevant to the task</p>
<p>Skills enable modularity. Instead of one massive AI that tries to do everything, you compose smaller, focused skills as needed. This makes AI systems more maintainable and allows specialized skills to be shared across different agents.</p>
]]></content:encoded></item><item><title><![CDATA[Was ist Vector Database]]></title><description><![CDATA[Imagine you are at a library with hundreds of thousands of books. Instead of searching by exact title or keyword, you want to find all the books that are about the same idea as your question.Traditional databases can answer: “Find me books where the ...]]></description><link>https://mohittilwani.xyz/was-ist-vector-database</link><guid isPermaLink="true">https://mohittilwani.xyz/was-ist-vector-database</guid><category><![CDATA[vector database]]></category><category><![CDATA[Databases]]></category><category><![CDATA[AI]]></category><category><![CDATA[agentic AI]]></category><dc:creator><![CDATA[Mohit Tilwani]]></dc:creator><pubDate>Thu, 28 Aug 2025 20:36:15 GMT</pubDate><content:encoded><![CDATA[<p>Imagine you are at a library with hundreds of thousands of books. Instead of searching by exact title or keyword, you want to find all the books that are about the same idea as your question.<br />Traditional databases can answer: <em>“Find me books where the title contains ‘blockchain’.”</em><br />But what if you ask: <em>“Show me books that explain how money moves without banks”</em>? A keyword match might miss it.</p>
<p>This is where vectors come in.</p>
<p>AI models can convert text, images, or audio into vectors which is basically long lists of numbers that capture meaning. Two pieces of content with similar meaning will have vectors that are close together in this high-dimensional number space.</p>
<p>A vector database is simply a database built to store these vectors and quickly find the ones most similar to your query.</p>
<p>Best way to think about it is like it is <strong>Google Maps for ideas → instead of distance between cafés, it’s distance between meanings.</strong></p>
<h2 id="heading-embedding-models">Embedding Models</h2>
<p>At the heart of every vector database is an embedding model. An embedding model takes an input like text, image, audio etc. and converts it into a vector which is a long list of numbers that captures its meaning.</p>
<p>Think of it as translation, just like Google Translate converts English into German, an embedding model converts human language into the “language of vectors.”</p>
<p>There are different kinds of embedding model based on the use case of the particular app. To name few</p>
<ul>
<li><p>Text Embeddings —&gt; semantic search, chatbots, classification, RAG.</p>
</li>
<li><p>Image Embeddings —&gt; “find similar images,” cross-modal search</p>
</li>
<li><p>Multimodal Embeddings —&gt; “find images that match a text description,” “align video with captions.”</p>
</li>
<li><p>Domain-Specific Embeddings —&gt; Specialized for legal, medical, financial, or code data</p>
</li>
</ul>
<p>There are many open source model and choosing the model is one of the most important decision that needs to be made earlier in the product development lifecycle.</p>
<h2 id="heading-embedding-dimensions">Embedding Dimensions</h2>
<p>The length of the vector is different based on the model you will choose. For example some models produces a 1536-dimensional vector, it means:</p>
<ul>
<li><p>Every “piece of text” you pass in is turned into an array of 1536 numbers.</p>
</li>
<li><p>Each number captures a tiny piece of information about the meaning of that text (kind of like “semantic ingredients”).</p>
</li>
<li><p>Together, these 1536 numbers form a position in a 1536-dimensional space.</p>
</li>
</ul>
<p>Imagine describing a fruit:</p>
<ul>
<li><p>In real life, you might use 3 dimensions (color, size, sweetness).</p>
</li>
<li><p>So “banana” might be (yellow=0.9, size=0.6, sweetness=0.8).</p>
</li>
</ul>
<p>Now, instead of 3 traits, an embedding model uses 1536 traits. They are not as intuitive as “color” or “size” as they are abstract semantic features learned from data. But the idea is the same: each text becomes a long numeric fingerprint.</p>
<p>Isn’t 1536 a very long array for a piece of text! Yes it is but also more dimensions means richer representation. With 1536 numbers, the model can capture subtle differences in meaning (e.g., “bank” as a financial institution vs. “bank” of a river).</p>
<h2 id="heading-distance-metrics">Distance Metrics</h2>
<p>Okay, so we have our embeddings but how does the database actually know which ones are closer to your question? Think of a vector database like Google Maps for ideas. To find the ‘nearest’ concepts, it needs a way to measure distance which is not in kilometers, but in terms of meaning. These measurement rules are called distance metrics.</p>
<p>There are some common distance metrics that is used by the vector DB to find the relevant results.</p>
<ul>
<li><p><strong>Cosine Similarity</strong></p>
<p>  Cosine similarity cares about the direction of meaning, not the length of the vector.</p>
</li>
<li><p><strong>Euclidean Distance</strong><br />  Euclidean distance measures how far two points are from each other in the vector space.</p>
</li>
</ul>
<p>Let’s say there are three users. 1st user has watched 2 comedy and 2 action movies. 2nd user has watched 20 comedy and 20 action movies and 3rd user has watched 10 comedy and 2 action movies.</p>
<p>If you use cosine similarity, 1st user and 2nd user are more similar compare to 1st and 3rd. If you use euclidean distance 1st user and 3rd user are more similar. Cosine similarity cares about taste proportions. Euclidean distance cares about how many movies watched.</p>
<h2 id="heading-metadata-filtering">Metadata Filtering</h2>
<p>When you store embeddings in a vector database, you don’t just store the vector. You usually also attach metadata: extra information about where the text came from, who owns it, when it was added, etc.</p>
<p>Metadata filtering means when searching for similar vectors, you can also apply conditions on this extra information. It’s like saying: <em>“Find me the most relevant results, but only from project X, written in English, and after 2023.”</em></p>
<p>Without metadata filters, you would risk retrieving semantically similar but irrelevant results.</p>
<p><strong>Why It Matters</strong></p>
<ul>
<li><p>Keeps results contextual and secure (e.g., tenant-based access).</p>
</li>
<li><p>Reduces noise (e.g., don’t show outdated info).</p>
</li>
<li><p>Saves latency (search smaller candidate pool).</p>
</li>
</ul>
<p>Let’s consider an e-commerce example where the data stored in vector DB looks like below</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"id"</span>: <span class="hljs-string">"p_902"</span>,
  <span class="hljs-attr">"vector"</span>: [...],
  <span class="hljs-attr">"text"</span>: <span class="hljs-string">"Leather sneakers with memory foam soles"</span>,
  <span class="hljs-attr">"metadata"</span>: {
    <span class="hljs-attr">"category"</span>: <span class="hljs-string">"shoes"</span>,
    <span class="hljs-attr">"price"</span>: <span class="hljs-number">120</span>,
    <span class="hljs-attr">"brand"</span>: <span class="hljs-string">"Nike"</span>,
    <span class="hljs-attr">"gender"</span>: <span class="hljs-string">"men"</span>
  }
}
</code></pre>
<p>User queries “comfortable men’s shoes”. Vector DB search would find sneakers as relevant with a filter applied gender = “men“. User sees only men’s shoes and not irrelevant women’s high heels.</p>
<h2 id="heading-hybrid-search">Hybrid Search</h2>
<p>When you search in a vector database, you can do it in two ways:</p>
<ol>
<li><p><strong>Keyword search (sparse search)</strong></p>
<ul>
<li><p>Looks for exact words that match.</p>
</li>
<li><p>Great for things like names, IDs, code, or very specific terms.</p>
</li>
<li><p>Example: If you search for <em>“iPhone 16 Pro”</em>, keyword search will catch documents with the exact phrase.</p>
</li>
</ul>
</li>
<li><p><strong>Vector search (dense search)</strong></p>
<ul>
<li><p>Looks for <em>meaning</em>, not exact words.</p>
</li>
<li><p>Great for natural language queries.</p>
</li>
<li><p>Example: If you search for <em>“latest Apple smartphone”</em>, vector search can still match documents about <em>“iPhone 16 Pro”</em> even if those words aren’t used.</p>
</li>
</ul>
</li>
</ol>
<p>The problem is keyword search alone misses documents if the wording is different and Vector search alone sometimes misses exact matches (like product codes or rare keywords). Hybrid search combines both methods. It looks at exact keywords and semantic meaning, then merges the results.</p>
<h2 id="heading-how-vector-databases-stay-fast">How Vector Databases Stay Fast</h2>
<p>If you had 10 documents, you could brute-force compare your query embedding to each one which is not efficient but still would be pretty fast. But what if you had 100 million vectors?</p>
<p>Doing “compare with every vector” would be too slow and too expensive. That’s why vector databases use Approximate Nearest Neighbor (ANN) search. Instead of scanning everything, they use clever shortcuts to jump directly to the “neighborhood” where the answer probably is. It’s like finding the nearest Starbucks by checking your neighborhood first instead of the whole city. You sacrifice a tiny bit of accuracy for huge speed gains.</p>
]]></content:encoded></item><item><title><![CDATA[Juicebox 🧃]]></title><description><![CDATA[While exploring options for securely storing encryption keys in a decentralized and trust-minimized way, I came across Juicebox — and it was exactly what I was looking for. I wanted a solution that wouldn't rely on centralized storage or risky backup...]]></description><link>https://mohittilwani.xyz/juicebox</link><guid isPermaLink="true">https://mohittilwani.xyz/juicebox</guid><category><![CDATA[Cryptography]]></category><dc:creator><![CDATA[Mohit Tilwani]]></dc:creator><pubDate>Sun, 06 Jul 2025 22:00:00 GMT</pubDate><content:encoded><![CDATA[<p>While exploring options for securely storing encryption keys in a decentralized and trust-minimized way, I came across <a target="_blank" href="https://juicebox.xyz/"><strong>Juicebox</strong></a> — and it was exactly what I was looking for. I wanted a solution that wouldn't rely on centralized storage or risky backups, but also wouldn't require users to remember anything more than a simple PIN.</p>
<h3 id="heading-the-problem-juicebox-solves">The Problem Juicebox Solves</h3>
<p>Backups are hard and risky. If a user loses their device, they lose access to their secret. If someone steals their backup, they can take everything. What's needed is a solution that:</p>
<ul>
<li><p>Doesn't rely on centralized trust</p>
</li>
<li><p>Protects against brute-force attacks</p>
</li>
<li><p>Doesn't require remembering long passwords or writing down recovery phrases</p>
</li>
<li><p>Works across multiple servers, devices, and threat models</p>
</li>
</ul>
<p>Juicebox delivers on all of this by combining cutting-edge cryptography with a developer-friendly design</p>
<h3 id="heading-how-juicebox-works-in-simple-terms">How Juicebox Works (in Simple Terms)</h3>
<p>Juicebox breaks your secret into multiple pieces and distributes them to different servers, called <strong>realms</strong>. To recover the secret, a user must interact with a threshold number of realms (e.g., 2 out of 3). Each realm contributes a piece of the puzzle, but no single realm can access the full secret.</p>
<p>To recover a secret, the user just enters their PIN. Juicebox performs a threshold-based <strong>Oblivious Pseudorandom Function</strong> (T-OPRF), allowing the realms to validate the PIN <strong>without ever seeing it</strong>. Once the correct PIN is validated, the user gets the pieces needed to reconstruct the secret.</p>
<h3 id="heading-realms-the-core-of-juiceboxs-security">Realms: The Core of Juicebox's Security</h3>
<p>There are two types of realms:</p>
<ul>
<li><p><strong>Software Realms</strong>: Easy to deploy, run on commodity cloud infrastructure.</p>
</li>
<li><p><strong>Hardware Realms</strong>: Backed by physical HSMs (like Entrust nShield), offering tamper resistance and brute-force protection.</p>
</li>
</ul>
<p>You can mix and match realms. For example, a 2-of-3 setup could involve 2 software realms and 1 hardware realm. This flexibility allows you to design a trust model that fits your app's security profile.</p>
<h3 id="heading-built-in-brute-force-protection">Built-in Brute-force Protection</h3>
<p>Juicebox doesn’t just validate PINs; it defends them. Each secret is protected by a maximum guess count. If a user enters the wrong PIN too many times, the share at that realm becomes unrecoverable. This means even if an attacker gets access to all realms, they can't brute-force their way into a user's secret.</p>
<h3 id="heading-use-cases">Use Cases</h3>
<ul>
<li><p><strong>Crypto wallets</strong>: Replace 12-word seed phrases with a simple PIN.</p>
</li>
<li><p><strong>Secure messaging</strong>: Recover encryption keys securely even after device loss.</p>
</li>
</ul>
<h3 id="heading-resources"><strong>Resources:</strong></h3>
<ul>
<li><p><a target="_blank" href="https://github.com/juicebox-systems">Juicebox Protocol on GitHub</a></p>
</li>
<li><p><a target="_blank" href="https://juicebox.xyz/blog/unlock-magic-blending-juicebox-with-your-app">Running a Software Realm</a></p>
</li>
<li><p><a target="_blank" href="https://juicebox.xyz/blog/running-a-hsm-realm">Running a Hardware Realm</a></p>
</li>
<li><p><a target="_blank" href="https://juicebox.xyz/assets/whitepapers/juiceboxprotocol_revision7_20230807.pdf">Juicebox Whitepaper</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Model Context Protocol]]></title><description><![CDATA[There is a new kid on the block called MCP stands for Model Context Protocol. Before we deep dive into what is MCP, we should understand how LLM gets the knowledge at first place to be able to spit out the response to the user.
How LLMs get their kno...]]></description><link>https://mohittilwani.xyz/model-context-protocol</link><guid isPermaLink="true">https://mohittilwani.xyz/model-context-protocol</guid><category><![CDATA[AI]]></category><category><![CDATA[mcp]]></category><dc:creator><![CDATA[Mohit Tilwani]]></dc:creator><pubDate>Sat, 08 Mar 2025 17:18:33 GMT</pubDate><content:encoded><![CDATA[<p>There is a new kid on the block called MCP stands for Model Context Protocol. Before we deep dive into what is MCP, we should understand how LLM gets the knowledge at first place to be able to spit out the response to the user.</p>
<h2 id="heading-how-llms-get-their-knowledge">How LLMs get their knowledge</h2>
<p>LLMs are basically trained on the internet data. So you can imagine all the websites, images, videos etc. is used by the companies creating the model to be able to train the LLMs.</p>
<p>LLMs have two training phases, pre-training and post training. In the pre-training phase, all the internet data is fed into the models to train it and in the post-training phase, the model is trained to be helpful to humans by feeding the conversation which in turn helps the model to develop a persona.</p>
<p>Now pre-training phase is very expensive like expensive expensive. Hence, AI engineers came up with a novel approach called tools. Using tools, you can fetch real time information like price of Bitcoin and provide it to LLMs and in this way we don’t need to do a pre-training phase every week.</p>
<p>Now that you understand how real time knowledge can fed into LLMs, let’s discuss the problem that MCP is trying to solve. Please read my previous <a target="_blank" href="https://mohittilwani.xyz/simple-af-ai-agent">article</a> where I explained tool a bit more in detail before proceeding</p>
<h2 id="heading-problem-to-be-solved">Problem to be solved</h2>
<p>Now that we have tools that can feed real time information to LLMs, the next problem to solve is creating tools. Imagine you want to create a web application and there are NO libraries exists out there. It’s just you and Javascript. Yikes, right!</p>
<p>Now imagine, there are open source tools for pretty much anything you can imagine like Notion, AWS, Jira, Postgres etc. which you can integrate in your AI agents. Boom! Your agents are now capable of fetching all the information from the MCP server you just added. Maybe below digram would help to understand how mind boggling it is</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741117545537/8023dea9-d156-462a-95a8-fcabda5ab7ff.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-official-introduction-of-mcp">Official Introduction of MCP</h2>
<p>MCP is an open protocol that standardizes how applications provide context to LLMs. Anthropic provides the best analogy to think of MCP <em>like a USB-C port for AI applications. Just as USB-C provides a standardized way to connect your devices to various peripherals and accessories, MCP provides a standardized way to connect AI models to different data sources and tools.</em></p>
<h2 id="heading-mcp-components">MCP Components</h2>
<ul>
<li><p><strong>MCP Hosts</strong>: The <strong>MCP Host</strong> is at the core of the system. It can be an application like a chat assistant, an IDE-integrated code assistant, or any AI-powered tool requiring access to external data. The host includes one or more MCP clients.</p>
</li>
<li><p><strong>MCP Clients</strong>: The <strong>MCP Client</strong> operates within the MCP Host, acting as an intermediary between the host application and the MCP Server. It facilitates communication and ensures that relevant tools and data sources are requested correctly.</p>
</li>
<li><p><strong>MCP Servers</strong>: The <strong>MCP Server</strong> serves as a bridge between the MCP Client and external data sources.</p>
</li>
<li><p><strong>Local Data Sources</strong>: Your computer’s files, databases, and services that MCP servers can securely access</p>
</li>
<li><p><strong>Remote Services</strong>: External systems available over the internet (e.g., through APIs) that MCP servers can connect to</p>
</li>
</ul>
<h2 id="heading-current-limitations"><strong>Current Limitations</strong></h2>
<p>At the time of writing this, MCP doesn’t support MCP server though there is a product called <a target="_blank" href="https://composio.dev/mcp/">Composio</a> which offers remote MCP server but it is not official implementation of hosting MCP servers remotely which is originally developed by Anthropic (company behind Claude LLM)</p>
<p>So you can only run MCP server locally to able to take advantage of it. Tools like Claude chat, Cursor etc. acts as MCP Host &amp; Client and you can run a MCP server locally to be able to take advantage of it.</p>
]]></content:encoded></item><item><title><![CDATA[ABC of Multi Agent]]></title><description><![CDATA[So in the last article we created a very simple agent which takes location as an input from the user and uses the necessary tools to provide a response to the user. But let’s be honest—the response was pretty bland. Large Language Models (LLMs) are k...]]></description><link>https://mohittilwani.xyz/abc-of-multi-agent</link><guid isPermaLink="true">https://mohittilwani.xyz/abc-of-multi-agent</guid><category><![CDATA[AI]]></category><category><![CDATA[multi-agent]]></category><dc:creator><![CDATA[Mohit Tilwani]]></dc:creator><pubDate>Fri, 31 Jan 2025 18:42:50 GMT</pubDate><content:encoded><![CDATA[<p>So in the last <a target="_blank" href="https://mohittilwani.xyz/simple-af-ai-agent">article</a> we created a very simple agent which takes location as an input from the user and uses the necessary tools to provide a response to the user. But let’s be honest—the response was pretty bland. Large Language Models (LLMs) are known for their engaging, conversational nature, so let’s take things up a notch. This time, we’ll create our first multi-agent system, allowing us to generate richer, more dynamic responses for our users.</p>
<h2 id="heading-why-multi-agent">Why Multi Agent?</h2>
<p>It's very important to answer "why" before making any system design decisions (or even life decisions 🤷‍♂️) to ensure we're not using a sword to cut a carrot.</p>
<p>First, let's review what an <strong>Agent</strong> is. An agent is a highly skilled helper that knows how to perform certain tasks very well to satisfy its master. If you teach this agent many tasks, as you add more capabilities over time, it might become difficult to manage and could lower the quality of its work due to task confusion. This is similar to the teams you work with now—some engineers are great at coding but not as good at presenting, while managers might excel at planning but not at marketing, etc.</p>
<p>The leaner your agent is, the better it will perform the task at hand, and it will be easier to manage. However, there are drawbacks. The more agents you create, the more latency there will be in providing a response to the end user, as you need to identify the right agent for the task, and that agent might rely on another agent to complete it. So, there's no right or wrong answer; it comes down to understanding the pros and cons and making a decision based on that. Now that you know the why, let's start cooking 👨‍🍳</p>
<h2 id="heading-objective">Objective</h2>
<p>We will create a response agent that will take JSON input from the weather agent to generate a response for the user.</p>
<h2 id="heading-high-level-flow">High Level Flow</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738340399896/5f148f93-2706-45e9-a7e0-56b691de6c9b.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-response-agent">Response Agent</h2>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> pydantic_ai <span class="hljs-keyword">import</span> Agent

response_agent = Agent(
    <span class="hljs-string">'openai:gpt-4o'</span>,
    system_prompt=(
        <span class="hljs-string">'Provide a detailed weather description based on the response from the weather agent. '</span>
        <span class="hljs-string">'Include temperature, humidity, wind speed, and any notable conditions like rain, snow, or storms. '</span>
        <span class="hljs-string">'Describe how the weather might feel to a person, such as whether it is comfortable, chilly, or humid.'</span>
    ),
    retries=<span class="hljs-number">2</span>,
    deps_type=str,
)
</code></pre>
<h2 id="heading-weather-agent">Weather Agent</h2>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> __future__ <span class="hljs-keyword">import</span> annotations <span class="hljs-keyword">as</span> _annotations
<span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> dataclass
<span class="hljs-keyword">import</span> logfire
<span class="hljs-keyword">from</span> httpx <span class="hljs-keyword">import</span> AsyncClient
<span class="hljs-keyword">from</span> pydantic_ai <span class="hljs-keyword">import</span> Agent, ModelRetry, RunContext

<span class="hljs-keyword">from</span> response_generator_agent <span class="hljs-keyword">import</span> response_agent

<span class="hljs-meta">@dataclass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Deps</span>:</span>
    client: AsyncClient
    weather_api_key: str | <span class="hljs-literal">None</span>
    geo_api_key: str | <span class="hljs-literal">None</span>


weather_agent = Agent(
    <span class="hljs-string">'openai:gpt-4o'</span>,
    system_prompt=(
        <span class="hljs-string">'Use the `get_lat_lng` tool to get the latitude and longitude of the locations, '</span>
        <span class="hljs-string">'then use the `get_weather` tool to get the weather, '</span>
        <span class="hljs-string">'then send the response from the `get_weather` tool as JSON'</span>
    ),
    deps_type=Deps,
    retries=<span class="hljs-number">2</span>,
)


<span class="hljs-meta">@weather_agent.tool</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_lat_lng</span>(<span class="hljs-params">
    ctx: RunContext[Deps], location_description: str
</span>) -&gt; dict[str, float]:</span>
    <span class="hljs-string">"""Get the latitude and longitude of a location.

    Args:
        ctx: The context.
        location_description: A description of a location.
    """</span>
    <span class="hljs-keyword">if</span> ctx.deps.geo_api_key <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
        <span class="hljs-comment"># if no API key is provided, return a dummy response (London)</span>
        <span class="hljs-keyword">return</span> {<span class="hljs-string">'lat'</span>: <span class="hljs-number">51.1</span>, <span class="hljs-string">'lng'</span>: <span class="hljs-number">-0.1</span>}

    params = {
        <span class="hljs-string">'q'</span>: location_description,
        <span class="hljs-string">'api_key'</span>: ctx.deps.geo_api_key,
    }
    <span class="hljs-keyword">with</span> logfire.span(<span class="hljs-string">'calling geocode API'</span>, params=params) <span class="hljs-keyword">as</span> span:
        r = <span class="hljs-keyword">await</span> ctx.deps.client.get(<span class="hljs-string">'https://geocode.maps.co/search'</span>, params=params)
        r.raise_for_status()
        data = r.json()
        span.set_attribute(<span class="hljs-string">'response'</span>, data)

    <span class="hljs-keyword">if</span> data:
        <span class="hljs-keyword">return</span> {<span class="hljs-string">'lat'</span>: data[<span class="hljs-number">0</span>][<span class="hljs-string">'lat'</span>], <span class="hljs-string">'lng'</span>: data[<span class="hljs-number">0</span>][<span class="hljs-string">'lon'</span>]}
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">raise</span> ModelRetry(<span class="hljs-string">'Could not find the location'</span>)


<span class="hljs-meta">@weather_agent.tool</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_weather</span>(<span class="hljs-params">ctx: RunContext[Deps], lat: float, lng: float</span>) -&gt; dict[str, str]:</span>
    <span class="hljs-string">"""Get the weather at a location.

    Args:
        ctx: The context.
        lat: Latitude of the location.
        lng: Longitude of the location.
    """</span>
    <span class="hljs-keyword">if</span> ctx.deps.weather_api_key <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
        <span class="hljs-comment"># if no API key is provided, return a dummy response</span>
        <span class="hljs-keyword">return</span> {<span class="hljs-string">'temperature'</span>: <span class="hljs-string">'21 °C'</span>, <span class="hljs-string">'description'</span>: <span class="hljs-string">'Sunny'</span>}

    params = {
        <span class="hljs-string">'apikey'</span>: ctx.deps.weather_api_key,
        <span class="hljs-string">'location'</span>: <span class="hljs-string">f'<span class="hljs-subst">{lat}</span>,<span class="hljs-subst">{lng}</span>'</span>,
        <span class="hljs-string">'units'</span>: <span class="hljs-string">'metric'</span>,
    }
    <span class="hljs-keyword">with</span> logfire.span(<span class="hljs-string">'calling weather API'</span>, params=params) <span class="hljs-keyword">as</span> span:
        r = <span class="hljs-keyword">await</span> ctx.deps.client.get(
            <span class="hljs-string">'https://api.tomorrow.io/v4/weather/realtime'</span>, params=params
        )
        r.raise_for_status()
        data = r.json()
        span.set_attribute(<span class="hljs-string">'response'</span>, data)

    values = data[<span class="hljs-string">'data'</span>][<span class="hljs-string">'values'</span>]
    <span class="hljs-comment"># https://docs.tomorrow.io/reference/data-layers-weather-codes</span>
    code_lookup = {
        <span class="hljs-number">1000</span>: <span class="hljs-string">'Clear, Sunny'</span>,
        <span class="hljs-number">1100</span>: <span class="hljs-string">'Mostly Clear'</span>,
        <span class="hljs-number">1101</span>: <span class="hljs-string">'Partly Cloudy'</span>,
        <span class="hljs-number">1102</span>: <span class="hljs-string">'Mostly Cloudy'</span>,
        <span class="hljs-number">1001</span>: <span class="hljs-string">'Cloudy'</span>,
        <span class="hljs-number">2000</span>: <span class="hljs-string">'Fog'</span>,
        <span class="hljs-number">2100</span>: <span class="hljs-string">'Light Fog'</span>,
        <span class="hljs-number">4000</span>: <span class="hljs-string">'Drizzle'</span>,
        <span class="hljs-number">4001</span>: <span class="hljs-string">'Rain'</span>,
        <span class="hljs-number">4200</span>: <span class="hljs-string">'Light Rain'</span>,
        <span class="hljs-number">4201</span>: <span class="hljs-string">'Heavy Rain'</span>,
        <span class="hljs-number">5000</span>: <span class="hljs-string">'Snow'</span>,
        <span class="hljs-number">5001</span>: <span class="hljs-string">'Flurries'</span>,
        <span class="hljs-number">5100</span>: <span class="hljs-string">'Light Snow'</span>,
        <span class="hljs-number">5101</span>: <span class="hljs-string">'Heavy Snow'</span>,
        <span class="hljs-number">6000</span>: <span class="hljs-string">'Freezing Drizzle'</span>,
        <span class="hljs-number">6001</span>: <span class="hljs-string">'Freezing Rain'</span>,
        <span class="hljs-number">6200</span>: <span class="hljs-string">'Light Freezing Rain'</span>,
        <span class="hljs-number">6201</span>: <span class="hljs-string">'Heavy Freezing Rain'</span>,
        <span class="hljs-number">7000</span>: <span class="hljs-string">'Ice Pellets'</span>,
        <span class="hljs-number">7101</span>: <span class="hljs-string">'Heavy Ice Pellets'</span>,
        <span class="hljs-number">7102</span>: <span class="hljs-string">'Light Ice Pellets'</span>,
        <span class="hljs-number">8000</span>: <span class="hljs-string">'Thunderstorm'</span>,
    }
    <span class="hljs-keyword">return</span> {
        **values,
        <span class="hljs-string">'description'</span>: code_lookup.get(values[<span class="hljs-string">'weatherCode'</span>], <span class="hljs-string">'Unknown'</span>),
    }
</code></pre>
<h2 id="heading-main-file">Main File</h2>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> asyncio
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">from</span> httpx <span class="hljs-keyword">import</span> AsyncClient
<span class="hljs-keyword">import</span> logfire
<span class="hljs-keyword">from</span> dotenv <span class="hljs-keyword">import</span> load_dotenv

<span class="hljs-comment"># Load environment variables</span>
load_dotenv()

<span class="hljs-keyword">from</span> weather_agent <span class="hljs-keyword">import</span> weather_agent, Deps
<span class="hljs-keyword">from</span> response_generator_agent <span class="hljs-keyword">import</span> response_agent

<span class="hljs-comment"># 'if-token-present' means nothing will be sent (and the example will work) if you don't have logfire configured</span>
logfire.configure(send_to_logfire=<span class="hljs-string">'if-token-present'</span>)


<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>():</span>
    <span class="hljs-keyword">async</span> <span class="hljs-keyword">with</span> AsyncClient() <span class="hljs-keyword">as</span> client:
        <span class="hljs-comment"># Get location from user input</span>
        location = input(<span class="hljs-string">"Enter a location: "</span>)
        <span class="hljs-comment"># create a free API key at https://www.tomorrow.io/weather-api/</span>
        weather_api_key = os.getenv(<span class="hljs-string">'WEATHER_API_KEY'</span>)
        <span class="hljs-comment"># create a free API key at https://geocode.maps.co/</span>
        geo_api_key = os.getenv(<span class="hljs-string">'GEO_API_KEY'</span>)
        deps = Deps(
            client=client, weather_api_key=weather_api_key, geo_api_key=geo_api_key
        )
        result = <span class="hljs-keyword">await</span> weather_agent.run(
            <span class="hljs-string">f'What is the weather like in <span class="hljs-subst">{location}</span>?'</span>, deps=deps
        )
        response = <span class="hljs-keyword">await</span> response_agent.run(
            <span class="hljs-string">f'Please generate a response based on the weather data for <span class="hljs-subst">{location}</span>: <span class="hljs-subst">{result.data}</span>'</span>,
            deps=result.data,
        )
        print(<span class="hljs-string">'Response:'</span>, response.data)


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    asyncio.run(main())
</code></pre>
<h2 id="heading-output">Output</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1738346799727/be8cfac4-c64e-4f2a-abf4-f27664fdca93.png" alt class="image--center mx-auto" /></p>
<p>The code for the ABC of multi agent is available <a target="_blank" href="https://github.com/MohitTilwani15/AI-Agent-Series/tree/main/abc-multi-agent"><strong>here</strong></a>.</p>
]]></content:encoded></item><item><title><![CDATA[Simple AF AI Agent]]></title><description><![CDATA[The best way to learn something is by doing it. Instead of diving deep into concepts from get go, let's jump straight into building an agent and work backward to understand each component.
Objective
We will build a weather agent. Sure, it may not be ...]]></description><link>https://mohittilwani.xyz/simple-af-ai-agent</link><guid isPermaLink="true">https://mohittilwani.xyz/simple-af-ai-agent</guid><category><![CDATA[crypto]]></category><category><![CDATA[AI]]></category><category><![CDATA[#ai-tools]]></category><dc:creator><![CDATA[Mohit Tilwani]]></dc:creator><pubDate>Sun, 26 Jan 2025 21:06:53 GMT</pubDate><content:encoded><![CDATA[<p>The best way to learn something is by doing it. Instead of diving deep into concepts from get go, let's jump straight into building an agent and work backward to understand each component.</p>
<h2 id="heading-objective">Objective</h2>
<p>We will build a weather agent. Sure, it may not be the most creative project (and it might feel a bit painful for those enduring gloomy European weather), but it is a great way to learn how to build an AI agent. And, who knows? You might reuse it for summer forecasts ☀️</p>
<p>Weather agent will take a location as input and provide the current weather details.</p>
<h2 id="heading-show-time">Show Time</h2>
<p>Let’s start by creating an agent using <a target="_blank" href="https://ai.pydantic.dev">Pydantic AI</a></p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> pydantic_ai <span class="hljs-keyword">import</span> Agent
<span class="hljs-keyword">from</span> httpx <span class="hljs-keyword">import</span> AsyncClient
<span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> dataclass

<span class="hljs-meta">@dataclass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Deps</span>:</span>
    client: AsyncClient
    weather_api_key: str | <span class="hljs-literal">None</span>
    geo_api_key: str | <span class="hljs-literal">None</span>

weather_agent = <span class="hljs-keyword">from</span> pydantic_ai <span class="hljs-keyword">import</span> Agent(
    <span class="hljs-string">'openai:gpt-4o'</span>,
    system_prompt=(
        <span class="hljs-string">'Be concise, reply with one sentence.'</span>
        <span class="hljs-string">'Use the `get_lat_lng` tool to get the latitude and longitude of the locations, '</span>
        <span class="hljs-string">'then use the `get_weather` tool to get the weather.'</span>
    ),
    retries=<span class="hljs-number">2</span>,
    deps_type=Deps,
)
</code></pre>
<p>In the above code, we instantiated the <code>Agent</code> with several parameters</p>
<ul>
<li><p><code>openai:gpt-4o</code> This is the name of the LLM model that you want to use for the agent. Pydantic <a target="_blank" href="https://ai.pydantic.dev/models/">support</a> many other models.</p>
</li>
<li><p><code>system_prompt</code> Prompt set by the developer to instruct the LLM what it needs to do. As you can see in the above prompt, I am instructing the LLM to reply concisely and use some tools. We will dive deeper into tools shortly.</p>
</li>
<li><p><code>retries</code> Is a functionality offered by Pydantic to retry if there is an error during generating the response. It is similar to how HTTP libraries provide a retry parameter mechanism.</p>
</li>
<li><p><code>deps_type</code> Specifies the dependency type used by the agent. We will discuss later in the blog about this</p>
</li>
</ul>
<h3 id="heading-tools-our-keys-to-the-outside-world">Tools: Our keys to the outside world</h3>
<p>LLMs are trained from the data available on the internet. This has two limitations:</p>
<ol>
<li><p><strong>Data Staleness</strong>: When we utilize LLMs in the present, they are trained on the data from the past. World doesn’t stop and generates millions of terabytes of information every hour which LLM isn’t aware of</p>
</li>
<li><p><strong>Limited Scope</strong>: LLMs can only use data that was accessible during their training. For instance, OpenAI models no longer have access to X.com data.</p>
</li>
</ol>
<p>oh Nein, what to do now? Don’t you worry fam, we got some <strong>Tools!</strong> Tools creates a bridge between LLM and outside world which allows agents to be much more accurate and reliable.</p>
<p>In coding terms, tools are essentially functions that the LLM can call to retrieve additional context or data, helping it generate more accurate and reliable responses.</p>
<p>Let’s create some tools:</p>
<pre><code class="lang-python"><span class="hljs-meta">@weather_agent.tool</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_lat_lng</span>(<span class="hljs-params">
    ctx: RunContext[Deps], location_description: str
</span>) -&gt; dict[str, float]:</span>
    params = {
        <span class="hljs-string">'q'</span>: location_description,
        <span class="hljs-string">'api_key'</span>: ctx.deps.geo_api_key,
    }
    <span class="hljs-keyword">with</span> logfire.span(<span class="hljs-string">'calling geocode API'</span>, params=params) <span class="hljs-keyword">as</span> span:
        r = <span class="hljs-keyword">await</span> ctx.deps.client.get(<span class="hljs-string">'https://geocode.maps.co/search'</span>, params=params)
        r.raise_for_status()
        data = r.json()
        span.set_attribute(<span class="hljs-string">'response'</span>, data)

    <span class="hljs-keyword">if</span> data:
        <span class="hljs-keyword">return</span> {<span class="hljs-string">'lat'</span>: data[<span class="hljs-number">0</span>][<span class="hljs-string">'lat'</span>], <span class="hljs-string">'lng'</span>: data[<span class="hljs-number">0</span>][<span class="hljs-string">'lon'</span>]}
    <span class="hljs-keyword">else</span>:
        <span class="hljs-keyword">raise</span> ModelRetry(<span class="hljs-string">'Could not find the location'</span>)

<span class="hljs-meta">@weather_agent.tool</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_weather</span>(<span class="hljs-params">ctx: RunContext[Deps], lat: float, lng: float</span>) -&gt; dict[str, Any]:</span>
    params = {
        <span class="hljs-string">'apikey'</span>: ctx.deps.weather_api_key,
        <span class="hljs-string">'location'</span>: <span class="hljs-string">f'<span class="hljs-subst">{lat}</span>,<span class="hljs-subst">{lng}</span>'</span>,
        <span class="hljs-string">'units'</span>: <span class="hljs-string">'metric'</span>,
    }
    <span class="hljs-keyword">with</span> logfire.span(<span class="hljs-string">'calling weather API'</span>, params=params) <span class="hljs-keyword">as</span> span:
        r = <span class="hljs-keyword">await</span> ctx.deps.client.get(
            <span class="hljs-string">'https://api.tomorrow.io/v4/weather/realtime'</span>, params=params
        )
        r.raise_for_status()
        data = r.json()
        span.set_attribute(<span class="hljs-string">'response'</span>, data)

    values = data[<span class="hljs-string">'data'</span>][<span class="hljs-string">'values'</span>]
    <span class="hljs-comment"># https://docs.tomorrow.io/reference/data-layers-weather-codes</span>
    code_lookup = {
        <span class="hljs-number">1000</span>: <span class="hljs-string">'Clear, Sunny'</span>,
        <span class="hljs-number">1100</span>: <span class="hljs-string">'Mostly Clear'</span>,
        <span class="hljs-number">1101</span>: <span class="hljs-string">'Partly Cloudy'</span>,
        <span class="hljs-number">1102</span>: <span class="hljs-string">'Mostly Cloudy'</span>,
        <span class="hljs-number">1001</span>: <span class="hljs-string">'Cloudy'</span>,
        <span class="hljs-number">2000</span>: <span class="hljs-string">'Fog'</span>,
        <span class="hljs-number">2100</span>: <span class="hljs-string">'Light Fog'</span>,
        <span class="hljs-number">4000</span>: <span class="hljs-string">'Drizzle'</span>,
        <span class="hljs-number">4001</span>: <span class="hljs-string">'Rain'</span>,
        <span class="hljs-number">4200</span>: <span class="hljs-string">'Light Rain'</span>,
        <span class="hljs-number">4201</span>: <span class="hljs-string">'Heavy Rain'</span>,
        <span class="hljs-number">5000</span>: <span class="hljs-string">'Snow'</span>,
        <span class="hljs-number">5001</span>: <span class="hljs-string">'Flurries'</span>,
        <span class="hljs-number">5100</span>: <span class="hljs-string">'Light Snow'</span>,
        <span class="hljs-number">5101</span>: <span class="hljs-string">'Heavy Snow'</span>,
        <span class="hljs-number">6000</span>: <span class="hljs-string">'Freezing Drizzle'</span>,
        <span class="hljs-number">6001</span>: <span class="hljs-string">'Freezing Rain'</span>,
        <span class="hljs-number">6200</span>: <span class="hljs-string">'Light Freezing Rain'</span>,
        <span class="hljs-number">6201</span>: <span class="hljs-string">'Heavy Freezing Rain'</span>,
        <span class="hljs-number">7000</span>: <span class="hljs-string">'Ice Pellets'</span>,
        <span class="hljs-number">7101</span>: <span class="hljs-string">'Heavy Ice Pellets'</span>,
        <span class="hljs-number">7102</span>: <span class="hljs-string">'Light Ice Pellets'</span>,
        <span class="hljs-number">8000</span>: <span class="hljs-string">'Thunderstorm'</span>,
    }
    <span class="hljs-keyword">return</span> {
        <span class="hljs-string">'temperature'</span>: <span class="hljs-string">f'<span class="hljs-subst">{values[<span class="hljs-string">"temperatureApparent"</span>]:<span class="hljs-number">0.0</span>f}</span>°C'</span>,
        <span class="hljs-string">'description'</span>: code_lookup.get(values[<span class="hljs-string">'weatherCode'</span>], <span class="hljs-string">'Unknown'</span>),
    }
</code></pre>
<p>In the code above, we defined two tools:</p>
<ol>
<li><p><code>get_lat_lng</code>: Retrieves the latitude and longitude of a given location using a geocoding API.</p>
</li>
<li><p><code>get_weather</code>: Fetches real-time weather data for a given latitude and longitude using a weather API.</p>
</li>
</ol>
<p>We passed the decorator <code>@weather_agent.tool</code> to both functions which provides the <code>weather_agent</code> aware of the tools it can call. Unlike some frameworks that require passing tools as a list during agent creation, Pydantic AI simplifies this with decorators.</p>
<h3 id="heading-dependencies-in-pydantic-ai">Dependencies in Pydantic AI</h3>
<p>PydanticAI uses a dependency injection system to provide data and services to your agent's tools. As you can see in the above code snippet, the first parameter in both function is ctx which has a property <code>deps</code> which is basically Pydantic AI way of injecting dependencies that is available to tools during run time.</p>
<h2 id="heading-lets-run-the-agent">Let’s Run the Agent</h2>
<pre><code class="lang-python"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>():</span>
    <span class="hljs-keyword">async</span> <span class="hljs-keyword">with</span> AsyncClient() <span class="hljs-keyword">as</span> client:
        <span class="hljs-comment"># Get location from user input</span>
        location = input(<span class="hljs-string">"Enter a location: "</span>)
        <span class="hljs-comment"># create a free API key at https://www.tomorrow.io/weather-api/</span>
        weather_api_key = os.getenv(<span class="hljs-string">'WEATHER_API_KEY'</span>)
        <span class="hljs-comment"># create a free API key at https://geocode.maps.co/</span>
        geo_api_key = os.getenv(<span class="hljs-string">'GEO_API_KEY'</span>)
        deps = Deps(
            client=client, weather_api_key=weather_api_key, geo_api_key=geo_api_key
        )
        result = <span class="hljs-keyword">await</span> weather_agent.run(
            <span class="hljs-string">f'What is the weather like in <span class="hljs-subst">{location}</span>?'</span>, deps=deps
        )
        print(<span class="hljs-string">'Response:'</span>, result.data)


<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    asyncio.run(main())
</code></pre>
<p>This script:</p>
<ol>
<li><p>Prompts the user to enter a location.</p>
</li>
<li><p>Fetches the weather and geocoding API keys from environment variables.</p>
</li>
<li><p>Passes dependencies to the agent.</p>
</li>
<li><p>Invokes the agent to get the weather data for the specified location.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737924904257/cbc3fad3-a7ed-4f8c-bb68-751aab31b9d0.png" alt class="image--center mx-auto" /></p>
<p>The code for the simple agent is available <a target="_blank" href="https://github.com/MohitTilwani15/AI-Agent-Series">here</a>.</p>
<h2 id="heading-motivation-links"><strong>Motivation links</strong></h2>
<ul>
<li><a target="_blank" href="https://www.kaggle.com/whitepaper-agents">Whitepaper on Agents from Google</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Fusion of Crypto & AI]]></title><description><![CDATA[Background
With the breakthrough of the transformer architecture and GPUs, LLMs emerged. Think of the transformer architecture as the prefrontal cortex of an LLM—it unlocked the processing of natural language (much much faster).
The transformer's cor...]]></description><link>https://mohittilwani.xyz/fusion-of-crypto-ai</link><guid isPermaLink="true">https://mohittilwani.xyz/fusion-of-crypto-ai</guid><category><![CDATA[crypto]]></category><category><![CDATA[AI]]></category><dc:creator><![CDATA[Mohit Tilwani]]></dc:creator><pubDate>Sat, 25 Jan 2025 21:06:39 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-background">Background</h2>
<p>With the breakthrough of the <a target="_blank" href="https://arxiv.org/pdf/1706.03762">transformer architecture</a> and GPUs, LLMs emerged. Think of the transformer architecture as the prefrontal cortex of an LLM—it unlocked the processing of natural language (<a target="_blank" href="https://youtu.be/LPZh9BOjkQs?feature=shared&amp;t=199">much much faster</a>).</p>
<p>The transformer's core innovation is the "attention" mechanism, which allows the model to dynamically focus on different parts of the input when generating each part of the output, mimicking how humans selectively concentrate on relevant information</p>
<p>GPUs (Graphics Processing Units) provided the computational muscle, offering massive parallel processing power that could handle the complex matrix calculations required by transformer models.</p>
<h2 id="heading-english-is-the-new-programming-language">English is the new programming language</h2>
<p>Soon, many engineers realized, LLM is performing task on a surface level i.e. it is using system 1 thinking<sup>5. </sup> How can we improve the AI models to use system 2 thinking<sup>5</sup>? This led to the development of different techniques to interact with AI. Approaches<sup>3</sup> like like zero-shot prompting, few-shot prompting, chain of thoughts, and tree of thoughts emerged. These are technical terms (which I won’t go into depth about here) for techniques we can use to interact with AI agents to produce higher-quality responses.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737823255634/0ce44718-86eb-4013-bdc1-e40dee9bece2.png?width=400&amp;height=400" alt class="image--center mx-auto" /></p>
<p>All of this worked remarkably well—so well that we now have dedicated platforms and tools built around these techniques. Then some smart folks thought: how can we utilize LLMs to also take <em>action</em> on behalf of us? In engineering terms, this is called automation—but automation powered by natural language computation.</p>
<p>Thus, AI agents were "born". But AI agents aren’t something new—we have been using agents for decades without even realizing it. One of the most famous agent is Google search. We type something in the language we are proficient at, and Google search agent does some magic to provide us with relevant links for further research.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737823280875/b3968380-d27b-4178-bae7-d1892f92ff4f.jpeg?width=400&amp;height=400" alt class="image--center mx-auto" /></p>
<h2 id="heading-coming-to-the-point">Coming to the point</h2>
<p>But why the heck are we involving AI agents in crypto? There are many compelling answers<sup>2</sup> to this, but the one that motivates me the most is: <em>how can I help people to grow their wealth while they are asleep?</em> I am a big fan of Naval Ravikant’s philosophy, and as he has said multiple times: “Seek wealth, not money or status.”<sup>1</sup> This is exactly what AI agents can help us achieve—giving “brains” to our money.</p>
<p>I am going to devote the next decade of my life to learn and build valuable products using AI. My goal is to create something that have a deep, positive impact on people’s daily lives.</p>
<h2 id="heading-what-can-you-expect-in-the-future-posts"><strong>What can you expect in the future posts</strong></h2>
<ol>
<li><p>Deep dive into AI agents and different types of architecture</p>
</li>
<li><p>Rolling up our sleeves and getting hands-on (as Linus Torvalds said, "Talk is cheap. Show me the code.")</p>
</li>
<li><p>"Explain it like I’m five" takes on new and trendy topics</p>
</li>
<li><p>Few surprises here and there</p>
</li>
</ol>
<h2 id="heading-motivation-links">Motivation links</h2>
<ol>
<li><p><a target="_blank" href="https://www.youtube.com/watch?v=jemPACNo1_I&amp;feature=youtu.be">Seek wealth not money or status from Naval Ravikant</a></p>
</li>
<li><p><a target="_blank" href="https://x.com/robbiepetersen_/status/1864351850134216966">Role of crypto in an Agentic Economy from Robbie Peterson</a></p>
</li>
<li><p><a target="_blank" href="https://www.promptingguide.ai/">Prompt Engineering Guide</a></p>
</li>
<li><p><a target="_blank" href="https://x.com/wayne_hamadi/status/1868742755402621103">You don't understand AI agents</a></p>
</li>
<li><p><a target="_blank" href="https://en.wikipedia.org/wiki/Thinking,_Fast_and_Slow">Thinking Fast and Slow from Daniel Kahneman</a></p>
</li>
</ol>
]]></content:encoded></item></channel></rss>