<?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[Sudheer Ranjan]]></title><description><![CDATA[Data Scientist]]></description><link>https://sudheerranjan.com</link><generator>RSS for Node</generator><lastBuildDate>Sat, 11 Apr 2026 04:41:10 GMT</lastBuildDate><atom:link href="https://sudheerranjan.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Exploring AI Agents: An Introduction to CrewAI]]></title><description><![CDATA[Evolution of AI Agents from LLMs
You might have experimented with Large Language Models from OpenAI and Hugging Face. They excel at predicting the next word using the vast data they are trained on. They are great for simple tasks, but what about comp...]]></description><link>https://sudheerranjan.com/exploring-ai-agents-an-introduction-to-crewai</link><guid isPermaLink="true">https://sudheerranjan.com/exploring-ai-agents-an-introduction-to-crewai</guid><category><![CDATA[CrewAI]]></category><category><![CDATA[ai agents]]></category><dc:creator><![CDATA[Sudheer Ranjan]]></dc:creator><pubDate>Fri, 31 May 2024 05:26:42 GMT</pubDate><content:encoded><![CDATA[<h3 id="heading-evolution-of-ai-agents-from-llms">Evolution of AI Agents from LLMs</h3>
<p>You might have experimented with Large Language Models from OpenAI and Hugging Face. They excel at predicting the next word using the vast data they are trained on. They are great for simple tasks, but what about complex tasks? If you think the answer needs changes, you would likely tweak the prompts (with Prompt Engineering skills) and add context to the LLM to get the desired output. However, this means we have to engage in the interactions ourselves. How do we automate this or make the LLM autonomous? Given that LLMs can put together words that make sense, agents are a way to help LLMs improve on their own.</p>
<h3 id="heading-agentic-automation">Agentic Automation</h3>
<p>Automation in traditional software development involves using if-else conditions to achieve an output. In AI, however, we simply provide a map. Unlike traditional software development, AI handles fuzzy inputs, performs fuzzy transformations, and produces fuzzy outputs. Additionally, the results can vary each time.</p>
<p>CrewAI is one such Open-source framework and platform for orchestrating role-playing, autonomous AI agents. CrewAI's building blocks include Agents, Tasks, and Crew, which we will discuss in detail.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1717132767383/cec55c09-e09f-4118-92da-459e60d968a4.png" alt="CrewAI Mindmap" class="image--center mx-auto" /></p>
<p><em>Image Credits: CrewAI</em></p>
<h3 id="heading-agents">Agents</h3>
<p>While Andrew Ng highlights Reflection, Tool Use, Planning, and Multi-agent collaboration in his blog <a target="_blank" href="https://www.deeplearning.ai/the-batch/how-agents-can-improve-llm-performance/?ref=dl-staging-website.ghost.io">Batch</a>, CrewAI adds a few more patterns. Think of these patterns as a way to interact with an LLM using a wrapper. These patterns help the agent complete complex tasks. Let's go through each of these.</p>
<ol>
<li><p><em>Role Playing:</em> Role-playing of Agent helps the LLM set context, leading to better results.</p>
</li>
<li><p><em>Focus:</em> Though we can provide a long context to the LLM with increasing context windows, too much information can cause the LLM to hallucinate. Narrowly focused tasks help the agent perform better.</p>
</li>
<li><p><em>Tools:</em> You might have seen LLMs failing miserably in mathematical calculations. LLMs have overcome this by converting the problem to Python and executing it. What about other scenarios where an LLM can't handle the task? Here, the agent should be able to access tools like specific websites, the internet, or files. However, too many tools can make it difficult for the agent (especially with a small model) to choose the right one. Always provide the key tools. With CrewAI, you can decide whether to give the tools at task level or agent level.</p>
</li>
<li><p><em>Cooperation:</em> Agents role-play and have conversations in their roles, which helps in getting better results. Taking feedback and delegating tasks also improve their output. Delegation doesn't need to happen every time; agents should decide to delegate based on the problem's complexity. Collaboration among multiple agents can occur sequentially, hierarchically (like a manager delegating tasks), or asynchronously.</p>
</li>
<li><p><em>Guardrails:</em> Unlike traditional software, AI systems have to handle unclear inputs, perform unclear transformations, and produce unclear outputs. Some tasks might end up in a loop. Guardrails help prevent your agent from getting off track and guide them to stay focused.</p>
</li>
<li><p><em>Memory:</em> Agents should remember the past, learn from it, and apply that knowledge to future tasks. Agents with memory can learn from their mistakes. CrewAI specifically offers three types of memory out of the box: short memory, long memory, and entity memory. With memory, you can achieve more reliable results and reduce randomness.</p>
<ol>
<li><p><em>Short Memory:</em> This memory/context is shared across all agents during crew's execution. Share intermediate information even before providing task completion output with other agents.</p>
</li>
<li><p><em>Long Memory:</em> This stays even after crew's execution, stored in Database, agents learn from its previous execution for future tasks. This leads to self improving agents.</p>
</li>
<li><p>Entity: This memory stays during crew's execution, it memorizes subjects being discussed.</p>
</li>
</ol>
</li>
</ol>
<h3 id="heading-multi-agent-systems">Multi Agent Systems</h3>
<ol>
<li><p>Multi Agent Systems are a group of agents in which each agent is customized to do one single thing and do it well.</p>
</li>
<li><p>Each agent can run from different LLMs.</p>
</li>
<li><p>They have ability to delegate or give feedback.</p>
</li>
</ol>
<h3 id="heading-basic-componentsclasses-of-crewai">Basic components/classes of CrewAI</h3>
<ol>
<li><p><strong><em>Agent:</em></strong> This class requires the role and goal of the agent along with some backstory of the task.</p>
</li>
<li><p><strong><em>Task:</em></strong> This class requires the description of the task, expected output and the agent to work on.</p>
</li>
<li><p><strong><em>Crew:</em></strong> Crew is something that puts together both agents and tasks. By default crew operates sequentially, but we assign weights to make it work asynchronously.</p>
</li>
</ol>
<h3 id="heading-what-makes-a-great-tool-for-an-ai-agent">What makes a great tool for an AI Agent?</h3>
<p>While an LLM on its own doesn't know everything we ask, we can give it tools to complete tasks. When creating a chatbot for specific domain data, we either fine-tune the LLM to that domain or use Retrieval Augmented Generation (RAG) to query the domain data. Think of this as a tool. More tools like this need to be created for various use cases. Below are some qualities you should look for when creating or using tools.</p>
<ol>
<li><p><em>Versatile:</em> A tool connects unclear input to unclear output. It should handle any input and any output that LLMs generate.</p>
</li>
<li><p><em>Fault-tolerant:</em> Exceptions should not stop the execution. Instead, they should prompt the agent to find alternative ways to achieve the goal.</p>
</li>
<li><p><em>Caching Strategy:</em> Tools are used to call internet services, internal/external services, and API services. The same tool with the same set of arguments is cached. This prevents unnecessary requests, saving requests per second and execution time. CrewAI offers cross-agent caching, allowing different agents to share the cache layer instead of making the same API call again.</p>
</li>
</ol>
<p>With CrewAI we can build our own custom tool.</p>
<h3 id="heading-examples-of-tools">Examples of tools</h3>
<ol>
<li><p>Search the internet</p>
</li>
<li><p>Scrape a website: RAG over a website</p>
</li>
<li><p>Connect to a Database</p>
</li>
<li><p>Call an API</p>
</li>
<li><p>Send Notifications</p>
</li>
</ol>
<h3 id="heading-how-to-decide-the-tasks">How to decide the Tasks</h3>
<p>This offers a mental framework of how we should think of solving a complex problem. Deciding how we frame the Tasks and Agents is key in solving the problem.</p>
<ol>
<li><p>What is the goal? What is the process?</p>
</li>
<li><p>What kind of individuals do I need to hire to complete this task? These individuals become the agents.</p>
</li>
<li><p>What processes and tasks do I expect the individuals on my team to perform?</p>
<p> These become tasks for those agents.</p>
</li>
<li><p>A few other parameters, like clear and concise expectations and setting the context, make up a detailed task.</p>
</li>
</ol>
<p>CrewAI represents a significant advancement in AI, moving beyond simple language models to sophisticated AI agents capable of handling complex tasks autonomously. Key features include agentic automation, role-playing for context, focused tasks to reduce hallucination, and access to external tools. Cooperation among agents and the use of guardrails ensure efficiency and accuracy. CrewAI's memory system—short-term, long-term, and entity memory—enables agents to learn from past experiences. Multi-agent systems specialize in specific tasks and collaborate seamlessly. Essential components include agents, tasks, and crews. Effective tools should be versatile, fault-tolerant, and utilize caching strategies. CrewAI's approach helps solve complex problems by defining clear goals, identifying necessary agents, and outlining tasks and expectations.</p>
<p><strong>References:</strong></p>
<p><a target="_blank" href="https://www.deeplearning.ai/the-batch/how-agents-can-improve-llm-performance/?ref=dl-staging-website.ghost.io">Andrew Ng's Article on Agentic Design Patterns</a></p>
<p><a target="_blank" href="https://learn.deeplearning.ai/login?callbackUrl=https%3A%2F%2Flearn.deeplearning.ai%2Fcourses%2Fmulti-ai-agent-systems-with-crewai">Multi AI Agent Systems with CrewAI course on Deeplearning.ai</a></p>
]]></content:encoded></item><item><title><![CDATA[Steps to Evaluate Fairness in Machine Learning Models]]></title><description><![CDATA[Businesses prioritize metrics that impact their bottom line, while data scientists often focus on accuracy. However, bias in a model can lead to allocative harms (unequal distribution of benefits) and representation harms (downplaying certain groups)...]]></description><link>https://sudheerranjan.com/steps-to-evaluate-fairness-in-machine-learning-models</link><guid isPermaLink="true">https://sudheerranjan.com/steps-to-evaluate-fairness-in-machine-learning-models</guid><category><![CDATA[fairlearn]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[AI]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[Python]]></category><dc:creator><![CDATA[Sudheer Ranjan]]></dc:creator><pubDate>Wed, 15 May 2024 18:30:00 GMT</pubDate><content:encoded><![CDATA[<p><img src="https://lh7-us.googleusercontent.com/Sai04Mjd5VLuaP5u24xer_U_9-mq8WvZ7yjT8zyMvLjBeT4wj2O6Hs4mZxajB3y1n3HNnxnOfH3u0SEIcw3cPRDiOksCHoxCuMOD9ZeGEnuur9KpAynwcKkEIEagoEVTKO0hz4fPvgVouTnzSOASwzK6Pw=s2048" alt="Meme on Fairness of ML solutions" class="image--center mx-auto" /></p>
<p>Businesses prioritize metrics that impact their bottom line, while data scientists often focus on accuracy. However, bias in a model can lead to allocative harms (unequal distribution of benefits) and representation harms (downplaying certain groups). These coupled with opaque black box models ultimately can erode trust in AI.</p>
<p>Here Data scientists play a critical role in developing responsible AI/ML solutions. Cloud platforms offer various fairness testing tools to help identify and mitigate bias. And it is possible to incorporate fairness testing in python notebooks.</p>
<p>One powerful open source tool I use for Fairness assessment in my project is <strong>Fairlearn</strong>, which quantifies bias in models with respect to sensitive features like age, gender, and race.</p>
<p>Sharing the code template that will help you to see your model fairness. Also it shows an example of unequal distribution of count and selection rate among different groups.</p>
<pre><code class="lang-python">!pip install --no-cache-dir fairlearn
<span class="hljs-keyword">from</span> fairlearn.metrics <span class="hljs-keyword">import</span> MetricFrame
<span class="hljs-keyword">from</span> fairlearn.metrics <span class="hljs-keyword">import</span> (accuracy_score, precision_score,
                              false_positive_rate, false_negative_rate,
                              selection_rate,count)

metrics = {
    <span class="hljs-string">"accuracy"</span>: accuracy_score,
    <span class="hljs-string">"precision"</span>: precision_score,
    <span class="hljs-string">"false positive rate"</span>: false_positive_rate,
    <span class="hljs-string">"false negative rate"</span>: false_negative_rate,
    <span class="hljs-string">"selection rate"</span>: selection_rate,
    <span class="hljs-string">"count"</span>: count,
}
metric_frame = MetricFrame(
    metrics=metrics, y_true=df[<span class="hljs-string">'y_true'</span>], y_pred=df[<span class="hljs-string">'y_pred'</span>], sensitive_features=df[<span class="hljs-string">'race'</span>]
)
metric_frame.by_group.plot.bar(
    subplots=<span class="hljs-literal">True</span>,
    layout=[<span class="hljs-number">3</span>, <span class="hljs-number">3</span>],
    legend=<span class="hljs-literal">False</span>,
    figsize=[<span class="hljs-number">12</span>, <span class="hljs-number">8</span>],
    title=<span class="hljs-string">"Fairness testing"</span>,
)
</code></pre>
<p>Running the above code on one of the biased dataset resulted in the below charts.</p>
<p><img src="https://lh7-us.googleusercontent.com/4XyHA_rgNa4pjfQvVVLcu1DuSkqEfbID6O44BwVvytvC03knkyivFdMqBqNEMGWOLx8kI6XENggxV9_chmnpFGlOL6-L2hm1jTJuFxPi2fC7JECShucqeVUQiQvFFdap5FFkjoyYprJ_0Qq-VO2TZ2CqbQ=s2048" alt /></p>
<p>Notice how some metrics, like selection rate and false positive rate, favor certain groups within the population. You will also see that there are more groups belonging to minorities in the population. Even with good accuracy, bias against certain minority groups can undermine their rights. We can measure this only when we shift our focus to how our metrics impact people's lives.</p>
]]></content:encoded></item><item><title><![CDATA[Quick Guide to Speeding Up Docker Builds for ML Applications]]></title><description><![CDATA[Docker builds are essential for deploying ML applications in a consistent and portable way. However, slow build times can significantly hinder development and deployment workflows, as well as streamlined CI/CD pipelines. Here are some strategies I fo...]]></description><link>https://sudheerranjan.com/quick-guide-to-speeding-up-docker-builds-for-ml-applications</link><guid isPermaLink="true">https://sudheerranjan.com/quick-guide-to-speeding-up-docker-builds-for-ml-applications</guid><category><![CDATA[Docker]]></category><category><![CDATA[mlops]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[Python]]></category><category><![CDATA[AI]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Sudheer Ranjan]]></dc:creator><pubDate>Wed, 01 May 2024 18:30:00 GMT</pubDate><content:encoded><![CDATA[<p>Docker builds are essential for deploying ML applications in a consistent and portable way. However, slow build times can significantly hinder development and deployment workflows, as well as streamlined CI/CD pipelines. Here are some strategies I follow to significantly improve Docker build speed.</p>
<ol>
<li><p><strong>Docker Layer Caching:</strong></p>
<p> Docker builds are composed of layers, where each instruction creates a new layer. Docker cleverly caches layers that haven't changed, significantly reducing build time on subsequent runs.</p>
<p> <strong>Order Matters:</strong> In your Dockerfile, place frequently modified instructions (like copying your code) towards the end. This ensures frequently changing layers don't invalidate the cache for earlier layers (like installing libraries using pip and copying the requirements.txt). Install the libraries in earlier layers to leverage the cache effectively. Below is an example of how to implement this idea of docker caching.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1716628378127/879cab78-62ad-43e8-accc-8d6519e58951.png" alt="Notice how this order has helped us to skip building of the first 5 layers using cache." class="image--center mx-auto" /></p>
<p> Notice how this order has helped us to skip re-building of the first 5 layers of the docker file using cache.</p>
</li>
<li><p><strong>Minimize Package Installation using --no-install-recommends:</strong></p>
<p> By default, package managers like apt-get install both essential and recommended packages. Use the --no-install-recommends flag to install only the strictly necessary packages for your application. This reduces download size and build time.</p>
<pre><code class="lang-dockerfile"> <span class="hljs-keyword">RUN</span><span class="bash"> apt-get update &amp;&amp; apt-get install --no-install-recommends libgomp1</span>
 <span class="hljs-comment">#libgmop1 provides support for OpenMP which is useful in parallel programming</span>
</code></pre>
</li>
<li><p><strong>Ignore unnecessary files for docker build:</strong></p>
<p> The .dockerignore file functions similarly to .gitignore but for Docker builds. Use it to exclude unnecessary files and folders from your build context. This avoids unnecessary copying during the build process, speeding things up. One common file that is not necessary during the training or inference pipeline is <code>ipynb_checkpoints</code>. Here is an example of how you can exclude them.</p>
<pre><code class="lang-plaintext"> **/*.ipynb_checkpoints/
</code></pre>
</li>
<li><p><strong>Choose a slim base image:</strong></p>
<p> Many base images like python:3.10 come with various pre-installed packages. Consider using slimmer alternatives like python:3.10-slim or python:3.10-alpine to minimize the image size and build time. These slim versions often only contain Python itself and essential libraries.</p>
<pre><code class="lang-dockerfile"> <span class="hljs-keyword">FROM</span> python:<span class="hljs-number">3.10</span>-slim
 <span class="hljs-comment">#instead of FROM python:latest or FROM python:3.10</span>
</code></pre>
<p> I hope these strategies—optimizing layer caching, minimizing unnecessary package installations, excluding irrelevant files, and choosing a slim image—will help you save time and enable faster, more frequent ML deployments.</p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[How to choose the right Python base image for containerizing your ML application]]></title><description><![CDATA[One often-overlooked aspect of deploying Machine Learning solutions with Docker is selecting the right base image. Discovering vulnerabilities in base images post-deployment in security-conscious organizations may result in building the ML models aga...]]></description><link>https://sudheerranjan.com/how-to-choose-the-right-python-base-image-for-containerizing-your-ml-application</link><guid isPermaLink="true">https://sudheerranjan.com/how-to-choose-the-right-python-base-image-for-containerizing-your-ml-application</guid><category><![CDATA[mlops]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Python]]></category><category><![CDATA[AI]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[Data Science]]></category><dc:creator><![CDATA[Sudheer Ranjan]]></dc:creator><pubDate>Wed, 24 Apr 2024 18:30:00 GMT</pubDate><content:encoded><![CDATA[<p>One often-overlooked aspect of deploying Machine Learning solutions with Docker is selecting the right base image. Discovering vulnerabilities in base images post-deployment in security-conscious organizations may result in building the ML models again. This can introduce additional time investment due to potential changes in library dependencies.</p>
<p>So, here are the two key factors I would consider in choosing the python image (also attached an image that illustrates the same):</p>
<ol>
<li><p><strong>Security:</strong></p>
<p> <strong>Minimize attack surface:</strong> Start with the most lightweight base image that fulfills your requirements. Images like "python: alpine" and "python: slim" offer a solid foundation without unnecessary bloatware. Remember, more libraries increase the potential attack surface. Popular "slim" variants include "bullseye" and "bookworm." You can always install missing libraries using apt or apk within the container. I often favor 'slim' variants over Alpine Linux. While Alpine offers a smaller footprint, 'slim' typically includes some pre-installed, commonly used libraries, reducing the need for additional installation steps.</p>
<p> <strong>Version Control:</strong> Use explicit version tags instead of the generic "latest" tag. The "latest" tag can point to different images over time, causing inconsistencies and potentially introducing vulnerabilities. Choose a base image with a known version that has been scanned for security issues. Consider official base images from trusted sources like Docker Hub.</p>
<p> And you might ask how to find vulnerabilities in your already deployed solution. Usually, enterprises use plugins like PRISMA to help identify vulnerabilities. If your enterprise doesn't offer such tools, here is a Docker command you can run to find the vulnerabilities.</p>
<pre><code class="lang-bash"> docker scout &lt;docker-image&gt;
</code></pre>
</li>
<li><p><strong>Size Optimization:</strong></p>
<p> <strong>Minimize footprint:</strong> Smaller base images lead to smaller container sizes, which translates to faster deployment and lower resource consumption. This is particularly important for large-scale deployments.</p>
<p> Let's see how to keep these factors in mind when choosing a base image from <a target="_blank" href="https://hub.docker.com/_/python">Docker Hub</a>. The image below shows the vulnerabilities and sizes of the popular base images available on Docker Hub. Using the 'latest' tag can be risky in production because you don't know what might go wrong as the vulnerabilities are yet to be scanned. 'Slim' variants usually have a reasonable size and fewer vulnerabilities. For example, the 'Slim' variant has 0 critical and 2 high vulnerabilities. In some cases, you can remove some of these vulnerabilities.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1716639936708/efcf9199-8e52-436b-b1d2-b6a4b49ed19a.png" alt class="image--center mx-auto" /></p>
<p> By focusing on minimizing the attack surface and optimizing the size of your base image, you can build a more secure and performant solution. Always use explicit version tags and rely on trusted sources for your base images. Regularly scan for vulnerabilities and stay informed about updates to maintain a robust deployment. With these considerations in mind, you can confidently deploy your ML applications with Docker, knowing they are secure and optimized.</p>
</li>
</ol>
]]></content:encoded></item></channel></rss>