<?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: ParthibanRajasekaran</title>
    <description>The latest articles on DEV Community by ParthibanRajasekaran (@parthibanrajasekaran).</description>
    <link>https://dev.to/parthibanrajasekaran</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F411888%2Ff664651b-19e1-4182-b1f8-fdba51a75d9b.png</url>
      <title>DEV Community: ParthibanRajasekaran</title>
      <link>https://dev.to/parthibanrajasekaran</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/parthibanrajasekaran"/>
    <language>en</language>
    <item>
      <title>The Lie of the Global Average: Why Taming Complex SLIs Requires Bucketing</title>
      <dc:creator>ParthibanRajasekaran</dc:creator>
      <pubDate>Wed, 03 Dec 2025 23:01:54 +0000</pubDate>
      <link>https://dev.to/parthibanrajasekaran/the-lie-of-the-global-average-why-taming-complex-slis-requires-bucketing-4mfg</link>
      <guid>https://dev.to/parthibanrajasekaran/the-lie-of-the-global-average-why-taming-complex-slis-requires-bucketing-4mfg</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fygjubviof6bvyrn71qbi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fygjubviof6bvyrn71qbi.gif" alt="OBservability" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As an engineering manager responsible for keeping serverless, event-driven systems alive, I’ve learned to fear green dashboards.&lt;/p&gt;

&lt;p&gt;There is no worse feeling than seeing your main status page happily report “99.9% up” while Slack is full of screenshots from customers who can’t check out, can’t pay, or can’t log in and a senior leader is asking, “Why does everything look fine if the business is clearly on fire?”&lt;/p&gt;

&lt;p&gt;That’s the core problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Global availability is a vanity metric.&lt;/li&gt;
&lt;li&gt;It smooths out the spikes.&lt;/li&gt;
&lt;li&gt;It tells you the system is fine, but it doesn’t tell you if the business is fine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In site reliability engineering (SRE), we like tidy global SLIs because they compress a lot of behaviour into one number. But that compression is exactly how pain gets hidden.&lt;/p&gt;

&lt;p&gt;If you have 1,000,000 requests and 1,000 fail, the math says you’re 99.9% successful. Everyone relaxes.&lt;/p&gt;

&lt;p&gt;But if those 1,000 failures are all POST /submit payment or POST /confirm-order, you’re not reliable. You’re losing money and trust.&lt;/p&gt;

&lt;p&gt;Reliability is not a percentage. It is a relationship with your users. And global averages destroy that relationship.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Antidote: Bucketing (Adding Dimensionality)
&lt;/h2&gt;

&lt;p&gt;The only honest way to deal with this is to stop worshipping global averages and start segmenting your SLIs along the dimensions that actually threaten your business.&lt;/p&gt;

&lt;p&gt;Call it bucketing, slicing, or adding dimensionality, the idea is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stop asking, “Is the site OK?”&lt;/li&gt;
&lt;li&gt;Start asking, “Who is it broken for, and where?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A global SLI is like a city wide traffic report:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Traffic is moving at 40 mph on average.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s a nice number, but it’s useless if I’m sitting in standstill traffic on the only bridge into the city.&lt;/p&gt;

&lt;p&gt;A bucketed SLI is more honest:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The highway is clear, but the bridge to downtown is blocked.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Same city. Same “average speed.” Completely different lived reality.&lt;/p&gt;

&lt;p&gt;In real systems, three buckets almost always matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bucket A : Reads vs Writes: The Hidden Fire
&lt;/h2&gt;

&lt;p&gt;Most systems are heavily skewed toward reads. In a typical API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;90–95% of traffic is GET : browsing, listing, fetching.&lt;/li&gt;
&lt;li&gt;5–10%
is POST/PUT : creating orders, payments, sign-ups, profile changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The trap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;95% of your traffic is product browsing (GET /products, GET /search).&lt;/li&gt;
&lt;li&gt;5% is checkout and payment (POST /checkout, POST /payment).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now a bad deploy or downstream issue makes every payment call fail.&lt;/p&gt;

&lt;p&gt;From the user’s perspective:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Browsing looks fine.&lt;/li&gt;
&lt;li&gt;Every attempt to give you money fails.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the global SLI’s perspective:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;5% of all requests are failing.&lt;/li&gt;
&lt;li&gt;You’re still at 95% “availability.”&lt;/li&gt;
&lt;li&gt;Depending on your alert thresholds, you might not even get paged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is how you end up in the classic “everything is green” screenshot while Support is drowning and Finance is asking why conversion just fell off a cliff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You split the SLI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;availability_read : success rate for read-only requests.&lt;/li&gt;
&lt;li&gt;availability_write : success rate for state changing requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suddenly a total outage on the write path shows up as 0% availability for writes, not “a small blip.” You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alert specifically on write failures.&lt;/li&gt;
&lt;li&gt;Tie that bucket to more conservative error budgets.&lt;/li&gt;
&lt;li&gt;Treat it as a higher-severity incident even if the homepage still loads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The business impact&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reads going down is annoying. Writes going down is existential.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If people can’t browse, they might come back later.&lt;/li&gt;
&lt;li&gt;If they can browse but can’t pay, they leave angry and they tell others.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Buckets make that difference painfully visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bucket B : Mobile vs Web: The Client Reality
&lt;/h2&gt;

&lt;p&gt;Web clients and mobile clients live in different universes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web tends to run on stable connections, with up-to-date JS, easy rollbacks.&lt;/li&gt;
&lt;li&gt;Mobile runs on flaky 4G, old app versions, and aggressive retry logic that can turn a subtle bug into a DDoS-shaped traffic pattern.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The trap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You ship a change that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Works fine for web checkout.&lt;/li&gt;
&lt;li&gt;Breaks a specific flow on the iOS app hitting POST /checkout with an older payload shape.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Global metrics barely blink:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web traffic dominates volume.&lt;/li&gt;
&lt;li&gt;Retries hide some of the errors.&lt;/li&gt;
&lt;li&gt;The average success rate looks “acceptably noisy.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meanwhile:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your App Store rating is sliding.&lt;/li&gt;
&lt;li&gt;Support is logging “mobile checkout broken” tickets.&lt;/li&gt;
&lt;li&gt;Product is asking, “Why didn’t we catch this before it hit customers?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You bucket by client type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;client_type = web&lt;/li&gt;
&lt;li&gt;client_type = ios&lt;/li&gt;
&lt;li&gt;client_type = android&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don’t need per-device madness. You need just enough segmentation to see when one channel is quietly dying while the others hide it.&lt;/p&gt;

&lt;p&gt;Once you do this, you can ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“What is write availability for iOS for the checkout journey?”&lt;/li&gt;
&lt;li&gt;“How does Android latency for search compare to web?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The business impact&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now when you get paged, it’s not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“High error rate on /checkout.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Write availability for iOS clients on /checkout has dropped below SLO.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That alert:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tells on-call who is broken.&lt;/li&gt;
&lt;li&gt;Points directly to where to start looking.&lt;/li&gt;
&lt;li&gt;Stops the “blame the network” dance and focuses everyone on the right API, payload, or versioning issue.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Bucket C : Premium vs Standard: The Revenue Bucket
&lt;/h2&gt;

&lt;p&gt;This is where engineering stops talking about “traffic” and starts talking about revenue.&lt;/p&gt;

&lt;p&gt;Not all users are equal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A single enterprise customer might be worth more than 10,000 free-tier users.&lt;/li&gt;
&lt;li&gt;A VIP credit-card holder being unable to transact has a different blast radius than a trial user who can’t update a profile picture.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The trap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Without buckets, a retry storm from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;50,000 free users hitting a low-value feature&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;can drown out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;50 failures from your top 10 enterprise customers hitting your highest-margin features.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On a global SLI chart, it all collapses into one line. If the total error rate is “within budget,” you might be technically winning while strategically losing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You tag traffic with user tier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;user_tier = premium / enterprise&lt;/li&gt;
&lt;li&gt;user_tier = standard / free&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then you define separate SLOs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Premium checkout success: 99.99%&lt;/li&gt;
&lt;li&gt;Standard/free checkout success: 99.5%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same system. Different promises.&lt;/p&gt;

&lt;p&gt;And more importantly: different reactions when the budget burns. If premium write availability wobbles, you slow down changes or roll back quickly. If free tier browsing is a bit flaky but within tolerance, you don’t knee-jerk into a full change freeze.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The business impact&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is how you align:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engineering anxiety with Where the company actually makes money.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also changes roadmap debates. Once you show Product and Sales a graph labeled “Enterprise checkout success”, nobody argues that a free-tier bug and an enterprise bug are equivalent priorities anymore.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Senior Caveat: Bucketing, SLOs, and the Cost of Cardinality
&lt;/h2&gt;

&lt;p&gt;At this point, every experienced engineer is thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If I bucket by method, client, region, and tier… won’t this explode my Prometheus / Datadog bill?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes. It can.&lt;/p&gt;

&lt;p&gt;Bucketing adds cardinality. If you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Put user_id or request_id into labels, or&lt;/li&gt;
&lt;li&gt;Try to slice by every endpoint and every dimension&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;you will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Melt your metrics backend, or&lt;/li&gt;
&lt;li&gt;Hand Finance a monitoring bill that looks like a production incident.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The art of bucketing is restraint:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don’t need a bucket for every variable.&lt;/li&gt;
&lt;li&gt;You need a bucket for every distinct failure domain you care about.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, that means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be ruthless about which labels are allowed on “SLO grade” metrics.&lt;/li&gt;
&lt;li&gt;Keep high cardinality detail (like raw logs) in cheaper systems, and only promote a small set of aggregated counters/gauges as SLIs.&lt;/li&gt;
&lt;li&gt;Review your metric schema regularly with both SREs and Finance in the room.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If bucketing is free, you’re doing it wrong either technically (too coarse) or financially (too expensive). A senior team treats cardinality as part of the reliability design, not an afterthought.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Silence Is Golden
&lt;/h2&gt;

&lt;p&gt;When you bucket SLIs along the fault lines that actually matter, reads vs writes, mobile vs web, premium vs standard, something interesting happens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The noise stops.&lt;/li&gt;
&lt;li&gt;“High error rate” pages that send you spelunking through logs get replaced with alerts like:
&amp;gt; “Write availability for iOS premium users in checkout has dropped below SLO.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s an honest alert. It tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who is affected.&lt;/li&gt;
&lt;li&gt;Where to look.&lt;/li&gt;
&lt;li&gt;How worried the business should be.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s also an alert your engineers will respect. When every page comes with a clear, specific blast radius, the pager stops feeling like a random punishment generator and starts feeling like what it should have been all along: a surgical tool.&lt;/p&gt;

&lt;p&gt;As a manager, that’s the difference between a team that dreads the pager and one that trusts it. Honest alerts are a retention tool as much as a reliability tool.&lt;/p&gt;

&lt;p&gt;Most of these opinions come from incidents I’d rather not repeat, not from slides. Revisiting Google’s “SRE: Measuring and Managing Reliability” course recently mainly gave me sharper language for what the on-call rotation already knew.&lt;/p&gt;

&lt;p&gt;Reliability isn’t about the nines you show the board; it’s about the promises you keep to your users and about whether your teams can keep those promises without burning out.&lt;/p&gt;

&lt;p&gt;So the next time your dashboard says 99.9% green, don’t congratulate yourself.&lt;/p&gt;

&lt;p&gt;Ask a harder question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Who is stuck on the bridge?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because if you don’t know, your global average is lying to you.&lt;/p&gt;

</description>
      <category>sre</category>
      <category>engineeringmanager</category>
      <category>softwareengineering</category>
      <category>observability</category>
    </item>
    <item>
      <title>From Zero to Local AI in 10 Minutes With Ollama + Python</title>
      <dc:creator>ParthibanRajasekaran</dc:creator>
      <pubDate>Mon, 10 Nov 2025 11:52:54 +0000</pubDate>
      <link>https://dev.to/parthibanrajasekaran/from-zero-to-local-ai-in-10-minutes-with-ollama-python-4fd8</link>
      <guid>https://dev.to/parthibanrajasekaran/from-zero-to-local-ai-in-10-minutes-with-ollama-python-4fd8</guid>
      <description>&lt;h2&gt;
  
  
  Why Ollama (and why now)?
&lt;/h2&gt;

&lt;p&gt;If you want production‑like experiments without cloud keys or per‑call fees, Ollama gives you a local‑first developer path:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero friction&lt;/strong&gt;: install once; pull models on demand; everything runs on localhost by default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One API, two runtimes&lt;/strong&gt;: the same API works for local and (optional) cloud models, so you can start on your laptop and scale later with minimal code changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batteries included&lt;/strong&gt;: simple CLI (ollama run, ollama pull), a clean REST API, an official Python client, embeddings, and vision support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repeatability&lt;/strong&gt;: a Modelfile (think: Dockerfile for models) captures system prompts and parameters so teams get the same behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s new in late 2025 (at a glance)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud models (preview)&lt;/strong&gt;: run larger models on managed GPUs with the same API surface; develop locally, scale in the cloud without code changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI‑compatible endpoints&lt;/strong&gt;: point OpenAI SDKs at Ollama (/v1) for easy migration and local testing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows desktop app&lt;/strong&gt;: official GUI for Windows users; drag‑and‑drop, multimodal inputs, and background service management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety/quality updates&lt;/strong&gt;: recent safety‑classification models and runtime optimizations (e.g., flash‑attention toggles in select backends) to improve performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Ollama works (architecture in 90 seconds)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Runtime&lt;/strong&gt;: a lightweight server listens on localhost:11434 and exposes REST endpoints for chat, generate, and embeddings. Responses stream token‑by‑token.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model format (GGUF)&lt;/strong&gt;: models are packaged in quantized .gguf binaries for efficient CPU/GPU inference and fast memory‑mapped loading.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inference engine&lt;/strong&gt;: built on the llama.cpp family of kernels with GPU offload via Metal (Apple Silicon), CUDA (NVIDIA), and others; choose quantization (Q4/Q5/…) for your hardware.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration&lt;/strong&gt;: Modelfile pins base model, system prompt, parameters, adapters (LoRA), and optional templates—so your team’s runs are reproducible.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install in 60 seconds
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;macOS / Windows / Linux&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download and install Ollama from the official site (choose your OS).&lt;/li&gt;
&lt;li&gt;Open a terminal and verify the service is running on port 11434:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ollama --version
curl http://localhost:11434/api/version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Apple Silicon uses Metal by default. On Windows/Linux with NVIDIA, make sure your GPU drivers/CUDA are set up to accelerate larger models. CPU‑only also works for smaller models.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  First run (no Python yet)
&lt;/h2&gt;

&lt;p&gt;Pull a model and chat in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ollama pull llama3.1:8b

ollama run llama3.1:8b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Three ways to call Ollama from your app
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) REST (works from any language)
&lt;/h3&gt;

&lt;p&gt;Base URL (local): &lt;a href="http://localhost:11434/api" rel="noopener noreferrer"&gt;http://localhost:11434/api&lt;/a&gt;&lt;br&gt;
Example (chat):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://localhost:11434/api/chat \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "llama3.1:8b",
    "messages": [
      {"role": "user", "content": "Give me 3 tips for writing clean Python"}
    ],
    "stream": false
  }'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common endpoints you’ll use:&lt;/p&gt;

&lt;p&gt;/api/chat – chat format (messages with roles)&lt;/p&gt;

&lt;p&gt;/api/generate – simple prompt in/out (one‑shot)&lt;/p&gt;

&lt;p&gt;/api/embeddings – generate vectors for search/RAG&lt;/p&gt;

&lt;p&gt;/api/pull, /api/list, /api/show, /api/delete – model management&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For streaming, send "stream": true and read chunks until the server closes the connection.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2) Python SDK (official)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Install:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install ollama
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Chat:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from ollama import chat

resp = chat(model='llama3.1:8b', messages=[
    {'role': 'user', 'content': 'Give me 3 beginner Python tips.'}
])
print(resp['message']['content'])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Vision (image → text):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from ollama import chat

resp = chat(
  model='llama3.2-vision:11b',
  messages=[{
    'role': 'user',
    'content': 'What does this receipt say?',
    'images': ['receipt.jpg']  # file path or URL
  }]
)
print(resp['message']['content'])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Embeddings:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from ollama import embeddings

text = "Ollama lets you run LLMs locally."
vec = embeddings(model='embeddinggemma', prompt=text)
print(len(vec['embedding']))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3) Ship repeatable configs with a Modelfile
&lt;/h3&gt;

&lt;p&gt;A Modelfile captures the base model, system message, and default parameters so teammates (and CI) get identical behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Modelfile:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM llama3.1:8b
PARAMETER temperature 0.6
SYSTEM """
You are a concise AI tutor for Python beginners. Prefer runnable examples.
"""
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Build &amp;amp; run:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ollama create py-tutor -f Modelfile
ollama run py-tutor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Your first tiny local RAG (no frameworks required)
&lt;/h2&gt;

&lt;p&gt;This script indexes a handful of .txt files and answers questions using nearest‑neighbor search on embeddings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import glob, faiss, numpy as np
from ollama import embeddings, chat

EMB = 'embeddinggemma'
LLM = 'llama3.1:8b'

# 1) Chunk a few local docs
chunks, files = [], []
for path in glob.glob('docs/*.txt'):
    text = open(path, 'r', encoding='utf-8').read()
    for i in range(0, len(text), 800):
        chunks.append(text[i:i+800])
        files.append(path)

# 2) Embed and index with FAISS (cosine)
X = np.array([embeddings(model=EMB, prompt=t)['embedding'] for t in chunks], dtype='float32')
faiss.normalize_L2(X)
index = faiss.IndexFlatIP(X.shape[1])
index.add(X)

# 3) Query → top‑k context → answer
q = "What does the onboarding checklist say about Python version?"
qv = np.array([embeddings(model=EMB, prompt=q)['embedding']], dtype='float32')
faiss.normalize_L2(qv)
D, I = index.search(qv, 5)
context = "\n\n".join(chunks[i] for i in I[0])

msg = [
  {'role': 'system', 'content': 'Answer strictly from the provided context. If unknown, say so.'},
  {'role': 'user', 'content': f'Context:\n{context}\n\nQuestion: {q}'}
]
ans = chat(model=LLM, messages=msg)['message']['content']
print(ans)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why this pattern is useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Works offline; no hosted vector DB needed to begin with.&lt;/li&gt;
&lt;li&gt;Clear upgrade path to LangChain/LlamaIndex + a proper vector store when your corpus grows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Performance &amp;amp; correctness tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Model size vs hardware: start with 7–8B models for fast iteration; scale upward once your UX is dialed in.&lt;/li&gt;
&lt;li&gt;Quantization matters: smaller GGUFs load faster and reduce memory but can slightly degrade quality; pick the best trade‑off for your use case.&lt;/li&gt;
&lt;li&gt;Stream responses in UI code for perceived latency; switch to non‑streaming for simple back‑office jobs.&lt;/li&gt;
&lt;li&gt;Keepalive sessions to avoid repeated load/unload overhead in short‑lived CLIs or serverless functions.&lt;/li&gt;
&lt;li&gt;Prompt discipline: lock a SYSTEM prompt in your Modelfile so teammates don’t accidentally regress output style in reviews.&lt;/li&gt;
&lt;li&gt;Security: don’t expose your local API on the internet by default; if you must, add authentication and network controls.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Security hardening checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Bind to 127.0.0.1 or a private interface; avoid public exposure by default.&lt;/li&gt;
&lt;li&gt;If remote access is required, front with a reverse proxy (auth + TLS), restrict by IP, and rate‑limit.&lt;/li&gt;
&lt;li&gt;Run the service under a dedicated OS user with least privilege; separate model storage from app logs.&lt;/li&gt;
&lt;li&gt;Watch model pulls and updates in CI; pin checksums for reproducibility.&lt;/li&gt;
&lt;li&gt;Add basic request logging and redact prompts that may contain secrets.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Local vs Cloud: choosing the right runtime
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local&lt;/strong&gt;: best for privacy, prototyping, and offline work; your laptop/GPU sets the ceiling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ollama Cloud&lt;/strong&gt;: same API surface, larger models, and no local hardware management; useful for workloads that outgrow your machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can develop locally and deploy to cloud without rewriting client code just point your client at the different base URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common pitfalls (and quick fixes)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;11434 is taken&lt;/strong&gt;: change the port via the OLLAMA_HOST or client host parameter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CORS in browser apps&lt;/strong&gt;: frontends that call Ollama directly from the browser will hit CORS; proxy through your backend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Model not found"&lt;/strong&gt;: did you ollama pull ? Use ollama list to confirm.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Out‑of‑memory&lt;/strong&gt;: try a smaller quantization (e.g., Q4 instead of Q6) or a smaller parameter count.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Templates surprise you&lt;/strong&gt;: inspect with ollama show ; override with your own Modelfile.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>python</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>AI Workflow Integration: From Models to Methods, How Engineering Teams Will Change</title>
      <dc:creator>ParthibanRajasekaran</dc:creator>
      <pubDate>Tue, 04 Nov 2025 14:33:24 +0000</pubDate>
      <link>https://dev.to/parthibanrajasekaran/ai-workflow-integration-from-models-to-methods-how-engineering-teams-will-change-3aff</link>
      <guid>https://dev.to/parthibanrajasekaran/ai-workflow-integration-from-models-to-methods-how-engineering-teams-will-change-3aff</guid>
      <description>&lt;p&gt;It’s feedback season. Calendars fill with “quick chats,” dashboards glow, and we try to stitch a quarter’s worth of activity into a clean story about impact. But 2025 brings a deeper shift: AI workflow integration. AI is moving from “use a chatbot on the side” to living inside the handoffs &lt;/p&gt;

&lt;p&gt;plan → code, code → ship, ship → learn&lt;/p&gt;

&lt;p&gt;where traceability, decisions, and outcomes actually live.&lt;/p&gt;

&lt;p&gt;Thesis: the next 12 months aren’t about picking the “best” model; they’re about embedding AI inside the workflow so the path from intent to impact is faster and more visible. When AI helps at each hop, you don’t need to perform productivity you can prove it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feedback Loops Are the New Feature Flags
&lt;/h2&gt;

&lt;p&gt;We already have the artifacts: OKRs, roadmaps, PRs, tickets, incidents. What we lack is low-friction stitching. The pattern that works is AI in the handoff, producing useful, structured outputs as work happens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Draft AI-generated PR descriptions that map changes to OKRs (not just file diffs).&lt;/li&gt;
&lt;li&gt;Summarize test failures into actionable hypotheses (owners, suspected root causes, next steps).&lt;/li&gt;
&lt;li&gt;Generate release notes linked to customer outcomes, not just commit logs.&lt;/li&gt;
&lt;li&gt;Prep retro packets by querying "planned vs. shipped vs. impact," with links to issues and incidents.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The competitive edge isn't headcount, it's how well your workflow speaks AI.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Google AI Studio: Ship the Workflow, Not a Demo
&lt;/h2&gt;

&lt;p&gt;Google AI Studio lowers the activation energy to put Gemini API integration where work lives. You can experiment with prompts, then click Get code to export ready-to-run snippets and drop them into backends, CLIs, or UIs, no bespoke glue just to get started.&lt;/p&gt;

&lt;h3&gt;
  
  
  What makes this useful (not just shiny):
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Drop-in Gemini setup&lt;/strong&gt;. Create and manage API keys in AI Studio; wire them into your app with official SDKs. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Experiment → export code&lt;/strong&gt;. Tune prompts and parameters in the browser, then export the working snippet to your stack. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APIs for application embedding&lt;/strong&gt;. The same endpoints you prototyped against become production ready integrations in services and tools. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaborative logs &amp;amp; datasets&lt;/strong&gt;. New Logs and Datasets let teams enable request logging without code changes, inspect interactions, and export datasets for regression-style prompt reviews, so AI changes are reviewable, not mysterious. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fine tuning reality check&lt;/strong&gt;. The public Gemini API currently does not offer fine tuning; Google says it plans to bring it back.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Case Study Pattern: EM-AI (Your Engineering Manager, in the Loop)
&lt;/h2&gt;

&lt;p&gt;If you prefer to see ideas running, explore &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FParthibanRajasekaran%2FEM-AI" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FParthibanRajasekaran%2FEM-AI" alt="EM-AI" width="" height=""&gt;&lt;/a&gt; on GitHub a small but opinionated app that puts Gemini behind a thin service layer to assist everyday engineering work (React + Vite + TypeScript). It's a pattern you can lift into your stack.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  What it does (scannable, keyword-rich)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Chat Bot &amp;amp; Live Conversation for coaching and "first-draft" tasks.&lt;/li&gt;
&lt;li&gt;Daily Planner &amp;amp; Weekly Summary that encourage realistic planning and reflective learning.&lt;/li&gt;
&lt;li&gt;OKR Manager to draft and refine objectives, linking tasks to outcomes.&lt;/li&gt;
&lt;li&gt;Voice 
Assistant for hands-free updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How it's put together (architecture decisions)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Service boundary for AI calls&lt;/strong&gt; via services/geminiService.ts (centralized prompts, easy model swaps, guardrails).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composable UX with modular components&lt;/strong&gt;: DailyPlanner.tsx, OkrManager.tsx, WeeklySummary.tsx, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech &amp;amp; audio utilities&lt;/strong&gt; (useSpeechRecognition.ts, utils/audio.ts, utils/speech.ts) isolate I/O from business logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security hygiene&lt;/strong&gt;: .env.example, no committed keys, CI typech
ecks, CodeQL/Dependabot. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Try the pattern: fork a single component and wire it to your most painful handoff (PR → release notes, flaky test → actionable summary). &lt;a href="https://github.com/ParthibanRajasekaran/EM-AI" rel="noopener noreferrer"&gt;Check out the repo&lt;/a&gt; and borrow what fits.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Guardrails: How You Go Fast Safely
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key management &amp;amp; permissions&lt;/strong&gt;. Keep secrets in envs and rotate; AI Studio explains API key creation and setup. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observable assistants&lt;/strong&gt;. Turn on Logs and Datasets to compare outputs before/after prompt edits; treat prompt diffs like code diffs. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tuning strategy&lt;/strong&gt;. If base prompts fall short, evaluate Vertex AI supervised fine-tuning for governed custom behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ (snippet-friendly)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; How do I integrate Gemini into a service?&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; Prototype in Google AI Studio, click Get code, add your API key, then wrap calls behind a service module (like geminiService.ts) to centralize prompts, error handling, and telemetry. Start with one assistant at a painful handoff (e.g., PR summaries). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; Can AI generate PR summaries that map changes to OKRs?&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; Yes. Use repo context (diffs, issue/OKR links) and a structured prompt that outputs objective, change summary, risk, owners. Embed it in PR creation so traceability is automatic, not after-the-fact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vision: Lean Scaling with Smarter Tools
&lt;/h2&gt;

&lt;p&gt;While headlines debate model leaderboards, the real story is inside teams that scale lean,by augmenting the people they have with AI assistants that improve the quality of the trace. The winners won't just choose the right model; they'll &lt;strong&gt;standardize AI-first ways of working&lt;/strong&gt; across delivery loops.&lt;/p&gt;

&lt;p&gt;Start small. &lt;strong&gt;Embed AI workflow&lt;/strong&gt; integration where work happens. Let the signal rise. Next feedback season, you'll point to a traceable audit trail, not a story.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>google</category>
      <category>gemini</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Coding by Vibe, by Tests, or by Spec Which Hat Are You Wearing?</title>
      <dc:creator>ParthibanRajasekaran</dc:creator>
      <pubDate>Sun, 26 Oct 2025 20:22:41 +0000</pubDate>
      <link>https://dev.to/parthibanrajasekaran/coding-by-vibe-by-tests-or-by-spec-which-hat-are-you-wearing-1h7b</link>
      <guid>https://dev.to/parthibanrajasekaran/coding-by-vibe-by-tests-or-by-spec-which-hat-are-you-wearing-1h7b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;We build the same FastAPI endpoint three ways and compare trade-offs with code&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;&lt;strong&gt;Have you ever shipped something that “felt right”… and a week later you’re untangling spaghetti?&lt;br&gt;
Have you ever written tests after the code and realised they’re just confirming happy paths?&lt;br&gt;
Have you ever had a perfectly fine implementation… that didn’t match what Product actually meant?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If any of that sounds familiar, this post is for you. We’ll compare three very real ways engineers work in 2025:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vibe coding (code-first, intuition-driven)&lt;/li&gt;
&lt;li&gt;Test-Driven Development (TDD) (red → green → refactor)&lt;/li&gt;
&lt;li&gt;Spec-Driven Development (start with an executable spec; code follows)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To keep it concrete, we’ll build the same tiny feature three ways: a POST /price endpoint that adds VAT and applies a discount code. You’ll see what each mode feels like, where it shines, where it bites and you can open the matching folders in the repo (vibe/, tdd/, spec_driven/) to run the examples and go deeper.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 60-second analogy you won’t forget
&lt;/h2&gt;

&lt;p&gt;Vibe coding is like cooking by feel. You throw in garlic “until it smells right.” It’s brilliant for exploring flavours fast but without a recipe, repeating success is hard.&lt;/p&gt;

&lt;p&gt;TDD is cooking with a scale. You weigh, taste, adjust, then refactor the plating. Fewer surprises; you can serve 20 plates consistently.&lt;/p&gt;

&lt;p&gt;Spec-driven is a recipe card everyone agrees on before you start: ingredients, steps, expected taste. The sous-chef, the server, and you are aligned.&lt;/p&gt;

&lt;p&gt;We’ll use all three to make the same dish so the differences pop.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: a tiny price API
&lt;/h2&gt;

&lt;p&gt;We want a single endpoint:&lt;/p&gt;

&lt;p&gt;POST /price&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{ "amount": 100.0, "vat_pct": 20, "code": "WELCOME10" } -&amp;gt; { "final": 108.0 }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Rule: VAT is applied first, then a 10% discount for WELCOME10. Round to 2 decimals.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Vibe Coding “I’ll just build it”
&lt;/h3&gt;

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

&lt;p&gt;Have you ever been in flow, built the endpoint in one sitting, and thought: tests can come later? That’s vibe coding. It’s excellent for prototypes and spikes. Risk: edge cases get discovered by users or future-you.&lt;/p&gt;

&lt;p&gt;What it feels like, step by step&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Spin up a FastAPI app.&lt;/li&gt;
&lt;li&gt;Implement the “obvious” math.&lt;/li&gt;
&lt;li&gt;Add basic tests after it works.&lt;/li&gt;
&lt;li&gt;Learn from behaviour, refactor in place.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Minimal snippet (from vibe/app.py)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;`# POST /price  -&amp;gt; {"final": number}&lt;br&gt;
from fastapi import FastAPI&lt;br&gt;
from pydantic import BaseModel&lt;br&gt;
from .calculator import final_price&lt;/p&gt;

&lt;p&gt;app = FastAPI(title="vibe-pricing")&lt;/p&gt;

&lt;p&gt;class PriceIn(BaseModel):&lt;br&gt;
    amount: float&lt;br&gt;
    vat_pct: float&lt;br&gt;
    code: str | None = None&lt;/p&gt;

&lt;p&gt;@app.post("/price")&lt;br&gt;
def price(body: PriceIn):&lt;br&gt;
    return {"final": final_price(body.amount, body.vat_pct, body.code)}`&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reality check (in vibe/tests/)&lt;/strong&gt;&lt;br&gt;
You’ll likely add tests that match what you already wrote:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;def test_vat_then_discount():&lt;br&gt;
    assert final_price(100, 20, "WELCOME10") == 108.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When it shines&lt;/p&gt;

&lt;p&gt;Spikes, demos, “feel the API” explorations&lt;br&gt;
Rapid iteration with minimal ceremony&lt;br&gt;
Watch-outs&lt;/p&gt;

&lt;p&gt;Hidden edge cases (rounding, nulls, unknown codes)&lt;br&gt;
Harder to reproduce success; tests risk becoming rubber stamps&lt;/p&gt;

&lt;h3&gt;
  
  
  2) TDD “Red → Green → Refactor”
&lt;/h3&gt;

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

&lt;p&gt;Have you ever wished your code told you when you broke something? TDD is that feedback loop you write a failing test (red), make it pass (green), then clean it up (refactor).&lt;/p&gt;

&lt;p&gt;What it feels like, step by step&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write a failing test that defines behaviour.&lt;/li&gt;
&lt;li&gt;Write the tiniest code to pass it.&lt;/li&gt;
&lt;li&gt;Refactor confidently (tests stay green).&lt;/li&gt;
&lt;li&gt;Repeat, growing behaviour by behaviour.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Start with a test (from tdd/tests/test_calculator.py)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;`from dev_modes.tdd.calculator import price_with_vat, final_price&lt;/p&gt;

&lt;p&gt;def test_vat_rounds_to_cents():&lt;br&gt;
    assert price_with_vat(19.99, 8.5) == 21.64&lt;/p&gt;

&lt;p&gt;def test_final_price_vat_then_discount():&lt;br&gt;
    assert final_price(100, 20, "WELCOME10") == 108.0`&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Then the code (from tdd/calculator.py)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;`def price_with_vat(amount: float, vat_pct: float) -&amp;gt; float:&lt;br&gt;
    return round(amount * (1 + vat_pct / 100), 2)&lt;/p&gt;

&lt;p&gt;def apply_discount(total: float, code: str | None) -&amp;gt; float:&lt;br&gt;
    if not code: return total&lt;br&gt;
    if code.lower() == "welcome10": return round(total * 0.9, 2)&lt;br&gt;
    return total&lt;/p&gt;

&lt;p&gt;def final_price(amount: float, vat_pct: float, code: str | None) -&amp;gt; float:&lt;br&gt;
    with_vat = price_with_vat(amount, vat_pct)&lt;br&gt;
    return apply_discount(with_vat, code)`&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When it shines&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Core business logic and refactor-heavy domains&lt;/li&gt;
&lt;li&gt;Teams that value predictability and regression safety&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Watch-outs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Over-mocking and “testing implementation not behaviour”&lt;/li&gt;
&lt;li&gt;You need discipline to resist jumping straight to code&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3) Spec-Driven “Agree on the recipe, then cook”
&lt;/h3&gt;

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

&lt;p&gt;Have you ever built the right thing the wrong way or the wrong thing perfectly? Spec-driven starts with a human-readable, executable spec so everyone agrees on “what good looks like” before code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it feels like, step by step&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write the spec in plain language (e.g., Gherkin).&lt;/li&gt;
&lt;li&gt;Derive tests from the spec.&lt;/li&gt;
&lt;li&gt;Implement the code to satisfy the spec.&lt;/li&gt;
&lt;li&gt;Treat the spec as living documentation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;*&lt;em&gt;Spec first (from spec_driven/specs/price.feature)&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;code&gt;Feature: Checkout price&lt;br&gt;
  Scenario: VAT then discount&lt;br&gt;
    Given a base amount of 100&lt;br&gt;
    And VAT is 20 percent&lt;br&gt;
    When I apply the code "WELCOME10"&lt;br&gt;
    Then the final price should be 108.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test shaped by the spec (from spec_driven/tests/test_from_spec.py)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;`from fastapi.testclient import TestClient&lt;br&gt;
from dev_modes.spec_driven.app import app&lt;/p&gt;

&lt;p&gt;client = TestClient(app)&lt;br&gt;
def test_vat_then_discount_from_spec():&lt;br&gt;
    r = client.post("/price", json={"amount": 100, "vat_pct": 20, "code": "WELCOME10"})&lt;br&gt;
    assert r.status_code == 200&lt;br&gt;
    assert r.json() == {"final": 108.0}`&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When it shines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cross-team features (Product, QA, Eng) and compliance-heavy work&lt;/p&gt;

&lt;p&gt;API contracts where misunderstandings are expensive&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch-outs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A little slower to start (but faster to align)&lt;/p&gt;

&lt;p&gt;Specs need ownership or they rot&lt;/p&gt;

&lt;h3&gt;
  
  
  How to choose (today)
&lt;/h3&gt;

&lt;p&gt;Ask yourself three questions before you start:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is this exploration or execution?&lt;/strong&gt;&lt;br&gt;
If you’re exploring unknowns, start with vibe for speed then tighten with TDD or a spec once the shape stabilises.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is this change cross-team or customer-visible?&lt;/strong&gt;&lt;br&gt;
If multiple stakeholders must agree, spec-driven pays for itself in clarity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will we refactor this a lot?&lt;/strong&gt;&lt;br&gt;
If yes, TDD buys you courage and speed with safety.&lt;/p&gt;

&lt;h3&gt;
  
  
  Show me the code (and how to run it)
&lt;/h3&gt;

&lt;p&gt;All three implementations build the same POST /price:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vibe/&lt;/code&gt; : code first, tests after&lt;br&gt;
&lt;code&gt;tdd/&lt;/code&gt; : tests first, then code&lt;br&gt;
&lt;code&gt;spec_driven/&lt;/code&gt; : feature spec → tests → code&lt;/p&gt;

&lt;p&gt;Run any folder with your FastAPI dev server and tests. For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;# Vibe&lt;br&gt;
uvicorn dev_modes.vibe.app:app --reload&lt;br&gt;
pytest vibe/tests -q&lt;/code&gt;&lt;br&gt;
&lt;code&gt;# TDD&lt;br&gt;
uvicorn dev_modes.tdd.app:app --reload&lt;br&gt;
pytest tdd/tests -q&lt;/code&gt;&lt;br&gt;
&lt;code&gt;# Spec-driven&lt;br&gt;
uvicorn dev_modes.spec_driven.app:app --reload&lt;br&gt;
pytest spec_driven/tests -q&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick “save yourself later” checklist
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Vibe?&lt;/strong&gt; Jot down two edge cases you didn’t code yet. Add a micro-test for each before merging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TDD?&lt;/strong&gt; Re-read your tests: do they describe behaviour, or mirror implementation? Trim mocks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spec-driven?&lt;/strong&gt; Keep the spec crisp and owned. If Product changes their mind, change the spec first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;All three modes are tools, not tribes. Great engineers switch hats on purpose. Explore with vibe, harden with TDD, align with specs and your future self (and your directors) will thank you.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>python</category>
      <category>fastapi</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
