<?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: Shanthanu C</title>
    <description>The latest articles on DEV Community by Shanthanu C (@codvik).</description>
    <link>https://dev.to/codvik</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%2F4028555%2F02dc2a65-c9d3-4a9a-b913-c01603678ef1.png</url>
      <title>DEV Community: Shanthanu C</title>
      <link>https://dev.to/codvik</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/codvik"/>
    <language>en</language>
    <item>
      <title>From AI Demo to Production: 6 Things We Add Before Shipping an LLM Feature</title>
      <dc:creator>Shanthanu C</dc:creator>
      <pubDate>Fri, 09 Oct 2026 06:52:00 +0000</pubDate>
      <link>https://dev.to/codvik/from-ai-demo-to-production-6-things-we-add-before-shipping-an-llm-feature-c0p</link>
      <guid>https://dev.to/codvik/from-ai-demo-to-production-6-things-we-add-before-shipping-an-llm-feature-c0p</guid>
      <description>&lt;p&gt;Getting an LLM feature to work in a demo takes an afternoon. Getting it to keep working when real users, real data and real traffic arrive is a different job.&lt;/p&gt;

&lt;p&gt;Most AI pilots I see stall at the same point: the prototype calls a model API directly from a route handler, and everything "works" until the first timeout, malformed response or surprise bill.&lt;/p&gt;

&lt;p&gt;Here are six things worth adding before you ship. Examples use Node.js/TypeScript, but the ideas apply to any stack (Python, .NET, Java).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Put a timeout and retry policy around every model call&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Model APIs are network calls. They will be slow or fail sometimes. Never let a request hang forever.&lt;/p&gt;

&lt;p&gt;ts&lt;br&gt;
import OpenAI from "openai";&lt;/p&gt;

&lt;p&gt;const client = new OpenAI({&lt;br&gt;
  apiKey: process.env.OPENAI_API_KEY,&lt;br&gt;
  timeout: 20_000,   // fail fast instead of hanging the request&lt;br&gt;
  maxRetries: 2,     // retries on transient errors (429, 5xx)&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;Decide up front what the user sees when the call fails. A clear fallback message beats a spinner that never ends.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Never trust the output: validate it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your app expects JSON, parse and validate it. Models occasionally return extra text, missing fields or wrong types.&lt;/p&gt;

&lt;p&gt;ts&lt;br&gt;
import { z } from "zod";&lt;/p&gt;

&lt;p&gt;const SummarySchema = z.object({&lt;br&gt;
  title: z.string().min(1).max(120),&lt;br&gt;
  bullets: z.array(z.string()).min(1).max(5),&lt;br&gt;
  sentiment: z.enum(["positive", "neutral", "negative"]),&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;export async function summarize(text: string) {&lt;br&gt;
  const res = await client.chat.completions.create({&lt;br&gt;
    model: process.env.LLM_MODEL!,&lt;br&gt;
    response_format: { type: "json_object" },&lt;br&gt;
    messages: [&lt;br&gt;
      {&lt;br&gt;
        role: "system",&lt;br&gt;
        content:&lt;br&gt;
          "Return JSON with keys: title, bullets (array of up to 5 strings), sentiment (positive|neutral|negative).",&lt;br&gt;
      },&lt;br&gt;
      { role: "user", content: text },&lt;br&gt;
    ],&lt;br&gt;
  });&lt;/p&gt;

&lt;p&gt;const raw = res.choices[0]?.message?.content ?? "{}";&lt;br&gt;
  const parsed = SummarySchema.safeParse(JSON.parse(raw));&lt;/p&gt;

&lt;p&gt;if (!parsed.success) {&lt;br&gt;
    // log it, retry once, or fall back, but never pass bad data downstream&lt;br&gt;
    throw new Error("Model returned invalid structure");&lt;br&gt;
  }&lt;br&gt;
  return parsed.data;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Treat model output like user input: untrusted until validated.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cache what you can&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Many requests are repeated or near-identical. A simple cache cuts both latency and cost.&lt;/p&gt;

&lt;p&gt;ts&lt;br&gt;
import { createHash } from "node:crypto";&lt;/p&gt;

&lt;p&gt;const cache = new Map(); // use Redis in production&lt;/p&gt;

&lt;p&gt;function keyFor(input: string) {&lt;br&gt;
  return createHash("sha256").update(input).digest("hex");&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;export async function cachedSummarize(text: string) {&lt;br&gt;
  const key = keyFor(text);&lt;br&gt;
  if (cache.has(key)) return cache.get(key);&lt;/p&gt;

&lt;p&gt;const result = await summarize(text);&lt;br&gt;
  cache.set(key, result);&lt;br&gt;
  return result;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Swap the Map for Redis with a TTL once you run more than one instance.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log the right things (and protect the wrong ones)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can't improve what you can't see. For every call, log:&lt;/p&gt;

&lt;p&gt;model name and prompt version&lt;br&gt;
latency&lt;br&gt;
token usage&lt;br&gt;
validation pass/fail&lt;br&gt;
an anonymous request ID&lt;/p&gt;

&lt;p&gt;Do not log raw user content or personal data by default. Decide what you're allowed to store, mask it, and set a retention period.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set cost and rate guardrails&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A bug or a bad actor can burn through your budget fast. Add:&lt;/p&gt;

&lt;p&gt;per-user and per-IP rate limits&lt;br&gt;
a maximum input length before the call is made&lt;br&gt;
a max_tokens cap on responses&lt;br&gt;
a monthly spend alert at your provider&lt;br&gt;
ts&lt;br&gt;
if (text.length &amp;gt; 8_000) {&lt;br&gt;
  throw new Error("Input too long");&lt;br&gt;
}&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Version your prompts and test them&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Prompts are code. Keep them in files, give them versions, and run a small regression set whenever you change one.&lt;/p&gt;

&lt;p&gt;ts&lt;br&gt;
// prompts/summarize.v2.ts&lt;br&gt;
export const SUMMARIZE_PROMPT_V2 = &lt;code&gt;...&lt;/code&gt;;&lt;/p&gt;

&lt;p&gt;A set of 20-30 representative inputs with expected properties (valid JSON, correct sentiment, no empty fields) catches most regressions before users do. Run it in CI next to your normal tests.&lt;/p&gt;

&lt;p&gt;A quick pre-launch checklist&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Timeouts and retries on every model call&lt;/li&gt;
&lt;li&gt; Output validated against a schema&lt;/li&gt;
&lt;li&gt; Cache for repeated inputs&lt;/li&gt;
&lt;li&gt; Structured logs without sensitive data&lt;/li&gt;
&lt;li&gt; Rate limits, input caps and spend alerts&lt;/li&gt;
&lt;li&gt; Versioned prompts with a small test set&lt;/li&gt;
&lt;li&gt; A user-facing fallback when the model is unavailable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Wrapping up&lt;/p&gt;

&lt;p&gt;None of this is glamorous, but it's what separates an impressive demo from a feature your team can trust. Start with validation and timeouts, since those two prevent most of the pain.&lt;/p&gt;

&lt;p&gt;I'm part of the team at &lt;a href="https://codvikscribe.com" rel="noopener noreferrer"&gt;CodvikScribe&lt;/a&gt;, where we build custom software, mobile apps and AI-powered products. If you're working on an AI feature and want a second pair of eyes, you can reach us through our contact page.&lt;/p&gt;

&lt;p&gt;What's the biggest thing that broke when you took an LLM feature to production? Tell me in the comments.&lt;/p&gt;

&lt;p&gt;Devto post ai pilot to production&lt;br&gt;
MD&lt;br&gt;
Web search&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>node</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Web Development Services — CodvikScribe</title>
      <dc:creator>Shanthanu C</dc:creator>
      <pubDate>Tue, 14 Jul 2026 10:33:19 +0000</pubDate>
      <link>https://dev.to/codvik/web-development-services-codvikscribe-38l2</link>
      <guid>https://dev.to/codvik/web-development-services-codvikscribe-38l2</guid>
      <description>&lt;p&gt;Your website is the first impression your business makes on every potential customer. A slow, outdated, or poorly structured website does not just look bad — it actively costs you leads, sales, and credibility every single day.&lt;br&gt;
At &lt;a href="https://codvikscribe.com" rel="noopener noreferrer"&gt;CodvikScribe&lt;/a&gt;, we build websites that work. Not just aesthetically, but technically, commercially, and strategically.&lt;br&gt;
What We Build:&lt;br&gt;
Custom Business Websites — Designed and developed from scratch around your brand identity, audience, and conversion goals. No generic templates. No cookie-cutter layouts.&lt;br&gt;
E-Commerce Platforms — Full-featured online stores with product catalogues, secure payment gateways, inventory management, and customer account systems built to drive sales at scale.&lt;br&gt;
Corporate Portals &amp;amp; Dashboards — Internal and external web portals for enterprises that need secure, role-based access to data, reporting, and operational tools.&lt;br&gt;
CMS-Powered Websites — WordPress and headless CMS implementations that give your team full content control without relying on a developer for every update.&lt;br&gt;
Landing Pages &amp;amp; Lead Generation Sites — High-converting, performance-optimised pages engineered to turn visitors into enquiries, signups, and paying customers.&lt;br&gt;
Web Application Development — Complex, logic-heavy web applications that go beyond standard websites — booking systems, SaaS interfaces, client portals, and more.&lt;br&gt;
How We Build It:&lt;br&gt;
Every CodvikScribe web project follows a structured, transparent process — discovery, wireframing, design, development, testing, and launch — with the client involved at every stage. We use a modern, battle-tested technology stack including React.js, Next.js, Vue.js, Node.js, PHP, and WordPress, deployed on reliable cloud infrastructure with performance and security baked in from the ground up.&lt;br&gt;
What Every Build Includes:&lt;/p&gt;

&lt;p&gt;Mobile-first, fully responsive design&lt;br&gt;
SEO-ready architecture and clean code structure&lt;br&gt;
Fast load times and Core Web Vitals optimisation&lt;br&gt;
SSL security and data protection compliance&lt;br&gt;
Cross-browser compatibility&lt;br&gt;
Post-launch support and maintenance&lt;/p&gt;

&lt;p&gt;Who It Is For:&lt;br&gt;
Startups launching their digital presence. Growing businesses replacing an outdated site. Enterprises needing a scalable web platform. Product founders building SaaS interfaces. If your current website is holding your business back — or if you do not yet have one — CodvikScribe builds the solution that moves you forward.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>seo</category>
    </item>
  </channel>
</rss>
