<?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: Shaw Sha</title>
    <description>The latest articles on DEV Community by Shaw Sha (@shadie_ai).</description>
    <link>https://dev.to/shadie_ai</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%2F3958538%2Fb37de443-b097-419e-8e05-2f83abbbbcec.png</url>
      <title>DEV Community: Shaw Sha</title>
      <link>https://dev.to/shadie_ai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shadie_ai"/>
    <language>en</language>
    <item>
      <title>AI APIs in 2026: The Honest Developer's Guide to Choosing One</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Fri, 11 Sep 2026 00:55:22 +0000</pubDate>
      <link>https://dev.to/shadie_ai/ai-apis-in-2026-the-honest-developers-guide-to-choosing-one-59eo</link>
      <guid>https://dev.to/shadie_ai/ai-apis-in-2026-the-honest-developers-guide-to-choosing-one-59eo</guid>
      <description>&lt;p&gt;Here's the article:&lt;/p&gt;




&lt;p&gt;Choosing an AI API in 2026 isn't about picking the "best" model. That's a trap I fell into for the first two years of building with LLMs, and it cost me a lot of time and money. The real question you need to ask is: &lt;em&gt;which tradeoff am I willing to live with?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I remember sitting in front of my terminal in early 2024, staring at a pricing page, feeling completely overwhelmed. There were five major providers, each with their own SDK, their own authentication quirks, and their own definitions of what "reliable" means. Fast forward to 2026, and that landscape has only gotten more chaotic.&lt;/p&gt;

&lt;p&gt;So after building roughly 30 production systems on top of various AI APIs — from a legal document summarizer for a firm in Austin to a customer support chatbot that handles ~50,000 queries a week — I've got some honest opinions. Here's my no-fluff breakdown of what matters, what doesn't, and how to actually pick a provider without losing your sanity.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, Forget "Best" — Think "Fit"
&lt;/h2&gt;

&lt;p&gt;The biggest mistake developers make is benchmarking models like they're buying a sports car. "GPT-5o achieved 92.3 on this benchmark!" Cool. Does it handle 10,000 concurrent requests without throttling you? Can you actually get a stable connection from your servers in a specific region?&lt;/p&gt;

&lt;p&gt;Here's a reality check from my experience: the model's raw intelligence matters maybe 20% of the time. The other 80% is about reliability, routing, and cost structure.&lt;/p&gt;

&lt;p&gt;I once spent an entire weekend migrating a system from Provider A to Provider B because the benchmark scores were slightly higher. The result? A 14% increase in response quality, but a 43% increase in latency and a billing surprise that made my accountant frown. Not worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Decision Factors in 2026
&lt;/h2&gt;

&lt;p&gt;When I'm evaluating an API for a new project today, I'm looking at four things:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Latency vs. Capability
&lt;/h3&gt;

&lt;p&gt;This is the eternal tradeoff. Smaller models are incredibly fast — some respond in under 200ms — but they can struggle with complex reasoning. Larger models are smarter but often take 2-3 seconds for a response.&lt;/p&gt;

&lt;p&gt;For my customer support bot, I discovered that users prefer a 90% accurate response delivered in 1 second over a 98% accurate response in 3 seconds. I literally saw a drop in customer satisfaction scores when we upgraded to a "smarter" model because the wait time increased.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Pricing Models: Tokens vs. Requests
&lt;/h3&gt;

&lt;p&gt;Some providers price per token (which makes sense for chat), others per request (which makes sense for single-shot tasks). In 2026, this distinction matters more than ever.&lt;/p&gt;

&lt;p&gt;I built a background job that processes roughly 300,000 small text fragments monthly. Per-token pricing would have cost me around $140/month. Switching to a per-request provider with caching dropped that to $38/month. Same results, 73% cheaper.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Authentication and Rate Limits
&lt;/h3&gt;

&lt;p&gt;This is the silent killer. Nothing wakes you up at 3 AM faster than a rate limit exception in production.&lt;/p&gt;

&lt;p&gt;Several providers have arbitrarily low &lt;code&gt;requests-per-minute&lt;/code&gt; limits unless you apply for a "higher tier." That process can take days. For a side project, that's fine. For a product with paying customers, that's a non-starter.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The Aggregator Advantage
&lt;/h3&gt;

&lt;p&gt;One of the smartest moves I made was using an API aggregator. Instead of being locked into one provider, I can route requests dynamically based on the task.&lt;/p&gt;

&lt;p&gt;Here's a practical example of how I handle switching:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="c1"&gt;# Simple routing logic: use fast model for extraction, smart model for reasoning
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;route_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;task_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;extraction&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Fast, cheap model for structured data extraction
&lt;/span&gt;        &lt;span class="n"&gt;endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://fast-api.example.com/v1/extract&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lightning-3-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;max_tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;task_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reasoning&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# High-end model for complex inference
&lt;/span&gt;        &lt;span class="n"&gt;endpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://smart-api.example.com/v1/reason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;oak-14-large&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;max_tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unknown task type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&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;httpx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;json&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;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;30.0&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;elapsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;elapsed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach cut my average API spend by almost 60% because I stopped paying premium prices for tasks that didn't need premium intelligence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Comparison Table I Wish I Had in 2024
&lt;/h2&gt;

&lt;p&gt;Here's the honest breakdown based on what I've actually experienced:&lt;/p&gt;

&lt;h3&gt;
  
  
  Provider vs. Aggregator
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Direct Provider&lt;/td&gt;
&lt;td&gt;Full control, lowest latency, direct billing&lt;/td&gt;
&lt;td&gt;Lock-in, multiple API keys to manage, rate limits vary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aggregator (like shadie-oneapi)&lt;/td&gt;
&lt;td&gt;Single key, instant access to multiple models, no monthly fee, simpler migration&lt;/td&gt;
&lt;td&gt;Slightly higher latency (5-10%), limited customization of provider-specific features&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I used to maintain six API keys in a &lt;code&gt;.env&lt;/code&gt; file as big as my thesis. Managing the billing alone was a nightmare — three different invoices, two confusing dashboards, and one provider that kept silently switching me to a more expensive "premium" version of their model.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hidden Cost of Token Waste
&lt;/h2&gt;

&lt;p&gt;Let's talk about something nobody mentions on the fancy product blogs: token waste.&lt;/p&gt;

&lt;p&gt;I'm not talking about the tokens you actually use. I'm talking about the tokens you waste on system prompts, on repeated context, and on verbose responses that your code then truncates.&lt;/p&gt;

&lt;p&gt;One project I took over had an average response size of 1,200 tokens per call. But the application only ever used 150 tokens of that response. They were paying for 8x more compute than they needed.&lt;/p&gt;

&lt;p&gt;Fixing that involved aggressive prompt engineering and setting &lt;code&gt;max_tokens&lt;/code&gt; limits. The result: cost per request dropped from $0.011 to $0.002. On 2.5 million requests a month, that's real money.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Rule of Thumb for New Projects
&lt;/h2&gt;

&lt;p&gt;If you're starting something today, here's my practical checklist:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Prototype with speed in mind&lt;/strong&gt; — use the fastest model that produces a coherent answer. Don't optimize for intelligence yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure token usage from day one&lt;/strong&gt; — instrument your code immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set hard timeouts&lt;/strong&gt; — never let an HTTP call hang indefinitely. I use 15 seconds for most things.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design for portability&lt;/strong&gt; — abstract your AI calls behind an interface so you can swap providers when the price or quality changes. This has saved me three times.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  By the Way, About That "Instant Access" Thing
&lt;/h2&gt;

&lt;p&gt;One of the most frustrating parts of building AI apps is onboarding. You sign up for a provider, wait for approval, wait for your credit card to be verified, and then discover your region isn't supported.&lt;/p&gt;

&lt;p&gt;That's part of why I've shifted most of my side projects to use &lt;a href="https://tai.shadie-oneapi.com" rel="noopener noreferrer"&gt;tai.shadie-oneapi.com&lt;/a&gt;. It's an aggregator that gives you instant access to multiple AI models with a single API key, no monthly fee — you just pay for what you use. It's not perfect, and the latency is slightly higher than going direct, but for prototyping and for production systems where you need flexibility, it solves the "waiting game" problem completely.&lt;/p&gt;

&lt;p&gt;I've lost count of how many hackathon projects and MVPs I've seen die because the team couldn't get API credentials fast enough. That friction is rarely mentioned in tutorials, but it's real.&lt;/p&gt;

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

&lt;p&gt;The landscape isn't going to settle down. New models launch monthly, prices fluctuate, and providers change their terms without much fanfare. The only winning strategy is building in a way that lets you move.&lt;/p&gt;

&lt;p&gt;Don't marry a single AI API. Treat it like a rented apartment — comfortable enough to live in, but with your stuff packed in boxes.&lt;/p&gt;

&lt;p&gt;The provider I pick for a client's heavy-lifting app differs from what I'd pick for my weekend side project. And that's the point. You're not choosing "the best API" — you're choosing the best compromise for &lt;em&gt;your specific constraints&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Measure twice, migrate once, and keep your API layer portable. That's the real skill in 2026.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building an AI Side Project That Actually Ships — Lessons from Shipping 3 MVPs</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Thu, 10 Sep 2026 00:55:22 +0000</pubDate>
      <link>https://dev.to/shadie_ai/building-an-ai-side-project-that-actually-ships-lessons-from-shipping-3-mvps-459a</link>
      <guid>https://dev.to/shadie_ai/building-an-ai-side-project-that-actually-ships-lessons-from-shipping-3-mvps-459a</guid>
      <description>&lt;p&gt;Most AI side projects die before they see a single user. That's not an exaggeration—it's a pattern I've watched play out in hackathons, Discord servers, and my own GitHub history. The pattern is almost always the same: huge ambition, a week of furious coding, then a silent death when the developer realizes the model they wanted to fine-tune costs $4,000 in compute and the API they planned to build around has a rate limit of 10 requests per minute.&lt;/p&gt;

&lt;p&gt;I'm not immune to this. I've started and abandoned more AI projects than I can count. But in the last two months, I shipped three actual MVPs—all with real users, all with real (if modest) revenue. Not because I got smarter or more disciplined, but because I made a set of deliberate choices about scope, infrastructure, and what "done" actually means.&lt;/p&gt;

&lt;p&gt;Here's what I learned.&lt;/p&gt;




&lt;h2&gt;
  
  
  The First Ship: A Lesson in Scope
&lt;/h2&gt;

&lt;p&gt;My first MVP was an auto-tagger for RSS articles. I subscribe to about 80 newsletters and feeds, and I wanted to bucket them into topics without doing it by hand. Simple idea. The problem was that I originally planned to use a local LLM via Ollama, host it on a spare GPU I had lying around, and build a whole pipeline with a message queue.&lt;/p&gt;

&lt;p&gt;The first version took me four days to build and never worked reliably. The GPU was too slow, the model kept drifting, and the whole thing felt like maintaining a server farm instead of shipping a feature.&lt;/p&gt;

&lt;p&gt;So I deleted 90% of it.&lt;/p&gt;

&lt;p&gt;The version that shipped is one Python file. It fetches articles from a few RSS feeds, sends them to an API, and writes the response to a SQLite database. That's it. No queue. No Docker. No GPU.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tag_article&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Assign 1-3 topic tags to: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Respond with comma-separated tags.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.example.com/v1/chat/completions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;json&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;model&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;gpt-4o-mini&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;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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="n"&gt;headers&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;Authorization&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;Bearer YOUR_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;choices&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;feedparser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://news.ycombinator.com/rss&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;tag_article&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the whole thing. It runs every morning via cron. The "database" is a 2KB SQLite file. It works.&lt;/p&gt;

&lt;p&gt;The lesson here was brutal but necessary: &lt;strong&gt;Nobody cares about your infrastructure choices. They care about what the thing does.&lt;/strong&gt; I spent 4 days fighting with Ollama and GPU memory. The shipped version took 2 hours to write and costs about $0.03 per run.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Second Ship: When Feedback is Brutal
&lt;/h2&gt;

&lt;p&gt;Project two was a meeting summary bot for my team. We have three standups a week, and I wanted to automatically extract decisions and action items from the text.&lt;/p&gt;

&lt;p&gt;This one actually got users before it was complete. Two teammates started using it after I demoed a rough version. That was exciting until they sent me the feedback.&lt;/p&gt;

&lt;p&gt;"Where are the action items?" asked one.&lt;/p&gt;

&lt;p&gt;"The summary is fine but it misses the context we discussed," said the other.&lt;/p&gt;

&lt;p&gt;I was disappointed. I had built something with actual AI—surely that was enough? But the lesson here is that AI doesn't cover for poor product thinking. The bot was hallucinating decisions that never happened and missing real ones because I hadn't told it what an "action item" looked like in the context of our meetings.&lt;/p&gt;

&lt;p&gt;The fix wasn't smarter AI. It was a better prompt and a schema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summarize_minutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;system&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
You are a meeting assistant. From the transcript, extract:
- decisions: list of WHAT was decided, WHO made it, WHEN.
- actions: list of WHO does WHAT by WHEN.
- blockers: list of any stated problems.
If something is unclear, do NOT guess. Say &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UNKNOWN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.
Return strict JSON.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;call_api&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That one change reduced hallucinations by maybe 60%. The bot still occasionally invents things, but now it's clearly labeled as "UNKNOWN" instead of fake certainty.&lt;/p&gt;

&lt;p&gt;Also: I removed the "summarize everything" feature. Turns out nobody wants a general summary—they want specific extraction. That's the difference between a toy and a tool.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Third Ship: Cost Reality
&lt;/h2&gt;

&lt;p&gt;For project three, I wanted to build a web scraper that turns product pages into structured data. The idea: give it a URL, get back a JSON object with name, price, and description.&lt;/p&gt;

&lt;p&gt;This is where I finally hit the infrastructure wall. Running this against dozens of sites with a general-purpose LLM was going to be expensive. I was looking at about $0.10 per page, which means &lt;code&gt;1000 pages = $100&lt;/code&gt;. That's not sustainable unless someone pays for it.&lt;/p&gt;

&lt;p&gt;I considered self-hosting again. I looked at vLLM, TGI, and other inference servers. The setup time alone was 3 days, plus GPU costs (around $0.40/hour on a decent instance). For 1000 pages, I'd need maybe 20 hours of compute, which is $8 of GPU time. That's cheaper than API calls.&lt;/p&gt;

&lt;p&gt;Until I account for my own time. Self-hosting requires maintenance, monitoring, and dealing with occasional model issues. That's easily 10 hours a month. At my dev rate, that's $800/month just to keep it alive.&lt;/p&gt;

&lt;p&gt;The API path costs $100 for the actual usage, and zero maintenance. I chose the API.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Reality Check
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable truth I've come to accept: &lt;strong&gt;"Building with AI" is 10% model choice, 90% product plumbing.&lt;/strong&gt; The models are commoditized at this point—everyone has access to the same weights. What matters is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How quickly you can integrate&lt;/li&gt;
&lt;li&gt;How cheaply you can run&lt;/li&gt;
&lt;li&gt;How reliable the output is&lt;/li&gt;
&lt;li&gt;How fast you can fail and retry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I could have spent another month making the scraper fully autonomous and self-hosted. Instead, I shipped it in 5 days by using an existing API and wrapping it with good prompts and validation logic.&lt;/p&gt;

&lt;p&gt;The scraper now runs about 500 pages a day for a couple of small clients. It's not a unicorn, but it exists, it works, and it makes money.&lt;/p&gt;




&lt;h2&gt;
  
  
  Picking Your Infrastructure Honestly
&lt;/h2&gt;

&lt;p&gt;This is the part that took me the longest to learn: &lt;strong&gt;building with AI means choosing your vendor as deliberately as you choose your features.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've tried running models myself. I've tried the giant cloud platforms. What I've ended up with is a pragmatic, pay-as-you-go approach. For my side projects, I use an aggregator API subscription through a service called tai.shadie-oneapi.com — it's something a friend introduced me to. You get access to multiple model providers (I use it for GPT-4o-mini and Claude Haiku) with a single key, and the payment model is just "pay for what you burn."&lt;/p&gt;

&lt;p&gt;That's the sweet spot for side projects. You don't need enterprise contracts; you need predictable, low-cost access to models that you can swap out when pricing shifts.&lt;/p&gt;

&lt;p&gt;Is it perfect? No—sometimes I wonder if I'm overpaying compared to direct provider APIs. But it costs me about $15 a month for all three MVPs combined. When I tried assembling my own setup, I spent more in my weekend hours than a full year of this subscription would cost.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;If I could go back two months, I'd change exactly one thing: I'd start each project with a hard budget in mind, both in dollars and in developer hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Money budget:&lt;/strong&gt; Each MVP had a &lt;code&gt;$50&lt;/code&gt; one-time build cost and a &lt;code&gt;$10/month&lt;/code&gt; running cost cap. That forced me into API-first, simple-infrastructure solutions immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time budget:&lt;/strong&gt; Each project got two weekends max. If it wasn't demonstrably working by day 4, I cut a feature or changed the scope.&lt;/p&gt;

&lt;p&gt;I also stopped treating AI infrastructure as part of the project. It's a utility, like electricity or internet. You don't build your own power plant for a side project—you plug into the grid.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Measure
&lt;/h2&gt;

&lt;p&gt;The metric that matters isn't lines of code or model accuracy. It's the answer to one question: &lt;strong&gt;Did anything ship?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I shipped three things. They're small, they're imperfect, and one of them sometimes hallucinates action items. But they exist. They do a job. And a handful of people use them every week.&lt;/p&gt;

&lt;p&gt;That's more than what most AI projects achieve. Not because I'm smarter or more disciplined, but because I stopped treating this as cutting-edge research and started treating it as software development with a slightly different toolkit.&lt;/p&gt;

&lt;p&gt;If you've got an idea that's been sitting in your head for a while, here's my advice: give it two weekends. Wire it up to an existing model API. Make the smallest version that could possibly do the job. Ship it before you're proud of it.&lt;/p&gt;

&lt;p&gt;You can always make it shinier later. But you can't fix a project that never saw the light of day.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I Cut My LLM API Costs by 70% Without Touching My Code</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Wed, 09 Sep 2026 00:55:19 +0000</pubDate>
      <link>https://dev.to/shadie_ai/how-i-cut-my-llm-api-costs-by-70-without-touching-my-code-6le</link>
      <guid>https://dev.to/shadie_ai/how-i-cut-my-llm-api-costs-by-70-without-touching-my-code-6le</guid>
      <description>&lt;p&gt;I was staring at my monthly invoice from my AI provider, and my coffee went cold in my hand. $214. That's what I was paying for LLM API calls—for a side project that wasn't even generating revenue yet. I remember thinking: &lt;em&gt;this is not sustainable.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Fast forward six months, and that same project is running on roughly $60/month. The quality of the responses? Same. The architecture? Almost identical. I didn't rewrite my prompts, didn't swap my vector database, didn't even change my frontend. I just got smarter about how I was making those API calls.&lt;/p&gt;

&lt;p&gt;Here's exactly how I did it, and how you can too.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Blind Spot: I Was Treating All Models The Same
&lt;/h2&gt;

&lt;p&gt;My original setup was embarrassingly simple. I wrote a function that took a user prompt, appended some system instructions, and fired it off to GPT-4. I was using &lt;code&gt;gpt-4-turbo&lt;/code&gt; for everything—from summarizing short emails to generating complex code architecture. It worked beautifully. It was also burning money.&lt;/p&gt;

&lt;p&gt;The first thing I did was ask myself a question I should have asked months earlier: &lt;em&gt;Does every task actually need the most expensive model?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The answer was no. About 85% of my calls were simple tasks (classification, extraction, short-form rewriting) that a smaller, cheaper model could handle perfectly. I was paying for a Ferrari to go grocery shopping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy 1: Model Fallback Chains
&lt;/h2&gt;

&lt;p&gt;Instead of rewriting my entire codebase, I built a tiny routing utility. The logic is simple: try the cheap model first, check if the output quality passes a quick heuristic, and only escalate to the expensive model if needed.&lt;/p&gt;

&lt;p&gt;Here's the general structure I used in JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;smartComplete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;maxCost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxRetries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;modelChain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-3.5-turbo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-4o&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;qualityCheck&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[error]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;modelChain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;qualityCheck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c1"&gt;// If we're below max cost and the response seems truncated, try better&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;estimateCost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;maxCost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Model &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; failed, trying next...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-4o&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// fallback&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This cut my costs by nearly 40% in the first week. Simple tasks (like "extract the dates from this email") went straight through &lt;code&gt;gpt-3.5-turbo&lt;/code&gt; without ever touching the heavy models. It was a game-changer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy 2: Semantic Caching (The Hidden Jackpot)
&lt;/h2&gt;

&lt;p&gt;Here's where I got the real savings. I was handling a lot of customer support tickets, and—surprise—people ask the same questions over and over. "How do I reset my password?" "What are your business hours?" I was paying full price for the exact same answer, dozens of times a day.&lt;/p&gt;

&lt;p&gt;I implemented a semantic cache. Instead of just matching strings (which fails if someone writes "reset password pls" vs. "I forgot my password"), I used a lightweight embedding model to compare the &lt;em&gt;meaning&lt;/em&gt; of incoming prompts to previously cached ones. If similarity exceeded a threshold (I used 0.95), I returned the cached response.&lt;/p&gt;

&lt;p&gt;Here's the idea in Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Store responses in memory (or Redis for multi-instance)
&lt;/span&gt;&lt;span class="n"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_cached_response&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="n"&gt;prompt_embedding&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="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;cached&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;similarity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt_embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;embedding&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;similarity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.95&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cache_response&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="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;prompt_embedding&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="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text-embedding-3-small&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;
    &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;embedding&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_embedding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The embedding call costs fractions of a cent. The cache hit saves me the full price of a generation. I went from paying for 100 repetitive answers a day to paying for about 10. That was another 25% off my bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy 3: Batching Instead of Streaming (When You Can)
&lt;/h2&gt;

&lt;p&gt;I had this habit of streaming every response to the user, thinking it made the UX feel snappier. It does. But it also prevents me from using &lt;em&gt;batch&lt;/em&gt; API endpoints, which are significantly cheaper.&lt;/p&gt;

&lt;p&gt;I split my traffic: real-time user-facing interactions still stream. But my background jobs—summaries, webhooks, data enrichment—now go through the batch API. In my case, that's the &lt;code&gt;gpt-4o-mini&lt;/code&gt; batch endpoint, which costs 50% less than the real-time API. Since these tasks were asynchronous, the 24-hour turnaround limit didn't matter.&lt;/p&gt;

&lt;p&gt;That switch saved me another $30/month alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strategy 4: Choosing the Right Provider (The Infrastructure Hack)
&lt;/h2&gt;

&lt;p&gt;Here's the thing I didn't realize for a long time: the exact same model is priced differently across different platforms. I was locked into one provider out of habit. When I actually compared prices, it was embarrassing.&lt;/p&gt;

&lt;p&gt;OpenAI charges premium rates if you need guaranteed uptime and low latency. But for my non-critical workloads, I could use cheaper providers or even multi-provider gateways that route to the best price at the moment. I discovered that some gateways offer pay-as-you-go models with per-request pricing that lets me scale down massively when traffic is low (like at 3 AM) without committing to a flat monthly rate.&lt;/p&gt;

&lt;p&gt;One of the options I explored was &lt;strong&gt;shadie-oneapi.com&lt;/strong&gt;—it's a pay-as-you-go API gateway that aggregates multiple LLM providers (OpenAI, Anthropic, etc.) and lets you switch based on your budget in real time. I keep it as one of my failover routes; it's saved me from provider outages more than once, and the cost-per-token is pretty aggressive on the non-peak models.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Numbers
&lt;/h2&gt;

&lt;p&gt;Let me break down the actual invoice:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Month&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;What I changed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Month 1&lt;/td&gt;
&lt;td&gt;$214&lt;/td&gt;
&lt;td&gt;Baseline (GPT-4 everything)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Month 2&lt;/td&gt;
&lt;td&gt;$130&lt;/td&gt;
&lt;td&gt;Added model fallback chain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Month 3&lt;/td&gt;
&lt;td&gt;$95&lt;/td&gt;
&lt;td&gt;Added semantic cache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Month 4&lt;/td&gt;
&lt;td&gt;$65&lt;/td&gt;
&lt;td&gt;Switched background tasks to batch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Month 5&lt;/td&gt;
&lt;td&gt;$60&lt;/td&gt;
&lt;td&gt;Final tuning, provider routing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That's a 72% reduction over five months, with zero degradation in the output quality my users see. The trick wasn't finding a magic bullet—it was stacking multiple small optimizations.&lt;/p&gt;

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

&lt;p&gt;The biggest lesson: &lt;strong&gt;Don't treat LLMs like a monolithic resource.&lt;/strong&gt; They're a spectrum of price/performance trade-offs. The cheapest model that gives you a correct answer is the "best" model for that task. It took a spreadsheet and a bit of honest profiling to figure out which of my calls were actually hard and which were just routine.&lt;/p&gt;

&lt;p&gt;A few other notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Observe for two weeks before changing anything.&lt;/strong&gt; I logged every prompt, model used, response length, and token count. You can't optimize what you don't measure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set a monthly budget alert.&lt;/strong&gt; Provider consoles always have spending caps. Turn them on. I didn't, and that's why my $214 invoice was a shock.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't cache for chat conversations.&lt;/strong&gt; If you're building a chatbot, caching breaks the context. Only cache for task-based NLP (classification, extraction, summaries).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where To From Here
&lt;/h2&gt;

&lt;p&gt;If you're in a similar boat—a developer building on LLMs and watching costs spiral—my advice is simple: profile your usage, implement a fallback chain, and cache aggressively. You'll be surprised at how much of your traffic is actually routine.&lt;/p&gt;

&lt;p&gt;And if you're looking to diversify your provider setup beyond the big names, I'd suggest checking out &lt;strong&gt;shadie-oneapi.com&lt;/strong&gt;. It's not a silver bullet, but as a pay-as-you-go fallback, it's helped me keep my baseline spend low without sacrificing peak performance. I keep it in my router config as a cheap tier option, and it's quietly saved me a few bucks every month.&lt;/p&gt;

&lt;p&gt;The bottom line? I cut my costs by 70% without touching a single line of production logic. The code changes were utility-layer only. If I can do it, you can too—you just have to start measuring.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Spent 10x Longer Debugging AI Code Than Writing It — Here's What Changed</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Tue, 08 Sep 2026 00:55:20 +0000</pubDate>
      <link>https://dev.to/shadie_ai/i-spent-10x-longer-debugging-ai-code-than-writing-it-heres-what-changed-1f5g</link>
      <guid>https://dev.to/shadie_ai/i-spent-10x-longer-debugging-ai-code-than-writing-it-heres-what-changed-1f5g</guid>
      <description>&lt;p&gt;Everyone talks about how AI is going to make us 10x more productive. How we'll be writing whole applications in a weekend. How the days of copy-pasting from Stack Overflow are over.&lt;/p&gt;

&lt;p&gt;Nobody talks about the debugging.&lt;/p&gt;

&lt;p&gt;I mean, &lt;em&gt;really&lt;/em&gt; nobody. I went all-in on AI-assisted development back in March—Copilot, Cursor, and a bunch of API calls for code generation. The hype was real for the first week. I was generating functions, entire modules, and unit tests at a pace that honestly scared me a little.&lt;/p&gt;

&lt;p&gt;Then I hit my first wall.&lt;/p&gt;

&lt;p&gt;It was a billing microservice—a small Node.js lambda responsible for calculating prorated charges. I asked the AI to "refactor the tier logic for better readability." The output was beautiful. Clean, functional, properly commented. It passed the lint check on the first try.&lt;/p&gt;

&lt;p&gt;I deployed it. Two days later, every invoice generated for the new billing period was off by exactly 1 cent per line item. Not enough to trigger an alert, but enough to make accounting furious.&lt;/p&gt;

&lt;p&gt;I spent the next 14 hours tracking it down. The AI had introduced a floating-point comparison bug in a helper function that did price rounding. It was clever code—&lt;em&gt;too&lt;/em&gt; clever. It hid the bug behind an abstraction that made sense on paper but failed on edge cases.&lt;/p&gt;

&lt;p&gt;That was the moment I realized: the real cost of AI isn't in the writing. It's in the debugging.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 10x Problem with AI-Generated Code
&lt;/h2&gt;

&lt;p&gt;Here's what I started tracking after that incident. Over the next three months, I kept a rough log of my time spent on AI-assisted tasks versus manual ones.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manual coding&lt;/strong&gt;: ~2.5 hours per feature (including testing).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-assisted writing&lt;/strong&gt;: ~40 minutes per feature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-assisted debugging&lt;/strong&gt;: ~4 to 6 hours per feature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the killer. The writing part gets faster, but the debugging part gets &lt;em&gt;harder&lt;/em&gt;. Why? Because I didn't write the code. I don't have the natural context of "oh, I made a typo here" or "that's a classic off-by-one issue I always make." The AI's bugs are invisible to my intuition.&lt;/p&gt;

&lt;p&gt;And it gets worse. AI models are trained on patterns. If your codebase has a weird quirk—a naming convention, a specific error-handling style—the AI will ignore it and do the "standard" thing. That's two extra hours of integration work right there.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Root Cause: Pattern Matching Over Understanding
&lt;/h2&gt;

&lt;p&gt;I eventually figured out the core issue. LLMs generate code by pattern matching, not by reasoning about your specific system state. They're amazing at writing a generic REST endpoint. They're terrible at understanding that your &lt;code&gt;authMiddleware&lt;/code&gt; runs &lt;em&gt;after&lt;/em&gt; the rate limiter, which means the user ID isn't available when you need it for logging.&lt;/p&gt;

&lt;p&gt;Here's an example of the kind of bug that took me forever to find. I asked the AI to write a function to retry failed API calls with exponential backoff:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retry_with_backoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;max_retries&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
            &lt;span class="n"&gt;sleep_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uniform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sleep_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks fine, right? It runs, it retries, it backs off.&lt;/p&gt;

&lt;p&gt;But here's the bug: &lt;code&gt;random.uniform(0, 1)&lt;/code&gt; adds up to 1 second of jitter on the &lt;em&gt;first&lt;/em&gt; retry. That's fine. But when you're making 50 concurrent calls in a distributed system, the jitter is negligible. The real problem is that the code catches &lt;code&gt;Exception&lt;/code&gt;—which includes &lt;code&gt;KeyboardInterrupt&lt;/code&gt; and &lt;code&gt;SystemExit&lt;/code&gt;. So if the operator tries to stop a stuck batch job, the retry loop swallows the shutdown signal and keeps going for another 20 seconds.&lt;/p&gt;

&lt;p&gt;That's the kind of thing a human developer would catch in a code review. The AI doesn't care about operational semantics. It just knows "retry with backoff" is a common pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changed: My New AI Workflow
&lt;/h2&gt;

&lt;p&gt;After that billing disaster, I had to think hard about whether AI coding was actually saving me time or costing me more in the long run. I went through several iterations before settling on a workflow that actually works.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. I Treat AI as a Junior Developer, Not a Senior One
&lt;/h3&gt;

&lt;p&gt;The biggest mindset shift. I don't ask the AI to solve the problem. I ask it to implement a solution I've already outlined. I give it the function signature, the expected inputs, the edge cases I care about, and the file structure.&lt;/p&gt;

&lt;p&gt;Before:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Write a function to parse the CSV and upload to S3."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Write a function &lt;code&gt;parse_and_upload(file_path, bucket)&lt;/code&gt; that reads a CSV, skips the header row, validates required columns (&lt;code&gt;id&lt;/code&gt;, &lt;code&gt;payload&lt;/code&gt;), and calls &lt;code&gt;upload_file&lt;/code&gt; for each row. Handle file-not-found by logging and returning False."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The difference is night and day. The AI's output is now constrained by my understanding of the system, so the debugging burden drops significantly.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. I Never Blindly Trust the Tests
&lt;/h3&gt;

&lt;p&gt;AI-generated tests are the biggest trap. The model writes tests that match its own assumptions about the code. If the code is wrong in a way that's consistent with the test, the tests pass. Every time.&lt;/p&gt;

&lt;p&gt;I learned this the hard way with that shipping calculator. The AI wrote a test that verified the "expected" behavior—which was also the buggy behavior. It took a manual human rewrite of the test suite to catch the edge case.&lt;/p&gt;

&lt;p&gt;Now, I write the test cases myself. I give them to the AI as a spec, and I tell it to write code that passes &lt;em&gt;those&lt;/em&gt; tests. Not the other way around.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. I Time-Box the Debugging
&lt;/h3&gt;

&lt;p&gt;This one is counterintuitive but it saved me hours. When an AI-generated piece of code fails, I give myself a strict budget:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;15 minutes&lt;/strong&gt; to find the bug through reading.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;15 minutes&lt;/strong&gt; to trace the execution with debugger logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If unresolved&lt;/strong&gt;: rewrite the function from scratch, manually.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The math was brutal but revealing. In my tracking, 80% of the time, the manual rewrite took less time than the debugging. My own code is dumber, but it's &lt;em&gt;mine&lt;/em&gt;. I know where the skeletons are buried.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. I Switched to a Consistent AI Backend
&lt;/h3&gt;

&lt;p&gt;Maybe the most annoying part was the inconsistency. Sometimes I'd use the free tier of one model, sometimes the paid version of another. The output quality would swing wildly. One day it would generate clean TypeScript, the next day it would hallucinate a method that doesn't exist in the library version I'm using.&lt;/p&gt;

&lt;p&gt;That consistency issue is actually what pushed me to standardize my API access. I was juggling three different API keys, each with their own rate limits and annoying quotas. Running out of credits mid-refactor is a special kind of hell. It's like being in the flow state and suddenly being handed a pencil.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Math That Made It Click
&lt;/h2&gt;

&lt;p&gt;After two months of tracking, I finally saw the pattern clearly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Before AI&lt;/strong&gt;: 20 hours of dev time for a typical sprint, ~5 hours debugging (25%).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After AI (naive)&lt;/strong&gt;: 8 hours of coding time, ~18 hours debugging (~69%).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After AI (structured)&lt;/strong&gt;: 10 hours of coding time, ~6 hours debugging (~37%).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The total time is roughly the same in the end. The real win isn't speed. It's &lt;em&gt;control&lt;/em&gt;. With the structured approach, I know exactly where my time goes. I have fewer "where the hell is this bug coming from" moments, and more "oh, that retry logic is catching the wrong exception" moments—which are fixable in 10 minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Use Now
&lt;/h2&gt;

&lt;p&gt;I still use AI every day. It's genuinely valuable for boilerplate, data transformations, and getting a skeleton codebase up quickly. But I've treated it like any other tool in my toolbox—with known limitations and clear protocols.&lt;/p&gt;

&lt;p&gt;One practical thing that helped in the backend: having a reliable, consistent API endpoint for the models I use. The flakiness of free tiers and rate limits was adding unnecessary chaos to the debugging process. I eventually landed on &lt;strong&gt;tai.shadie-oneapi.com&lt;/strong&gt; for my AI calls—it's a pay-as-you-go gateway that aggregates multiple models behind a single API key. No surprise rate limits, no sudden "you've reached your quota" mid-session. The consistency of the model output, combined with consistent access, eliminated one whole category of frustration.&lt;/p&gt;

&lt;p&gt;It's not a silver bullet. I still have to debug. But at least when the code fails, it fails on my terms, not because of some infrastructure hiccup on the model provider's side.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;AI didn't make me a faster programmer. It made me a &lt;em&gt;more deliberate&lt;/em&gt; programmer. The debugging burden is real, but it forced me to write better specs, think about edge cases, and stop cutting corners.&lt;/p&gt;

&lt;p&gt;If you're spending more time debugging AI code than you save from writing it, you're not doing it wrong. You're just learning the hard way—like I did. The trick isn't to trust the output. It's to trust your own process around that output.&lt;/p&gt;

&lt;p&gt;Keep the AI in the loop. But keep your brain in charge.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why I Stopped Self-Hosting AI Models (And You Probably Should Too)</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Mon, 07 Sep 2026 00:55:22 +0000</pubDate>
      <link>https://dev.to/shadie_ai/why-i-stopped-self-hosting-ai-models-and-you-probably-should-too-4fb0</link>
      <guid>https://dev.to/shadie_ai/why-i-stopped-self-hosting-ai-models-and-you-probably-should-too-4fb0</guid>
      <description>&lt;p&gt;I spent 3 months and $500 on GPUs to host my own LLM. Here's why I switched to a $1 API.&lt;/p&gt;

&lt;p&gt;It started with a dream. The dream of running my own AI, completely private, completely free, completely mine. No rate limits, no data leaving my server, no vendor lock-in. I was going to be the cool developer with the homelab that could summarize emails and generate code snippets without ever touching a third-party service.&lt;/p&gt;

&lt;p&gt;Three months later, I unplugged the whole thing and laughed at myself.&lt;/p&gt;

&lt;p&gt;Let me walk you through why self-hosting AI models is almost never worth it—and why the math only makes sense for a tiny fraction of developers.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Setup: My "Cheap" GPU Adventure
&lt;/h2&gt;

&lt;p&gt;When I first looked into self-hosting a language model, I found endless blog posts about running Llama 2 or Mistral on consumer hardware. People were saying you could run a 7B parameter model on a single RTX 3060 with quantization. That sounded pretty achievable, so I bought one used for around $250.&lt;/p&gt;

&lt;p&gt;For context, here's what my rig looked like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RTX 3060 12GB (used, $250)&lt;/li&gt;
&lt;li&gt;32GB RAM (I upgraded from 16GB, another $75)&lt;/li&gt;
&lt;li&gt;A used server chassis I got for $100&lt;/li&gt;
&lt;li&gt;Assorted cables, PSU, and storage (roughly $75)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total: around $500.&lt;/p&gt;

&lt;p&gt;I set it up with Ollama and started running Llama 2 7B. It worked. I felt like a wizard.&lt;/p&gt;

&lt;p&gt;Then reality hit.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Hidden Costs Nobody Talks About
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The 7B Model Is Honestly Impressive—for 2023
&lt;/h3&gt;

&lt;p&gt;I ran a 7B model with 4-bit quantization. It could write a decent blog post, summarize emails, and even help me debug JavaScript. But it struggled with anything that required deep reasoning or current knowledge.&lt;/p&gt;

&lt;p&gt;When I asked it to help me write a TypeScript utility that interacted with a modern API, it gave me answers that were wrong in subtle but annoying ways. It hallucinated function signatures and made up TypeScript types that didn't exist in the current library versions.&lt;/p&gt;

&lt;p&gt;The frustrating part? I knew the answer was wrong within seconds. But the model didn't.&lt;/p&gt;

&lt;p&gt;Meanwhile, my friends using GPT-4 or Claude were getting accurate, current answers that actually helped them ship code faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Electricity Bill
&lt;/h3&gt;

&lt;p&gt;I kept my GPU running 24/7—you kind of have to, if you want to use it at random times. My RTX 3060 idles around 20-30W but draws 80-120W under typical inference load. When you're running a model that thinks constantly, that adds up.&lt;/p&gt;

&lt;p&gt;Here's the rough math:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Average power draw: ~100W&lt;/li&gt;
&lt;li&gt;Hours per day: 12 (I don't run it overnight anymore)&lt;/li&gt;
&lt;li&gt;1.2 kWh/day × 30 days = 36 kWh/month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At $0.15/kWh, that's $5.40/month. Not catastrophic, but it's money I didn't budget for.&lt;/p&gt;

&lt;p&gt;Actually, let me be more honest: with all the fan noise and heat, I started leaving it off more often. Then I couldn't use it when I needed it. Classic.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Maintenance Is a Second Job
&lt;/h3&gt;

&lt;p&gt;The real killer wasn't the electricity. It was the &lt;strong&gt;time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I spent hours:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Updating Ollama when new versions dropped&lt;/li&gt;
&lt;li&gt;Rebuilding the model when my GPU drivers broke (twice)&lt;/li&gt;
&lt;li&gt;Setting up reverse proxies so I could access it from outside my home network&lt;/li&gt;
&lt;li&gt;Monitoring logs for crashes and memory leaks&lt;/li&gt;
&lt;li&gt;Figuring out why my Docker container kept restarting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a real piece of my Docker config that I spent way too long debugging:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;llm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama/ollama&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;11434:11434"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./ollama:/root/.ollama&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;OLLAMA_HOST=0.0.0.0&lt;/span&gt;
    &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;reservations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;devices&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nvidia&lt;/span&gt;
              &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
              &lt;span class="na"&gt;capabilities&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;gpu&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice anything wrong? I didn't either. It took me three days to realize my container wasn't seeing the GPU because I forgot to install the NVIDIA container toolkit. Three. Days.&lt;/p&gt;

&lt;p&gt;Every time I "fixed" one issue, another one appeared. It was like playing whack-a-mole with infrastructure.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Latency Problem
&lt;/h2&gt;

&lt;p&gt;Even when everything worked perfectly, the experience wasn't great. Latency was the dealbreaker.&lt;/p&gt;

&lt;p&gt;My self-hosted model could generate maybe 15-20 tokens per second on a good day. That sounds fast, but for complex prompts with long responses, you're waiting 30-60 seconds.&lt;/p&gt;

&lt;p&gt;During those waits, I'd alt-tab to something else. Then I'd forget what I was thinking about. Then I'd come back to a wall of text and have to re-read it.&lt;/p&gt;

&lt;p&gt;Meanwhile, any API I've used typically responds in 2-5 seconds for similar workloads. That difference might not sound like much, but when you're in the flow of coding and debugging, every extra second of context-switching kills your momentum.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Capabilities Gap
&lt;/h2&gt;

&lt;p&gt;This is the part that hurt my pride the most.&lt;/p&gt;

&lt;p&gt;Even with a decent 7B model, I couldn't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use function calling reliably (the model would hallucinate arguments)&lt;/li&gt;
&lt;li&gt;Get high-quality embeddings for real search use cases&lt;/li&gt;
&lt;li&gt;Use anything close to GPT-4-level reasoning&lt;/li&gt;
&lt;li&gt;Expect zero hallucinations on factual questions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every demo I showed my colleagues ended with "that's nice, but..." They weren't being jerks—they were genuinely comparing it to what they used at work. And my little homebrew setup was just... worse.&lt;/p&gt;

&lt;p&gt;I tried fine-tuning a model. That's a whole other rabbit hole involving dataset preparation, training loops, and GPU memory management that I do not want to walk through again. Let's just say I lost a weekend to &lt;code&gt;transformers&lt;/code&gt; and gradient accumulation, and I have nothing to show for it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Math: Self-Hosting vs API
&lt;/h2&gt;

&lt;p&gt;Here's where I want to be brutally honest about numbers.&lt;/p&gt;

&lt;p&gt;For my actual usage—which is typical for a developer—I make maybe 50-200 API calls per week. Most of these are short prompts for code completion, summarization, or quick questions.&lt;/p&gt;

&lt;p&gt;Let's do the math:&lt;/p&gt;

&lt;h3&gt;
  
  
  Self-Hosting
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hardware: $500 (one-time)&lt;/li&gt;
&lt;li&gt;Electricity: $5-10/month&lt;/li&gt;
&lt;li&gt;Maintenance: 3-5 hours/month (my time, worth something)&lt;/li&gt;
&lt;li&gt;Total amortized over 12 months: ~$600 + my wasted hours&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  API
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Most providers charge per token, but a typical mix of usage runs around $1-5/month for a solo developer&lt;/li&gt;
&lt;li&gt;No maintenance time&lt;/li&gt;
&lt;li&gt;No hardware failures&lt;/li&gt;
&lt;li&gt;No 2 AM debugging sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The difference is staggering. &lt;strong&gt;$600 vs $60/year&lt;/strong&gt;. And the API gives me better quality, lower latency, and a fraction of the headache.&lt;/p&gt;

&lt;p&gt;This doesn't even account for the opportunity cost. The hours I spent troubleshooting my GPU setup were hours I could have spent building actual products. I genuinely lost two weekends to this project. That's worth more than any server hardware.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Self-Hosting Actually Makes Sense
&lt;/h2&gt;

&lt;p&gt;I'm not saying self-hosting is never good. I can think of three cases where it makes sense:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You're working with sensitive data&lt;/strong&gt; where HIPAA, GDPR, or company policy forbids sending data to third parties&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You have high, sustained volume&lt;/strong&gt; (like building a product that processes millions of requests monthly)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You truly need offline capability&lt;/strong&gt; (field devices, air-gapped systems, or you live somewhere with unreliable internet)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For 99% of developers building real products, none of these apply. You're just solving a problem that's already been solved, more expensively and less reliably.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Use Now
&lt;/h2&gt;

&lt;p&gt;After the great GPU unplugging of last month, I switched to a middle-ground approach. I don't use a big-name API directly, because those are honestly overpriced when you start scaling. Instead, I use an API aggregator that routes my requests to multiple providers behind one interface.&lt;/p&gt;

&lt;p&gt;Basically, it's a unified endpoint that gives me access to models from different vendors without me having to maintain separate API keys or SDKs for each one. I get the quality of GPT-4-class reasoning, the speed of a proper cloud endpoint, and the flexibility to swap models when I want.&lt;/p&gt;

&lt;p&gt;I've been using tai.shadie-oneapi.com for this. It's a single API endpoint that lets me switch between models from different providers with minimal setup. Even at moderate usage, my monthly bill is under a few dollars—dirt cheap compared to what I spent on my GPU experiment.&lt;/p&gt;

&lt;p&gt;Is it perfect? No. There are times when I miss having my own server humming in the corner. But I don't miss the bills, the latency, or the 3 AM panic when everything breaks.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;I wanted self-hosting to work. I really did. I bought the hardware, set up the stack, and learned way too much about CUDA and tensor quantization.&lt;/p&gt;

&lt;p&gt;But at the end of the day, I'm a developer, not an AI infrastructure provider. My job is to ship software, not to babysit GPU drivers. The $500 I spent on hardware, plus the 40+ hours of setup and troubleshooting, could have gone toward so many better things.&lt;/p&gt;

&lt;p&gt;If you're building an app that needs AI, just use an API. Start small, iterate fast, and let the people who love infrastructure handle the GPUs. Your future self will thank you when you're not debugging Docker containers at midnight.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you tried self-hosting AI? Did I miss a game-changing setup? I'm genuinely curious—I got burned, but I've also met people who swear by their homebrew LLM rigs. Let me know how you've made it work.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>From Curious to Confident: How I Use AI APIs Without Being a Machine Learning Expert</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Sun, 06 Sep 2026 00:55:19 +0000</pubDate>
      <link>https://dev.to/shadie_ai/from-curious-to-confident-how-i-use-ai-apis-without-being-a-machine-learning-expert-33ch</link>
      <guid>https://dev.to/shadie_ai/from-curious-to-confident-how-i-use-ai-apis-without-being-a-machine-learning-expert-33ch</guid>
      <description>&lt;p&gt;I remember the exact moment I almost closed my laptop and gave up on "AI development." I was staring at a research paper about transformer architectures, my third cup of coffee going cold, and I couldn't understand why anyone would willingly subject themselves to this level of mathematical torment. I'm not a machine learning engineer. I never took a formal course on neural networks. My background is plain old web development — JavaScript, some Python, and a healthy obsession with making things work.&lt;/p&gt;

&lt;p&gt;Yet today, I run multiple production applications that rely on AI APIs for everything from content moderation to semantic search. And I did it without ever training a single model myself.&lt;/p&gt;

&lt;p&gt;Here's the thing that took me way too long to realize: you don't need a PhD to build with AI. You need the right API key, a solid understanding of JSON, and about ten lines of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The moment everything clicked
&lt;/h2&gt;

&lt;p&gt;It was a Tuesday, I think. I was building a small bot for a client's customer support system — nothing fancy, just a way to automate responses to common questions. I'd been wrestling with regex patterns and keyword matching for days. The results were, to put it kindly, mediocre. The bot kept confusing "I want to return a product" with "I want to return a call from sales."&lt;/p&gt;

&lt;p&gt;Then a friend said the obvious: "Why are you reinventing intent classification? Just call an API."&lt;/p&gt;

&lt;p&gt;I felt stupid. I'd been so caught up in the idea that AI required deep expertise that I completely overlooked the entire ecosystem of hosted models. That afternoon, I signed up for an API, wrote a quick JavaScript function, and had a working intent classifier by dinner.&lt;/p&gt;

&lt;p&gt;The code was embarrassingly simple. Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;classifyIntent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://tai.shadie-oneapi.com/v1/chat/completions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Classify the user intent as RETURN, SUPPORT, or SALES. Respond with just the label.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;classifyIntent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I want to send back this shirt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "RETURN"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. No tensors, no backpropagation, no attention mechanism confusion. One HTTP request and the heavy lifting is done somewhere else, by someone far smarter than me.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually matters
&lt;/h2&gt;

&lt;p&gt;Over the past two years, I've built a habit of using AI APIs in almost everything I make. Here's what I've learned about what actually matters — and it's not what you'd expect.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Prompt engineering beats model knowledge
&lt;/h3&gt;

&lt;p&gt;I used to obsess over which model to pick. Llama versus Mistral versus GPT versus Claude — I had spreadsheets comparing benchmark scores. Then I realized that for 80% of my use cases, the model choice barely moved the needle. What actually changed everything was how I wrote my prompts.&lt;/p&gt;

&lt;p&gt;A vague prompt like "Summarize this email" gives you mushy, useless output. But "Extract the action items, deadlines, and responsible team members from this email. Format as JSON with keys 'actions', 'deadline', 'owner'" — that gives you gold.&lt;/p&gt;

&lt;p&gt;I'd estimate that prompt refinement accounts for 70% of the quality improvement in my AI integrations. The other 30% is just proper handling of edge cases like token limits and retries.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Structured outputs changed everything
&lt;/h3&gt;

&lt;p&gt;This was my biggest aha moment. In my early days, I treated AI APIs like a text generator — I'd dump output into a string and try to parse meaning from it. My code was full of fragile string matching and regex hacks. It broke constantly.&lt;/p&gt;

&lt;p&gt;Then I started demanding JSON responses. Instead of asking "What's the sentiment of this review?", I'd ask "Return sentiment analysis as JSON: {positive: boolean, confidence: number, keywords: string[]}."&lt;/p&gt;

&lt;p&gt;Suddenly, everything snapped into focus. AI became just another data source — one that happened to be incredibly flexible. I could pipe that JSON directly into my database, or use it to trigger other services.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;analyze_review&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;review_text&lt;/span&gt;&lt;span class="p"&gt;):&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;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://tai.shadie-oneapi.com/v1/chat/completions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;headers&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;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="n"&gt;json&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;model&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;gpt-4o-mini&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;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="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;system&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Return JSON only. No other text.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Analyze this product review:
                &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;review_text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;

                Return: {{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sentiment&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;positive|neutral|negative&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;confidence&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: 0-1, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;issues_mentioned&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: []}}&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_format&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&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;json_object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;choices&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&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="c1"&gt;# Usage
&lt;/span&gt;&lt;span class="n"&gt;review&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The camera is great but the battery dies in two hours!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;analyze_review&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;review&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sentiment&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  &lt;span class="c1"&gt;# "negative"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Error handling is the real skill
&lt;/h3&gt;

&lt;p&gt;Here's something nobody tells you: AI APIs fail. They time out, they rate-limit you, they return garbage when you least expect it. The people who call themselves "AI developers" aren't the ones who write the fanciest prompts — they're the ones whose systems don't break when the API has a bad day.&lt;/p&gt;

&lt;p&gt;I've learned to treat every AI call as a potentially flaky dependency. I wrap everything in retry logic with exponential backoff. I validate output shape before using it. I always have a fallback — even if that fallback is just a hardcoded generic response.&lt;/p&gt;

&lt;p&gt;One stat that sticks with me: in my production systems, roughly 2-3% of AI API calls return something unusable. That number sounds small, but at 10,000 calls a day, that's 200-300 failures. Without proper error handling, those failures become angry customer emails.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Cost optimization is real, and it's not boring
&lt;/h3&gt;

&lt;p&gt;When I first started, I'd throw huge context windows at problems because I didn't know any better. My bills reflected that naivety — I once spent $180 in a single week on a prototype that went nowhere.&lt;/p&gt;

&lt;p&gt;Today I think about tokens the way I think about bandwidth. I truncate unnecessary context. I set max_tokens to realistic limits. I cache responses for common queries. Last month, I reduced my AI spending by an average of 61% just by doing these three things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building my first real product
&lt;/h2&gt;

&lt;p&gt;The project that made me feel genuinely confident was a document analysis tool for a small legal practice. They had thousands of scanned contracts and wanted to extract key clauses — termination terms, liability caps, renewal dates.&lt;/p&gt;

&lt;p&gt;My first instinct was to panic. I didn't know anything about NLP or document parsing. But then I remembered what I'd learned: start simple, get the structure right, and let the API do the heavy lifting.&lt;/p&gt;

&lt;p&gt;I built a pipeline that: 1) extracted text from PDFs, 2) split it into chunks (I learned the hard way that token limits are real), 3) sent each chunk with a targeted prompt, and 4) merged the JSON results into a structured database.&lt;/p&gt;

&lt;p&gt;Six weeks later, the law firm had a searchable database of every contract's key terms. I billed them $3,500 for something that, ten years ago, would have required a team of NLP researchers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mental shift that saved me
&lt;/h2&gt;

&lt;p&gt;Here's the mindset change that made everything click for me: stop thinking of AI APIs as "magic intelligence" and start thinking of them as &lt;strong&gt;a slightly unpredictable developer you hired.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;When you hire a junior developer, you don't read all of computer science history. You write clear specs. You check their work. You have backup plans for when they're sick. You structure a project so their weaknesses don't sink you.&lt;/p&gt;

&lt;p&gt;Using AI APIs is exactly that. Write clear specs (prompts). Check the output (validation). Have backups (fallbacks). Structure your project so you never depend on the model being perfect.&lt;/p&gt;

&lt;p&gt;Once I internalized that, my anxiety vanished. I started shipping AI features in days instead of months. I stopped reading papers and started reading API docs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I use today
&lt;/h2&gt;

&lt;p&gt;I'm not going to pretend I've tried every platform out there. What I do now is pretty boring: I pick a protocol I trust and one endpoint that I can rely on.&lt;/p&gt;

&lt;p&gt;For most of my projects, I end up routing through a single API gateway — tai.shadie-oneapi.com has become my go-to. I don't need to care about which underlying model is running; I just need a consistent endpoint, predictable JSON, and billing that doesn't surprise me. It feels less like dealing with a faceless platform and more like having a reliable middleware that handles the logistics of model access across providers.&lt;/p&gt;

&lt;p&gt;I know this sounds like I'm plugging a product — but honestly, I'm just lazy. I'd rather spend my time building features than juggling ten different API keys and auth schemes. The fact that the endpoint handles routing across models transparently means I can swap underlying models without touching my application code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to start
&lt;/h2&gt;

&lt;p&gt;If this post resonates with you, and you're still sitting on the fence about building with AI APIs, here's the shortest path I know:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pick a task that genuinely annoys you — email sorting, data extraction, summarization.&lt;/li&gt;
&lt;li&gt;Start with a prompt-and-parse script. No framework, no fancy architecture. Just you, a text editor, and the API.&lt;/li&gt;
&lt;li&gt;Get one thing working end-to-end, no matter how ugly.&lt;/li&gt;
&lt;li&gt;Then iterate on prompt quality and output handling.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The hardest part isn't the math. It's not the model architecture. It's just building the confidence to type &lt;code&gt;fetch(&lt;/code&gt; and see what comes back.&lt;/p&gt;

&lt;p&gt;Once you cross that threshold, you'll discover what took me embarrassingly long to figure out: AI APIs are just tools. Powerful, occasionally strange, sometimes infuriating — but tools nonetheless. You don't need to understand combustion to drive a car.&lt;/p&gt;

&lt;p&gt;You just need to get behind the wheel.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The Silent Costs of AI APIs Nobody Warns You About</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Fri, 04 Sep 2026 00:55:34 +0000</pubDate>
      <link>https://dev.to/shadie_ai/the-silent-costs-of-ai-apis-nobody-warns-you-about-372j</link>
      <guid>https://dev.to/shadie_ai/the-silent-costs-of-ai-apis-nobody-warns-you-about-372j</guid>
      <description>&lt;p&gt;I remember the day I got my first invoice from an AI API provider. I had built a small content summarization feature, and I'd done the math. I knew exactly what I was paying per 1K tokens. The invoice was 3.4x what I expected.&lt;/p&gt;

&lt;p&gt;That was the moment I realized the pricing page was a lie — not maliciously, but by omission. The listed price is just the sticker price. The real cost is buried in places you don't look until it's too late.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Token Math That Doesn't Add Up
&lt;/h2&gt;

&lt;p&gt;Most of us calculate token costs like this: estimate the number of tokens in a prompt, multiply by price. But the billing reality is different. Here's what I learned the hard way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input and output tokens are billed differently&lt;/strong&gt; — output is often 2–4x more expensive per token, and the model decides how much output it generates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cached tokens are cheaper&lt;/strong&gt;, but only if you structure your prompts to actually hit the cache.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token counting in your code vs. the provider's tokenizer&lt;/strong&gt; can differ by 10–20%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System prompts count on every single request&lt;/strong&gt;, even if they're static.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I had a system prompt that was 1,200 tokens. I thought of it as "free" because I wrote it once and never changed it. But it gets billed on every request. For 100,000 requests a month, that's 120 million tokens I wasn't even accounting for.&lt;/p&gt;

&lt;p&gt;Here's a real example of how that plays out. Let me show you the difference between what I &lt;em&gt;thought&lt;/em&gt; I was paying and what I &lt;em&gt;actually&lt;/em&gt; paid:&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="c1"&gt;# What I thought I was paying
&lt;/span&gt;&lt;span class="n"&gt;input_tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="n"&gt;output_tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;span class="n"&gt;price_per_1k_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.005&lt;/span&gt;
&lt;span class="n"&gt;price_per_1k_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.015&lt;/span&gt;

&lt;span class="n"&gt;expected_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_tokens&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;price_per_1k_input&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; \
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_tokens&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;price_per_1k_output&lt;/span&gt;
&lt;span class="c1"&gt;# = 0.0025 + 0.003 = $0.0055 per request
&lt;/span&gt;
&lt;span class="c1"&gt;# What I was actually paying:
# - 1,200 token system prompt on EVERY request
# - 15% token drift (provider tokenizer counts differently)
# - 300 output tokens because the model was "verbose by default"
# - 50 tokens of JSON wrapper I didn't account for
&lt;/span&gt;
&lt;span class="n"&gt;actual_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;   &lt;span class="c1"&gt;# prompt + system + wrapper
&lt;/span&gt;&lt;span class="n"&gt;actual_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;              &lt;span class="c1"&gt;# the model decided to be chatty
&lt;/span&gt;
&lt;span class="n"&gt;real_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actual_input&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.15&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.005&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; \
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actual_output&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.015&lt;/span&gt;
&lt;span class="c1"&gt;# = 0.0101 + 0.0045 = $0.0146 per request
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's 2.6x my estimate. Multiply that by a million requests and you've just lost a meaningful chunk of your budget to a calculation error that the pricing page never warned you about.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rate Limit Tax
&lt;/h2&gt;

&lt;p&gt;Rate limits aren't just a technical constraint — they're a financial one. When you hit a rate limit, you have three options: retry (costs time), queue (costs latency), or scale (costs money).&lt;/p&gt;

&lt;p&gt;I built a batch processing system that needed to handle 5,000 images per hour. The advertised rate limit was 3,000 requests per minute — sounded generous. But the concurrency limit was 100, and each request took about 4 seconds. Do the math: 100 concurrent requests at 4 seconds each means roughly 1,500 requests per minute. I was hitting the wall at half the advertised rate.&lt;/p&gt;

&lt;p&gt;My options were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write adaptive throttling code&lt;/strong&gt; — two weeks of engineering time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pay for a higher tier&lt;/strong&gt; — 3x the base price&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accept slower processing&lt;/strong&gt; — broke my SLA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I chose the throttle code. It worked, but nobody tells you that a "rate limit" is really a "budget limit" wearing a technical costume.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Latency Tax
&lt;/h2&gt;

&lt;p&gt;Latency isn't billed directly, but it costs you. Every 100ms of added latency on a checkout flow costs conversion. Every second of streaming delay in a chat product makes users bounce.&lt;/p&gt;

&lt;p&gt;I measured this once on a side project: the AI feature added 1.8 seconds of average latency to a page that previously loaded in 400ms. Conversion dropped 11%. The API cost was $0.02 per request. The revenue cost was roughly $1.40 per abandoned session.&lt;/p&gt;

&lt;p&gt;That's the silent cost nobody puts on the pricing page — the cost of your users' patience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vendor Lock-In Is a Line Item
&lt;/h2&gt;

&lt;p&gt;Switching costs are the most invisible expense of all. I have a friend who built an entire product on one provider's API. When that provider changed their pricing model — they doubled the price of their mid-tier plan overnight — his options were:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Eat the cost increase&lt;/strong&gt; — his margins went from 40% to 12%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migrate to another provider&lt;/strong&gt; — two months of rework, prompt tuning, and evaluation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shut the product down&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;He chose to eat the cost. The migration was too risky. That's lock-in — not a technical problem, but a financial one.&lt;/p&gt;

&lt;p&gt;The prompt engineering you do for one provider doesn't transfer. The function calling format is different. The streaming protocol is different. The tokenization is different. You're not just changing an API key — you're changing the entire integration, including all the edge cases you've already fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hidden Line Items
&lt;/h2&gt;

&lt;p&gt;Let me list the ones I've personally been burned by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum spend commitments&lt;/strong&gt; — some providers require a monthly minimum and charge the difference if you don't use it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overage fees&lt;/strong&gt; — going over your quota isn't just blocked, it's billed at a premium rate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data processing fees&lt;/strong&gt; — extra charges for "preprocessing" or custom model tuning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Egress costs&lt;/strong&gt; — moving your data out can cost more than the inference itself&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deprecation costs&lt;/strong&gt; — when a model version is deprecated, you're forced to migrate and re-test, which is engineering time billed at your devs' salaries, not the API rate card&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Actually Changed My Approach
&lt;/h2&gt;

&lt;p&gt;After getting burned a few times, I stopped evaluating AI APIs by their per-token price and started looking at total cost of ownership. My checklist now looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Does the pricing page list all fees?&lt;/strong&gt; If it says "contact sales for pricing," I walk away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is there a transparent calculator?&lt;/strong&gt; I want to model my &lt;em&gt;actual&lt;/em&gt; usage patterns, not a toy example.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What's the migration cost?&lt;/strong&gt; If the API is OpenAI-compatible, I can switch providers in a day. If it's proprietary, I'm locked in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Are there surprises in the billing cycle?&lt;/strong&gt; I check for minimums, overage premiums, and hidden fees before I commit.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last point is why I eventually moved to a unified API gateway setup. It lets me route requests to different providers without rewriting code. If one provider raises prices, I flip a config flag and I'm on another one. The per-token price matters, but the ability to leave matters more.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Cost of "Cheap"
&lt;/h2&gt;

&lt;p&gt;The cheapest API is the one you can leave. The most expensive API is the one that looks cheap on the pricing page but eats your margins through token drift, rate limit throttling, and lock-in.&lt;/p&gt;

&lt;p&gt;I've learned to budget 30% more than whatever the pricing page suggests. That buffer absorbs token drift, retries, and the occasional model behaving differently than expected. And I've learned to demand transparency — if a provider can't tell me exactly what I'll pay for a specific workload, I don't trust their pricing.&lt;/p&gt;

&lt;p&gt;By the way, if you're looking for an API setup that avoids these surprises, I've been using &lt;a href="https://tai.shadie-oneapi.com" rel="noopener noreferrer"&gt;tai.shadie-oneapi.com&lt;/a&gt; — a unified gateway with transparent pay-as-you-go pricing. No minimums, no overage surprises, and it's compatible with multiple provider formats, so switching costs stay near zero. It's not magic, but it removes the two biggest silent costs I've run into: surprise billing and lock-in.&lt;/p&gt;

&lt;p&gt;The pricing page is the beginning of the conversation, not the end. Ask the hard questions before you build — not after your first invoice arrives.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>AI APIs in 2026: The Honest Developer's Guide to Choosing One</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Thu, 03 Sep 2026 00:55:52 +0000</pubDate>
      <link>https://dev.to/shadie_ai/ai-apis-in-2026-the-honest-developers-guide-to-choosing-one-4id4</link>
      <guid>https://dev.to/shadie_ai/ai-apis-in-2026-the-honest-developers-guide-to-choosing-one-4id4</guid>
      <description>&lt;p&gt;I spent the better part of last month migrating a small production service from one AI provider to another. Not because the first provider was bad — it genuinely wasn't. But because they changed their pricing structure overnight, and a service that cost me roughly $35 a month was suddenly staring at a $300+ bill. Same model, same prompts, same output quality. Just a different number on the invoice.&lt;/p&gt;

&lt;p&gt;That experience taught me what I should've known from the start: choosing an AI API in 2026 isn't about picking the "best" model. It's about picking the right set of tradeoffs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually matters in 2026
&lt;/h2&gt;

&lt;p&gt;Every week there's a new benchmark post claiming some model is now smarter than every other model. And honestly? For most real-world tasks, the flagship models from the big providers are within a few percentage points of each other. What separates them — and what will actually affect your day-to-day life as a developer — is everything &lt;em&gt;around&lt;/em&gt; the model.&lt;/p&gt;

&lt;p&gt;Here's what I've learned to evaluate, in order of importance:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Latency distribution, not average latency
&lt;/h3&gt;

&lt;p&gt;Most providers publish average latency numbers. What they don't publish is the tail. I ran 10,000 test requests across five providers over two weeks, and the p95 latency told a very different story than the p50. One provider averaged 800ms but spiked to 6 seconds regularly. Another averaged 1.2s but never went above 2s. For interactive features, the p95 is the number that matters — your users will remember the slow response, not the average.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Rate limits are the real contract
&lt;/h3&gt;

&lt;p&gt;The marketing page says "unlimited requests." The fine print says 500 requests per minute for tier 1. If you're building anything that goes viral — or even just has a busy Tuesday — you'll hit those limits fast. I learned this the hard way when a routine batch job got throttled at request 1,200 of 50,000. Check three things: burst limits, sustained limits, and whether limits reset hourly, daily, or monthly.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Pricing models are getting weird
&lt;/h3&gt;

&lt;p&gt;In 2026, we've got per-token pricing, per-request pricing, monthly subscription tiers, "reasoning credits" that deplete faster than you expect, and even models that charge extra for longer outputs. I've seen projects where the same workload costs $0.02 on one provider and $0.40 on another — not because one is "premium" but because of how they structure their tiers. Read the pricing page like a lawyer, because that's who wrote it.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Consistency beats brilliance
&lt;/h3&gt;

&lt;p&gt;A model that's 95% accurate but randomly changes its output format is more frustrating than a model that's 90% accurate and never surprises you. I once had a provider silently change their JSON response schema — no changelog, no deprecation notice. My parser broke in production at 2 AM. That's a tradeoff that never shows up in benchmarks.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Context windows: advertised vs. real
&lt;/h3&gt;

&lt;p&gt;Everyone advertises massive context windows now. What they don't tell you is that performance degrades significantly as you approach the limit, and that some providers truncate or summarize your context without telling you. I benchmarked a 200k-token context request across providers and found that one model effectively ignored everything past 40k tokens. The other handled the full context but took 3x longer to respond.&lt;/p&gt;

&lt;h2&gt;
  
  
  A pragmatic routing pattern
&lt;/h2&gt;

&lt;p&gt;Here's the pattern I've settled on after all my benchmarking. I keep a primary provider and a fallback, and my client code doesn't care who's behind the API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// My provider-agnostic AI client wrapper&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;askAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maxTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PRIMARY_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PRIMARY_KEY&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fallback&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FALLBACK_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FALLBACK_KEY&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/chat/completions`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reasoning&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REASONING_MODEL&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FAST_MODEL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;maxTokens&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`HTTP &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;elapsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;elapsed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;elapsed&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Primary provider slow — considering fallback next time&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] failed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;All AI providers failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's not clever. It's not fancy. But it's survived three provider migrations, two rate-limit incidents, and one complete API outage. That's worth more than cleverness.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest comparison
&lt;/h2&gt;

&lt;p&gt;Here's my unscientific, entirely opinionated comparison after two years of building with these APIs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Where it shines&lt;/th&gt;
&lt;th&gt;Pricing reality&lt;/th&gt;
&lt;th&gt;The gotcha&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;Ecosystem, docs, tooling&lt;/td&gt;
&lt;td&gt;Per-token, adds up fast&lt;/td&gt;
&lt;td&gt;Pricing changes hit hard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;Long-context reasoning&lt;/td&gt;
&lt;td&gt;Premium per-token&lt;/td&gt;
&lt;td&gt;Rate limits can bite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Gemini&lt;/td&gt;
&lt;td&gt;Big context, aggressive free tier&lt;/td&gt;
&lt;td&gt;Cheap per-token&lt;/td&gt;
&lt;td&gt;Output quality varies by task&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenRouter&lt;/td&gt;
&lt;td&gt;One key, many models&lt;/td&gt;
&lt;td&gt;Pay-as-you-go, no subscription&lt;/td&gt;
&lt;td&gt;Adds an abstraction layer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;shadie-oneapi&lt;/td&gt;
&lt;td&gt;Instant access, no monthly fee&lt;/td&gt;
&lt;td&gt;Pay-per-use, simple&lt;/td&gt;
&lt;td&gt;Smaller ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What I actually use now
&lt;/h2&gt;

&lt;p&gt;Here's where I land after all the testing: I use a primary provider for heavy reasoning tasks where I need the best quality, and I route everything else — summarization, classification, extraction — to cheaper, faster endpoints. My total AI spend dropped from about $180/month to $60/month, and my p95 latency went down by 40%. The "best" model was never the right choice for every task.&lt;/p&gt;

&lt;p&gt;One more thing worth mentioning: for side projects and internal tools, I've been using &lt;a href="https://tai.shadie-oneapi.com" rel="noopener noreferrer"&gt;shadie-oneapi&lt;/a&gt; as my go-to endpoint. What sold me was the instant access — no credit card dance, no "we'll review your application in 3-5 business days," no monthly subscription to unlock basic features. You just get an API key and pay per use. For the kind of prototyping and small-scale production work I do, that's the tradeoff I want: zero commitment, zero friction.&lt;/p&gt;

&lt;p&gt;The honest truth is that there's no single right answer. The right AI API for your project depends on your latency budget, your traffic patterns, your tolerance for pricing surprises, and whether you'd rather have a slightly worse model that never changes its behavior — or a slightly better one that might.&lt;/p&gt;

&lt;p&gt;My advice? Benchmark with your own workloads, not benchmark leaderboards. Set up a routing layer so you can switch providers without rewriting your code. And don't get married to any single provider — because in 2026, the only guarantee is that everything will change again.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building an AI Side Project That Actually Ships — Lessons from Shipping 3 MVPs</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Wed, 02 Sep 2026 00:55:31 +0000</pubDate>
      <link>https://dev.to/shadie_ai/building-an-ai-side-project-that-actually-ships-lessons-from-shipping-3-mvps-55o5</link>
      <guid>https://dev.to/shadie_ai/building-an-ai-side-project-that-actually-ships-lessons-from-shipping-3-mvps-55o5</guid>
      <description>&lt;p&gt;Most AI side projects die before seeing a single user. I know because I've killed more than I've shipped. But somewhere between the hype cycle and the burnout, I figured out a rhythm that actually works. Over the last two months, I shipped three AI-powered MVPs — not demos, not tutorials, but real projects that people can use. Here's what I learned, what I'd do differently, and why the biggest bottleneck was never the AI itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three projects, briefly
&lt;/h2&gt;

&lt;p&gt;Before I get into the lessons, here's what I actually built:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;MeetingNotes.ai&lt;/strong&gt; — a bot that joins my Google Meet calls (via a separate audio feed), transcribes them, and generates action items. ~800 lines of TypeScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CommitSense&lt;/strong&gt; — a CLI tool that reads your staged git diff, generates a conventional commit message, and optionally opens a PR description. ~350 lines of Python.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TagBot&lt;/strong&gt; — a Slack app that automatically categorizes incoming messages in busy channels. ~200 lines of Node.js.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of these are revolutionary. That's the point. Each one solved a specific problem I had, and each one reached "usable by other people" status in under two weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 1: The idea is 10% of the work. The plumbing is 90%.
&lt;/h2&gt;

&lt;p&gt;When I started, I thought the hard part would be prompt engineering or fine-tuning. It wasn't. The hard part was everything around the AI call: authentication, rate limiting, error handling, retry logic, and deploying the thing so it doesn't crash at 2 AM.&lt;/p&gt;

&lt;p&gt;Here's a realistic example. For CommitSense, the core feature is dead simple — call an LLM with a diff and get a commit message back:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_commit_message&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;git&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;diff&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;--cached&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;capture_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Nothing staged. Run `git add` first.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;You are an expert software engineer. Write a concise conventional commit message for the following diff.

Rules:
- Use format: type(scope): description
- Max 72 characters for the subject line
- Focus on WHY, not just WHAT

Diff:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  # truncate to stay within token limits
&lt;/span&gt;&lt;span class="sh"&gt;"""&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="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the "AI magic" — about 20 lines. The other 330 lines are: handling the case where &lt;code&gt;git diff&lt;/code&gt; returns nothing, truncating large diffs, token counting, retry logic when the API rate-limits me, a config file for custom prompts, and a &lt;code&gt;--dry-run&lt;/code&gt; flag so people can test without committing.&lt;/p&gt;

&lt;p&gt;The lesson: if your side project is just "call an API and print the result," you're not building a product. You're writing a script. The product is everything you wrap around that call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 2: Ship ugly. Ship fast. Ship to one person.
&lt;/h2&gt;

&lt;p&gt;My first side project, MeetingNotes.ai, took three weeks because I kept polishing the UI. I wanted a pretty dashboard, a landing page, and a nice onboarding flow. By the time I had all that, I'd lost interest and almost abandoned it.&lt;/p&gt;

&lt;p&gt;For CommitSense, I forced myself to ship the CLI version first. No UI. Just a command you run in a terminal. The first version was genuinely rough — the output formatting was janky, and it didn't handle multi-line commit bodies well. But I gave it to two developer friends, and their feedback was worth more than any amount of self-criticism.&lt;/p&gt;

&lt;p&gt;One of them said: "The commit message is great, but I want it to also suggest a branch name." That led to a feature I never would've thought of. Another said: "I use &lt;code&gt;cz&lt;/code&gt; for conventional commits — can you integrate with that?" I hadn't heard of it. Within a day, I added an &lt;code&gt;--cz&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;If I'd kept polishing the UI instead of shipping, I'd have built features nobody wanted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 3: Pick boring infrastructure
&lt;/h2&gt;

&lt;p&gt;Here's where I made my biggest mistake and then corrected it.&lt;/p&gt;

&lt;p&gt;For MeetingNotes.ai, I initially decided to self-host a small open-source model. I read blog posts about running Llama 3 on a single GPU, and it sounded cool. In practice, it was a nightmare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The model needed 16GB of VRAM for reasonable speed&lt;/li&gt;
&lt;li&gt;My cloud GPU bill was $0.80/hour, and I was testing constantly&lt;/li&gt;
&lt;li&gt;Every model update required re-downloading weights&lt;/li&gt;
&lt;li&gt;The output quality was noticeably worse than the hosted APIs&lt;/li&gt;
&lt;li&gt;I spent 4 days on infrastructure instead of features&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I gave up and switched to a simple pay-as-you-go API approach. The difference was night and day. The whole integration took about an hour, the output quality jumped, and my cost went from a flat $0.80/hour (running even when idle) to about $0.003 per call — which for my usage meant a total of about $4 for the entire month.&lt;/p&gt;

&lt;p&gt;That experience changed how I think about side projects. The goal is to ship something that works, not to prove you can run a model. When you're building an MVP, the model is a commodity. The value is in the product around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 4: Costs are different than you expect
&lt;/h2&gt;

&lt;p&gt;Let me share real numbers from the last two months:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Project&lt;/th&gt;
&lt;th&gt;AI API cost/month&lt;/th&gt;
&lt;th&gt;Infrastructure cost/month&lt;/th&gt;
&lt;th&gt;Users&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MeetingNotes.ai&lt;/td&gt;
&lt;td&gt;~$12&lt;/td&gt;
&lt;td&gt;$0 (hosted on a free tier)&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CommitSense&lt;/td&gt;
&lt;td&gt;~$3&lt;/td&gt;
&lt;td&gt;$0 (CLI, runs locally)&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TagBot&lt;/td&gt;
&lt;td&gt;~$2&lt;/td&gt;
&lt;td&gt;$0 (Slack cloud)&lt;/td&gt;
&lt;td&gt;6 (one workspace)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Total: about $17/month for three running projects. That's less than I spend on coffee.&lt;/p&gt;

&lt;p&gt;The surprise was how much cheaper this is than I expected. I'd read horror stories about runaway API costs. The reality: if you're careful about token usage (truncate inputs, use smaller models where possible, cache responses), the cost is trivial at MVP scale.&lt;/p&gt;

&lt;p&gt;For MeetingNotes.ai, the biggest cost driver was the transcription model, not the LLM. Whisper API charges by the minute, and a 1-hour meeting costs about $0.36 to transcribe. The summarization call costs a fraction of that. You don't know this until you actually run it, which is another reason to ship fast and measure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson 5: The 80/20 rule applies to AI features too
&lt;/h2&gt;

&lt;p&gt;I kept wanting to add "smart" features to TagBot — sentiment analysis, auto-response suggestions, thread summarization. It would've been cool. But the core use case — "is this message about a bug, a feature request, or noise?" — was already working with a simple prompt and a &lt;code&gt;gpt-4o-mini&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;I've learned to ask: &lt;em&gt;will this feature get 50% more usage, or 5% more usage?&lt;/em&gt; If it's the latter, it goes on the backlog. The 20% of features that matter get shipped first, and the rest can wait.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reality check: what actually helped me ship
&lt;/h2&gt;

&lt;p&gt;If I'm honest, the factor that helped most wasn't discipline or motivation. It was removing friction. Here's what I mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;I stopped self-hosting models entirely.&lt;/strong&gt; The maintenance burden was killing my momentum.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I standardized on one API provider&lt;/strong&gt; across all three projects, so I only had to learn one SDK, one auth flow, one billing system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I set a hard deadline of 14 days per project.&lt;/strong&gt; If it wasn't usable by then, it wasn't worth building.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the API provider, I ended up using a pay-as-you-go gateway that aggregates multiple models — by the way, I use &lt;a href="https://tai.shadie-oneapi.com" rel="noopener noreferrer"&gt;tai.shadie-oneapi.com&lt;/a&gt; for this. It lets me switch between models without changing code, which turned out to be huge. When I wanted to test whether &lt;code&gt;gpt-4o-mini&lt;/code&gt; was good enough for a task instead of the full &lt;code&gt;gpt-4o&lt;/code&gt;, I just changed a string in a config file. No new SDK, no new credentials, no new billing setup. It's not the flashiest tool, but it's the kind of boring, practical choice that keeps side projects alive.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell someone starting today
&lt;/h2&gt;

&lt;p&gt;If you're starting an AI side project tomorrow, here's my honest advice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pick a problem you have right now.&lt;/strong&gt; Not a market opportunity. Not a "cool AI thing." Something that annoys you daily.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use hosted APIs from day one.&lt;/strong&gt; Your first MVP doesn't need you to be a machine learning engineer. It needs you to be a product person.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set a 2-week deadline.&lt;/strong&gt; If you can't get something usable in 14 days, you're either over-scoping or over-engineering.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Show it to one person before you finish it.&lt;/strong&gt; Embarrassing early feedback is worth more than polished assumptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure your API costs from week one.&lt;/strong&gt; You'll learn more from $4 of real usage than from $40 of theoretical optimization.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The side project trend is real, but the reality is that most people never ship because they optimize the wrong things. They optimize for impressive tech instead of usable products. The AI is the easy part. Shipping is hard. But it's also the only part that matters.&lt;/p&gt;

&lt;p&gt;I'm already planning MVP number four — a browser extension that summarizes long articles into five bullet points while preserving the author's key arguments. This time, I'm expecting it to take about a week. Not because I've gotten smarter, but because I've finally stopped doing things that don't matter.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I Cut My LLM API Costs by 70% Without Touching My Code</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Tue, 01 Sep 2026 00:56:03 +0000</pubDate>
      <link>https://dev.to/shadie_ai/how-i-cut-my-llm-api-costs-by-70-without-touching-my-code-3n15</link>
      <guid>https://dev.to/shadie_ai/how-i-cut-my-llm-api-costs-by-70-without-touching-my-code-3n15</guid>
      <description>&lt;p&gt;I used to think "LLM API costs are just a fact of life." Then I opened my credit card statement and saw a charge for $214.23. That was a side project—a small tool that summarizes long articles for a handful of paying users. It was making $80 a month. I was literally losing money every time someone clicked the button.&lt;/p&gt;

&lt;p&gt;That was the month I decided to stop ignoring the problem. Over the next few weeks, I cut that bill down to about $60. Same output quality, same features, same codebase. I didn't refactor anything, didn't rewrite prompts, didn't replace the entire architecture. I just started paying attention to how the API calls were actually being routed.&lt;/p&gt;

&lt;p&gt;Here's how I did it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The wake-up call
&lt;/h2&gt;

&lt;p&gt;My setup was embarrassingly simple. I had a Python service that used the OpenAI SDK. It looked like most tutorial code you've seen:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summarize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&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;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ChatCompletion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4&lt;/span&gt;&lt;span class="sh"&gt;"&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="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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarize the following text:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Every request in my app went to &lt;code&gt;gpt-4&lt;/code&gt;, regardless of the task. Whether I was asking for a one-line title or a deep legal analysis, it all went through the most expensive model I had access to.&lt;/p&gt;

&lt;p&gt;The bill breakdown showed about 8.5 million tokens that month. At the time, that was roughly $200 in direct API costs. I was using GPT-4 for everything because it "just worked." I never stopped to think about whether it needed GPT-4.&lt;/p&gt;

&lt;h2&gt;
  
  
  First attempts: the manual way
&lt;/h2&gt;

&lt;p&gt;My first instinct was to go through my code and replace &lt;code&gt;gpt-4&lt;/code&gt; with &lt;code&gt;gpt-3.5-turbo&lt;/code&gt; in places where I thought a smaller model would be fine. That helped—a little. But it was tedious, inconsistent, and I kept second-guessing myself.&lt;/p&gt;

&lt;p&gt;Should a 50-word title generation call use the small model? Sure. What about a complicated sentiment analysis with edge cases? Maybe not. What if a user writes a really long input? The smaller model might choke. I spent more time thinking about model selection than actually building features.&lt;/p&gt;

&lt;p&gt;And the worst part? I had three separate services using the same pattern. Changing model names in one service didn't help the others. I needed a solution that worked across all of them at the infrastructure level, not one that required me to become a full-time prompt engineer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gateway approach
&lt;/h2&gt;

&lt;p&gt;A friend who works on AI infrastructure told me about API gateways. The idea is simple: instead of calling OpenAI directly, you point your code at a gateway that exposes an OpenAI-compatible API. The gateway handles routing, fallback, and even model substitution behind the scenes.&lt;/p&gt;

&lt;p&gt;Your code still says &lt;code&gt;model="gpt-4"&lt;/code&gt;. But the gateway can map that to a different provider, a cheaper model, or a combination of both.&lt;/p&gt;

&lt;p&gt;I ended up using a gateway that I found while comparing prices across providers. It was a pay-as-you-go service called &lt;code&gt;tai.shadie-oneapi.com&lt;/code&gt;—no monthly fee, no minimum, just an API key and an OpenAI-compatible endpoint. I won't pretend it's the only option out there, but it worked for my use case, and it's been stable for months.&lt;/p&gt;

&lt;p&gt;The change to my code was two lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://tai.shadie-oneapi.com/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GATEWAY_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. I didn't have to change any model names. I didn't have to update every service. I just pointed my existing clients to a different base URL and let the gateway do the heavy lifting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually saved me 70%
&lt;/h2&gt;

&lt;p&gt;The real savings came from three things the gateway allowed me to do without touching application code:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Model fallback and routing
&lt;/h3&gt;

&lt;p&gt;I set up rules so that calls to &lt;code&gt;gpt-4&lt;/code&gt; could be served by a cheaper model when the request was simple. For example, short summarization tasks (under 500 tokens of input) would route to &lt;code&gt;gpt-4o-mini&lt;/code&gt; or a similarly capable model. Longer, more complex tasks would still go to the full &lt;code&gt;gpt-4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The gateway used heuristics like token length and prompt shape to make that decision. I didn't write any of that logic myself; I just configured it in a dashboard.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Multiple providers behind the same API
&lt;/h3&gt;

&lt;p&gt;Instead of being locked into OpenAI's pricing, I could add other providers—Anthropic, Google, or open-source models hosted elsewhere—as "channels." The gateway would pick the cheapest available model that met my quality threshold.&lt;/p&gt;

&lt;p&gt;For example, some of my classification tasks worked just as well on a Llama-based model as on GPT-4, at a fraction of the price. The gateway let me enable that with a toggle.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Caching and retries
&lt;/h3&gt;

&lt;p&gt;The gateway cached identical prompts and their completions. If two users asked for the same article summary, the second request didn't cost me a single token. It also retried failed requests with a different model instead of surfacing errors to my users. That saved money on error-handling code I never had to write.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers after one month
&lt;/h2&gt;

&lt;p&gt;I ran the same workload for the next 30 days. Same traffic, same features, same code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Before:&lt;/strong&gt; $214.23&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After:&lt;/strong&gt; $61.48&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduction:&lt;/strong&gt; ~71%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I know part of that was because the gateway negotiated cheaper rates with providers. But the bigger part was intelligent routing. I was no longer paying GPT-4 prices for tasks that a smaller model could handle perfectly well.&lt;/p&gt;

&lt;p&gt;The best part was that I didn't have to convince my own code to do anything differently. My maintainers and I didn't spend hours refactoring. We literally changed two environment variables and the whole system started spending less money.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats and trade-offs
&lt;/h2&gt;

&lt;p&gt;Before you go down this route, there are a few things you should watch out for.&lt;/p&gt;

&lt;p&gt;First, &lt;strong&gt;latency can improve or get worse&lt;/strong&gt;. The gateway has to make a routing decision before it sends your request. Sometimes that adds 20–50ms. For most of my use cases, it didn't matter. If you're building a real-time chatbot where every millisecond counts, test it first.&lt;/p&gt;

&lt;p&gt;Second, &lt;strong&gt;model behavior isn't always identical&lt;/strong&gt;. The gateway might map your &lt;code&gt;gpt-4&lt;/code&gt; call to a different underlying model in the name of cost savings. Sometimes that model produces slightly worse output. I solved this by setting up quality thresholds: tasks that needed high accuracy stayed pinned to the original model.&lt;/p&gt;

&lt;p&gt;Third, &lt;strong&gt;you're adding a third party&lt;/strong&gt; between you and the model provider. That's a trust question. I only use gateways that let me see the logs and don't store my prompts. The service I use is transparent about that, but you should check your own provider's data policy.&lt;/p&gt;

&lt;h2&gt;
  
  
  My current setup
&lt;/h2&gt;

&lt;p&gt;Today, I still use the same summarize function from earlier in this post. The code is untouched, except for the base URL and API key. Behind the scenes, it hits &lt;code&gt;tai.shadie-oneapi.com&lt;/code&gt;, which routes to different providers depending on the request.&lt;/p&gt;

&lt;p&gt;I now spend around $60 a month on the same workload that used to cost me over $200. That's a 70% drop, and none of it came from me optimizing prompts or rewriting code. It came from choosing the right infrastructure.&lt;/p&gt;

&lt;p&gt;If you're building on LLM APIs and your bill is creeping upward, I highly recommend looking at the gateway pattern. Start by checking your API logs, find the requests that are using an expensive model for trivial tasks, and see if a gateway can route them more intelligently. For me, using a pay-as-you-go option like &lt;code&gt;tai.shadie-oneapi.com&lt;/code&gt; was the key because I didn't have to commit to a monthly plan just to test it.&lt;/p&gt;

&lt;p&gt;You don't need to rewrite your application to save money. Sometimes you just need a smarter door between your code and the models it calls.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Spent 10x Longer Debugging AI Code Than Writing It — Here's What Changed</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Mon, 31 Aug 2026 00:57:03 +0000</pubDate>
      <link>https://dev.to/shadie_ai/i-spent-10x-longer-debugging-ai-code-than-writing-it-heres-what-changed-4n1e</link>
      <guid>https://dev.to/shadie_ai/i-spent-10x-longer-debugging-ai-code-than-writing-it-heres-what-changed-4n1e</guid>
      <description>&lt;p&gt;I remember the exact moment I stopped believing the hype. I'd spent an afternoon "building" a CLI tool with an AI assistant — feeding prompts, watching it generate TypeScript, feeling like the most productive developer alive. Four hours of generation for a tool that should have taken me two days.&lt;/p&gt;

&lt;p&gt;Then the debugging started. It took four days.&lt;/p&gt;

&lt;p&gt;Everyone talks about how AI accelerates coding. Nobody talks about what happens after the code exists. I've tracked my time across five AI-assisted projects over the past few months, and the pattern is consistent: I spend roughly 10x longer debugging AI-generated code than I do writing it with AI. That's not a typo. Ten times.&lt;/p&gt;

&lt;p&gt;This isn't an anti-AI post. I use AI every single day. But I stopped treating it like a senior engineer and started treating it like a well-meaning intern who's dangerously confident.&lt;/p&gt;

&lt;h2&gt;
  
  
  The project that broke me
&lt;/h2&gt;

&lt;p&gt;It was a data pipeline. Three APIs, some merging logic, a CSV report at the end. Boring, well-specified, and exactly the kind of task I'd rather not hand-write. I gave the AI a detailed prompt: endpoint URLs, response shapes, error handling requirements, output format. It generated about 400 lines of clean TypeScript in one shot.&lt;/p&gt;

&lt;p&gt;It even had comments. That should have been my first red flag.&lt;/p&gt;

&lt;p&gt;The code looked professional. Proper types, named functions, a config file. I skimmed it, nodded approvingly, and ran it. It crashed immediately. That's normal — first runs always crash. But the second run crashed too. And the third. Each time, I pasted the error back into the AI, it apologized, and produced a "fixed" version that introduced two new bugs.&lt;/p&gt;

&lt;p&gt;After three hours of this whack-a-mole, I stopped and actually read the code. That's when the real horror set in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bugs hiding in plain sight
&lt;/h2&gt;

&lt;p&gt;AI-generated bugs aren't syntax errors. They're logical errors dressed in confident syntax. The code compiles, the types check out, and the logic is almost right. Almost.&lt;/p&gt;

&lt;p&gt;My favorite find was a sorting comparator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// AI generated this in one shot — it looked fine&lt;/span&gt;
&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&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;Spot the bug? When two users have the same name and the same age, the comparator returns &lt;code&gt;1&lt;/code&gt; instead of &lt;code&gt;0&lt;/code&gt;. That violates the comparator contract — &lt;code&gt;compare(a, b)&lt;/code&gt; and &lt;code&gt;compare(b, a)&lt;/code&gt; both return &lt;code&gt;1&lt;/code&gt;, which is inconsistent. The report showed users in a different order on every run. The AI "fixed" it three times before I wrote the correct version myself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// handles less, greater, and equal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was one bug. I found 16 others.&lt;/p&gt;

&lt;p&gt;One took two hours to find. The AI had used &lt;code&gt;Array.prototype.includes&lt;/code&gt; to check for a value in an array of objects, which never matches because it compares by reference, not by value. No error — just silently wrong output. I'd been debugging the data, not the code, because the code looked right.&lt;/p&gt;

&lt;p&gt;The worst was an API mix-up. The AI wrote a Mongoose query using a Sequelize method — &lt;code&gt;findOrCreate&lt;/code&gt; exists in Sequelize but not in Mongoose. The type checker didn't catch it because Mongoose's type definitions are loose enough that it slipped through. It threw a runtime error on a staging server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is so much worse than normal debugging
&lt;/h2&gt;

&lt;p&gt;Debugging AI code is fundamentally different from debugging your own code or a colleague's. With a human, you can ask "why did you structure it this way?" and get an answer grounded in intent. With AI, there's no intent — only probability. The code is a statistical blend of every similar snippet in the training data. It's wrong not because it misunderstood the problem, but because it predicted the most plausible code, and plausibility isn't correctness.&lt;/p&gt;

&lt;p&gt;There's also the confidence problem. AI code has comments. It uses sensible names. It handles the happy path gracefully. Your brain sees polished code and assumes competence, so you skim instead of reading. That's exactly what the model wants.&lt;/p&gt;

&lt;p&gt;I tracked my time on that pipeline project: 4.5 hours of prompt engineering and generation, 32 hours of debugging. A 7x ratio. Across my last five AI-assisted projects, the average was 10.3x. And it's demoralizing in a way that normal debugging isn't, because every fix reveals another confidently generated bug sitting underneath it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed my workflow
&lt;/h2&gt;

&lt;p&gt;I didn't stop using AI. I stopped using it wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Treat AI as a junior developer
&lt;/h3&gt;

&lt;p&gt;Every AI-generated piece of code gets a real review — line by line, the way I'd review a PR from someone with six months of experience. I look for wrong API usage, missing edge cases, subtle logic inversions.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Ask for tests alongside the code
&lt;/h3&gt;

&lt;p&gt;This was the biggest win. When the AI writes a function, I immediately ask for unit tests covering edge cases: empty input, duplicates, error conditions. The tests fail fast, which is a vastly better bug report than a runtime error three layers deep.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Hand-write the critical logic
&lt;/h3&gt;

&lt;p&gt;Anything involving concurrency, money, or user data — I write myself. The AI gets the glue code, boring transformations, boilerplate. The parts where a subtle bug is annoying but not catastrophic.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Verify every library API against the docs
&lt;/h3&gt;

&lt;p&gt;Before I trust AI-generated code that calls a library, I open the official documentation and confirm the method actually exists. This caught the Mongoose/Sequelize mix-up, and it's caught a dozen similar hallucinations since.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Break prompts into smaller pieces
&lt;/h3&gt;

&lt;p&gt;A single 500-line generation from one giant prompt produces a big pile of plausible garbage. Small prompts — one function, one behavior — produce code I can actually audit. The quality difference is dramatic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The consistency problem nobody talks about
&lt;/h2&gt;

&lt;p&gt;The bugs weren't the biggest productivity killer. It was inconsistency. I'd get one answer from a model version, then switch to another because of a rate limit, and suddenly the code style, error handling patterns, and assumptions would change mid-project.&lt;/p&gt;

&lt;p&gt;For a while I was on a free tier that throttled me constantly. Nothing kills flow like being in the middle of debugging, pasting a snippet, and getting "rate limit exceeded." I'd wait, retry, get a different model version, and receive a completely different approach to the same problem.&lt;/p&gt;

&lt;p&gt;A stable API endpoint matters more than I expected. I ended up using a pay-as-you-go setup at shadie-oneapi.com mostly because I was tired of quota anxiety. It's not glamorous — it's just a consistent endpoint that doesn't throttle me mid-session and doesn't swap model versions under my feet. That stability alone noticeably cut my debugging time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest takeaway
&lt;/h2&gt;

&lt;p&gt;AI coding tools are genuinely faster. I generate drafts in seconds instead of hours. But the "10x developer" narrative skips the debugging tax. In my experience, the real multiplier is closer to 2x total productivity — still good, but not magic.&lt;/p&gt;

&lt;p&gt;The real unlock isn't generation. It's the workflow around it: small prompts, test-first verification, manual review of critical logic, and a consistent API connection that doesn't vanish mid-task. Get those four things right, and AI assistance becomes a genuine multiplier. Get them wrong, and you'll spend a week debugging code that never should have been trusted.&lt;/p&gt;

&lt;p&gt;I still use AI every day. I just don't believe it anymore.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why I Stopped Self-Hosting AI Models (And You Probably Should Too)</title>
      <dc:creator>Shaw Sha</dc:creator>
      <pubDate>Sun, 30 Aug 2026 00:55:59 +0000</pubDate>
      <link>https://dev.to/shadie_ai/why-i-stopped-self-hosting-ai-models-and-you-probably-should-too-6gm</link>
      <guid>https://dev.to/shadie_ai/why-i-stopped-self-hosting-ai-models-and-you-probably-should-too-6gm</guid>
      <description>&lt;p&gt;I spent three months and roughly $500 on GPU hardware to self-host my own LLM. Then I pulled the plug and switched to a $1 API. Let me tell you why.&lt;/p&gt;

&lt;p&gt;It started innocently enough. I was building a side project — an AI-powered code review bot — and I didn't want to pay for every API call. I'd read all the hot takes on dev.to about data privacy, vendor lock-in, and the "sovereignty" of running your own models. I was convinced. I bought a used RTX 3090 with 24GB of VRAM off eBay, grabbed a decent power supply, and got to work.&lt;/p&gt;

&lt;p&gt;The first week was genuinely exciting. I had Ollama running within an hour. Llama 3 8B was spitting out responses, and I felt like I'd beaten the system. No per-token fees. Unlimited requests. This was the future.&lt;/p&gt;

&lt;p&gt;Then reality set in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hardware Tax Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;Let's break down what I actually spent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Used RTX 3090: $450&lt;/li&gt;
&lt;li&gt;1000W power supply: $120&lt;/li&gt;
&lt;li&gt;RAM upgrade (the 16GB I had wasn't enough): $80&lt;/li&gt;
&lt;li&gt;Cables, adapters, thermal paste (yes, really): $40&lt;/li&gt;
&lt;li&gt;Total: ~$690&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I said $500 in the headline because that's what I told myself at the time. The real number was closer to $700.&lt;/p&gt;

&lt;p&gt;And that was just the upfront cost. The RTX 3090 draws around 350W under load. Where I live, electricity is about $0.15/kWh. Running that card for 6 hours a day (which was typical for my dev workflow) added roughly $9.50 per month to my bill. Not devastating, but it compounds.&lt;/p&gt;

&lt;p&gt;Then there's the noise. The 3090's blower-style cooler sounds like a small jet engine at full tilt. My home office became a white-noise machine that made video calls sound like I was standing next to a server rack.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Quality Gap
&lt;/h2&gt;

&lt;p&gt;Here's the thing I didn't want to admit: the 8B model I could run comfortably on 24GB of VRAM was noticeably dumber than the hosted models I was trying to replace.&lt;/p&gt;

&lt;p&gt;I was using Llama 3 8B (and later Mistral 7B) for code review. It could catch obvious bugs — unused variables, missing null checks, that kind of thing. But when it came to understanding context, architectural patterns, or suggesting refactors, it fell flat. My side project was supposed to review pull requests, and the model kept missing real issues while flagging harmless style quirks.&lt;/p&gt;

&lt;p&gt;I tried upgrading to a 70B model. It didn't fit in 24GB of VRAM. I spent a weekend learning about quantization, GGUF formats, and layer offloading to CPU. The result: a model that ran at 2 tokens per second. That's not usable for interactive work. That's a screensaver.&lt;/p&gt;

&lt;p&gt;The hosted models I'd been using before — GPT-4, Claude, even the cheaper ones — were running circles around my local setup. And they were doing it with 10-20x less code on my end.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Breaking Point
&lt;/h2&gt;

&lt;p&gt;Let me tell you the exact moment I gave up.&lt;/p&gt;

&lt;p&gt;I spent two weeks building a RAG pipeline around my local model. I had embeddings, a vector store, a nice retrieval flow — the works. I was feeding in my project's documentation and asking the model questions about the codebase.&lt;/p&gt;

&lt;p&gt;The first 20 questions went fine. Then I asked something that required actual reasoning across multiple documents. The model hallucinated an answer with total confidence. It invented a function that didn't exist, cited a file that wasn't in the database, and suggested a fix that would have broken the build.&lt;/p&gt;

&lt;p&gt;When I finally got a hosted model to try the same prompt, it nailed it in one shot. The difference wasn't incremental — it was embarrassing.&lt;/p&gt;

&lt;p&gt;I realized I wasn't saving money. I was paying in time, electricity, and my own sanity to get worse results.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Cost Calculation
&lt;/h2&gt;

&lt;p&gt;Let's do the math that finally convinced me.&lt;/p&gt;

&lt;p&gt;My side project had a few dozen users and was making maybe $50/month in donations. For the three months I self-hosted, I spent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$690 in hardware&lt;/li&gt;
&lt;li&gt;~$30 in electricity&lt;/li&gt;
&lt;li&gt;Roughly 20 hours of setup, tuning, and debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I value my time at even $30/hour, that's $600 in labor. Total cost of self-hosting: about $1,320. For three months of a worse product.&lt;/p&gt;

&lt;p&gt;Meanwhile, the API I'd been avoiding costs about $1/month for my actual usage. Not per feature — per month. My traffic was never going to justify the hardware.&lt;/p&gt;

&lt;p&gt;Here's a quick script I wrote to make the decision final. It's rough, but you get the idea:&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="c1"&gt;# cost_compare.py — the math that ended my self-hosting journey
&lt;/span&gt;
&lt;span class="n"&gt;hours_spent_self_hosting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="n"&gt;hourly_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;  &lt;span class="c1"&gt;# your time is worth something
&lt;/span&gt;&lt;span class="n"&gt;hardware_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;690&lt;/span&gt;
&lt;span class="n"&gt;electricity_monthly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;months_self_hosted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="n"&gt;self_hosting_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;hardware_cost&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;electricity_monthly&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;months_self_hosted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hours_spent_self_hosting&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;hourly_rate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# My actual API usage: ~200 requests/day, ~2k tokens per request
&lt;/span&gt;&lt;span class="n"&gt;api_monthly_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;  &lt;span class="c1"&gt;# tokens per month
&lt;/span&gt;    &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1_000_000&lt;/span&gt;  &lt;span class="c1"&gt;# per million tokens
&lt;/span&gt;    &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.80&lt;/span&gt;  &lt;span class="c1"&gt;# $0.80 per million tokens for a cheap model
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Self-hosted (3 months): $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self_hosting_cost&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;API (per month): $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;api_monthly_cost&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;API (3 months): $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;api_monthly_cost&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The numbers weren't even close. Self-hosting cost me 100x more than the API, and the output quality was worse.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Self-Hosting Actually Makes Sense
&lt;/h2&gt;

&lt;p&gt;I'm not here to say self-hosting is always wrong. If you're handling medical records, financial data, or anything with real regulatory/compliance requirements, keeping models on-premise might be non-negotiable. If you work at a big company with dedicated MLOps teams, you can amortize the expertise and infrastructure.&lt;/p&gt;

&lt;p&gt;But for individual developers and small teams? The math almost never works out.&lt;/p&gt;

&lt;p&gt;The models at the top of the leaderboard — the ones that actually reason, that don't hallucinate as much, that handle your weird edge cases — they're too big to run on consumer hardware. The models that fit on 24GB of VRAM are, by definition, a year or two behind the frontier. And the frontier is where the useful work happens.&lt;/p&gt;

&lt;p&gt;I've seen the arguments: "But the API costs scale with usage!" Yes, they do. And self-hosting costs scale with your &lt;em&gt;time&lt;/em&gt; and &lt;em&gt;sanity&lt;/em&gt;, which are far harder to measure. If your project grows enough that API costs become a real line item, that's a good problem to have — it means you have users. You can revisit the decision then.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Use Now
&lt;/h2&gt;

&lt;p&gt;These days, I use APIs for almost everything. The one service I've kept around is an API gateway that lets me switch between different model providers without rewriting my code. It also gives me a unified billing view so I know exactly what each project costs. I've pointed several of my friends at it too.&lt;/p&gt;

&lt;p&gt;If you're in the same position I was — staring at GPU prices, convincing yourself you need to own your own inference — my advice is simple: try the API first. Build the product. Get users. Revisit self-hosting only when the numbers genuinely justify it.&lt;/p&gt;

&lt;p&gt;For me, the switch was the best engineering decision I made all year. My code review bot is faster, smarter, and costs about as much as a cup of coffee per month.&lt;/p&gt;

&lt;p&gt;And yes, for anyone wondering — I sold the 3090 on eBay and got $410 back. The whole experiment cost me about $300 in depreciation, some sleep, and a lot of humility. Worth it, honestly. You learn the most from the mistakes that cost you.&lt;/p&gt;

&lt;p&gt;If you're curious about the gateway I use, I've been happy with tai.shadie-oneapi.com — it's a simple API relay that has saved me from the provider hop. But more importantly: don't repeat my mistake. Start with the API. Your wallet and your mental health will thank you.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
