<?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: Abhisek Roy</title>
    <description>The latest articles on DEV Community by Abhisek Roy (@abhisekroy169).</description>
    <link>https://dev.to/abhisekroy169</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4154383%2F10c0c329-e7d5-43c9-92c1-719c499c1751.png</url>
      <title>DEV Community: Abhisek Roy</title>
      <link>https://dev.to/abhisekroy169</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abhisekroy169"/>
    <language>en</language>
    <item>
      <title>Built a Local AI Code Reviewer with Ollama | Private &amp; Open Source 🚀</title>
      <dc:creator>Abhisek Roy</dc:creator>
      <pubDate>Thu, 22 Oct 2026 08:10:21 +0000</pubDate>
      <link>https://dev.to/abhisekroy169/built-a-local-ai-code-reviewer-with-ollama-private-open-source-237b</link>
      <guid>https://dev.to/abhisekroy169/built-a-local-ai-code-reviewer-with-ollama-private-open-source-237b</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Code reviews are essential but draining. Reading every changed line of a junior’s or colleague’s PR, spotting edge cases, and explaining fixes takes focus that’s hard to find at the end of a long day, so issues slip through.&lt;/p&gt;

&lt;p&gt;Local AI PR Reviewer does the first pass for you. It watches your chosen repos, reviews every new or updated PR with a local open-weight model on Ollama, and posts senior-engineer-style feedback: critical issues, why they matter, and suggested fixes. It’s comment-only, free to run, and your code never leaves your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/NggUfsl9bgM" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feqdv5zuurll2z6lkyrf7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feqdv5zuurll2z6lkyrf7.png" alt="AI_Review" width="613" height="891"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/abhisek247767" rel="noopener noreferrer"&gt;
        abhisek247767
      &lt;/a&gt; / &lt;a href="https://github.com/abhisek247767/local-ai-pr-reviewer" rel="noopener noreferrer"&gt;
        local-ai-pr-reviewer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A Python-based GitHub Pull Request reviewer powered by a local Ollama LLM. Manually review PR diffs for potential bugs, security issues, logic errors, and missing tests, with human-controlled review comments.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/abhisek247767/local-ai-pr-reviewer" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The whole project runs on open-source, local AI. No paid APIs, no cloud model calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  The model
&lt;/h3&gt;

&lt;p&gt;Reviews are generated by &lt;strong&gt;Qwen2.5-Coder&lt;/strong&gt;, an open-weight coding model, running locally through &lt;strong&gt;Ollama&lt;/strong&gt;. The model is set with a single line in &lt;code&gt;.env&lt;/code&gt;, so I can switch to a bigger or different model without changing any code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OLLAMA_MODEL=qwen2.5-coder:3b
GITHUB_TOKEN= Your GitHub access token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt;, managed with &lt;strong&gt;uv&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ollama&lt;/strong&gt; for local inference (&lt;code&gt;/api/chat&lt;/code&gt; in JSON mode)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub REST API&lt;/strong&gt; for reading pull requests and posting reviews&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;python-dotenv&lt;/strong&gt; for configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Code is sensitive, and many teams can't send it to third-party AI APIs. Because this reviewer runs an open-weight model locally through Ollama, every diff stays on my own machine. It also costs nothing to run, so I can review every PR and every new commit without worrying about API bills. Open tools give me full control: I can swap models with one line, tune the prompt, and never deal with rate limits or deprecated models. A local model isn't as sharp as the biggest closed ones, but for a first-pass reviewer, being private, free, and always on matters more.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;p&gt;I ran it on my own demo repo this week. On the note deletion and search PR, it posted a review in about 2 minutes without me opening a single file, and caught two real bugs: a missing &lt;code&gt;useEffect&lt;/code&gt; cleanup and unhandled errors in &lt;code&gt;deleteNote&lt;/code&gt;. Normally a careful first pass on a PR like that takes me [15–20 minutes]. Now I start from a list of real issues instead of a blank diff, and spend my time only on design decisions. The reviewer works while I don't, which is exactly how a sloth would want it. 🦥&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Best Use of ElevenLabs&lt;/li&gt;
&lt;li&gt;Best Use of MongoDB Atlas&lt;/li&gt;
&lt;li&gt;Best Use of Mastra&lt;/li&gt;
&lt;li&gt;Best Use of GitHub Copilot&lt;/li&gt;
&lt;li&gt;Best Use of Auth0 for AI Agents&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>InvoicePilot AI: Smarter Invoice Automation with TEv1 and MCP</title>
      <dc:creator>Abhisek Roy</dc:creator>
      <pubDate>Fri, 16 Oct 2026 06:22:59 +0000</pubDate>
      <link>https://dev.to/abhisekroy169/invoicepilot-ai-smarter-invoice-automation-with-tev1-and-mcp-2dlb</link>
      <guid>https://dev.to/abhisekroy169/invoicepilot-ai-smarter-invoice-automation-with-tev1-and-mcp-2dlb</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built a local invoice assistant for freelancers who lose hours chasing late payments. You upload a photo or screenshot of an invoice, a vision model running on your own laptop reads the client, amount, and due dates, and after you confirm the fields it saves them to a local database. You can then ask plain questions like “which invoices are overdue?” or “how much does this client owe me?”, and it drafts a polite reminder email with the exact amount and days overdue. Freelancers would pay for it because it turns an awkward, tedious chore into one click, without ever sending their clients’ details to a cloud service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6r34ziestco3l3ce24m1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6r34ziestco3l3ce24m1.png" alt="DB Data" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbhyy2sqbq43r0osmnau4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbhyy2sqbq43r0osmnau4.png" alt="user query" width="800" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuo6pue2bknu6xpg75v4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuo6pue2bknu6xpg75v4u.png" alt="Assistant answer" width="800" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe0kiz5wvnxds8uosgjih.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe0kiz5wvnxds8uosgjih.png" alt="Second user query" width="791" height="34"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl8ixkgjnm80lbmdj6uzx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl8ixkgjnm80lbmdj6uzx.png" alt="Assistant answer" width="800" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;InvoicePilot AI is split into two repositories to keep the AI agent and invoice tools separate.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. MCP Client — The AI Agent
&lt;/h3&gt;

&lt;p&gt;This repository contains the agent logic, TEv1 tool-selection flow, and LLM integration. It selects the appropriate invoice tool and handles argument generation and tool execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/abhisek247767/MCPHybridRAG-Client" rel="noopener noreferrer"&gt;MCP Client&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. MCP Server — Invoice Tools
&lt;/h3&gt;

&lt;p&gt;This repository exposes invoice operations as MCP tools, allowing the client to interact with invoice data through a standardized interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/abhisek247767/MCPHybridRAG-Server" rel="noopener noreferrer"&gt;MCP Server&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;I built this project using &lt;strong&gt;TEv1, Ollama, open-weight language models, and the Model Context Protocol (MCP)&lt;/strong&gt; to explore reliable AI agent tool selection and execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;gemini-flash-latest (vision):&lt;/strong&gt; Reads invoice images locally and extracts the client, amount, and dates as structured JSON.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQLite:&lt;/strong&gt; Stores confirmed invoices on the user's own machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TEv1:&lt;/strong&gt; Tool selection and decision-making.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ollama:&lt;/strong&gt; Run open-weight models locally.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Qwen 2.5 3B:&lt;/strong&gt; Local language model experimentation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP:&lt;/strong&gt; Standardized communication between the AI agent and its tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python:&lt;/strong&gt; Agent orchestration and tool execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project explores whether combining a lightweight decision model with an LLM can improve tool-calling reliability while reducing input-token usage.&lt;/p&gt;

&lt;p&gt;By running the decision model locally, the project avoids additional API costs for tool selection while keeping the main LLM responsible for generating tool arguments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Open innovation lets me build and experiment with AI agents without depending entirely on closed, proprietary APIs. Using Ollama and open-weight models, I can run AI locally and test different approaches without per-token costs for tool selection. TEv1 helps select the right invoice tool, while MCP connects the client and server. This project shows how open models and protocols can make AI agents more reliable, accessible, and customizable.&lt;/p&gt;

&lt;h2&gt;
  
  
  My First User
&lt;/h2&gt;

&lt;p&gt;My first user is me. I haven't put it in front of a freelancer yet, so I can't claim a paying customer, but I did pay for this project in a different currency: time and curiosity. Building it taught me things I couldn't pick up from tutorials alone: how an MCP server and client actually talk to each other, why a small router model like tev1 can pick tools better than a big model guessing, how a local vision model reads a messy invoice, and how much a real database query beats asking an LLM to add up numbers.&lt;/p&gt;

&lt;p&gt;Using it on my own sample invoices also showed me what a real user would ask for next: PDF support, editing a saved invoice when the model misreads a date, and marking invoices as paid. That's my roadmap, and my next step is to hand it to a freelancer friend and see if they'd pay for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Featured Categories
&lt;/h4&gt;

&lt;p&gt;*Best Use of Gemma&lt;/p&gt;

&lt;h4&gt;
  
  
  Partner Categories
&lt;/h4&gt;

&lt;p&gt;*Best Use of a .tech Domain&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Have 1 Hour Free" A Walk Plan in 10 Seconds, Powered by Local AI</title>
      <dc:creator>Abhisek Roy</dc:creator>
      <pubDate>Sat, 10 Oct 2026 09:54:41 +0000</pubDate>
      <link>https://dev.to/abhisekroy169/i-have-1-hour-free-a-walk-plan-in-10-seconds-powered-by-local-ai-2kol</link>
      <guid>https://dev.to/abhisekroy169/i-have-1-hour-free-a-walk-plan-in-10-seconds-powered-by-local-ai-2kol</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Free Time Walk Planner&lt;/strong&gt; is a local AI agent that turns &lt;em&gt;"I have 1 hour free"&lt;/em&gt; into a real plan for getting outside.&lt;/p&gt;

&lt;p&gt;It picks a nearby park, tells you &lt;strong&gt;when to leave&lt;/strong&gt; and &lt;strong&gt;when to turn back&lt;/strong&gt; so you're home before sunset, and says &lt;strong&gt;what to carry&lt;/strong&gt; based on the weather.&lt;/p&gt;

&lt;p&gt;It's for anyone with a short gap in their day who would otherwise spend it scrolling. The answer takes about 10 seconds to read, and then you're out the door. The screen is the shortest part of the experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8yug71pgbwq94vm44x0l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8yug71pgbwq94vm44x0l.png" alt="Free Time Walk Planner home screen, where the user types how much free time they have and their location" width="800" height="396"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Tell the agent how much free time you have and where you are.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffb7pwabta1bsrvz6i9nk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffb7pwabta1bsrvz6i9nk.png" alt="Generated walk plan showing the suggested park, leave-by time, turn-back time, home-by time and what to carry" width="800" height="396"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A short plan you can read in about 10 seconds: where to go, when to leave, and when to turn back.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fano55f0ngkf7xwaabf64.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fano55f0ngkf7xwaabf64.png" alt="Map view of nearby parks and green spaces found through OpenStreetMap" width="800" height="434"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Nearby parks and trails, pulled from OpenStreetMap.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmssuy32q9ff7tbl5fe11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmssuy32q9ff7tbl5fe11.png" alt="How this answer was made panel listing each tool call the agent made with its inputs and results" width="800" height="427"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Full transparency: every tool the local models chose, and what each one returned.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/abhisek247767" rel="noopener noreferrer"&gt;
        abhisek247767
      &lt;/a&gt; / &lt;a href="https://github.com/abhisek247767/free-time-agent" rel="noopener noreferrer"&gt;
        free-time-agent
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A local-first AI agent that turns your free time into a concrete outdoor plan using Ollama, LangChain, weather, sunset, and nearby green-space tools.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/abhisek247767/free-time-agent" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Two small local models on Ollama, each with one job:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tev1:0.8b&lt;/code&gt;: a tiny decision model that only decides &lt;em&gt;which&lt;/em&gt; tools a request needs (plan a walk, weather, daylight, or politely decline).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;qwen2.5:3b&lt;/code&gt;: fills in the tool arguments via LangChain tool calling, then writes a short, friendly headline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Free, keyless open data:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open-Meteo&lt;/strong&gt;: weather forecast&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nominatim (OpenStreetMap)&lt;/strong&gt;: place name → coordinates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overpass API (OpenStreetMap)&lt;/strong&gt;: nearby parks, gardens and trails&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OSRM&lt;/strong&gt;: walking routes and distances&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;astral&lt;/code&gt;&lt;/strong&gt;: sunrise, sunset and golden hour, calculated fully offline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Safety logic in plain Python, not the LLM:&lt;/strong&gt;&lt;br&gt;
Leave-by, turn-back and home-by times, plus warnings for rain, wind or a return close to sunset, are all calculated in code, so the numbers are always correct. The LLM only explains them. Tool results are cached locally, so a plan still works when the network drops.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend:&lt;/strong&gt;&lt;br&gt;
A Streamlit app with live progress, a map of nearby parks, and a &lt;strong&gt;"how this answer was made"&lt;/strong&gt; view that shows every tool call the agent made.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Private by design:&lt;/strong&gt; Both models run on my machine. My location and walking habits are never sent to a closed AI provider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero cost:&lt;/strong&gt; No API keys, no usage bills. A daily "go outside" nudge costs nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Right-sized models:&lt;/strong&gt; Open weights let me pair a 0.8B model for decisions with a 3B model for writing. That split is fast on a laptop, and I can swap either model without touching the rest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open data for the real world:&lt;/strong&gt; OpenStreetMap and Open-Meteo give the agent real parks and real weather for free.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A closed API would have turned a personal "go touch grass" tool into something that costs money per request and sends my location to someone else's server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Best Use of Gemma (Featured categories)&lt;/li&gt;
&lt;li&gt;Best Use of GitHub Copilot (Partner categories)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>python</category>
      <category>opensource</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>AgentToolEval: Grading How LLM Agents Use Tools, Not Just What They Answer</title>
      <dc:creator>Abhisek Roy</dc:creator>
      <pubDate>Thu, 08 Oct 2026 06:51:00 +0000</pubDate>
      <link>https://dev.to/abhisekroy169/agenttooleval-grading-how-llm-agents-use-tools-not-just-what-they-answer-26mn</link>
      <guid>https://dev.to/abhisekroy169/agenttooleval-grading-how-llm-agents-use-tools-not-just-what-they-answer-26mn</guid>
      <description>&lt;p&gt;Written for: dev.to readers and the Kaggle Benchmarking Challenge judges.&lt;/p&gt;

&lt;p&gt;I kept your format and headings, shortened the intro, added the two local models and the decision test, and filled the Ollama placeholders with numbers from your latest results.&lt;/p&gt;

&lt;p&gt;Before you paste it, two corrections affect what the post can claim:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tev1&lt;/code&gt; is not faster than the cloud models on fresh prompts.&lt;/strong&gt; The 0.096s in your decision results came from Ollama's prompt cache, because your full run reused the exact prompts from my earlier test run. Measured fresh, it takes &lt;strong&gt;about 2.1s per decision&lt;/strong&gt;, against 0.66–1.43s for the cloud models. I re-ran &lt;code&gt;tev1&lt;/code&gt; fresh and replaced its rows in &lt;code&gt;results/decisions/&lt;/code&gt;, so the time chart is now correct. The post says "close to cloud speed while running on a laptop", which is true. "Faster" would not be.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;gemma4:31b&lt;/code&gt; and &lt;code&gt;gpt-oss&lt;/code&gt; didn't run on your machine.&lt;/strong&gt; They ran on &lt;strong&gt;Ollama Cloud&lt;/strong&gt; (your &lt;code&gt;.env&lt;/code&gt; points at &lt;code&gt;ollama.com&lt;/code&gt;). Only &lt;code&gt;tev1&lt;/code&gt; and &lt;code&gt;qwen2.5:3b&lt;/code&gt; ran locally. The post now says this.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/kaggle-2026-09-23"&gt;Kaggle Benchmarking Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Benchmarked
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;AgentToolEval&lt;/strong&gt;, a small benchmark that checks whether LLM agents use tools &lt;em&gt;correctly&lt;/em&gt;, not just whether they reach the right answer. Did the agent check stock or guess? Did it make five calls when two would do? When a tool failed, did it retry, give up, or make something up? A final-answer check hides all of that.&lt;/p&gt;

&lt;p&gt;The model plays a shopping assistant for a fake electronics store with four tools: &lt;code&gt;search_products&lt;/code&gt; (prices but &lt;strong&gt;not&lt;/strong&gt; stock), &lt;code&gt;check_stock&lt;/code&gt;, &lt;code&gt;place_order&lt;/code&gt;, and &lt;code&gt;get_shipping_estimate&lt;/code&gt;, a distractor no task needs. The tools are deterministic, so every run is reproducible, and failures are injected on purpose (a timeout once, a service that never recovers, an out-of-stock order).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;The trap&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cheapest in-stock laptop&lt;/td&gt;
&lt;td&gt;The cheapest laptop overall is out of stock&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Laptops under ₹50,000 in stock&lt;/td&gt;
&lt;td&gt;One laptop costs exactly ₹50,000 ("under" means strictly below)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Order an out-of-stock phone&lt;/td&gt;
&lt;td&gt;The model must refuse, not claim success&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MacBook price&lt;/td&gt;
&lt;td&gt;The search fails once, so the model must retry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acer stock check&lt;/td&gt;
&lt;td&gt;The stock service never recovers, so the model must answer UNKNOWN&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each scenario scores 0 to 1: &lt;strong&gt;60%&lt;/strong&gt; correct answer, &lt;strong&gt;15%&lt;/strong&gt; right tools, &lt;strong&gt;15%&lt;/strong&gt; correct arguments, &lt;strong&gt;10%&lt;/strong&gt; efficiency (only when the answer is right). The model never sees the answer key; grading happens afterwards, from a log of every tool call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Models Tested
&lt;/h2&gt;

&lt;p&gt;I ran &lt;strong&gt;8 models on Kaggle&lt;/strong&gt; and &lt;strong&gt;5 models with Ollama&lt;/strong&gt;, chosen in groups that each answer a specific question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On Kaggle ([5] scenarios):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Maker&lt;/th&gt;
&lt;th&gt;Why it's in the lineup&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;claude-opus-5-5-default&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;Newest frontier model, paired with Opus 4.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;claude-opus-4-5-20251101&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;Previous generation, to see whether newer means better at tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-5.4-2026-03-05&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;Frontier closed model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-oss-20b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;Small open model from the same maker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gemini-3.5-flash&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;Fast closed model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;Small open model from the same maker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;glm-5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Z.ai&lt;/td&gt;
&lt;td&gt;Open model from another maker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;grok-4.20-0309-non-reasoning&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;xAI&lt;/td&gt;
&lt;td&gt;Non-reasoning model from a fourth maker&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;With Ollama (12 scenarios):&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Where it ran&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gemma4:31b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ollama Cloud&lt;/td&gt;
&lt;td&gt;Counterpart to the Gemma model on Kaggle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-oss:120b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ollama Cloud&lt;/td&gt;
&lt;td&gt;Large vs small from the same family...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gpt-oss:20b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ollama Cloud&lt;/td&gt;
&lt;td&gt;...to test whether size improves tool use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;qwen2.5:3b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;My laptop&lt;/td&gt;
&lt;td&gt;A small general model, as a baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tev1:0.8b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;My laptop&lt;/td&gt;
&lt;td&gt;A 0.8B &lt;strong&gt;decision model&lt;/strong&gt; built to pick one option from a list, not to run as an agent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The lineup lets me ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Does a newer generation help?&lt;/strong&gt; Claude Opus 5.5 vs Opus 4.5.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Closed vs open from the same maker:&lt;/strong&gt; GPT-5.4 vs gpt-oss-20b, and Gemini 3.5 Flash vs Gemma 4.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does size help?&lt;/strong&gt; gpt-oss 20b vs 120b, and 1–3B local models against cloud ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is a small decision model good enough to choose an agent's next step?&lt;/strong&gt; tev1 vs the general models.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Findings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Kaggle leaderboard
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Maker&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;gemini-3.5-flash&lt;/td&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;0.99&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;claude-opus-5-5-default&lt;/td&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;0.99&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;glm-5&lt;/td&gt;
&lt;td&gt;Z.ai&lt;/td&gt;
&lt;td&gt;0.86&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;gemma-4-26b-a4b-it&lt;/td&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;0.85&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;gpt-5.4-2026-03-05&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;0.84&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;claude-opus-4-5-20251101&lt;/td&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;0.84&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;grok-4.20-0309-non-reasoning&lt;/td&gt;
&lt;td&gt;xAI&lt;/td&gt;
&lt;td&gt;0.71&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;gpt-oss-20b&lt;/td&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;0.69&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The top two tied at 0.99, and there's a clear gap after them.&lt;/strong&gt; Both solved every scenario correctly. The 0.01 they lost comes from &lt;strong&gt;[e.g. one extra tool call on one scenario]&lt;/strong&gt;. The next group (GLM-5, Gemma, GPT-5.4, Opus 4.5) is packed between 0.84 and 0.86, so the order within that group isn't meaningful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A newer generation made a big difference.&lt;/strong&gt; Claude Opus 5.5 scored 0.99 and Opus 4.5 scored 0.84, a jump of 15 points from the same maker. &lt;strong&gt;[Which scenario Opus 4.5 failed, from its trace.]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A small open model kept up with frontier models.&lt;/strong&gt; Gemma 4 26B (0.85) scored about the same as GPT-5.4 (0.84) and Opus 4.5 (0.84), and close to GLM-5 (0.86). On structured tool tasks, size wasn't decisive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fast models did well.&lt;/strong&gt; Gemini 3.5 Flash tied for first. Speed and tool discipline don't seem to conflict here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The bottom two:&lt;/strong&gt; Grok non-reasoning (0.71) and gpt-oss-20b (0.69). &lt;strong&gt;[What went wrong, from the traces.]&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Ollama: Gemma was the most efficient
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Where&lt;/th&gt;
&lt;th&gt;Correct answers&lt;/th&gt;
&lt;th&gt;Avg tool calls&lt;/th&gt;
&lt;th&gt;Tokens per task&lt;/th&gt;
&lt;th&gt;Time per task&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gemma4:31b&lt;/td&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;91.7%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2.5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2,073&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3.0s&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gpt-oss:120b&lt;/td&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;91.7%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2.75&lt;/td&gt;
&lt;td&gt;2,776&lt;/td&gt;
&lt;td&gt;3.0s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gpt-oss:20b&lt;/td&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;83.3%&lt;/td&gt;
&lt;td&gt;2.75&lt;/td&gt;
&lt;td&gt;2,689&lt;/td&gt;
&lt;td&gt;4.8s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tev1:0.8b&lt;/td&gt;
&lt;td&gt;Laptop&lt;/td&gt;
&lt;td&gt;41.7%&lt;/td&gt;
&lt;td&gt;2.92&lt;/td&gt;
&lt;td&gt;3,435&lt;/td&gt;
&lt;td&gt;9.5s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen2.5:3b&lt;/td&gt;
&lt;td&gt;Laptop&lt;/td&gt;
&lt;td&gt;16.7%&lt;/td&gt;
&lt;td&gt;1.0&lt;/td&gt;
&lt;td&gt;1,282&lt;/td&gt;
&lt;td&gt;4.9s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;gemma4:31b tied gpt-oss:120b on correct answers (91.7%) but got there with fewer calls and 25% fewer tokens&lt;/strong&gt;, so it was the cheapest per correct answer. gpt-oss:120b beat its 20b sibling by 8 points, so size did help within one family.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The small local models struggled as agents.&lt;/strong&gt; qwen2.5:3b made one call on average and then guessed. tev1 did more work but often skipped the required &lt;code&gt;FINAL:&lt;/code&gt; answer line, and twice took actions nobody asked for (below). &lt;strong&gt;Fewer tokens didn't mean cheaper:&lt;/strong&gt; both small models cost about 3.5× more than Gemma &lt;em&gt;per correct answer&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Chart: accuracy by model&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnul9wqkhthnvg4dddy6r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnul9wqkhthnvg4dddy6r.png" alt="Bar chart comparing task accuracy across evaluated models" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Chart: tokens per task, input + output&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fytync13df4j1tyepz3tk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fytync13df4j1tyepz3tk.png" alt="Bar chart comparing average tokens used per task, including input and output tokens" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Chart: time per task&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faeonne3z9u27bzuai7hf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faeonne3z9u27bzuai7hf.png" alt="Bar chart comparing average execution time per task across the evaluated models, measured in seconds" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Chart: cost per task&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6xqg5wpi7jpaqg4k0z8d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6xqg5wpi7jpaqg4k0z8d.png" alt="Cost" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The decision test: tev1 is good at choosing, not at acting
&lt;/h3&gt;

&lt;p&gt;tev1 is a decision model, so judging it only as an agent felt unfair. I added a second test: &lt;strong&gt;20 single decisions&lt;/strong&gt; taken from the same scenarios (which tool first, which tool next, when to stop, retry or give up). Every model saw the same situation and the same five options. tev1 answered through its decision endpoint; the other models answered a plain prompt.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Where&lt;/th&gt;
&lt;th&gt;Correct decisions&lt;/th&gt;
&lt;th&gt;Input tokens&lt;/th&gt;
&lt;th&gt;Output tokens&lt;/th&gt;
&lt;th&gt;Time per decision&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;gemma4:31b&lt;/td&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;232&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0.66s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gpt-oss:120b&lt;/td&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;td&gt;262&lt;/td&gt;
&lt;td&gt;75&lt;/td&gt;
&lt;td&gt;0.92s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;gpt-oss:20b&lt;/td&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;td&gt;262&lt;/td&gt;
&lt;td&gt;78&lt;/td&gt;
&lt;td&gt;1.43s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tev1:0.8b&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Laptop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;85%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;315&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2.13s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;qwen2.5:3b&lt;/td&gt;
&lt;td&gt;Laptop&lt;/td&gt;
&lt;td&gt;55%&lt;/td&gt;
&lt;td&gt;229&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;2.44s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Same model, two very different results:&lt;/strong&gt; tev1 chose correctly &lt;strong&gt;85%&lt;/strong&gt; of the time, but completed only &lt;strong&gt;42%&lt;/strong&gt; of tasks as an agent. Choosing the next step works; carrying out a whole task doesn't.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It beat a model nearly 4× its size:&lt;/strong&gt; 85% vs 55% for qwen2.5:3b, both on the same laptop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One output token per decision&lt;/strong&gt;, against about 75 for gpt-oss. Its total tokens (~316) were in line with the cloud models.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Close to cloud speed on a laptop:&lt;/strong&gt; about 2.1s per decision, against 0.7–1.4s for cloud models running on data-centre hardware.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Its three misses were telling:&lt;/strong&gt; it checked stock before finding the product, chose to order again after an order was already confirmed, and gave up after a "please retry" error.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;_Chart: accuracy by mode _&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0q7fahv56yycpq6tnt1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0q7fahv56yycpq6tnt1c.png" alt="Bar chart comparing task accuracy across evaluated models. The chart shows the percentage of tasks completed correctly for each model." width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Chart: tokens per task, input + output&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz8c8lqj52832pwf6nt82.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz8c8lqj52832pwf6nt82.png" alt="Bar chart comparing average tokens used per task, including input and output tokens, across the evaluated models." width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Chart: time per task&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxoihhm2mvda142al4lvy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxoihhm2mvda142al4lvy.png" alt="Bar chart comparing average execution time per task across the evaluated models, measured in seconds." width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Specific failures from the traces (Ollama run)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Persistent failure (Acer stock):&lt;/strong&gt; all three cloud models answered UNKNOWN. tev1 said the laptop was &lt;strong&gt;in stock&lt;/strong&gt; and &lt;strong&gt;placed an order nobody asked for&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The ₹50,000 boundary:&lt;/strong&gt; &lt;strong&gt;every Ollama model&lt;/strong&gt; that answered with product IDs included the laptop priced at exactly ₹50,000. This was the hardest trap in the set.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Out-of-stock order:&lt;/strong&gt; no model claimed success. gpt-oss:20b answered UNKNOWN instead of OUT_OF_STOCK.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distractor tool:&lt;/strong&gt; no model called &lt;code&gt;get_shipping_estimate&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unneeded tools:&lt;/strong&gt; for "what is 15% of 2000?", tev1 placed an order for &lt;strong&gt;300 laptops, four times&lt;/strong&gt;. The cloud models answered directly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What surprised me
&lt;/h3&gt;

&lt;p&gt;I expected the frontier models to be clearly on top. Instead, a fast model tied for first, and a 26B open model scored the same as GPT-5.4 and Claude Opus 4.5. The biggest single difference was between two generations of the same model, not between makers or sizes.&lt;/p&gt;

&lt;p&gt;The second surprise was tev1: the same 0.8B model looked weak as an agent and strong as a decision-maker. &lt;strong&gt;How a model is used mattered as much as how big it is.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What changed in how I think about these models:&lt;/strong&gt; grading the &lt;em&gt;path&lt;/em&gt;, not just the answer, showed that models with the same final answer can behave very differently. One checks stock properly and the other gets lucky. Defining "correct" also forced decisions I hadn't expected, like whether ₹50,000 counts as "under ₹50,000."&lt;/p&gt;

&lt;h3&gt;
  
  
  Caveats
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;With [5] scenarios on Kaggle, one scenario is worth up to 20 points, so scores within a few points (0.84–0.86) are effectively tied.&lt;/li&gt;
&lt;li&gt;Each model ran once. Models can behave differently on repeat runs.&lt;/li&gt;
&lt;li&gt;Laptop and cloud times run on different hardware, so compare them loosely. I measured local times on fresh prompts, because repeated prompts hit Ollama's cache and look 20× faster.&lt;/li&gt;
&lt;li&gt;Token counts aren't fully comparable across model families, because each uses its own tokenizer and chat template.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I'd measure next
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A small decision model inside an agent:&lt;/strong&gt; let tev1 pick each next step and a larger model fill in the arguments, to see whether the pair beats either model alone on cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reasoning on vs off:&lt;/strong&gt; Grok's reasoning version alongside the non-reasoning one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Held-out phrasings:&lt;/strong&gt; paraphrases, typos, and Hinglish ("MacBook Air M2 ka price kya hai?").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repeat runs&lt;/strong&gt; per model, to measure consistency.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Benchmark
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.kaggle.com/benchmarks/abhialex/agentcallbench-tool-calling-reliability" rel="noopener noreferrer"&gt;AgentCallBench: Tool-Calling Reliability on Kaggle&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The task code, including the products, scenarios, fake tools, and scoring, is in the benchmark's task notebook.&lt;/p&gt;




</description>
      <category>devchallenge</category>
      <category>kagglechallenge</category>
      <category>ai</category>
      <category>discuss</category>
    </item>
    <item>
      <title>My Parents Kept Asking "Is This SMS a Scam?" So I Built Her an Offline AI That Explains Every Message</title>
      <dc:creator>Abhisek Roy</dc:creator>
      <pubDate>Sat, 03 Oct 2026 04:24:00 +0000</pubDate>
      <link>https://dev.to/abhisekroy169/my-parents-kept-asking-is-this-sms-a-scam-so-i-built-her-an-offline-ai-that-explains-every-5067</link>
      <guid>https://dev.to/abhisekroy169/my-parents-kept-asking-is-this-sms-a-scam-so-i-built-her-an-offline-ai-that-explains-every-5067</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Every few days my phone buzzes with a screenshot from &lt;strong&gt;my mom&lt;/strong&gt;. It's always an SMS, and it's always followed by the same question: &lt;em&gt;"What does this mean? Should I do something?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sometimes it's harmless: a subscription renewal, an EMI reminder, a recharge confirmation. Sometimes it's a scam: &lt;em&gt;"Your KYC has expired, your account will be blocked today, click this link."&lt;/em&gt; To her, they look exactly the same. Bank messages are full of short forms like &lt;em&gt;A/c XX1234&lt;/em&gt;, &lt;em&gt;NEFT&lt;/em&gt;, &lt;em&gt;Avl Bal&lt;/em&gt;, and &lt;em&gt;debited&lt;/em&gt;, and scammers copy that style on purpose.&lt;/p&gt;

&lt;p&gt;I'm not always free to answer right away. And the worst time for her to be confused is when a &lt;strong&gt;scammer is creating urgency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Offline SMS Buddy&lt;/strong&gt;: a small app on her laptop where she pastes any confusing SMS and presses one big button. It answers three questions in plain language:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧠 &lt;strong&gt;What does this SMS mean?&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;⚠️ &lt;strong&gt;What should I do?&lt;/strong&gt; (often: "nothing, this is just information")&lt;/li&gt;
&lt;li&gt;🛑 &lt;strong&gt;What should I be careful about?&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;SMS:&lt;/strong&gt; Your account will be debited ₹499 on 5 October for your recurring subscription.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Offline SMS Buddy:&lt;/strong&gt; ₹499 will be automatically taken from your account on 5 October for a subscription. You don't need to do anything if you know about this subscription. If you don't recognise it, call your bank using the number on your card.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And when a message looks like a scam, the app shows a clear red warning: don't click the link, don't share any OTP, and call the bank directly.&lt;/p&gt;

&lt;p&gt;The most important part: &lt;strong&gt;her SMS never leaves her computer.&lt;/strong&gt; No cloud, no account, and it even works with the &lt;strong&gt;Wi-Fi turned off&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/abhisek247767/offline-sms-buddy/tree/main/demo" rel="noopener noreferrer"&gt;Demo Video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjujvhavfxkbbgnzbjdfc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjujvhavfxkbbgnzbjdfc.png" alt=" " width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7i6lsneyvduwzsh7a4e0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7i6lsneyvduwzsh7a4e0.png" alt=" " width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/abhisek247767/offline-sms-buddy" rel="noopener noreferrer"&gt;offline-sms-buddy&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The stack is entirely open source and runs locally:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://ollama.com/library/qwen2.5" rel="noopener noreferrer"&gt;Qwen 2.5&lt;/a&gt;&lt;/strong&gt;, an open-weight LLM. I use the 3B version so it runs comfortably on an ordinary laptop with 8 GB RAM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;&lt;/strong&gt;, which runs the model locally and serves it at &lt;code&gt;localhost:11434&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://streamlit.io" rel="noopener noreferrer"&gt;Streamlit&lt;/a&gt;&lt;/strong&gt; for the UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python + uv&lt;/strong&gt; for packaging.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Structured output instead of free text
&lt;/h3&gt;

&lt;p&gt;I didn't want to parse a paragraph and guess where "what to do" starts. Ollama lets you pass a JSON schema, so I define the answer shape with Pydantic and the model must fill in exactly those three fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SmsExplanation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;meaning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;what_to_do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;be_careful&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MODEL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PROMPT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sms&lt;/span&gt;&lt;span class="p"&gt;)}],&lt;/span&gt;
    &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SmsExplanation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model_json_schema&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each field goes straight into its own section on the page. The low temperature (0.2) keeps the model close to what the SMS actually says instead of getting creative.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. A prompt written for safety, not cleverness
&lt;/h3&gt;

&lt;p&gt;The prompt tells the model to use short sentences and avoid banking jargon. It also sets some strict rules: don't invent information that isn't in the SMS, and never suggest sharing an OTP. If a message asks her to click a link, update KYC, or threatens to block her account, the model must tell her to verify with the official bank or company first.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. A safety net that doesn't depend on the AI
&lt;/h3&gt;

&lt;p&gt;Small models are good, but they aren't perfect, and with scams a single miss matters. So the app also runs a plain regex check. If an SMS contains a link, a shortened URL, "KYC" or "blocked", the red warning appears &lt;strong&gt;no matter what the model says&lt;/strong&gt;. If it mentions an OTP, there's always a "never share this code" reminder. The AI explains, and the simple code makes sure the most important warning is never skipped.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Designed for my mom, not for developers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Text is about 21px, and the button is huge and full width&lt;/li&gt;
&lt;li&gt;There's one text box and one button, nothing else to figure out&lt;/li&gt;
&lt;li&gt;Errors are in plain language: &lt;em&gt;"The AI helper is not running. Please start Ollama and try again."&lt;/em&gt; instead of a Python stack trace&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Privacy that's actually true
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;For this project, open-source AI isn't just a nice extra. &lt;strong&gt;Without it, the idea doesn't work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Her SMS messages are some of the most private data she has.&lt;/strong&gt;&lt;br&gt;
They contain bank balances, partial account numbers, OTPs, loan EMIs, and delivery addresses. Sending all of that to a cloud API I don't control (with its own logging, retention and terms of service) would create a new privacy risk inside a tool meant to protect her. With an open-weight model running through Ollama, the message goes from the text box to &lt;code&gt;localhost&lt;/code&gt; and back. That's the whole journey.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. It works without internet.&lt;/strong&gt;&lt;br&gt;
Once the model is downloaded, the app works fully offline. I tested it with the Wi-Fi switched off. That matters for a tool she should be able to trust at any moment, not only when the connection is good.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. It costs nothing to run.&lt;/strong&gt;&lt;br&gt;
There are no API keys, no per-request billing, and no subscription that runs out. She can paste a hundred messages a day and it costs ₹0. A closed API would mean I'd have to manage billing for my mom's laptop forever.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. I can swap or tune the model freely.&lt;/strong&gt;&lt;br&gt;
The model name is a single constant in &lt;code&gt;llm.py&lt;/code&gt;. If a better small open model comes out next month, I run &lt;code&gt;ollama pull&lt;/code&gt; and change one line. With a closed API, the provider decides when the model changes, and that can change the app's behaviour without warning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Nobody can take it away.&lt;/strong&gt;&lt;br&gt;
If an API gets deprecated, a price changes, or an account gets locked, the app keeps working. The model file sits on her disk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Featured categories&lt;/li&gt;
&lt;li&gt;Partner categories&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
