<?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: Kalpak Kale</title>
    <description>The latest articles on DEV Community by Kalpak Kale (@kalpak_kale).</description>
    <link>https://dev.to/kalpak_kale</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%2F4195317%2F94b94d7a-a1b2-4b5b-9ef2-5cbbe354d9d1.png</url>
      <title>DEV Community: Kalpak Kale</title>
      <link>https://dev.to/kalpak_kale</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kalpak_kale"/>
    <language>en</language>
    <item>
      <title>What Dussehra knows about building with AI</title>
      <dc:creator>Kalpak Kale</dc:creator>
      <pubDate>Tue, 20 Oct 2026 04:46:34 +0000</pubDate>
      <link>https://dev.to/kalpak_kale/what-dussehra-knows-about-building-with-ai-47dj</link>
      <guid>https://dev.to/kalpak_kale/what-dussehra-knows-about-building-with-ai-47dj</guid>
      <description>&lt;p&gt;Every October the effigy goes up in the ground near my home in Akola, forty feet of bamboo and paper, and every October I watch it burn with a few hundred people and think about nothing at all. This year I thought about work. Not because the festival is about work, but because the story it tells is the most accurate description I know of what goes wrong when capable people, or capable machines, are left to their own devices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In one line:&lt;/strong&gt; Dussehra is a yearly review disguised as a festival: a checklist of ten ways judgement fails, a ritual for maintaining your tools, a boundary that must not be crossed, and a public deletion of what you have outgrown.&lt;/p&gt;

&lt;p&gt;A word on the title. I am not going to tell you the festival is secretly a physics lesson. Most of what gets called the "science" of Indian festivals is wishful. What I am doing is narrower: reading the festival as a system that encodes practical knowledge, the way a checklist or a runbook does, and asking what that knowledge says to someone who spends their day building software with AI tools. Where I lean on actual research, I say so.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ravana knew everything
&lt;/h2&gt;

&lt;p&gt;The detail everyone forgets about Ravana is that he was the most learned figure in the epic. A scholar of the Vedas, a composer, an astronomer, a king who ran a wealthy city. The story is not about an idiot losing to a hero. It is about the most capable mind in the room losing because capability and judgement are different things, and he had only one of them.&lt;/p&gt;

&lt;p&gt;That is the exact shape of the problem with today's AI tools. A coding agent has read more code than any human. It can produce a working feature in the time it takes me to describe it. And it will, with full confidence, invent a library function that does not exist, skip the input validation it was never asked about, or report "done" on something it has not tested. Not because it is stupid. Because knowing is not the same as judging, and the judging part was never in the model.&lt;/p&gt;

&lt;p&gt;The practical consequence is the rule I wrote about in &lt;a href="https://kalpakkale.com/blog/a-brief-goes-in-software-comes-out/" rel="noopener noreferrer"&gt;the brief post&lt;/a&gt;: read every diff. Not to write the code, to supply the judgement the tool does not have. Ravana had no one reading his diffs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ten heads, ten ways to be wrong
&lt;/h2&gt;

&lt;p&gt;The popular reading gives Ravana's ten heads as ten vices: desire, anger, greed, attachment, pride, envy, and the restless mind, the intellect, the memory and the ego turned inward. Different tellings vary the list. The point is not the exact ten. The point is that failure has recognisable shapes, and naming them is most of the defence.&lt;/p&gt;

&lt;p&gt;Here are the ten I see most in AI-assisted work, which is my own list, not scripture:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Speed over understanding.&lt;/strong&gt; Accepting output because it arrived fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope creep.&lt;/strong&gt; Ten changes of mind cost ten rebuilds. The agent makes indecision cheap and therefore common.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence without evidence.&lt;/strong&gt; The answer that sounds right and cites nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skipping the boring defaults.&lt;/strong&gt; Encryption, signed links, secrets outside the repository. Always "later".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trusting the demo path.&lt;/strong&gt; It works on the one route somebody tried.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Letting the tool choose the architecture.&lt;/strong&gt; It will pick what it has seen most, not what you need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not filing the bug you fixed in the same breath.&lt;/strong&gt; The record disappears.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mistaking fluency for correctness.&lt;/strong&gt; Prose quality says nothing about truth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No test set.&lt;/strong&gt; If you cannot name how it fails, you do not understand the corpus yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ego.&lt;/strong&gt; Believing you no longer need the review because the last ten went fine.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pin that list above the monitor and you have most of the value of the festival without the bamboo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ayudha Puja: honour the tool by maintaining it
&lt;/h2&gt;

&lt;p&gt;On the day before, or on the day itself depending on where you are, families clean their tools and put them away for the day. Carpenters their chisels, drivers their vehicles, students their books. In Akola the auto drivers garland their rickshaws. In our office we have started doing the same with the thing we actually depend on: the evaluation set.&lt;/p&gt;

&lt;p&gt;A ritual of maintenance sounds quaint until you notice how rarely maintenance happens without one. &lt;a href="https://kalpakkale.com/blog/the-21-case-test-before-a-rag-chatbot-ships/" rel="noopener noreferrer"&gt;The 21-case test&lt;/a&gt; that decides whether our chatbot ships only gets run because running it after every change became a rule, not a judgement call. There is good evidence that rituals work this way. A 2018 review in Personality and Social Psychology Review by Hobson, Schroeder, Risen, Xygalatas and Inzlicht found that rituals regulate emotion, performance and social connection largely by making an action fixed and repeatable rather than optional. Make the tool check a festival and it happens. Leave it to willpower and it does not.&lt;/p&gt;

&lt;p&gt;So, this week: the proxy that serves AI tools to our developers gets its spend limits reviewed, the evaluation sheet gets its cases re-read, the backups get tested by restoring one. Garlands optional.&lt;/p&gt;

&lt;h2&gt;
  
  
  The line that must not be crossed
&lt;/h2&gt;

&lt;p&gt;Before Ravana arrives, Lakshman draws a line around the hut and tells Sita not to step over it. The whole disaster starts when she does, for a good reason, to feed a visitor. The guardrail was not wrong. The exception felt reasonable.&lt;/p&gt;

&lt;p&gt;Every guardrail I have put around an AI tool has been crossed for a reasonable exception. "Just this once, let it push to production." "Just this once, skip the review, it is a one-line change." The rule for us now is that a guardrail can be changed, in writing, with a reason, but never stepped over in the moment. The agent does not get to decide that the visitor is harmless, and neither do I at 11 at night.&lt;/p&gt;

&lt;h2&gt;
  
  
  Burn the effigy
&lt;/h2&gt;

&lt;p&gt;The part of the festival people travel for is the deletion. The thing you have been building for weeks goes up in flames, in public, on purpose. Nobody keeps the effigy for next year.&lt;/p&gt;

&lt;p&gt;Code does not get this treatment. We keep the prototype "in case", the old prompt "for reference", the branch "we might need". This year the review includes a list of things to burn: the chatbot's first Flask prototype, which has been dead since the FastAPI service shipped; three Claude Code configurations nobody has used since the proxy; and two internal tools that a single spreadsheet replaced. Deleting is a skill, and the festival gives it a date.&lt;/p&gt;

&lt;h2&gt;
  
  
  Begin
&lt;/h2&gt;

&lt;p&gt;Vijayadashami is also the day children are traditionally started on their letters, and the day new ventures are supposed to begin. The festival that burns things also starts things. The two go together: you cannot start the next thing while the effigy of the last one is still standing in the yard.&lt;/p&gt;

&lt;p&gt;So the final item on the list is the one thing I have been deferring. For me this year it is the evaluation template, the 21-case sheet in a form other teams can use, which I have talked about for a month and not written. It starts today.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this comes to
&lt;/h2&gt;

&lt;p&gt;Capability without judgement loses. Name the ways you fail. Maintain the tools on a schedule, not a whim. Draw the line and do not step over it for a reasonable exception. Burn what you have outgrown. Then begin.&lt;/p&gt;

&lt;p&gt;That is the festival, and it turns out to be a decent engineering review. Happy Dussehra.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Hobson, N. M., Schroeder, J., Risen, J. L., Xygalatas, D. and Inzlicht, M. (2018). The psychology of rituals: an integrative review and process-based framework. &lt;em&gt;Personality and Social Psychology Review&lt;/em&gt;, 22(3), 260 to 284.&lt;/li&gt;
&lt;li&gt;The Ramayana, Yuddha Kanda, for Ravana's learning and his defeat; the Lakshman Rekha episode appears in later tellings such as the Ramcharitmanas rather than in Valmiki.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kalpakkale.com/blog/the-21-case-test-before-a-rag-chatbot-ships/" rel="noopener noreferrer"&gt;The 21-case test that decides whether a RAG chatbot ships&lt;/a&gt; and &lt;a href="https://kalpakkale.com/blog/a-brief-goes-in-software-comes-out/" rel="noopener noreferrer"&gt;A brief goes in, software comes out&lt;/a&gt;, for the evaluation and review practices referred to above.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://kalpakkale.com/blog/what-dussehra-knows-about-building-with-ai/" rel="noopener noreferrer"&gt;kalpakkale.com&lt;/a&gt;, where I write Dispatches, field notes on putting AI to work.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>A brief goes in, software comes out. Shipping client products without a dev team assigned.</title>
      <dc:creator>Kalpak Kale</dc:creator>
      <pubDate>Tue, 20 Oct 2026 04:45:24 +0000</pubDate>
      <link>https://dev.to/kalpak_kale/a-brief-goes-in-software-comes-out-shipping-client-products-without-a-dev-team-assigned-1bmg</link>
      <guid>https://dev.to/kalpak_kale/a-brief-goes-in-software-comes-out-shipping-client-products-without-a-dev-team-assigned-1bmg</guid>
      <description>&lt;p&gt;I am not a developer by title. I run operations for an IT services firm. Yet in the last year I have taken several client briefs to deployed, paying, production software without a development team assigned to them. Not prototypes: systems with payments, encryption, QA cycles and clients using them daily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In one line:&lt;/strong&gt; An operations manager with an agentic coding tool can take a client brief to a paying production system, but only with a fixed process that puts payments and security first.&lt;/p&gt;

&lt;p&gt;The tool is an agentic coding assistant. The tool is not the point. The process is the point, and it is repeatable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shape of the process
&lt;/h2&gt;

&lt;p&gt;Every build runs through the same eight stages. "Agent" is the coding assistant; "me" is the human in the loop. The gates are the points where nothing moves until a person has looked.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Brief to decisions.&lt;/strong&gt; The agent reads the statement of work and lists every question a careful engineer would ask. I get the answers from the client: what happens when payment fails, who sees which fields, what "done" means for the first release. &lt;em&gt;Gate: no code until the page of decisions is signed off.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slice plan.&lt;/strong&gt; The product is cut into vertical slices, each one a thing a user can do end to end. One form saved. Then payment. Then the admin view.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build one slice.&lt;/strong&gt; The agent builds it against the decisions page, in its own run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read the diff.&lt;/strong&gt; I read every change before it is committed. Not to write it, to understand it. &lt;em&gt;Gate: human review. A diff I cannot explain does not merge.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test in a real browser, commit, record.&lt;/strong&gt; The slice is exercised by hand on the running app, committed, and the tracker gets an entry with the measured time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security pass before the first real data.&lt;/strong&gt; The five non-negotiables below are checked, and the deploy script's leak check runs. &lt;em&gt;Gate: security testing. Personal data does not enter the system until this passes.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QA cycle.&lt;/strong&gt; Test, file, fix, deploy, verify, close. Every bug is filed, even the ones fixed in the same breath, because the record is what the client is paying for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy and verify, then hand over.&lt;/strong&gt; After each production deploy: the live URL is smoke-tested, the payment reconciliation job is watched through one real cycle, and the rollback path is tried once. &lt;em&gt;Gate: deployment verification.&lt;/em&gt; Then the runbook, admin panel, environment notes and rollback steps go to the client, so their next developer can pick it up from the repository alone.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Stages 3 to 5 repeat per slice. Stage 6 happens once before real data and again whenever a slice touches personal data or money. Stage 8 happens on every release, not only the first.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a travel platform taught me about payment-first design
&lt;/h2&gt;

&lt;p&gt;The first product I built this way was a travel entry platform: travellers fill in the right government form for their destination and pay for the service. The obvious design records the application, then takes payment. That design produces orphaned applications, angry refunds, and support tickets.&lt;/p&gt;

&lt;p&gt;The design that worked is &lt;strong&gt;payment-first and idempotent&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nothing is recorded as an application until the payment provider confirms the money cleared.&lt;/li&gt;
&lt;li&gt;Confirmation can arrive three ways: the provider's webhook, the customer returning to the success page, and a cron job that reconciles anything the first two missed. All three paths create the same record once, keyed on the payment reference, so it does not matter which arrives first or twice.&lt;/li&gt;
&lt;li&gt;Every state change is logged with a source. When a customer says "I paid and nothing happened", the answer is in the log within a minute.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pattern is not specific to travel. Any product that takes money before doing work should be built this way, and an agent will not do it unless you ask.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security defaults I no longer negotiate
&lt;/h2&gt;

&lt;p&gt;Because the platform handled passport-level personal data, a few things became fixed rules for every build since:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Personal data encrypted at rest&lt;/strong&gt; with a modern authenticated cipher, keys outside the database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documents behind short-lived signed links&lt;/strong&gt;, never a public URL that works forever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uploads checked by content&lt;/strong&gt;, reading the file's magic bytes, not trusting the extension the browser sent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets in environment files, never in the repository&lt;/strong&gt;, and a check in the deploy script that refuses to ship if one leaks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin actions behind a real login&lt;/strong&gt; with rate limiting, not a shared link.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these are hard. All of them are skipped by default in a demo, and demos have a way of becoming production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Forty prototypes, and a colleague who now runs the process
&lt;/h2&gt;

&lt;p&gt;The same process, with the security rules relaxed and mock data instead of real, is how our sales team gets prototypes. In six months we built more than forty for prospects across government, finance, healthcare and consumer businesses: secure messaging for a state agency, a fraud-detection demo, scheme portals, clinical dashboards. A prospect who can click through a working screen behaves very differently from one reading a proposal. Several of those prototypes went into investor pitches and converted into paid projects.&lt;/p&gt;

&lt;p&gt;Once the process was stable I wrote it down as a standard operating procedure and trained a colleague to run it. That is the real test of a process: it works when you are not the one running it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results so far
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Production systems shipped this way:&lt;/strong&gt; several, each with payments, encryption, a QA record and clients using it daily.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Travel entry platform:&lt;/strong&gt; six destination workflows live in production, payment-first and idempotent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prototypes for sales:&lt;/strong&gt; more than 40 in six months, across government, finance, healthcare and consumer businesses. Several went into investor pitches and converted into paid projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process handed over:&lt;/strong&gt; written up as a standard operating procedure and run by a trained colleague without me in the loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security defaults applied on every build since:&lt;/strong&gt; encryption at rest with keys outside the database, short-lived signed links for documents, uploads checked by content, secrets kept out of the repository with a deploy-time check, admin actions behind a rate-limited login.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What the numbers do not show is the shape of the work: most of the time goes into the decisions page and reading diffs, not into typing code. That is the part the agent cannot do for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it breaks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;When the brief keeps moving.&lt;/strong&gt; Agents amplify indecision. Ten changes of mind cost ten rebuilds, fast but not free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When nobody reads the code.&lt;/strong&gt; I read every diff. Not to write it, to understand it. The day I stop is the day something ships that nobody can explain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When "it works on the demo path" is accepted as done.&lt;/strong&gt; The QA cycle exists to make that unacceptable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you run operations, product, or a small business, and you have a brief that has been waiting for a free developer for three months: the wait may be over. Just do not skip the page of decisions, the vertical slices, or the payment-first rule.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://kalpakkale.com/blog/a-brief-goes-in-software-comes-out/" rel="noopener noreferrer"&gt;kalpakkale.com&lt;/a&gt;, where I write Dispatches, field notes on putting AI to work.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>softwareengineering</category>
      <category>security</category>
      <category>startup</category>
    </item>
    <item>
      <title>Giving 19 developers AI access through one proxy, and what actually changed</title>
      <dc:creator>Kalpak Kale</dc:creator>
      <pubDate>Tue, 20 Oct 2026 04:40:45 +0000</pubDate>
      <link>https://dev.to/kalpak_kale/giving-19-developers-ai-access-through-one-proxy-and-what-actually-changed-2kdl</link>
      <guid>https://dev.to/kalpak_kale/giving-19-developers-ai-access-through-one-proxy-and-what-actually-changed-2kdl</guid>
      <description>&lt;p&gt;When a company decides its developers should use AI tools, the first instinct is to buy seats. That gets you nineteen people with nineteen different setups, nineteen billing surprises, and no idea whether any of it helped. We did it differently, and most of what follows would work for any team between ten and a hundred people.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In one line:&lt;/strong&gt; Rolling AI coding tools out to 19 developers worked because of one gateway, a spending policy, an evaluation habit and a set of working rules, not because of the licences.&lt;/p&gt;

&lt;h2&gt;
  
  
  One gateway, not nineteen API keys
&lt;/h2&gt;

&lt;p&gt;Every model call from the team goes through a self-hosted proxy. Developers get a key to the proxy, not to any vendor. The proxy holds the vendor keys, routes each request to the model configured for that team, logs usage per person and per project, and enforces spending caps.&lt;/p&gt;

&lt;p&gt;This one decision solved four problems at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost visibility.&lt;/strong&gt; A weekly report shows who used what, on which project, at what cost. Nobody argues about the AI bill any more, because it is itemised.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model changes without disruption.&lt;/strong&gt; When a better or cheaper model appears, it is one config change at the proxy. Nobody edits their editor settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Off-boarding.&lt;/strong&gt; Revoke one proxy key and the person's access is gone everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A place to add rules later.&lt;/strong&gt; Rate limits, allowed models per project, redaction of secrets in prompts: all of it lives in one place.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We used an open-source proxy. It runs on a small VPS, took an afternoon to set up, and has needed almost no attention since.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standardise the workflow, not the editor
&lt;/h2&gt;

&lt;p&gt;People are attached to their editors, so we did not fight that battle. We standardised on an agentic command-line tool for the heavy work, and let people keep whatever editor they like for the rest. The workflow that stuck:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Read before writing.&lt;/strong&gt; The agent reads the relevant part of the codebase and states its plan in a few lines. The developer approves or corrects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One logical change per run.&lt;/strong&gt; Not "build the feature", but "add the migration", then "add the endpoint", then "add the test".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify against something real.&lt;/strong&gt; Type checks and tests, then the actual page in a real browser. An agent that only reports "tests pass" is not finished.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit with the time it took.&lt;/strong&gt; Every completed change is logged in the tracker with the commit hash and the measured, AI-assisted time. Clients know the work is AI-assisted, and they see honest numbers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The fourth rule turned out to be the important one. Measured time makes the productivity claim concrete, and it stops the temptation to bill imaginary hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluate tools relentlessly, and expect to say no
&lt;/h2&gt;

&lt;p&gt;Over about six months I ran 38 structured evaluations of AI tools, plugins, models and services. Each one followed the same short template:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What job would this do for us, in one sentence?&lt;/li&gt;
&lt;li&gt;One hour of real use on a real task from a live project.&lt;/li&gt;
&lt;li&gt;What it did well. What it did badly. What it would cost per month at our size.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recommendation: adopt, trial for a month, or decline.&lt;/strong&gt; Written down, with a date.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most ended in "decline". A few became standard. The value of the exercise was not the wins; it was that every "no" came with a reason, so the same tool was not re-evaluated by a different person three weeks later. The written verdict is the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Invest in people, not just seats
&lt;/h2&gt;

&lt;p&gt;Twelve engineers enrolled in a vendor's certification programme for building on its platform. Not because certificates matter, but because a structured course gives a shared vocabulary. When everyone understands tool use, context windows and evaluation the same way, the arguments get shorter and better.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed, honestly
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Prototypes for sales conversations went from weeks to days. More than forty were built in six months, and several converted into paid work.&lt;/li&gt;
&lt;li&gt;Small client projects that used to wait for a free developer now get built by whoever holds the brief, with the agent doing the typing.&lt;/li&gt;
&lt;li&gt;The senior developers spend more time reviewing and less time writing boilerplate. They like this.&lt;/li&gt;
&lt;li&gt;Junior developers need more supervision, not less. An agent will confidently build the wrong thing at speed. Read-before-write and one-change-per-run exist for this reason.&lt;/li&gt;
&lt;li&gt;The bill is real, itemised, and lower than the licensing route would have been, because heavy users and light users are no longer paying the same flat fee.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  If you are about to do this
&lt;/h2&gt;

&lt;p&gt;Set up the proxy first, before anyone gets a key. Write the four working rules on one page. Pick one evaluation template and use it every time. Measure time honestly. Then buy the seats, if you still need them. In our case, we mostly did not.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://kalpakkale.com/blog/giving-19-developers-ai-through-one-proxy/" rel="noopener noreferrer"&gt;kalpakkale.com&lt;/a&gt;, where I write Dispatches, field notes on putting AI to work.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>productivity</category>
      <category>management</category>
    </item>
    <item>
      <title>The 21-case test that decides whether a RAG chatbot ships</title>
      <dc:creator>Kalpak Kale</dc:creator>
      <pubDate>Tue, 20 Oct 2026 04:39:46 +0000</pubDate>
      <link>https://dev.to/kalpak_kale/the-21-case-test-that-decides-whether-a-rag-chatbot-ships-4geg</link>
      <guid>https://dev.to/kalpak_kale/the-21-case-test-that-decides-whether-a-rag-chatbot-ships-4geg</guid>
      <description>&lt;p&gt;Every retrieval-augmented chatbot demo looks the same: paste in a folder of PDFs, ask a question, get a plausible answer, applause. Then it meets real users, who ask real questions, and the plausible answers start being wrong in ways nobody planned for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In one line:&lt;/strong&gt; A regulated financial client's document chatbot shipped only after a weighted 21-case evaluation, nine rounds of structured QA and a daily accuracy report the client ran themselves.&lt;/p&gt;

&lt;p&gt;I spent most of this year taking one such chatbot from a demo to a client beta for a wealth-management firm in a regulated market. The model mattered less than I expected. The evaluation mattered more than anything else. This is the evaluation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the failure modes, not the happy path
&lt;/h2&gt;

&lt;p&gt;Before writing a single test case I listed the ways the bot could be wrong. Three families covered almost everything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Intent failures.&lt;/strong&gt; The bot answers a different question from the one asked, usually because the question was short, colloquial, or used the user's internal jargon.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retrieval failures.&lt;/strong&gt; The right passage exists in the corpus but the bot never sees it, so it answers from the wrong document, or from nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic drift.&lt;/strong&gt; The bot retrieves the right passage and still says something the passage does not say: an extra claim, a softened caveat, a number rounded the wrong way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each family got seven cases, so 21 in total. Not more. A test set you can run by hand in an afternoon gets run. A test set of 300 gets automated badly or ignored.&lt;/p&gt;

&lt;h3&gt;
  
  
  The 21 cases at a glance
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Family&lt;/th&gt;
&lt;th&gt;What it checks&lt;/th&gt;
&lt;th&gt;A typical case&lt;/th&gt;
&lt;th&gt;Weight&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Intent&lt;/td&gt;
&lt;td&gt;The bot answers the question that was asked, not a nearby one&lt;/td&gt;
&lt;td&gt;A four-word question in the client's internal jargon&lt;/td&gt;
&lt;td&gt;1 to 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retrieval&lt;/td&gt;
&lt;td&gt;The right passage reaches the model&lt;/td&gt;
&lt;td&gt;A figure that lives only inside a chart on a slide&lt;/td&gt;
&lt;td&gt;1 to 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semantic drift&lt;/td&gt;
&lt;td&gt;The answer says only what the passage says&lt;/td&gt;
&lt;td&gt;A number the passage gives to two decimals, which the bot must not round&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scope, inside each family&lt;/td&gt;
&lt;td&gt;The bot declines or redirects what it must not answer&lt;/td&gt;
&lt;td&gt;"Which of these two funds should my mother buy"&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Scope cases are spread across the three families rather than kept as a fourth, because a scope failure usually looks like an intent or retrieval failure until you read the answer. Every weight-3 case is a scope case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Weight the cases by what a wrong answer costs
&lt;/h2&gt;

&lt;p&gt;Each case carries a weight of 1, 2 or 3, set by what a wrong answer would cost the client, not by how hard the case is.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Weight 1:&lt;/strong&gt; an embarrassing answer. Wrong product name, clumsy citation, a date off by a day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weight 2:&lt;/strong&gt; an answer that would mislead a customer. A rounded number, a softened caveat, a feature the document does not promise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weight 3:&lt;/strong&gt; an answer that would put the client outside the regulator's boundaries. Advice, a recommendation, an opinion on a product's suitability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A round's score is the weighted pass rate: the sum of the weights of the cases that passed, divided by the sum of all weights. A case passes only if a reviewer reads the answer and agrees it is correct, cited and inside scope; a near miss is a fail.&lt;/p&gt;

&lt;p&gt;Two rules sit on top of the score:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Any weight-3 failure blocks the release&lt;/strong&gt;, whatever the overall score. A 95 percent round with one weight-3 failure does not ship.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A case that passed last round and fails this round is a regression&lt;/strong&gt;, and a regression blocks the release until it is explained. Prompt "improvements" caused most of ours.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The weight-3 cases were all about scope: questions the bot must decline or redirect, phrased in ways that make declining hard. "Which of these two funds should my mother buy" is a weight-3 case. The correct answer is a polite refusal plus a pointer to a human, and it has to be the correct answer every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nine rounds, and what each one found
&lt;/h2&gt;

&lt;p&gt;We ran the 21 cases as a formal round after every meaningful change, nine rounds in total before beta. A sample of what each round caught:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieval was fine on long questions and poor on short ones. Fix: expand short queries with the user's previous message before embedding.&lt;/li&gt;
&lt;li&gt;Slide decks in the corpus were nearly unreadable. Standard OCR on exported PowerPoint pages captured roughly 75 to 80 percent of the text and lost everything inside charts. Fix: render each slide to an image and extract with a vision model, which took accuracy to 95 to 98 percent and finally read the numbers in the charts.&lt;/li&gt;
&lt;li&gt;The bot answered questions about a product that had been discontinued, from a document nobody had removed. Fix: a document registry with an "in force" flag, and retrieval filtered by it.&lt;/li&gt;
&lt;li&gt;Three weight-3 scope cases failed after a prompt "improvement" made the bot friendlier. Rolled back. Friendliness is not a requirement; staying inside the lines is.&lt;/li&gt;
&lt;li&gt;Duplicate questions in the same session got different answers. Fix: cache by normalised question within a session.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rounds six to nine were smaller: citation formatting, a date-parsing bug, and a case where the correct answer was "the document does not say", which the bot found very hard to produce.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "ready for beta" meant, written down
&lt;/h2&gt;

&lt;p&gt;The release criteria lived on one page, and every round ended by checking it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All seven weight-3 cases pass.&lt;/li&gt;
&lt;li&gt;Weighted score at or above the pass line we had agreed with the client, for two consecutive rounds.&lt;/li&gt;
&lt;li&gt;No regressions against the previous round.&lt;/li&gt;
&lt;li&gt;Every document in the corpus is in the registry with an "in force" flag, and retrieval filters on it.&lt;/li&gt;
&lt;li&gt;The bot can say "the document does not say" and did so in at least one case this round.&lt;/li&gt;
&lt;li&gt;The client's operations team has the daily scoring sheet and has used it on real questions for a week.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last criterion is the one people skip. The beta did not open until the client could measure it without us.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hand the scoring to the client
&lt;/h2&gt;

&lt;p&gt;The most useful thing we did was let the client's operations team score the bot daily, in their own spreadsheet, against their own real questions. Every incorrect answer got one of three labels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bot issue&lt;/strong&gt;: the bot had the right material and still got it wrong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document issue&lt;/strong&gt;: the material was missing, outdated, or contradictory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User understanding&lt;/strong&gt;: the question was ambiguous or outside scope, and a human would have asked a follow-up.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A typical day in the beta: 79 queries, 87 percent correct, 10 incorrect, of which 7 were bot issues, 2 were user-understanding cases, and 1 was a duplicate. The trend over the first weeks moved between 82 and 91 percent. Two things came out of this that no internal test could have given us.&lt;/p&gt;

&lt;p&gt;First, the split told us where to spend effort. When document issues dominate, the fix is content governance, not engineering. When user-understanding dominates, the fix is a clarifying-question behaviour, not a better model.&lt;/p&gt;

&lt;p&gt;Second, the client stopped asking "is it accurate?" and started asking "what is today's number and why did it move?". That is the conversation you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack, briefly
&lt;/h2&gt;

&lt;p&gt;The prototype was a React front end talking to a Flask script with a FAISS index. For beta it became a containerised FastAPI service with Celery workers, Redis, a Milvus vector store and PostgreSQL, behind Traefik, with images built in CI and pulled from a registry. None of that improved accuracy. It made the evaluation repeatable, which is what improved accuracy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would tell anyone starting one of these
&lt;/h2&gt;

&lt;p&gt;Lessons, in the order we learned them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Failure modes first, prompt second.&lt;/strong&gt; If you cannot name seven ways each family fails, you do not understand the corpus yet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Twenty-one cases you run by hand beat three hundred you automate badly.&lt;/strong&gt; The set has to fit in an afternoon or it stops being run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weight by the cost of being wrong&lt;/strong&gt;, and let one heavy failure block a release.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read the corpus the way the bot does.&lt;/strong&gt; Slides that looked fine to us were 75 to 80 percent readable to standard OCR; rendering each slide as an image and reading it with a vision model took that to 95 to 98 percent and recovered the numbers in the charts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stale documents are a retrieval failure in disguise.&lt;/strong&gt; A registry with an "in force" flag fixed a whole class of wrong answers that no prompt could.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Friendliness is not a requirement.&lt;/strong&gt; One prompt change that made the bot warmer broke three scope cases. We rolled it back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hand the scoring to the client with a three-way label&lt;/strong&gt;: bot issue, document issue, user understanding. The split tells you where to spend the next week.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The stack is plumbing.&lt;/strong&gt; Moving from a Flask script and a FAISS index to FastAPI, Celery, Redis, Milvus and PostgreSQL behind Traefik did not change accuracy. It made the rounds repeatable, and repeatable rounds changed accuracy.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The bot is still in beta. The number still moves. But every move now has a reason attached to it, and that is the difference between a demo and a product.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://kalpakkale.com/blog/the-21-case-test-before-a-rag-chatbot-ships/" rel="noopener noreferrer"&gt;kalpakkale.com&lt;/a&gt;, where I write Dispatches, field notes on putting AI to work.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>testing</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
