<?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: Rohith Davuluri</title>
    <description>The latest articles on DEV Community by Rohith Davuluri (@rohith_davuluri).</description>
    <link>https://dev.to/rohith_davuluri</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%2F3897082%2F5aa088fd-0f5e-411a-a795-87efbc8e0304.png</url>
      <title>DEV Community: Rohith Davuluri</title>
      <link>https://dev.to/rohith_davuluri</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rohith_davuluri"/>
    <language>en</language>
    <item>
      <title>TF-IDF + LLM Reranking: How I Improved Vector Search Accuracy from 60% to 86%</title>
      <dc:creator>Rohith Davuluri</dc:creator>
      <pubDate>Sat, 25 Apr 2026 07:24:22 +0000</pubDate>
      <link>https://dev.to/rohith_davuluri/tf-idf-llm-reranking-how-i-improved-vector-search-accuracy-from-60-to-86-31b1</link>
      <guid>https://dev.to/rohith_davuluri/tf-idf-llm-reranking-how-i-improved-vector-search-accuracy-from-60-to-86-31b1</guid>
      <description>&lt;p&gt;TF-IDF + LLM Reranking: How I Improved Vector Search Accuracy from 60% to 86%&lt;br&gt;
Vector search is powerful — but it’s not perfect. When I was building a database discovery pipeline at work, our initial semantic search was only matching the right schemas about 60% of the time. That wasn’t good enough for production. Here’s exactly how I fixed it using a hybrid TF-IDF and LLM reranking approach.&lt;br&gt;
The Problem&lt;br&gt;
Our pipeline needed to match user queries to the correct database schemas from a large pool of candidates. Pure vector search (embeddings + cosine similarity) was fast but kept returning semantically similar but contextually wrong results.&lt;br&gt;
For example, searching for “customer account balance” would return results about “user wallet transactions” — close, but not what we needed in a strict banking compliance context.&lt;br&gt;
The Solution: Hybrid Retrieval + LLM Reranking&lt;br&gt;
Instead of relying on one method, I combined three layers:&lt;br&gt;
    1.  TF-IDF for keyword precision&lt;br&gt;
    2.  Vector embeddings for semantic similarity&lt;br&gt;
    3.  LLM reranking for contextual judgment&lt;br&gt;
Step 1 — TF-IDF First Pass&lt;br&gt;
TF-IDF is great at catching exact keyword matches that embeddings sometimes miss:&lt;/p&gt;

&lt;p&gt;from sklearn.feature_extraction.text import TfidfVectorizer&lt;br&gt;
from sklearn.metrics.pairwise import cosine_similarity&lt;br&gt;
import numpy as np&lt;/p&gt;

&lt;p&gt;def tfidf_retrieve(query: str, corpus: list, top_k: int = 20) -&amp;gt; list:&lt;br&gt;
    vectorizer = TfidfVectorizer()&lt;br&gt;
    tfidf_matrix = vectorizer.fit_transform(corpus)&lt;br&gt;
    query_vec = vectorizer.transform([query])&lt;br&gt;
    scores = cosine_similarity(query_vec, tfidf_matrix).flatten()&lt;br&gt;
    top_indices = np.argsort(scores)[::-1][:top_k]&lt;br&gt;
    return [(corpus[i], scores[i]) for i in top_indices]&lt;/p&gt;

&lt;p&gt;This gives us a broad candidate set of top 20 results.&lt;br&gt;
Step 2 — Vector Embedding Re-Filter&lt;br&gt;
Next we re-score those 20 candidates using semantic embeddings:&lt;/p&gt;

&lt;p&gt;from sentence_transformers import SentenceTransformer&lt;br&gt;
import numpy as np&lt;/p&gt;

&lt;p&gt;model = SentenceTransformer("all-MiniLM-L6-v2")&lt;/p&gt;

&lt;p&gt;def embedding_rerank(query: str, candidates: list, top_k: int = 5) -&amp;gt; list:&lt;br&gt;
    query_embedding = model.encode(query)&lt;br&gt;
    scored = []&lt;br&gt;
    for text, _ in candidates:&lt;br&gt;
        emb = model.encode(text)&lt;br&gt;
        score = np.dot(query_embedding, emb)&lt;br&gt;
        scored.append((text, score))&lt;br&gt;
    scored.sort(key=lambda x: x[1], reverse=True)&lt;br&gt;
    return scored[:top_k]&lt;/p&gt;

&lt;p&gt;Now we’re down to top 5 highly relevant candidates.&lt;br&gt;
Step 3 — LLM Reranking&lt;br&gt;
This is where the magic happens. We ask Gemini to pick the best match:&lt;/p&gt;

&lt;p&gt;import google.generativeai as genai&lt;/p&gt;

&lt;p&gt;def llm_rerank(query: str, candidates: list) -&amp;gt; str:&lt;br&gt;
    candidate_text = "\n".join(&lt;br&gt;
        [f"{i+1}. {c[0]}" for i, c in enumerate(candidates)]&lt;br&gt;
    )&lt;br&gt;
    prompt = f"""&lt;br&gt;
    Query: {query}&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Candidates:
{candidate_text}

Which candidate best matches the query in a banking compliance context?
Return only the number of the best match.
"""
model = genai.GenerativeModel("gemini-2.0-flash")
response = model.generate_content(prompt)
return candidates[int(response.text.strip()) - 1][0]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The LLM understands context, domain specifics, and nuance that pure math simply can’t capture.&lt;br&gt;
The Results&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Accuracy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vector search only&lt;/td&gt;
&lt;td&gt;~60%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TF-IDF only&lt;/td&gt;
&lt;td&gt;~65%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TF-IDF + Embeddings&lt;/td&gt;
&lt;td&gt;~75%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full hybrid + LLM rerank&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;86%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each layer added meaningful improvement. The LLM reranking alone jumped accuracy by 11 points.&lt;br&gt;
Why This Works&lt;br&gt;
    • TF-IDF catches exact terminology matches&lt;br&gt;
    • Embeddings capture semantic meaning&lt;br&gt;
    • LLM applies domain reasoning and context&lt;br&gt;
No single method is perfect. Combined, they cover each other’s weaknesses.&lt;br&gt;
When Should You Use This?&lt;br&gt;
Use this approach when:&lt;br&gt;
    • Your search corpus is domain-specific (legal, medical, banking)&lt;br&gt;
    • Exact keyword matches matter alongside semantic meaning&lt;br&gt;
    • You can afford a small LLM call per query&lt;br&gt;
    • Accuracy matters more than raw speed&lt;br&gt;
Key Takeaway&lt;br&gt;
Don’t default to pure vector search just because it’s trendy. A hybrid approach with LLM reranking is more accurate for specialized domains — and the implementation is simpler than you’d think.&lt;br&gt;
Follow me for more practical AI engineering content. 🚀&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>python</category>
      <category>vectorsearch</category>
    </item>
    <item>
      <title>Why I Use Playwright for AI Agent Automation (And You Should Too)</title>
      <dc:creator>Rohith Davuluri</dc:creator>
      <pubDate>Sat, 25 Apr 2026 07:21:34 +0000</pubDate>
      <link>https://dev.to/rohith_davuluri/why-i-use-playwright-for-ai-agent-automation-and-you-should-too-4f5e</link>
      <guid>https://dev.to/rohith_davuluri/why-i-use-playwright-for-ai-agent-automation-and-you-should-too-4f5e</guid>
      <description>&lt;p&gt;Why I Use Playwright for AI Agent Automation (And You Should Too)&lt;br&gt;
When I first started building AI agents that needed to interact with web-based banking systems, I tried everything — Selenium, requests, BeautifulSoup. Nothing came close to what Playwright offers. Here’s why I switched and never looked back.&lt;br&gt;
What is Playwright?&lt;br&gt;
Playwright is a modern browser automation library developed by Microsoft. It supports Chromium, Firefox, and WebKit, and works seamlessly with Python, JavaScript, and TypeScript.&lt;br&gt;
But what makes it special for AI agent workflows isn’t just speed — it’s reliability.&lt;br&gt;
The Problem With Other Tools&lt;br&gt;
Traditional automation tools struggle with:&lt;br&gt;
    • Dynamic JavaScript-rendered content&lt;br&gt;
    • Complex login flows and session management&lt;br&gt;
    • Multi-step form interactions&lt;br&gt;
    • Real-time page state changes&lt;br&gt;
AI agents need to navigate these challenges autonomously. One failed selector and the entire workflow breaks.&lt;br&gt;
Why Playwright Wins for AI Agents&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Auto-Waiting
Playwright automatically waits for elements to be ready before interacting. No more:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;time.sleep(3)  # the old way&lt;/p&gt;

&lt;p&gt;Instead:&lt;/p&gt;

&lt;p&gt;await page.click("#submit-button")  # waits automatically&lt;/p&gt;

&lt;p&gt;This alone eliminates 80% of flaky automation failures.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Powerful Selectors
Playwright supports multiple selector strategies:&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  By text
&lt;/h1&gt;

&lt;p&gt;await page.get_by_text("Login").click()&lt;/p&gt;

&lt;h1&gt;
  
  
  By role
&lt;/h1&gt;

&lt;p&gt;await page.get_by_role("button", name="Submit").click()&lt;/p&gt;

&lt;h1&gt;
  
  
  By placeholder
&lt;/h1&gt;

&lt;p&gt;await page.get_by_placeholder("Enter username").fill("rohith")&lt;/p&gt;

&lt;p&gt;These make your agents resilient to minor UI changes.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Screenshot and State Capture
AI agents often need to verify what they’re seeing:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;await page.screenshot(path="current_state.png")&lt;br&gt;
content = await page.content()&lt;/p&gt;

&lt;p&gt;This is incredibly useful for debugging agent behavior and feeding visual context back to your LLM.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Headless and Headed Modes
Run silently in production:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;browser = await playwright.chromium.launch(headless=True)&lt;/p&gt;

&lt;p&gt;Or visually during development:&lt;/p&gt;

&lt;p&gt;browser = await playwright.chromium.launch(headless=False)&lt;/p&gt;

&lt;p&gt;Real-World Example&lt;br&gt;
Here’s a simplified version of how I use Playwright inside an AI agent for web navigation:&lt;/p&gt;

&lt;p&gt;from playwright.async_api import async_playwright&lt;/p&gt;

&lt;p&gt;async def extract_account_data(url: str, credentials: dict) -&amp;gt; str:&lt;br&gt;
    async with async_playwright() as p:&lt;br&gt;
        browser = await p.chromium.launch(headless=True)&lt;br&gt;
        page = await browser.new_page()&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    await page.goto(url)
    await page.get_by_placeholder("Username").fill(credentials["username"])
    await page.get_by_placeholder("Password").fill(credentials["password"])
    await page.get_by_role("button", name="Login").click()
    await page.wait_for_load_state("networkidle")

    data = await page.inner_text(".account-summary")
    await browser.close()
    return data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The agent calls this function as a tool, processes the returned data with an LLM, and takes the next action. Clean, reliable, production-ready.&lt;br&gt;
When Should You Use Playwright?&lt;br&gt;
Use Playwright when your AI agent needs to:&lt;br&gt;
    • Log into web applications&lt;br&gt;
    • Extract data from dynamic dashboards&lt;br&gt;
    • Fill and submit multi-step forms&lt;br&gt;
    • Navigate complex enterprise portals&lt;br&gt;
    • Take screenshots for visual verification&lt;br&gt;
Getting Started&lt;/p&gt;

&lt;p&gt;pip install playwright&lt;br&gt;
playwright install chromium&lt;/p&gt;

&lt;p&gt;That’s it. You’re ready to build agents that can actually interact with the web like a human.&lt;br&gt;
Final Thoughts&lt;br&gt;
Playwright isn’t just a testing tool — it’s a powerful engine for AI agent automation. If you’re building agents that need to interact with the real web, stop fighting with unreliable tools and give Playwright a try.&lt;br&gt;
Follow me for more practical AI engineering content. 🚀&lt;/p&gt;

</description>
      <category>playwright</category>
      <category>ai</category>
      <category>automation</category>
      <category>python</category>
    </item>
    <item>
      <title>Getting Started with Google ADK: Build Your First AI Agent in Python</title>
      <dc:creator>Rohith Davuluri</dc:creator>
      <pubDate>Sat, 25 Apr 2026 07:14:54 +0000</pubDate>
      <link>https://dev.to/rohith_davuluri/getting-started-with-google-adk-build-your-first-ai-agent-in-python-3gd</link>
      <guid>https://dev.to/rohith_davuluri/getting-started-with-google-adk-build-your-first-ai-agent-in-python-3gd</guid>
      <description>&lt;p&gt;AI agents are no longer just research concepts — they’re being deployed in production systems across industries. Google’s Agent Development Kit (ADK) makes it easier than ever to build, orchestrate, and deploy intelligent agents using Python. In this guide, I’ll walk you through building your first AI agent from scratch using Google ADK.&lt;br&gt;
What is Google ADK?&lt;br&gt;
Google ADK (Agent Development Kit) is an open-source framework designed to help developers build multi-agent AI systems. It provides:&lt;br&gt;
    • A structured way to define agents and their tools&lt;br&gt;
    • Built-in orchestration for sequential and parallel workflows&lt;br&gt;
    • Native integration with Gemini AI models&lt;br&gt;
    • YAML-based configuration for agent behavior&lt;br&gt;
Think of it as the backbone that connects your AI model to real-world actions.&lt;br&gt;
Prerequisites&lt;br&gt;
Before we start, make sure you have:&lt;br&gt;
    • Python 3.9+&lt;br&gt;
    • A Google Cloud account&lt;br&gt;
    • Gemini API access&lt;br&gt;
    • Basic Python knowledge&lt;br&gt;
Installation&lt;/p&gt;

&lt;p&gt;pip install google-adk&lt;br&gt;
pip install google-generativeai&lt;/p&gt;

&lt;p&gt;Building Your First Agent&lt;br&gt;
Let’s build a simple research agent that can answer questions using tools.&lt;br&gt;
Step 1 — Define Your Tool&lt;br&gt;
Tools are functions your agent can call to interact with the world.&lt;/p&gt;

&lt;p&gt;def search_knowledge_base(query: str) -&amp;gt; str:&lt;br&gt;
    """Search internal knowledge base for information."""&lt;br&gt;
    # Your logic here&lt;br&gt;
    return f"Results for: {query}"&lt;/p&gt;

&lt;p&gt;Step 2 — Create the Agent&lt;/p&gt;

&lt;p&gt;from google.adk.agents import Agent&lt;br&gt;
from google.adk.models import Gemini&lt;/p&gt;

&lt;p&gt;agent = Agent(&lt;br&gt;
    name="research_agent",&lt;br&gt;
    model=Gemini(model="gemini-2.0-flash"),&lt;br&gt;
    description="An agent that answers questions",&lt;br&gt;
    instruction="You are a helpful research assistant. Use your tools to find accurate information.",&lt;br&gt;
    tools=[search_knowledge_base]&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;Step 3 — Run the Agent&lt;/p&gt;

&lt;p&gt;from google.adk.runners import Runner&lt;/p&gt;

&lt;p&gt;runner = Runner(agent=agent)&lt;br&gt;
response = runner.run("What is machine learning?")&lt;br&gt;
print(response)&lt;/p&gt;

&lt;p&gt;How It Works&lt;br&gt;
When you send a query to the agent:&lt;br&gt;
    1.  Gemini receives your input&lt;br&gt;
    2.  Decides whether to use a tool or respond directly&lt;br&gt;
    3.  Calls the tool if needed and gets results&lt;br&gt;
    4.  Formulates a final response&lt;br&gt;
This loop is what makes agents powerful — they can reason, act, and respond dynamically.&lt;br&gt;
Real-World Use Case&lt;br&gt;
At my day job, I use Google ADK to build multi-agent pipelines for banking compliance automation. One pipeline I built has 9 sequential agents — each handling a specific task like schema discovery, data sampling, and SQL generation. ADK made orchestrating all of them clean and maintainable.&lt;br&gt;
What’s Next?&lt;br&gt;
Once you’re comfortable with a single agent, you can:&lt;br&gt;
    • Chain multiple agents sequentially&lt;br&gt;
    • Run agents in parallel for faster pipelines&lt;br&gt;
    • Add memory and context persistence&lt;br&gt;
    • Integrate with databases and external APIs&lt;br&gt;
Conclusion&lt;br&gt;
Google ADK is one of the most practical frameworks for building production-grade AI agents today. With just a few lines of Python, you can have an intelligent agent running and ready to extend.&lt;br&gt;
If you found this helpful, follow me for more content on AI agents, automation, and GenAI engineering. 🚀&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>googleadk</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Getting Started with Google ADK: Build Your First AI Agent in Python</title>
      <dc:creator>Rohith Davuluri</dc:creator>
      <pubDate>Sat, 25 Apr 2026 07:14:54 +0000</pubDate>
      <link>https://dev.to/rohith_davuluri/getting-started-with-google-adk-build-your-first-ai-agent-in-python-epe</link>
      <guid>https://dev.to/rohith_davuluri/getting-started-with-google-adk-build-your-first-ai-agent-in-python-epe</guid>
      <description>&lt;p&gt;AI agents are no longer just research concepts — they’re being deployed in production systems across industries. Google’s Agent Development Kit (ADK) makes it easier than ever to build, orchestrate, and deploy intelligent agents using Python. In this guide, I’ll walk you through building your first AI agent from scratch using Google ADK.&lt;br&gt;
What is Google ADK?&lt;br&gt;
Google ADK (Agent Development Kit) is an open-source framework designed to help developers build multi-agent AI systems. It provides:&lt;br&gt;
    • A structured way to define agents and their tools&lt;br&gt;
    • Built-in orchestration for sequential and parallel workflows&lt;br&gt;
    • Native integration with Gemini AI models&lt;br&gt;
    • YAML-based configuration for agent behavior&lt;br&gt;
Think of it as the backbone that connects your AI model to real-world actions.&lt;br&gt;
Prerequisites&lt;br&gt;
Before we start, make sure you have:&lt;br&gt;
    • Python 3.9+&lt;br&gt;
    • A Google Cloud account&lt;br&gt;
    • Gemini API access&lt;br&gt;
    • Basic Python knowledge&lt;br&gt;
Installation&lt;/p&gt;

&lt;p&gt;pip install google-adk&lt;br&gt;
pip install google-generativeai&lt;/p&gt;

&lt;p&gt;Building Your First Agent&lt;br&gt;
Let’s build a simple research agent that can answer questions using tools.&lt;br&gt;
Step 1 — Define Your Tool&lt;br&gt;
Tools are functions your agent can call to interact with the world.&lt;/p&gt;

&lt;p&gt;def search_knowledge_base(query: str) -&amp;gt; str:&lt;br&gt;
    """Search internal knowledge base for information."""&lt;br&gt;
    # Your logic here&lt;br&gt;
    return f"Results for: {query}"&lt;/p&gt;

&lt;p&gt;Step 2 — Create the Agent&lt;/p&gt;

&lt;p&gt;from google.adk.agents import Agent&lt;br&gt;
from google.adk.models import Gemini&lt;/p&gt;

&lt;p&gt;agent = Agent(&lt;br&gt;
    name="research_agent",&lt;br&gt;
    model=Gemini(model="gemini-2.0-flash"),&lt;br&gt;
    description="An agent that answers questions",&lt;br&gt;
    instruction="You are a helpful research assistant. Use your tools to find accurate information.",&lt;br&gt;
    tools=[search_knowledge_base]&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;Step 3 — Run the Agent&lt;/p&gt;

&lt;p&gt;from google.adk.runners import Runner&lt;/p&gt;

&lt;p&gt;runner = Runner(agent=agent)&lt;br&gt;
response = runner.run("What is machine learning?")&lt;br&gt;
print(response)&lt;/p&gt;

&lt;p&gt;How It Works&lt;br&gt;
When you send a query to the agent:&lt;br&gt;
    1.  Gemini receives your input&lt;br&gt;
    2.  Decides whether to use a tool or respond directly&lt;br&gt;
    3.  Calls the tool if needed and gets results&lt;br&gt;
    4.  Formulates a final response&lt;br&gt;
This loop is what makes agents powerful — they can reason, act, and respond dynamically.&lt;br&gt;
Real-World Use Case&lt;br&gt;
At my day job, I use Google ADK to build multi-agent pipelines for banking compliance automation. One pipeline I built has 9 sequential agents — each handling a specific task like schema discovery, data sampling, and SQL generation. ADK made orchestrating all of them clean and maintainable.&lt;br&gt;
What’s Next?&lt;br&gt;
Once you’re comfortable with a single agent, you can:&lt;br&gt;
    • Chain multiple agents sequentially&lt;br&gt;
    • Run agents in parallel for faster pipelines&lt;br&gt;
    • Add memory and context persistence&lt;br&gt;
    • Integrate with databases and external APIs&lt;br&gt;
Conclusion&lt;br&gt;
Google ADK is one of the most practical frameworks for building production-grade AI agents today. With just a few lines of Python, you can have an intelligent agent running and ready to extend.&lt;br&gt;
If you found this helpful, follow me for more content on AI agents, automation, and GenAI engineering. 🚀&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>googleadk</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
