<?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: Emma Schmidt</title>
    <description>The latest articles on DEV Community by Emma Schmidt (@emma_schmidt_).</description>
    <link>https://dev.to/emma_schmidt_</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%2F3450005%2Fcd01195d-0cef-48c0-9d0b-8033f6246f7e.jpeg</url>
      <title>DEV Community: Emma Schmidt</title>
      <link>https://dev.to/emma_schmidt_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emma_schmidt_"/>
    <language>en</language>
    <item>
      <title>Your AI Assistant Forgets What You Told It an Hour Ago, and It Never Says So</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Thu, 10 Sep 2026 05:30:53 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/your-ai-assistant-forgets-what-you-told-it-an-hour-ago-and-it-never-says-so-1ojm</link>
      <guid>https://dev.to/emma_schmidt_/your-ai-assistant-forgets-what-you-told-it-an-hour-ago-and-it-never-says-so-1ojm</guid>
      <description>&lt;p&gt;Long &lt;a href="https://zignuts.com/blog/top-ai-coding-tools-for-developers-2026?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=9" rel="noopener noreferrer"&gt;AI coding&lt;/a&gt; sessions have a failure mode nobody warns you about upfront. Not a crash, not an error message. The &lt;a href="https://zignuts.com/llm-genai-services/ai-chatbot-development/internal-ai-assistant-development?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=9" rel="noopener noreferrer"&gt;assistant&lt;/a&gt; just quietly starts acting like earlier instructions never happened, and it does this with exactly the same confident tone it uses when it's right.&lt;/p&gt;

&lt;p&gt;I started paying close attention to this after noticing a pattern across long sessions: constraints I'd set early on, "don't touch this file," "always use this naming convention," would get silently violated well into a session, with zero indication anything had changed. This is what's often called context degradation, and it's become one of the more actively discussed reliability concerns around long-running AI coding sessions this year, right alongside the usual conversation about &lt;a href="https://zignuts.com/ai-services/custom-ai-development?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=9" rel="noopener noreferrer"&gt;custom AI development&lt;/a&gt; and how much production infrastructure actually needs to sit around a model to make it trustworthy at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Happens at All
&lt;/h2&gt;

&lt;p&gt;Every AI assistant works within a fixed context window, everything it can "see" at once: the conversation, the code, the instructions. As a session grows, older parts of that context matter less to how the model weighs its next response, even when they're technically still present.&lt;/p&gt;

&lt;p&gt;This isn't a bug in the traditional sense. It's a structural property of how these systems work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instructions given early in a long session compete with everything said afterward for the model's attention&lt;/li&gt;
&lt;li&gt;There's no built-in mechanism forcing a model to re-check "wait, did I violate something I was told forty messages ago"&lt;/li&gt;
&lt;li&gt;A model degrading gracefully looks identical, on the surface, to a model working correctly, until the specific violated constraint actually matters&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  An Illustrative Pattern, Not a Formal Benchmark
&lt;/h2&gt;

&lt;p&gt;I want to be upfront about something here. What follows is a simplified illustration of a pattern that shows up anecdotally across long sessions, not a rigorously controlled experiment with precise run counts. I haven't published raw transcripts or a reproducible harness for this one, so I'm deliberately not dressing it up as harder data than it is.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Session Length&lt;/th&gt;
&lt;th&gt;Common Pattern Observed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Early in session&lt;/td&gt;
&lt;td&gt;Constraints followed closely and consistently&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mid-session&lt;/td&gt;
&lt;td&gt;Constraints generally still respected, occasional inconsistency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Late in session, many turns in&lt;/td&gt;
&lt;td&gt;Constraints increasingly treated as optional, without any signal that anything changed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The shape of that pattern, gradual, silent drift rather than a sudden failure, is the part worth taking seriously, even without a formal number attached to exactly when it happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Concrete Example of What This Looks Like
&lt;/h2&gt;

&lt;p&gt;Early in a session:&lt;/p&gt;

&lt;p&gt;User: Never modify files in the /legacy folder, they're frozen for a compliance audit.&lt;br&gt;
Assistant: Understood, I'll leave /legacy untouched for the rest of this session.&lt;/p&gt;

&lt;p&gt;Forty messages later, deep into an unrelated refactor:&lt;/p&gt;

&lt;p&gt;Assistant: I've updated the shared utility function and its usage across&lt;br&gt;
the codebase, including legacy/utils/formatter.js, to match the new signature.&lt;/p&gt;

&lt;p&gt;No warning. No "I know you said not to touch this, but." Just a quiet, confident violation of something established earlier, presented with the exact same tone as every correct thing the assistant did in between.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Is Genuinely Dangerous, Not Just Annoying
&lt;/h2&gt;

&lt;p&gt;The comment-staleness problem and this one share a root cause: a model treating something as true well past the point where it stopped being reliably true, without any signal that the confidence should have dropped.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A security constraint set early in a session can quietly stop being honored without any error or warning&lt;/li&gt;
&lt;li&gt;A reviewer skimming a long session's final output has no easy way to know which instructions from turn three are still actually being respected by turn eighty&lt;/li&gt;
&lt;li&gt;The failure looks identical to success right up until the specific violated constraint gets tested by something real, a deployment, an audit, a data leak&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Actually Helps
&lt;/h2&gt;

&lt;p&gt;A few practical habits that reduce how often this bites, based on how teams building serious AI tooling this year are approaching it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Re-state critical constraints periodically&lt;/strong&gt;, rather than assuming a single early mention holds for the entire session&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Break long tasks into shorter, focused sessions&lt;/strong&gt; where possible, since a fresh session starts with full attention on the current instructions rather than competing with dozens of prior turns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treat critical constraints as things to verify in review&lt;/strong&gt;, the same way stale comments should get flagged, a violated early instruction should be something a reviewer is actively checking for, not assuming was respected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build guardrails outside the conversation itself&lt;/strong&gt; where the constraint really matters, a file permission, a linter rule, a CI check, rather than relying purely on the model remembering an instruction from earlier&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Where This Gets Genuinely Hard to Solve Alone
&lt;/h2&gt;

&lt;p&gt;Building actual production-grade reliability around this, proper session management, automated re-verification of critical constraints, structural guardrails that don't depend purely on a model remembering something from fifty messages ago, is real engineering work that goes well beyond writing a good system prompt. This is exactly the kind of gap that custom AI development and &lt;a href="https://zignuts.com/ai-services/ai-workflow-automation" rel="noopener noreferrer"&gt;AI workflow automation&lt;/a&gt; work tends to close, building the surrounding infrastructure that catches what a model alone eventually drifts on, rather than hoping a longer, more carefully worded prompt fixes something that's a structural property of how these systems function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats, Genuinely
&lt;/h2&gt;

&lt;p&gt;This piece leans on a widely observed pattern rather than a controlled study I ran myself, and I want to be honest about that rather than presenting invented precision. If you've run rigorous, reproducible testing on this specific failure mode, I'd genuinely like to see it, and I'd trust real data over my own anecdotal pattern-matching here without hesitation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;A model degrading gracefully and a model working correctly look identical from the outside, right up until the moment the gap actually matters. The fix isn't a cleverer &lt;a href="https://zignuts.com/llm-genai-services/prompt-engineering?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=9" rel="noopener noreferrer"&gt;prompt&lt;/a&gt;, it's treating long-session reliability as an engineering problem with structural guardrails, not a memory problem you can politely ask a model to solve better.&lt;/p&gt;

&lt;p&gt;Has anyone actually run controlled tests on this specific failure mode? I'd love to see real numbers instead of my own anecdotal pattern here.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>testing</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Your Codebase Is About to Start Fixing Itself. Are You Ready?</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Wed, 09 Sep 2026 08:47:01 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/your-codebase-is-about-to-start-fixing-itself-are-you-ready-a5</link>
      <guid>https://dev.to/emma_schmidt_/your-codebase-is-about-to-start-fixing-itself-are-you-ready-a5</guid>
      <description>&lt;p&gt;A bug hits production. Nobody's paged. No Slack alert wakes anyone up. By the time your team checks the dashboard the next morning, an autonomous agent has already traced the error, written a patch in a sandbox, tested it against the full suite, and shipped the fix.&lt;/p&gt;

&lt;p&gt;That's not a thought experiment. It's what "&lt;a href="https://zignuts.com/agentic-ai-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=9" rel="noopener noreferrer"&gt;agentic AI&lt;/a&gt;" actually looks like in practice in September 2026, and it's the single biggest shift happening in how software gets built right now.&lt;/p&gt;

&lt;p&gt;If you're a developer, this isn't a trend to watch from the sidelines. It's changing the shape of the stack you'll be working in for the next decade.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Autocomplete to Autonomy
&lt;/h2&gt;

&lt;p&gt;The last generation of "AI in dev" was reactive: you typed, the model suggested. Useful, but fundamentally a tool waiting for input.&lt;/p&gt;

&lt;p&gt;Agentic AI flips that relationship. Agents now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plan multi-step tasks on their own (not just single completions)&lt;/li&gt;
&lt;li&gt;Call tools, &lt;a href="https://zignuts.com/ai-services/custom-ai-development/ai-api-development-services" rel="noopener noreferrer"&gt;APIs&lt;/a&gt;, and other agents to gather context&lt;/li&gt;
&lt;li&gt;Test their own output against real environments&lt;/li&gt;
&lt;li&gt;Course-correct without a human re-prompting them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's why 2026 conversations aren't just about "AI code assistants" anymore. They're about &lt;strong&gt;agent architectures&lt;/strong&gt;: how you design systems where autonomous components make real decisions, and where you draw the line for human sign-off.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where This Is Actually Showing Up in Engineering Work
&lt;/h2&gt;

&lt;p&gt;Here's the part that matters for anyone shipping software right now. Agentic AI isn't one feature bolted onto a product, it's touching nearly every layer of the stack:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. AI/ML Development
&lt;/h3&gt;

&lt;p&gt;The foundation of any agent is the model layer underneath it: predictive models, NLP pipelines, and computer vision systems that give an agent something real to reason over. Teams building agentic systems are investing heavily in &lt;a href="https://zignuts.com/ai-ml-development-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=9" rel="noopener noreferrer"&gt;AI/ML development&lt;/a&gt; to make sure the "brain" behind the agent is actually grounded in their data, not just wired to a generic API call.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. AI-Driven Software Development
&lt;/h3&gt;

&lt;p&gt;This is where agentic AI stops being a bolt-on and starts being architecture. Instead of writing rigid, rule-based logic, engineering teams are designing software where AI-driven decision-making is baked into the core workflow from day one, things like automated triage, self-adjusting business logic, and intelligent process orchestration.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Custom Software Development
&lt;/h3&gt;

&lt;p&gt;Off-the-shelf tools rarely handle agent orchestration well out of the box. Companies are turning to &lt;a href="https://zignuts.com/ai-services/custom-ai-development/ai-software-development-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=9" rel="noopener noreferrer"&gt;custom software development&lt;/a&gt; to build the specific guardrails, permission systems, and audit trails their industry and compliance requirements demand, rather than retrofitting a generic platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. SaaS Development
&lt;/h3&gt;

&lt;p&gt;Multi-tenant &lt;a href="https://zignuts.com/ai-services/custom-ai-development/ai-saas-development-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=9" rel="noopener noreferrer"&gt;SaaS&lt;/a&gt; platforms are a natural home for agentic features: think an agent that autonomously manages onboarding, usage-based scaling, or customer support triage across every tenant. SaaS development teams are now designing multi-tenant architecture with "agent slots" in mind from the start, so autonomous features can scale safely across the whole customer base.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Mobile App Development
&lt;/h3&gt;

&lt;p&gt;Agents aren't staying server-side. On-device and hybrid agents are starting to handle scheduling, personalization, and workflow automation directly inside mobile apps, which means mobile app development now has to account for local inference, permission boundaries, and battery-conscious agent design.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Digital Transformation
&lt;/h3&gt;

&lt;p&gt;For larger organizations, agentic AI isn't a feature request, it's a full operating-model shift. Digital transformation initiatives are increasingly centered on figuring out which business processes can safely be handed to autonomous systems and which still need a human in the loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Digital Product Engineering
&lt;/h3&gt;

&lt;p&gt;Building an agent-ready product from scratch (rather than retrofitting one) is its own discipline. Digital product engineering teams are baking agent orchestration, observability, and rollback mechanisms into products at the architecture stage, not as an afterthought.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Hiring Dedicated Developers
&lt;/h3&gt;

&lt;p&gt;Because agentic architecture is still a rapidly evolving specialty, a lot of teams are choosing to hire dedicated developers with hands-on agent-building experience rather than trying to upskill an entire team overnight.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Engineering Challenge: Trust, Not Just Capability
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable truth every engineering team is running into: getting an agent to &lt;em&gt;act&lt;/em&gt; autonomously is the easy part now. Getting your organization to &lt;em&gt;trust&lt;/em&gt; that action is the hard part.&lt;/p&gt;

&lt;p&gt;That means the real 2026 engineering work isn't just "add an agent." It's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building permission scopes so agents can't touch what they shouldn't&lt;/li&gt;
&lt;li&gt;Logging every decision an agent makes so it's auditable after the fact&lt;/li&gt;
&lt;li&gt;Designing rollback paths for when an agent gets it wrong&lt;/li&gt;
&lt;li&gt;Deciding, explicitly, where a human still has to approve before anything ships&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Skip these, and you don't have agentic AI. You have an unsupervised script with a marketing budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where This Leaves Developers
&lt;/h2&gt;

&lt;p&gt;If you're heads-down writing code right now, here's the practical takeaway: the value of a developer is shifting from "writes the logic" to "designs the boundaries the logic operates within." Understanding how to architect for autonomous systems, not just how to code around them, is quickly becoming a core skill, not a nice-to-have.&lt;/p&gt;

&lt;p&gt;The teams pulling ahead aren't the ones with the flashiest agent demo. They're the ones who've quietly figured out how to make autonomy safe, auditable, and boring in the best possible way.&lt;/p&gt;

&lt;p&gt;That's the real story behind the "agentic AI" headlines this September. Not magic. Just really good engineering discipline applied to a genuinely new kind of system.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Are you building with agents yet, or still evaluating where they fit in your stack? Drop your experience in the comments, I'd love to compare notes.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>agentaichallenge</category>
      <category>ai</category>
      <category>webdev</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Payment Gateway Integration in 2026 Isn't What It Was Two Years Ago. Here's What Actually Changed.</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Tue, 08 Sep 2026 12:27:31 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/payment-gateway-integration-in-2026-isnt-what-it-was-two-years-ago-heres-what-actually-changed-29in</link>
      <guid>https://dev.to/emma_schmidt_/payment-gateway-integration-in-2026-isnt-what-it-was-two-years-ago-heres-what-actually-changed-29in</guid>
      <description>&lt;p&gt;Ask a developer who last touched payment integration in 2023 to rebuild the same flow today, and they'll hit friction almost immediately. Compliance requirements have shifted, fraud prevention has moved from a bolted-on rules engine to something running continuously in real time, and the messaging standard underneath the whole transaction pipeline is being replaced globally. This is exactly the ground where &lt;a href="https://zignuts.com/industries/fintech/digital-banking-software" rel="noopener noreferrer"&gt;digital banking software development&lt;/a&gt; has quietly moved the furthest since the last time most teams touched this part of their stack.&lt;/p&gt;

&lt;p&gt;Here's what's genuinely different about payment integration this year, and what to actually plan for if you're building or modernizing this now.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Messaging Standard Shift Nobody Outside Fintech Is Talking About
&lt;/h2&gt;

&lt;p&gt;The financial industry has been migrating to ISO 20022, a richer, structured messaging standard replacing older, more limited &lt;a href="https://zignuts.com/industries/fintech/payment-gateway-development-services" rel="noopener noreferrer"&gt;payment&lt;/a&gt; message formats. This isn't a cosmetic update.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Old Standard Limitation&lt;/th&gt;
&lt;th&gt;What ISO 20022 Changes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Limited, truncated reference data on transactions&lt;/td&gt;
&lt;td&gt;Rich, structured data travels with every payment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manual reconciliation often required&lt;/td&gt;
&lt;td&gt;Machine-readable structured data makes automated reconciliation far more reliable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inconsistent formats across regions and networks&lt;/td&gt;
&lt;td&gt;A common structured format designed for global interoperability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fraud detection working with sparse transaction context&lt;/td&gt;
&lt;td&gt;Fraud systems get meaningfully more data per transaction to work with&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For anyone doing core banking software development or building payment flows that need to interoperate internationally, this migration isn't optional background noise, it directly affects how transaction data needs to be structured and processed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fraud Prevention Moved From Rules Engine to Real-Time AI
&lt;/h2&gt;

&lt;p&gt;The old model was largely reactive: a rules engine flagging transactions that matched known &lt;a href="https://zignuts.com/ml-services/anomaly-detection/fraud-detection-solutions" rel="noopener noreferrer"&gt;fraud&lt;/a&gt; patterns, reviewed after the fact. That model hasn't kept pace with how fast synthetic identity fraud and account takeover techniques have evolved.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Continuous risk scoring&lt;/strong&gt; now happens throughout a transaction, not just at a single checkpoint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavioral biometrics&lt;/strong&gt; increasingly factor into risk assessment, typing patterns, device handling, session behavior, not just the transaction data itself&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synthetic identity detection&lt;/strong&gt; has become a genuine specialty, since fabricated identities built from a mix of real and fake data are harder to catch with traditional verification checks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Merchant account requirements have gotten more data-intensive&lt;/strong&gt; specifically to combat this, meaning onboarding now typically requires more verification than it did even a couple of years ago&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Modern Integration Actually Requires
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step one: understand your settlement model&lt;/strong&gt;&lt;br&gt;
Real-time settlement rails have expanded significantly, and choosing between real-time and traditional batch settlement affects everything downstream, reconciliation timing, cash flow visibility, and how quickly disputes can actually be resolved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step two: plan for structured ISO 20022 data from the start&lt;/strong&gt;&lt;br&gt;
Retrofitting rich, structured transaction data after building around a simpler format is significantly more painful than designing for it from the beginning. This is one of the most common gaps in &lt;a href="https://zignuts.com/industries/fintech/legacy-banking-modernization" rel="noopener noreferrer"&gt;legacy banking modernization&lt;/a&gt; projects, systems that were never built to carry this much structured context per transaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step three: build fraud detection as a continuous layer, not a single checkpoint&lt;/strong&gt;&lt;br&gt;
Rather than one fraud check at the point of payment, effective systems now score risk continuously across the transaction lifecycle, adjusting friction dynamically rather than applying the same static check to every transaction regardless of risk profile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step four: design for biometric-friendly, low-friction checkout&lt;/strong&gt;&lt;br&gt;
Reducing checkout friction while maintaining strong verification is a genuine balancing act. Biometric authentication has become a standard expectation for mobile banking app development specifically, since users increasingly expect a fingerprint or face check rather than typing a password on a small screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step five: account for emerging settlement patterns like escrow-based flows&lt;/strong&gt;&lt;br&gt;
For higher-value or automated transactions, smart contract-based escrow patterns are gaining ground, holding funds until delivery or fulfillment conditions are verifiably met, an approach that's becoming more relevant as automated purchasing and agentic commerce grow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where This Gets Genuinely Complicated
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-region compliance.&lt;/strong&gt; A payment flow that works cleanly in one jurisdiction can require substantial rework to meet another region's specific data and settlement requirements, particularly as open banking APIs development expands what's expected across markets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legacy core system compatibility.&lt;/strong&gt; Older core banking infrastructure often wasn't built to carry ISO 20022's richer data structures, which makes this as much a modernization project as an integration one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reconciliation complexity during migration.&lt;/strong&gt; Running old and new message formats in parallel during a transition period is common, and it adds real operational overhead that's easy to underestimate in a project timeline&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Mistakes Worth Avoiding
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Treating this as a purely technical integration task and underestimating the compliance and data structure implications of the ISO 20022 shift&lt;/li&gt;
&lt;li&gt;Bolting fraud detection on as an afterthought rather than designing it as a continuous part of the transaction flow&lt;/li&gt;
&lt;li&gt;Assuming existing merchant account setups will transfer cleanly, when data requirements for these accounts have gotten meaningfully stricter&lt;/li&gt;
&lt;li&gt;Underestimating how much legacy banking modernization work is actually required before a modern payment flow can run cleanly on top of older core systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Quick Self-Check Before You Start
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Is your current transaction data structure ready to carry ISO 20022's richer data, or would this require a genuine schema rework?&lt;/li&gt;
&lt;li&gt;Does your fraud detection run continuously across the transaction lifecycle, or only at a single checkpoint?&lt;/li&gt;
&lt;li&gt;Have you actually verified your merchant account setup meets the current, more data-intensive onboarding requirements?&lt;/li&gt;
&lt;li&gt;If you're operating across multiple regions, have you confirmed compliance requirements for each one specifically, rather than assuming one setup covers all of them?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Deserves Real Planning
&lt;/h2&gt;

&lt;p&gt;Getting payment integration right in 2026 touches compliance, fraud architecture, core banking data structures, and the mobile experience all at once, which makes it a genuinely cross-functional project rather than a narrow technical task. This is exactly the kind of work that benefits from real experience across digital banking software development, core banking modernization, and open banking &lt;a href="https://zignuts.com/ai-services/custom-ai-development/ai-api-development-services" rel="noopener noreferrer"&gt;API&lt;/a&gt; integration together, rather than treating payment integration as an isolated feature bolted onto an otherwise unrelated system.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;Payment gateway integration has quietly become a substantially different discipline than it was even two years ago. The messaging standard underneath transactions is changing globally, fraud prevention has shifted from reactive to continuous, and the compliance bar for merchant onboarding has risen meaningfully. Teams still building against the old assumptions are going to hit real friction the moment they need to interoperate with a modernized counterpart.&lt;/p&gt;

&lt;p&gt;Has your team already started planning for the ISO 20022 shift, or is this still sitting further down the roadmap? Curious how far along different teams actually are with this transition.&lt;/p&gt;

</description>
      <category>fintech</category>
      <category>ai</category>
      <category>api</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Your Banking App's Chatbot Isn't the Problem. What's Behind It Is.</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Mon, 07 Sep 2026 05:38:56 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/your-banking-apps-chatbot-isnt-the-problem-whats-behind-it-is-1jfe</link>
      <guid>https://dev.to/emma_schmidt_/your-banking-apps-chatbot-isnt-the-problem-whats-behind-it-is-1jfe</guid>
      <description>&lt;p&gt;Ask a typical bank's &lt;a href="https://zignuts.com/llm-genai-services/ai-chatbot-development?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;chatbot&lt;/a&gt; to dispute a transaction, and watch it either loop you through a rigid decision tree or hand you off to a human anyway, the exact outcome the chatbot was supposed to prevent. That gap between "we have an &lt;a href="https://zignuts.com/llm-genai-services/ai-chatbot-development/internal-ai-assistant-development?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;AI assistant&lt;/a&gt;" and "our customer operations actually got faster" is exactly where a lot of &lt;a href="https://zignuts.com/industries/fintech/digital-banking-software?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;digital banking software development&lt;/a&gt; is quietly shifting focus right now.&lt;/p&gt;

&lt;p&gt;Here's what's actually changing in how banks are using natural language processing for customer operations, why the old chatbot approach fell short, and what a genuinely effective setup looks like.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the First Wave of Banking Chatbots Disappointed Everyone
&lt;/h2&gt;

&lt;p&gt;Most early banking chatbots were built on rigid, rule-based decision trees. Ask something slightly outside the expected phrasing, and the whole experience broke down.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Intent recognition was shallow.&lt;/strong&gt; A question phrased even slightly differently than the training examples often failed to match any intent at all&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No real context retention.&lt;/strong&gt; Every message was treated in isolation, so a natural follow-up question required the customer to repeat information they'd already given&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalation happened too late or too early.&lt;/strong&gt; Either the bot stubbornly tried to handle something it clearly couldn't, frustrating the customer, or it escalated routine questions that a well-built system should have resolved on its own&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance and accuracy were treated as an afterthought.&lt;/strong&gt; In a regulated industry, a confidently wrong answer about fees, terms, or account status isn't just annoying, it's a real liability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Modern NLP Actually Changes
&lt;/h2&gt;

&lt;p&gt;The shift happening now isn't just "a smarter chatbot." It's NLP applied across the entire customer operations pipeline, not just the visible chat window.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Traditional Approach&lt;/th&gt;
&lt;th&gt;Modern NLP-Driven Approach&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rigid decision trees, exact phrase matching&lt;/td&gt;
&lt;td&gt;Genuine intent understanding across varied phrasing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No memory between messages&lt;/td&gt;
&lt;td&gt;Contextual memory carried through a full conversation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manual routing of support tickets&lt;/td&gt;
&lt;td&gt;Automated classification and routing based on actual content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generic responses regardless of customer history&lt;/td&gt;
&lt;td&gt;Personalized responses informed by account and transaction context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human review needed for most escalations&lt;/td&gt;
&lt;td&gt;Automated resolution for a meaningfully larger share of routine requests&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Real Ways Banks Are Applying This Right Now
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automated transaction dispute intake&lt;/strong&gt;, where NLP classifies the nature of a dispute and routes it to the correct resolution workflow instead of a generic support queue&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sentiment-aware escalation&lt;/strong&gt;, detecting frustration or urgency in a customer's message and prioritizing it for human review before it becomes a complaint&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document and KYC processing&lt;/strong&gt;, extracting and validating information from submitted &lt;a href="https://zignuts.com/ai-services/ai-workflow-automation/ai-document-automation-solutions?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;documents&lt;/a&gt; far faster than manual review&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multilingual support at scale&lt;/strong&gt;, handling customer queries across languages without maintaining separate support teams for each one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fraud pattern detection in customer communications&lt;/strong&gt;, flagging unusual language patterns in support requests that may indicate account takeover attempts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Matters More for Banking Than Most Industries
&lt;/h2&gt;

&lt;p&gt;Two forces make this particularly relevant to financial services right now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Legacy banking modernization is already underway.&lt;/strong&gt; A large share of banks are actively working through legacy banking modernization efforts, replacing decades-old core systems. NLP-driven customer operations is often one of the more visible, customer-facing parts of that broader modernization, since it's where customers directly feel the difference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open banking is raising the complexity of customer questions.&lt;/strong&gt; As &lt;a href="https://zignuts.com/industries/fintech/open-banking-apis-development-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;open banking APIs development&lt;/a&gt; expands what customers can actually do, connecting accounts across providers, initiating payments through third parties, the range of questions customer support needs to handle has grown substantially. A rigid, rule-based system simply can't keep pace with that expanding surface area the way genuine language understanding can.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Framework for Evaluating This
&lt;/h2&gt;

&lt;p&gt;Before investing in an &lt;a href="https://zignuts.com/ml-services/nlp?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;NLP&lt;/a&gt;-driven customer operations overhaul, these questions are worth answering honestly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What percentage of current support volume is genuinely routine and repetitive, versus requiring real human judgment?&lt;/li&gt;
&lt;li&gt;Does your current system retain context across a conversation, or does every message start from zero?&lt;/li&gt;
&lt;li&gt;How is compliance and accuracy currently verified for AI-generated responses, especially anything touching account details or regulatory information?&lt;/li&gt;
&lt;li&gt;Is your legacy &lt;a href="https://zignuts.com/industries/fintech/core-banking-systems?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;core banking software development&lt;/a&gt; stack capable of feeding real-time data into an NLP layer, or does that integration itself need modernization first?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Mistakes Worth Avoiding
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Deploying NLP-driven automation without a clear, tested escalation path for anything genuinely ambiguous or high-stakes&lt;/li&gt;
&lt;li&gt;Treating this as a pure customer support project when it actually requires deep integration with core banking and account systems to be genuinely useful&lt;/li&gt;
&lt;li&gt;Underestimating the compliance review needed before any AI-generated response touches account-specific or regulatory information&lt;/li&gt;
&lt;li&gt;Rolling this out across every channel simultaneously instead of piloting on a lower-risk workflow first, like general inquiries, before touching disputes or account changes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Deserves Real Investment, Not a Quick Bolt-On
&lt;/h2&gt;

&lt;p&gt;Getting this right touches more than a chatbot interface. It requires real integration with core banking systems, careful compliance review, and often work on the mobile banking app development side too, since a growing share of these interactions now happen inside the app itself rather than through a website or phone call. This is exactly the kind of cross-cutting fintech software development work that benefits from experience across both the AI layer and the underlying banking infrastructure, rather than treating the two as separate projects that happen to sit near each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;The gap between a bank that "has a chatbot" and one that's genuinely automating customer operations well usually comes down to what's happening underneath the interface, real intent understanding, real context retention, and real integration with the systems that actually hold the answers. As legacy banking modernization and open banking both continue expanding what customers expect to be able to do, the operations layer handling their questions needs to keep pace, not lag a generation behind.&lt;/p&gt;

&lt;p&gt;Has your team started genuinely modernizing customer operations with NLP, or is the current setup still the same rigid chatbot from a few years ago wearing a new coat of paint? Curious how far along different banks and fintechs actually are with this.&lt;/p&gt;

</description>
      <category>fintech</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The Vulnerability That Took Down Your Build Wasn't in Your Code</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Wed, 19 Aug 2026 05:46:54 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/the-vulnerability-that-took-down-your-build-wasnt-in-your-code-kp9</link>
      <guid>https://dev.to/emma_schmidt_/the-vulnerability-that-took-down-your-build-wasnt-in-your-code-kp9</guid>
      <description>&lt;p&gt;You didn't write a single insecure line. You reviewed every pull request. Your own code is clean. And yet a routine dependency update just pulled in a compromised package three layers deep in your dependency tree, and now there's malicious code running in your CI pipeline that nobody on your team ever actually looked at. This isn't a hypothetical, it's the exact pattern behind a wave of real software &lt;strong&gt;&lt;a href="https://zignuts.com/ml-services/forecasting-models/supply-chain-forecasting?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;supply chain&lt;/a&gt;&lt;/strong&gt; attacks that's made securing the dependency chain one of the most active DevSecOps priorities of the year, not a compliance checkbox anymore, but a genuine engineering discipline.&lt;/p&gt;

&lt;p&gt;Here's what's actually driving this, what a real defense looks like in practice, and how to start building it into a pipeline that doesn't already have it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Became Urgent Rather Than Theoretical
&lt;/h2&gt;

&lt;p&gt;For years, supply chain security lived in the "we should probably think about this someday" category for most teams. A few things changed that.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Attackers shifted their target.&lt;/strong&gt; Compromising one popular open-source package gives an attacker access to every downstream project that depends on it, which is a dramatically better return on effort than attacking one company directly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency trees have grown enormous and mostly invisible.&lt;/strong&gt; A modern project with a handful of direct dependencies can easily pull in hundreds of transitive ones, most of which nobody on the team has ever actually reviewed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD pipelines became a genuine attack surface of their own.&lt;/strong&gt; A compromised build step doesn't just affect one developer's machine, it can inject malicious code directly into what gets shipped to production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regulatory pressure caught up.&lt;/strong&gt; Software bill of materials requirements are increasingly showing up in vendor contracts and compliance frameworks, turning "do we know what's in our dependency tree" from a nice-to-have into a real audit question&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-driven systems raised the stakes further.&lt;/strong&gt; As more production pipelines now include model training, &lt;strong&gt;&lt;a href="https://zignuts.com/llm-genai-services/fine-tuning?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;fine-tuning&lt;/a&gt;&lt;/strong&gt;, and inference steps alongside traditional code, the same supply chain exposure now extends to model weights, training data sources, and the infrastructure feeding them&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What a Real Supply Chain Attack Actually Looks Like
&lt;/h2&gt;

&lt;p&gt;Understanding the shape of these attacks makes the defense make a lot more sense.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A maintainer's account on a popular package gets compromised, and a malicious update gets published under a trusted name&lt;/li&gt;
&lt;li&gt;A typosquatted package with a name one character off from a popular library gets installed by mistake during a routine &lt;code&gt;npm install&lt;/code&gt; or &lt;code&gt;pip install&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A legitimate package gets acquired or handed off to a new maintainer who quietly introduces malicious code in a later version&lt;/li&gt;
&lt;li&gt;A build script inside a dependency runs arbitrary code during installation, before your own application code ever executes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these require your team to write a single insecure line. They exploit the trust baked into how modern dependency management works by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Defenses Worth Actually Building
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Software Bill of Materials (SBOM)&lt;/strong&gt;&lt;br&gt;
A structured, complete inventory of every dependency in your project, direct and transitive. Without this, you genuinely don't know what's actually running in production, which makes it impossible to respond quickly when a vulnerability in a specific package gets disclosed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependency pinning and lockfiles&lt;/strong&gt;&lt;br&gt;
Pinning exact versions rather than accepting a range prevents a compromised update from silently flowing into your build the next time someone runs an install. Lockfiles should be committed and treated as part of your actual source of truth, not a generated afterthought.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automated vulnerability scanning&lt;/strong&gt;&lt;br&gt;
Continuously checking your dependency tree against known vulnerability databases, ideally as part of CI, so a newly disclosed issue in something you already depend on gets flagged automatically rather than discovered by accident.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Provenance verification&lt;/strong&gt;&lt;br&gt;
Confirming that a package actually came from where it claims to have come from, using cryptographic signing where the ecosystem supports it, rather than trusting a package registry blindly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Least-privilege CI pipelines&lt;/strong&gt;&lt;br&gt;
Build steps should only have access to exactly what they need. A compromised dependency running inside an overprivileged CI job can do far more damage than one running with tightly scoped permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Starting Sequence
&lt;/h2&gt;

&lt;p&gt;You don't need to solve every layer of this at once. A reasonable order to tackle it in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate an SBOM for your existing project&lt;/strong&gt; as a baseline, so you actually know what's in your dependency tree today&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable automated vulnerability scanning&lt;/strong&gt; in CI, so new issues surface automatically going forward&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audit and commit your lockfiles&lt;/strong&gt;, closing the gap where version ranges could silently pull in something unexpected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review CI pipeline permissions&lt;/strong&gt;, scoping down anything with broader access than it actually needs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set a recurring cadence for dependency review&lt;/strong&gt;, not just reacting when something breaks or gets flagged&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Common Mistakes Worth Avoiding
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Treating an SBOM as a one-time compliance document instead of something that needs to stay current as dependencies change&lt;/li&gt;
&lt;li&gt;Scanning for vulnerabilities but never actually acting on what gets flagged, which makes the scanning theater rather than defense&lt;/li&gt;
&lt;li&gt;Assuming a popular, widely-used package is automatically safe, when popularity is exactly what makes a package an attractive target&lt;/li&gt;
&lt;li&gt;Giving CI pipelines broad, unscoped access "to make things easier," which turns a single compromised dependency into a much bigger incident&lt;/li&gt;
&lt;li&gt;Skipping this entirely for internal tools and side projects, when those often have the least oversight and the most direct access to sensitive systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Quick Self-Check
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Do you actually know every dependency in your project right now, including the transitive ones, or would you have to go find out?&lt;/li&gt;
&lt;li&gt;Is your CI pipeline scanning for known vulnerabilities automatically, or does that only happen when someone remembers to check?&lt;/li&gt;
&lt;li&gt;If a popular package you depend on were compromised tomorrow, how quickly could your team confirm whether you're affected?&lt;/li&gt;
&lt;li&gt;Do your CI build steps have more access than they actually need to do their job?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If more than one of those gave you pause, there's real, addressable exposure sitting in your pipeline right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Deserves Real Investment, Not a Checkbox
&lt;/h2&gt;

&lt;p&gt;Supply chain security tends to get deprioritized precisely because it's invisible until the day it isn't. Building this properly, real SBOM tooling, automated scanning wired into CI, scoped pipeline permissions, is genuinely cross-cutting work that touches DevOps, security, and every team shipping code, and it's easy to underestimate the ongoing maintenance this requires as dependencies constantly shift underneath a project. This is exactly where &lt;strong&gt;&lt;a href="https://zignuts.com/ai-services/enterprise-ai/ai-security-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;AI security&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://zignuts.com/ai-services/enterprise-ai/ai-infrastructure-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;AI infrastructure&lt;/a&gt;&lt;/strong&gt; work increasingly overlaps with traditional DevSecOps too, since teams running models in production now need the same rigor applied to &lt;strong&gt;&lt;a href="https://zignuts.com/ml-services/mlops/ml-ci-cd?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;ML CI/CD&lt;/a&gt;&lt;/strong&gt; pipelines, model governance, and compliance around training data provenance that they'd apply to any other dependency chain. Getting this foundation right early, across both code and model infrastructure, is a lot cheaper than untangling it after an incident.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;The vulnerability that takes down your build was never guaranteed to be one your own team wrote. Most modern software is built on a foundation of trust in dependencies nobody on the team has actually reviewed, and that trust is exactly what attackers are exploiting at scale right now. Treating supply chain security as core infrastructure, not an afterthought, is quickly becoming table stakes rather than a nice-to-have.&lt;/p&gt;

&lt;p&gt;Has your team actually built out SBOM tooling and automated dependency scanning yet, or is this still sitting on the someday list? Curious how far along everyone actually is with this.&lt;/p&gt;

</description>
      <category>devsecops</category>
      <category>security</category>
      <category>cicd</category>
      <category>discuss</category>
    </item>
    <item>
      <title>7 AI Integration Mistakes I Keep Seeing Teams Make in 2026</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Tue, 18 Aug 2026 05:32:29 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/7-ai-integration-mistakes-i-keep-seeing-teams-make-in-2026-djd</link>
      <guid>https://dev.to/emma_schmidt_/7-ai-integration-mistakes-i-keep-seeing-teams-make-in-2026-djd</guid>
      <description>&lt;p&gt;I don't write about &lt;strong&gt;&lt;a href="https://zignuts.com/ai-services/ai-integration?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;AI integration&lt;/a&gt;&lt;/strong&gt; failures because they're rare.&lt;/p&gt;

&lt;p&gt;I write about them because I keep seeing the exact same ones, on different teams, in different industries, month after month.&lt;/p&gt;

&lt;p&gt;A mistake earns a spot on this list when I've watched it happen more than once. Not a one-off bad decision. A pattern.&lt;/p&gt;

&lt;p&gt;I've spent a lot of time this year looking closely at how companies actually bring AI into existing products, not the demo version, the real production version with real users and real data on the line.&lt;/p&gt;

&lt;p&gt;These are the seven mistakes that showed up again and again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Treating AI Integration Like a Feature Flag&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Repository of thought: "we'll just bolt it on and see how it goes."&lt;/p&gt;

&lt;p&gt;I get why this feels reasonable. Ship fast, learn fast, iterate. But AI features aren't like a new button on a page. They touch data flow, user trust, and cost in ways a typical feature toggle doesn't.&lt;/p&gt;

&lt;p&gt;The teams that get burned here usually find out the hard way, weeks later, when the "quick add" needs a rewrite because nobody thought about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where the data actually comes from&lt;/li&gt;
&lt;li&gt;What happens when the model is wrong&lt;/li&gt;
&lt;li&gt;How much this costs at real usage volume&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Skipping the "What Happens When It's Wrong" Conversation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every demo works. Every demo is cherry-picked, even unintentionally.&lt;/p&gt;

&lt;p&gt;The conversation that actually matters happens after the demo: what does the user see when the AI confidently gives a wrong answer? Is there a fallback? Is there a way to flag it? Does anyone even find out it happened?&lt;/p&gt;

&lt;p&gt;I've watched teams skip this conversation entirely and only have it for the first time after a customer complaint. That's the wrong order.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. No Evaluation Loop, Just Vibes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"It feels like it's working well" is not a metric.&lt;/p&gt;

&lt;p&gt;Teams that are serious about this build some kind of evaluation loop, a way to systematically check output quality against known good examples, before shipping and continuously after. Teams that skip this find out their AI feature quietly got worse three months in, and nobody noticed until a user did.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Underestimating the Data Quality Problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This one isn't glamorous, which is probably why it gets skipped so often.&lt;/p&gt;

&lt;p&gt;AI integration is only as good as the data feeding it. I've seen teams spend weeks tuning a &lt;strong&gt;&lt;a href="https://zignuts.com/llm-genai-services/prompt-engineering/prompt-design-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;prompt&lt;/a&gt;&lt;/strong&gt; to fix a problem that was actually a data quality issue the whole time. Messy, inconsistent, or outdated source data will sink an otherwise well-built integration every time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. One Model, No Fallback&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Betting an entire feature on a single model provider with no fallback plan is a real, recurring pattern I keep seeing.&lt;/p&gt;

&lt;p&gt;What happens when that provider has an outage. What happens when pricing changes overnight. What happens when a model update shifts behavior in a way that breaks your carefully tuned prompts.&lt;/p&gt;

&lt;p&gt;Teams that plan for this from day one recover from disruptions in hours. Teams that don't scramble for days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Governance as an Afterthought&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the one that worries me most, because it's invisible until it's a real problem.&lt;/p&gt;

&lt;p&gt;Who's responsible for reviewing what the AI feature actually does. Who signs off on it touching sensitive data. Who's accountable if it produces something harmful or wrong in a regulated context. If nobody can answer these clearly, that's the actual gap, not a hypothetical one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Measuring the Wrong Thing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"We shipped an AI feature" isn't a success metric. Neither is "users are using it."&lt;/p&gt;

&lt;p&gt;The teams doing this well are measuring whether the feature actually improved the outcome it was supposed to improve, resolution time, task completion, accuracy against a real baseline. Everything else is activity dressed up as progress.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Quick Table, Because Patterns Are Easier to See This Way&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mistake&lt;/th&gt;
&lt;th&gt;What It Actually Costs You&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bolting AI on like a feature flag&lt;/td&gt;
&lt;td&gt;Rework once real data and edge cases show up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No plan for wrong answers&lt;/td&gt;
&lt;td&gt;Trust erosion the first time a user hits one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No evaluation loop&lt;/td&gt;
&lt;td&gt;Silent quality drift nobody catches in time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ignoring data quality&lt;/td&gt;
&lt;td&gt;Wasted weeks tuning prompts that were never the real problem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No fallback model&lt;/td&gt;
&lt;td&gt;Full outages instead of graceful degradation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No governance ownership&lt;/td&gt;
&lt;td&gt;A real incident with no clear accountability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vanity metrics&lt;/td&gt;
&lt;td&gt;Confidently shipping something that isn't actually working&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What I'd Tell a Team Starting This Today&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Slow down on the parts that feel boring. Data quality, evaluation, &lt;strong&gt;&lt;a href="https://zignuts.com/ai-services/enterprise-ai/ai-governance-consulting-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;governance&lt;/a&gt;&lt;/strong&gt;, none of it is exciting, all of it is where the real risk actually lives.&lt;/p&gt;

&lt;p&gt;The AI part is usually not the hard part anymore. The hard part is everything around it, the parts that don't show up in a demo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;None of these seven mistakes are exotic. They're not edge cases. They're the ordinary, predictable ways AI integration goes sideways when a team moves fast without slowing down for the boring, unglamorous parts.&lt;/p&gt;

&lt;p&gt;I don't think that's a knock on any team that's hit one of these. I've watched genuinely sharp engineers walk into every single one of them, because the pressure to ship fast is real and these mistakes are easy to make with the best of intentions.&lt;/p&gt;

&lt;p&gt;If you're integrating AI into a real product right now, I'd rather you catch these on paper than in production.&lt;/p&gt;

&lt;p&gt;Which of these have you actually run into? Curious how many of these seven are familiar to people reading this.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>discuss</category>
      <category>softwaredevelopment</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Top AI Coding Tools Every Developer Should Know in 2026</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Mon, 17 Aug 2026 12:56:58 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/top-ai-coding-tools-every-developer-should-know-in-2026-51j4</link>
      <guid>https://dev.to/emma_schmidt_/top-ai-coding-tools-every-developer-should-know-in-2026-51j4</guid>
      <description>&lt;p&gt;A year ago, "AI coding assistant" mostly meant autocomplete on steroids. In 2026, that's no longer true. We've moved from &lt;strong&gt;inline suggestions&lt;/strong&gt; to &lt;strong&gt;&lt;a href="https://zignuts.com/agentic-ai-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;agentic AI&lt;/a&gt;&lt;/strong&gt; tools that can plan a task, write across multiple files, run your test suite, and fix their own mistakes before you even open the diff.&lt;/p&gt;

&lt;p&gt;If you're a developer trying to figure out which tools are actually worth wiring into your workflow (and which are just hype), this guide breaks it down: what's changed, how to evaluate these tools, a side-by-side comparison, and a practical framework for adopting them on a real engineering team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Shift Matters
&lt;/h2&gt;

&lt;p&gt;The jump from "autocomplete" to "agent" isn't just a marketing term. It changes &lt;em&gt;how&lt;/em&gt; you work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Autocomplete-era tools&lt;/strong&gt; predicted the next few lines of code based on context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chat-era tools&lt;/strong&gt; let you ask questions and get code snippets back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agentic-era tools&lt;/strong&gt; take a goal ("add pagination to this &lt;strong&gt;&lt;a href="https://zignuts.com/ai-services/custom-ai-development/ai-api-development-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;API&lt;/a&gt;&lt;/strong&gt; and update the tests"), break it into steps, execute those steps across your codebase, and self-correct using tool feedback like compiler errors or failing tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last category is what's driving real productivity gains right now but it also introduces new questions around code review, security, and trust that teams need a process for, not just a tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Evaluate an AI Coding Tool
&lt;/h2&gt;

&lt;p&gt;Before comparing specific products, it helps to have a checklist. Here's what actually matters when you're picking a tool for a team (not just a solo side project):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context window &amp;amp; codebase awareness&lt;/strong&gt;: Can it reason across your whole repo, or just the open file?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agentic capability&lt;/strong&gt;: Can it execute multi-step tasks (run tests, fix errors, open a PR) or only suggest text?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IDE / CLI fit&lt;/strong&gt;: Does it live where your team already works, or does it force a workflow change?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security &amp;amp; data handling&lt;/strong&gt;: Where does your code go? Is there an enterprise/on-prem option?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost model&lt;/strong&gt;: Per-seat, usage-based, or bundled into an existing subscription?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review friction&lt;/strong&gt;: Does it produce diffs a human can review quickly, or large unreviewable rewrites?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparison: Popular AI Coding Tools in 2026
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;th&gt;Works In&lt;/th&gt;
&lt;th&gt;Agentic?&lt;/th&gt;
&lt;th&gt;Notable Strength&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Copilot&lt;/td&gt;
&lt;td&gt;General-purpose autocomplete + chat&lt;/td&gt;
&lt;td&gt;VS Code, JetBrains, GitHub.com&lt;/td&gt;
&lt;td&gt;Partial (Copilot Workspace)&lt;/td&gt;
&lt;td&gt;Deep GitHub/PR integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;Terminal-first, multi-file agentic coding&lt;/td&gt;
&lt;td&gt;CLI, VS Code, JetBrains&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Strong reasoning on large refactors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor&lt;/td&gt;
&lt;td&gt;AI-native IDE experience&lt;/td&gt;
&lt;td&gt;Standalone editor (VS Code fork)&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Tight inline editing + chat loop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon Q Developer&lt;/td&gt;
&lt;td&gt;AWS-centric teams&lt;/td&gt;
&lt;td&gt;IDEs, AWS Console&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Native AWS service knowledge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windsurf&lt;/td&gt;
&lt;td&gt;Agentic pair-programming&lt;/td&gt;
&lt;td&gt;Standalone editor&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;"Flow" mode for long tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tabnine&lt;/td&gt;
&lt;td&gt;Privacy-conscious teams&lt;/td&gt;
&lt;td&gt;Most major IDEs&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Self-hosted / on-prem options&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Note: this landscape moves fast pricing, features, and even product names shift every few months, so treat this as a snapshot rather than a permanent ranking. Always check the vendor's docs before committing a team to one.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Adoption Framework
&lt;/h2&gt;

&lt;p&gt;Handing an entire engineering org an AI coding tool on day one usually backfires you get inconsistent usage, review bottlenecks, and skepticism from senior engineers who've been burned by low-quality AI output. A more reliable rollout looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pilot with a small, willing team&lt;/strong&gt;: on a real (but non-critical) project for 2–4 weeks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define review rules&lt;/strong&gt;: e.g., AI-generated PRs still require the same review bar as human ones, no exceptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track outcomes, not vibes&lt;/strong&gt;: cycle time, bug rate, and PR size are better signals than "it feels faster."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standardize the toolchain&lt;/strong&gt;: so context (style guides, architecture docs) is shared across the team instead of living in one engineer's prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revisit quarterly&lt;/strong&gt;:this space changes fast enough that a tool decision from six months ago may already be outdated.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is close to how engineering teams evaluate any new dependency: agentic AI coding tools are powerful, but they still need the same rigor as any other addition to a production workflow. Teams that treat AI tooling as an accelerant for experienced engineers not a replacement for code review and architecture decisions tend to get the most durable results.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Quick Example: Agentic Refactor in Practice
&lt;/h2&gt;

&lt;p&gt;Here's a simplified illustration of the kind of task an agentic tool can now handle end-to-end, versus what you'd have done manually a year ago:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Old way: you write the prompt, get a snippet, paste it, fix imports, run tests manually&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ai &lt;span class="s2"&gt;"write a function to paginate this list"&lt;/span&gt;

&lt;span class="c"&gt;# Agentic way: the tool plans, edits multiple files, runs tests, and reports back&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;agent run &lt;span class="s2"&gt;"add cursor-based pagination to /api/users, update the OpenAPI spec, and make the existing tests pass"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Example output the agent might produce and then validate against your test suite
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;paginate_users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;next_cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;next_cursor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;next_cursor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference isn't the code itself it's that the agent verified the change against your real test suite before handing it back, closing the loop that used to require a human every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where This Is Heading
&lt;/h2&gt;

&lt;p&gt;A few trends worth watching as 2026 progresses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agentic AI moving from "assistant" to "team member"&lt;/strong&gt;: tools that pick up tickets, open draft PRs, and tag humans only when they're stuck.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-driven workflow automation&lt;/strong&gt;: spreading beyond coding into project management, QA, and DevOps pipelines not just writing code, but operating around it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low-code/no-code and pro-code converging&lt;/strong&gt;: with AI acting as the translation layer between visual builders and hand-written code for teams that outgrow no-code tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stronger emphasis on governance&lt;/strong&gt;: code provenance, license compliance, and audit trails for AI-generated code, especially in regulated industries like fintech and healthcare.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;AI coding tools in 2026 aren't a novelty anymore they're infrastructure. The teams getting the most value aren't the ones chasing every new tool, but the ones treating adoption like any other engineering decision: pilot it, measure it, standardize it, and keep your review bar exactly where it was before AI showed up.&lt;/p&gt;

&lt;p&gt;If you're building out this kind of process for your own team, start small, measure real outcomes, and resist the urge to lower your review bar just because the code came from an agent instead of a human.&lt;/p&gt;




</description>
      <category>ai</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Your AI Chatbot Forgets Everything the Moment You Close the Tab. Here's the Fix Nobody's Talking About Yet.</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Wed, 05 Aug 2026 05:18:19 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/your-ai-chatbot-forgets-everything-the-moment-you-close-the-tab-heres-the-fix-nobodys-talking-1iob</link>
      <guid>https://dev.to/emma_schmidt_/your-ai-chatbot-forgets-everything-the-moment-you-close-the-tab-heres-the-fix-nobodys-talking-1iob</guid>
      <description>&lt;p&gt;Ask a typical RAG-powered &lt;a href="https://zignuts.com/llm-genai-services/ai-chatbot-development/internal-ai-assistant-development?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;AI assistant&lt;/a&gt; a follow-up question that depends on something you mentioned three messages ago, and watch it quietly lose the thread. Standard retrieval-augmented generation is excellent at pulling relevant chunks of text based on similarity, and genuinely terrible at understanding how pieces of information actually relate to each other or persisting what it learned about you across a session. This exact gap is what's pushing serious AI application development toward &lt;strong&gt;&lt;a href="https://zignuts.com/blog/graphrag-contextual-memory-smart-app?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;GraphRAG&lt;/a&gt;&lt;/strong&gt; and contextual memory, two of the fastest-moving concepts in AI architecture right now.&lt;/p&gt;

&lt;p&gt;Here's what's actually broken with traditional RAG, what GraphRAG and contextual memory do differently, and how to think about building with them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Standard RAG Hits a Wall
&lt;/h2&gt;

&lt;p&gt;Traditional RAG works by chunking &lt;a href="https://zignuts.com/ai-services/ai-workflow-automation/ai-document-automation-solutions?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;documents&lt;/a&gt;, embedding them, and retrieving the chunks most semantically similar to a user's query. It's simple, effective for straightforward lookup questions, and has become the default pattern for grounding AI responses in real data.&lt;/p&gt;

&lt;p&gt;It also has real, well-known limitations that show up quickly in production.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Limitation&lt;/th&gt;
&lt;th&gt;What It Looks Like in Practice&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No relationship awareness&lt;/td&gt;
&lt;td&gt;Retrieves individual chunks but misses how entities and facts connect across documents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weak multi-hop reasoning&lt;/td&gt;
&lt;td&gt;Struggles with questions requiring several linked facts, like "which vendor supplies the part used in the product that failed last quarter"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No persistent memory&lt;/td&gt;
&lt;td&gt;Each query is treated in isolation, with no real understanding of what happened earlier in the conversation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chunking artifacts&lt;/td&gt;
&lt;td&gt;Splitting documents into fixed-size chunks can sever context that spans a chunk boundary, losing meaning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redundant retrieval&lt;/td&gt;
&lt;td&gt;Similar chunks from different documents often surface together, adding noise instead of new information&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;None of this makes standard RAG useless. It makes it a genuinely good starting point that runs out of runway the moment your application needs to reason across relationships or remember anything meaningfully across turns.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Concrete Example of Where This Breaks Down
&lt;/h2&gt;

&lt;p&gt;Picture an internal AI assistant built for a mid-sized company's operations team, trained on years of vendor contracts, compliance documents, and internal policy memos. Someone asks: "Which of our vendors would be affected if the new data residency policy applies to our EU contracts?"&lt;/p&gt;

&lt;p&gt;A standard RAG setup retrieves chunks mentioning "vendors," separately retrieves chunks mentioning "data residency policy," and separately retrieves chunks mentioning "EU contracts." Nothing in that retrieval step actually confirms which vendors are tied to which contracts, or which contracts fall under EU jurisdiction. The model is left to guess at the connections from loosely related text, and in a compliance context, a confident guess dressed up as an answer is genuinely dangerous.&lt;/p&gt;

&lt;p&gt;This is exactly the class of failure that pushed graph-based approaches from a research curiosity into a real production pattern this year, anywhere the cost of a wrong but confident-sounding answer is high.&lt;/p&gt;

&lt;h2&gt;
  
  
  What GraphRAG Actually Changes
&lt;/h2&gt;

&lt;p&gt;GraphRAG restructures the underlying knowledge as a graph, entities as nodes, relationships as edges, instead of a flat collection of embedded text chunks. Instead of retrieving isolated pieces of text based purely on similarity, the system can traverse relationships to answer questions that require connecting multiple facts together.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Entity-relationship structure.&lt;/strong&gt; Facts aren't just stored, they're connected: a product links to its supplier, which links to a region, which links to a regulation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-hop query support.&lt;/strong&gt; A question requiring three connected facts can be answered by traversing the graph, rather than hoping all three facts happen to land in the same retrieved chunk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community-level summarization.&lt;/strong&gt; Graph-based approaches can summarize entire clusters of related entities, giving a system a genuine overview rather than a pile of disconnected snippets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better handling of sparse or niche domains.&lt;/strong&gt; Where a document corpus is small or highly specialized, relationship structure often surfaces relevant context that pure similarity search misses entirely&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How a Knowledge Graph Actually Gets Built
&lt;/h2&gt;

&lt;p&gt;It's worth demystifying this a bit, since "build a knowledge graph" can sound more exotic than the actual process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Entity extraction.&lt;/strong&gt; An initial pass through the source documents identifies key entities, people, products, organizations, regulations, dates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Relationship extraction.&lt;/strong&gt; A second pass identifies how those entities connect, which vendor supplies which product, which contract falls under which jurisdiction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graph construction.&lt;/strong&gt; Entities become nodes and relationships become edges, forming a structured map of the underlying data instead of a flat pile of text chunks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community detection.&lt;/strong&gt; Related clusters of nodes get grouped, which enables the community-level summarization that flat retrieval simply can't produce&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing maintenance.&lt;/strong&gt; As source documents update, the graph needs re-processing to reflect new entities and relationships, which is the step most teams underestimate when planning a build&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Contextual Memory: The Other Half of the Problem
&lt;/h2&gt;

&lt;p&gt;GraphRAG solves the relationship problem. Contextual memory solves the persistence problem, the part where a system actually remembers relevant information across a conversation or across sessions, instead of starting from zero every single time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Short-term working memory&lt;/strong&gt; tracks what's been discussed in the current session, so a follow-up question doesn't need to restate context the user already gave&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long-term memory&lt;/strong&gt; persists meaningful facts about a user or task across sessions, a returning customer's preferences, a project's ongoing status, a prior decision that shouldn't need repeating&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selective memory, not total recall&lt;/strong&gt; matters just as much as remembering. A well-designed system decides what's actually worth retaining rather than storing every message verbatim, which keeps retrieval fast and relevant instead of bloated&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Different Approaches to Implementing Memory
&lt;/h2&gt;

&lt;p&gt;Not all contextual memory systems work the same way, and picking the right approach matters.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;How It Works&lt;/th&gt;
&lt;th&gt;Best Suited For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sliding window&lt;/td&gt;
&lt;td&gt;Keeps the last N messages in full&lt;/td&gt;
&lt;td&gt;Short interactions where recent context is all that matters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Summarization-based&lt;/td&gt;
&lt;td&gt;Periodically compresses older turns into a running summary&lt;/td&gt;
&lt;td&gt;Longer conversations where full detail on early turns matters less over time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fact extraction&lt;/td&gt;
&lt;td&gt;Pulls out specific durable facts and stores them separately from the raw conversation&lt;/td&gt;
&lt;td&gt;Cross-session persistence, like remembering a user's stated preferences&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hybrid&lt;/td&gt;
&lt;td&gt;Combines a short-term window with extracted long-term facts&lt;/td&gt;
&lt;td&gt;Most production systems, balancing responsiveness with genuine persistence&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Most serious production systems end up using some version of the hybrid approach, since a sliding window alone can't persist across sessions, and pure summarization alone tends to lose specific, useful details that fact extraction preserves.&lt;/p&gt;

&lt;h2&gt;
  
  
  How These Two Pieces Fit Together
&lt;/h2&gt;

&lt;p&gt;GraphRAG and contextual memory solve different problems, and the strongest AI applications right now are combining both rather than picking one.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GraphRAG handles reasoning across your knowledge base, connecting facts that live in different documents or records&lt;/li&gt;
&lt;li&gt;Contextual memory handles reasoning across the conversation itself, remembering what the user already told the system&lt;/li&gt;
&lt;li&gt;Together, they let an AI application answer a question like "does this apply to the client I mentioned earlier, given the update we discussed last week" by pulling both the relationship structure from the knowledge graph and the recalled context from memory&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Simplified Illustration of the Difference
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Standard RAG on a multi-hop question:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which of our suppliers are affected by the new import regulation?"&lt;br&gt;
Retrieves chunks mentioning "suppliers" and chunks mentioning "import regulation" separately, with no guarantee the system connects which supplier is actually affected by which regulation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;GraphRAG on the same question:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Traverses supplier nodes connected to region nodes connected to regulation nodes, returning the specific suppliers actually linked to the affected region, because that relationship is explicitly modeled rather than inferred from text similarity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Add contextual memory:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the user previously said "we're focused on our European suppliers this quarter," the system recalls that context and narrows the answer accordingly, without the user needing to repeat it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where Teams Get This Wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Jumping to GraphRAG for every use case&lt;/strong&gt;, when a simple, well-chunked standard RAG setup is genuinely sufficient for straightforward lookup tasks and adds unnecessary complexity for no real benefit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building memory that stores everything indiscriminately&lt;/strong&gt;, which bloats retrieval and actually makes responses slower and noisier rather than smarter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treating graph construction as a one-time task&lt;/strong&gt;, when knowledge graphs need ongoing maintenance as entities and relationships change over time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring evaluation entirely&lt;/strong&gt;, shipping a GraphRAG or memory system without a way to systematically test whether it's actually improving answer quality over the simpler baseline it replaced&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conflating memory with logging&lt;/strong&gt;, storing raw conversation history and calling it memory, without any real process for deciding what's actually worth retaining long term&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Quick Framework for Deciding What You Need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Does your use case genuinely require connecting facts across multiple documents or records, or are most queries simple, single-fact lookups?&lt;/li&gt;
&lt;li&gt;Does your application need to remember information across turns or sessions, or is each interaction naturally self-contained?&lt;/li&gt;
&lt;li&gt;Do you have the ongoing resources to maintain a knowledge graph as your underlying data evolves?&lt;/li&gt;
&lt;li&gt;How costly is a wrong but confident-sounding answer in your specific use case? The higher that cost, the stronger the case for the added structure GraphRAG provides&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Questions Teams Ask When Evaluating This
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does GraphRAG replace standard RAG entirely?&lt;/strong&gt;&lt;br&gt;
No, most production systems use both together. Simple lookups can still go through standard retrieval, while multi-hop reasoning questions route through the graph.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does this increase latency?&lt;/strong&gt;&lt;br&gt;
Graph traversal adds some overhead compared to a single similarity search, though well-indexed graphs with efficient traversal patterns keep this manageable for most interactive use cases. Benchmarking on your actual data is essential rather than assuming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is this only worth it for large enterprises?&lt;/strong&gt;&lt;br&gt;
No. Smaller, highly specialized domains often benefit even more, since sparse document corpora are exactly where relationship structure tends to add the most value over pure similarity search.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Is Worth Building Properly
&lt;/h2&gt;

&lt;p&gt;Getting graph construction, retrieval traversal, and memory persistence right together is genuinely more involved than standing up a basic RAG pipeline, and it's easy to underestimate the ongoing maintenance a knowledge graph requires as your data changes. This is exactly the kind of &lt;a href="https://zignuts.com/llm-genai-services/rag-development?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=8" rel="noopener noreferrer"&gt;RAG development&lt;/a&gt; and AI application architecture work that separates a genuinely smarter AI app from one that just looks smart in a demo, and it's usually worth getting a second opinion on before committing to a full build.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;Standard RAG got a lot of AI applications off the ground, and it's still the right choice for plenty of use cases. But the moment an application needs to reason across relationships or remember anything meaningfully across a conversation, that flat, isolated retrieval model runs out of road fast. GraphRAG and contextual memory are exactly the pair of ideas closing that gap this year, and understanding when you actually need them, not just how to build them, is quickly becoming a core skill for anyone building serious AI products.&lt;/p&gt;

&lt;p&gt;Has your team started experimenting with GraphRAG or persistent memory yet, or is standard RAG still handling everything you're throwing at it? Curious how far along everyone actually is with this.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>llm</category>
      <category>genai</category>
    </item>
    <item>
      <title>Your App Has AI Features. That's Not the Same Thing as Being an AI Company Anymore.</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Fri, 31 Jul 2026 10:48:07 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/your-app-has-ai-features-thats-not-the-same-thing-as-being-an-ai-company-anymore-5a0n</link>
      <guid>https://dev.to/emma_schmidt_/your-app-has-ai-features-thats-not-the-same-thing-as-being-an-ai-company-anymore-5a0n</guid>
      <description>&lt;p&gt;There's a quiet but important distinction reshaping how serious software gets built in 2026, and most teams haven't caught up to it yet. Bolting a chatbot onto an existing app and designing an application where AI is the actual architecture are two completely different engineering disciplines, and the gap between them is becoming one of the clearest competitive differentiators in software today. This is exactly the shift driving demand for real &lt;strong&gt;&lt;a href="https://zignuts.com/ai-services/custom-ai-development?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;custom AI development&lt;/a&gt;&lt;/strong&gt;, not a plugin added after the fact, but AI woven into how a system makes decisions, processes data, and adapts from the very first architectural diagram.&lt;/p&gt;

&lt;p&gt;Here's what actually separates AI-native software from AI-enhanced software, why the distinction matters more than it sounds, and how to think about it if you're planning a build.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI-Enhanced vs AI-Native: The Real Difference
&lt;/h2&gt;

&lt;p&gt;Most existing "AI-powered" products today are AI-enhanced. A traditional application, built the same way it always would have been, with a recommendation widget, a search-with-AI feature, or a support &lt;strong&gt;&lt;a href="https://zignuts.com/chatbot-development-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;chatbot&lt;/a&gt;&lt;/strong&gt; added on top. The underlying system, its data flow, its decision logic, its architecture, remains essentially unchanged.&lt;/p&gt;

&lt;p&gt;An AI-native application is architected differently from day one. Intelligence isn't a feature sitting on top, it's part of how the system actually functions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;AI-Enhanced&lt;/th&gt;
&lt;th&gt;AI-Native&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Where AI sits&lt;/td&gt;
&lt;td&gt;Bolted on as a feature or module&lt;/td&gt;
&lt;td&gt;Built into the core architecture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data flow&lt;/td&gt;
&lt;td&gt;Static, mostly predefined&lt;/td&gt;
&lt;td&gt;Continuous, feeding real-time model decisions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adaptability&lt;/td&gt;
&lt;td&gt;Fixed behavior between releases&lt;/td&gt;
&lt;td&gt;Learns and adjusts from ongoing data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical origin&lt;/td&gt;
&lt;td&gt;Retrofit of an existing product&lt;/td&gt;
&lt;td&gt;Designed around AI from the first architecture decision&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failure mode when done poorly&lt;/td&gt;
&lt;td&gt;AI feature feels bolted on, inconsistent with the rest of the app&lt;/td&gt;
&lt;td&gt;Poor governance and evaluation gaps compound across the whole system&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Neither approach is inherently wrong. A lot of genuinely good products are AI-enhanced and don't need to be anything else. But for products where intelligence is meant to be the actual value proposition, retrofitting an existing architecture tends to be far more expensive and painful than building AI-native from the start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Shift Is Happening Now
&lt;/h2&gt;

&lt;p&gt;A few forces are converging to push serious teams toward AI-native thinking rather than incremental AI feature additions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Retrofitting is proving genuinely costly.&lt;/strong&gt; Teams that added AI as an afterthought are running into architectural walls, data pipelines that weren't built for continuous model input, decision logic that was never designed to be adaptive, and it's turning into expensive rework rather than a quick feature addition&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluation and observability are now considered table stakes, not extras.&lt;/strong&gt; Serious AI development in 2026 increasingly means having real evaluation pipelines that systematically test outputs against known-good examples, not just shipping a prompt and hoping it behaves&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security expectations have caught up with adoption.&lt;/strong&gt; Prompt injection, data exfiltration through AI interfaces, and output manipulation are now treated as real attack vectors, which means the AI layer needs the same security discipline as any other system boundary, not a bolted-on afterthought&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-model orchestration is becoming a standard architectural component.&lt;/strong&gt; Rather than routing everything through one model, AI-native systems increasingly route different tasks to different models based on cost, latency, and capability, which only works cleanly if the architecture was designed with that flexibility in mind&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What AI-Native Architecture Actually Requires
&lt;/h2&gt;

&lt;p&gt;Building this way touches more of the stack than a typical feature addition would.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data pipelines designed for continuous flow&lt;/strong&gt;, not periodic batch updates, since adaptive systems need fresh data to actually adapt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluation infrastructure built in from the start&lt;/strong&gt;, tracking output quality, catching model regressions, and validating behavior against real, known-good examples&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear governance around AI decision-making&lt;/strong&gt;, especially for anything touching regulated data or high-stakes outcomes, where explainability and audit trails matter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architecture flexible enough for multi-model routing&lt;/strong&gt;, so the system isn't locked into a single model provider or a single point of failure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security treated as a first-class concern for the AI layer specifically&lt;/strong&gt;, not assumed to be covered by the same protections as the rest of the application&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Scenarios Where This Distinction Actually Matters
&lt;/h2&gt;

&lt;p&gt;To make this concrete, here's where the AI-native versus AI-enhanced choice genuinely changes the outcome.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A support platform&lt;/strong&gt; adding a chatbot to an existing ticketing system is AI-enhanced. A support platform where routing, prioritization, and resolution suggestions are all driven continuously by live data from the start is AI-native, and it behaves fundamentally differently as ticket volume and complexity grow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A financial analytics tool&lt;/strong&gt; with an AI summary feature bolted onto existing dashboards is AI-enhanced. One where risk scoring and forecasting are core to how the system processes every transaction is AI-native&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An internal knowledge tool&lt;/strong&gt; with search-with-AI added to an existing wiki is AI-enhanced. One built around continuously updated embeddings and adaptive retrieval from the ground up is AI-native&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A logistics platform&lt;/strong&gt; with a recommendation widget for routing suggestions is AI-enhanced. One where routing decisions are made continuously by an adaptive model integrated into the core dispatch logic is AI-native&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where Teams Get This Wrong
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Assuming AI-native means "use more AI features."&lt;/strong&gt; It's an architectural distinction, not a feature count. A product can have fewer visible AI features and still be genuinely AI-native if intelligence is core to how it functions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skipping the evaluation and governance layer to move faster.&lt;/strong&gt; This is the corner that gets cut most often, and it's the one that causes the most expensive problems later, once the system is handling real production decisions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treating security as something to add after the AI features work.&lt;/strong&gt; By the time an AI-native system is live, retrofitting proper security around prompt handling and data access is far harder than designing it in from the start&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Underestimating the data infrastructure work.&lt;/strong&gt; Teams often plan for the model and the interface, but underestimate how much of the actual effort lives in the data pipelines that feed continuous, adaptive behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Quick Framework for Deciding What You Actually Need
&lt;/h2&gt;

&lt;p&gt;Before committing to a full AI-native rebuild, it's worth being honest about which category your product actually falls into.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is intelligence the core value proposition, or a helpful addition to a product that works fine without it?&lt;/li&gt;
&lt;li&gt;Does your system need to adapt continuously based on new data, or would periodic updates genuinely be sufficient?&lt;/li&gt;
&lt;li&gt;Do you have, or are you willing to build, the evaluation and governance infrastructure this approach requires?&lt;/li&gt;
&lt;li&gt;Is your team prepared for the security implications of treating the AI layer as a first-class system boundary?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the honest answer to the first two questions is "yes, genuinely," AI-native architecture is worth the upfront investment. If AI is a nice complement to an otherwise solid, deterministic product, a well-built AI-enhanced approach is often the more practical, lower-risk choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Is Genuinely Hard to Get Right Alone
&lt;/h2&gt;

&lt;p&gt;This isn't a criticism of any team, it's just an honest reflection of how new and fast-moving this discipline still is. The specific technical profile this requires, deep experience across data pipeline design, model evaluation, multi-model orchestration, and AI-specific security, remains genuinely scarce in most hiring markets right now. That's exactly why a lot of serious &lt;strong&gt;&lt;a href="https://zignuts.com/ai-services/custom-ai-development/ai-software-development-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;AI software development&lt;/a&gt;&lt;/strong&gt; work today involves custom AI development support and &lt;strong&gt;&lt;a href="https://zignuts.com/ai-services/ai-consulting/ai-readiness-assessment-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;AI readiness assessment&lt;/a&gt;&lt;/strong&gt; brought in from outside, specifically to architect the foundation correctly before a team commits to a direction that's expensive to unwind later. Getting an experienced second opinion on whether a product genuinely needs full AI-native architecture, or whether a well-built AI-enhanced approach would serve it just as well, is often the highest-leverage conversation to have before writing a single line of the core architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future Outlook
&lt;/h2&gt;

&lt;p&gt;The gap between AI-enhanced and AI-native products is likely to keep widening over the next year or two, not narrow. As evaluation tooling matures and multi-model orchestration becomes more standardized, AI-native architecture is expected to shift from a differentiator into a baseline expectation, particularly for products where intelligence genuinely is the value proposition rather than a nice-to-have layered on top.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;Having AI features and being architected as an AI company are not the same thing, and that distinction is only going to matter more as the products competing for the same users diverge further along these two paths. The teams thinking carefully now about whether they genuinely need AI-native architecture, versus a solid, well-built AI-enhanced product, are the ones avoiding the expensive retrofit conversation a year or two from now.&lt;/p&gt;

&lt;p&gt;Is your product built AI-native from the ground up, or is it AI-enhanced with intelligence layered on top? Curious where most teams here actually land on that distinction once they think it through honestly.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>machinelearning</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Build Your First MCP Server: A Practical Guide to Connecting AI Agents to Real Tools</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Thu, 30 Jul 2026 06:43:25 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/build-your-first-mcp-server-a-practical-guide-to-connecting-ai-agents-to-real-tools-2o43</link>
      <guid>https://dev.to/emma_schmidt_/build-your-first-mcp-server-a-practical-guide-to-connecting-ai-agents-to-real-tools-2o43</guid>
      <description>&lt;p&gt;Learn how to build a working MCP server from scratch and connect it to an AI client, step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you've ever needed an &lt;strong&gt;&lt;a href="https://zignuts.com/llm-genai-services/ai-agent-development?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;AI agent&lt;/a&gt;&lt;/strong&gt; to check a database, call an internal API, or search a knowledge base, you've probably hit the same wall: every tool integration ends up as custom, one-off code that doesn't transfer to your next project. MCP server development and &lt;strong&gt;&lt;a href="https://zignuts.com/llm-genai-services/multi-agent-systems/mcp-integration-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;MCP integration &lt;/a&gt;&lt;/strong&gt;solve this by giving you one standardized way to expose any tool or data source to any compatible AI client, instead of writing bespoke glue code for every combination.&lt;/p&gt;

&lt;p&gt;This tutorial walks through building an actual working&lt;a href="https://zignuts.com/llm-genai-services/mcp-development/mcp-server-development-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt; &lt;strong&gt;MCP server&lt;/strong&gt;&lt;/a&gt;, connecting it to a client, and testing that it works end to end. By the end, you'll have a functioning server exposing a real tool, and you'll understand exactly what's happening at each layer instead of just copying a snippet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Comfortable reading and writing basic Python&lt;/li&gt;
&lt;li&gt;Python 3.10 or later installed&lt;/li&gt;
&lt;li&gt;A terminal and a code editor&lt;/li&gt;
&lt;li&gt;Roughly 30-45 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What We're Building
&lt;/h2&gt;

&lt;p&gt;We're building a small MCP server that exposes one practical tool: looking up the weather for a given city. It's simple enough to fully understand in one sitting, but it demonstrates every core piece of setting up MCP tool integration.&lt;/p&gt;

&lt;p&gt;The finished server will be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Advertise its available tools to any connecting MCP client&lt;/li&gt;
&lt;li&gt;Accept a tool call with a specific input (a city name)&lt;/li&gt;
&lt;li&gt;Return a structured response back to the calling AI agent&lt;/li&gt;
&lt;li&gt;Run locally so you can test it directly from your terminal&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Set Up Your Environment
&lt;/h2&gt;

&lt;p&gt;Create a project folder and install the MCP SDK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;mcp-weather-server
&lt;span class="nb"&gt;cd &lt;/span&gt;mcp-weather-server
python &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate  &lt;span class="c"&gt;# on Windows use venv\Scripts\activate&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;mcp requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you the core MCP library plus &lt;code&gt;requests&lt;/code&gt;, which we'll use to call a public weather API inside our tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Define the Server and Register Your Tool
&lt;/h2&gt;

&lt;p&gt;Create a file called &lt;code&gt;server.py&lt;/code&gt;. This is illustrative, simplified code meant for learning, not a full production implementation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# server.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.server&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.types&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TextContent&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weather-server&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.list_tools&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_tools&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_weather&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Get the current weather for a given city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;inputSchema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;properties&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;string&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Name of the city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;list_tools&lt;/code&gt; function is how a client discovers what your server can do. When an AI agent connects, it asks "what tools do you have," and this is the answer it gets back, in a structured format it can reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Implement What the Tool Actually Does
&lt;/h2&gt;

&lt;p&gt;Now add the logic that runs when the tool is actually called.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# server.py (continued)
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="nd"&gt;@app.call_tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_weather&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="c1"&gt;# Simplified example call, replace with a real weather API and key
&lt;/span&gt;        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://example-weather-api.test/v1/current?city=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The weather in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;condition&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;unknown&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; at &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;temp&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;?&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;°&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;TextContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the execution layer. The AI model never talks to the weather API directly, it calls your tool through the protocol, and your code decides exactly what happens and what comes back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Run the Server Locally
&lt;/h2&gt;

&lt;p&gt;Add a simple entry point so the server can actually start.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# server.py (continued)
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.server.stdio&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;stdio_server&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;stdio_server&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nf"&gt;as &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;read_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;read_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_initialization_options&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python server.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, the server is running and waiting for a client to connect over standard input and output, which is the simplest transport for local development and testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Connect a Client and Test It
&lt;/h2&gt;

&lt;p&gt;To actually test this, you need an MCP-compatible client configured to launch your server. Most MCP client configurations use a simple JSON entry pointing to your script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"weather"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"/full/path/to/server.py"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your client is configured and connected, ask it something like "what's the weather in Lisbon." If everything is wired correctly, the client will discover your &lt;code&gt;get_weather&lt;/code&gt; tool through the &lt;code&gt;list_tools&lt;/code&gt; call, invoke it with the city argument, and return the result from your &lt;code&gt;call_tool&lt;/code&gt; function back through the model's response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing / Verifying It Works
&lt;/h2&gt;

&lt;p&gt;A few checks to confirm your MCP server integration is actually functioning correctly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Confirm the client's tool list shows &lt;code&gt;get_weather&lt;/code&gt; as an available tool after connecting&lt;/li&gt;
&lt;li&gt;Manually call the tool with a test city and check that the response text looks correct&lt;/li&gt;
&lt;li&gt;Try an invalid or missing argument and confirm your server doesn't crash silently&lt;/li&gt;
&lt;li&gt;Restart the client and reconnect to make sure the server initializes cleanly every time, not just on the first run&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Pitfalls and How to Avoid Them
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Forgetting to validate input.&lt;/strong&gt; A missing or malformed &lt;code&gt;city&lt;/code&gt; argument will crash a naive implementation. Add basic validation before making the external call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blocking calls inside async functions.&lt;/strong&gt; Using a purely synchronous HTTP library inside an async tool handler can freeze your server under load. Consider an async HTTP client for anything beyond a simple learning project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not handling API failures gracefully.&lt;/strong&gt; If the weather API is down, your tool should return a clear error message, not throw an unhandled exception that breaks the whole session.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overloading one server with too many unrelated tools.&lt;/strong&gt; Keeping a server focused on one coherent set of capabilities makes it easier for both you and the connecting AI agent to reason about.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best Practices for Production Use
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add proper authentication and scoped permissions before exposing any server beyond local testing&lt;/li&gt;
&lt;li&gt;Log every tool call, including inputs and outcomes, so failures are debuggable after the fact&lt;/li&gt;
&lt;li&gt;Set reasonable timeouts on any external API calls inside your tools&lt;/li&gt;
&lt;li&gt;Validate all inputs against your declared schema before executing any logic&lt;/li&gt;
&lt;li&gt;Version your tool definitions so you can evolve them without silently breaking existing clients&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What to Explore Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add a second, related tool to the same server, like a multi-day forecast, and see how tool discovery scales&lt;/li&gt;
&lt;li&gt;Swap the stdio transport for Streamable HTTP to run your server as a proper remote service&lt;/li&gt;
&lt;li&gt;Explore adding authentication middleware so only verified callers can invoke your tools&lt;/li&gt;
&lt;li&gt;Look into structured output schemas so responses can be validated programmatically instead of just returned as plain text&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Building your first MCP server strips away a lot of the mystery around MCP integration once you've actually wired up discovery, execution, and a real client connection yourself. The pattern you just built scales directly to far more complex tools, databases, internal APIs, search systems, without changing the underlying shape of what you learned here. Once this clicks, adding your next tool is a lot faster than the first one was.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>tutorial</category>
      <category>python</category>
    </item>
    <item>
      <title>There's a New Universal Plug for AI, and Most Developers Haven't Wired It In Yet</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Wed, 29 Jul 2026 12:26:39 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/theres-a-new-universal-plug-for-ai-and-most-developers-havent-wired-it-in-yet-1fc8</link>
      <guid>https://dev.to/emma_schmidt_/theres-a-new-universal-plug-for-ai-and-most-developers-havent-wired-it-in-yet-1fc8</guid>
      <description>&lt;p&gt;Picture this. You've built an AI feature that needs to check a customer's order status, pull data from your CRM, and search internal documentation, three separate systems, three separate custom integrations, each with its own auth, its own data format, its own maintenance burden. Now imagine adding a fourth tool next quarter. And a fifth. This exact integration sprawl is precisely the problem the Model Context Protocol was built to solve, and it's become one of the fastest-adopted standards in recent memory across &lt;a href="https://zignuts.com/llm-genai-services/mcp-development/mcp-server-development-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;&lt;strong&gt;LLM &amp;amp; GenAI&lt;/strong&gt;&lt;/a&gt; development. Understanding how to actually build with it, not just read about it, is quickly becoming a core skill for anyone shipping AI features that need to touch real data and real tools.&lt;/p&gt;

&lt;p&gt;Here's what MCP actually is, why it's spreading this fast, and how to build your first working MCP server step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Protocol Is Spreading Faster Than Almost Anything in AI Tooling
&lt;/h2&gt;

&lt;p&gt;The adoption numbers here are genuinely unusual, even for an industry used to fast-moving trends.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Figure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Monthly SDK downloads (March 2026)&lt;/td&gt;
&lt;td&gt;97 million, up from roughly 100,000 at launch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to reach 100M+ monthly downloads&lt;/td&gt;
&lt;td&gt;About 16 months&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comparable milestone for React's npm package&lt;/td&gt;
&lt;td&gt;Roughly 3 years&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public MCP servers in the official registry&lt;/td&gt;
&lt;td&gt;Around 9,600 as of a May 2026 snapshot&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fortune 500 companies with MCP deployed&lt;/td&gt;
&lt;td&gt;Roughly 28% within 18 months of launch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Major platforms with shipped MCP support&lt;/td&gt;
&lt;td&gt;OpenAI, Google, Microsoft, and others within about 13 months of launch&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That last row is the one worth sitting with. A protocol originally released by Anthropic in November 2024 has since been adopted broadly enough across the industry that it now functions as shared infrastructure rather than one company's proprietary approach, which is exactly the kind of cross-platform momentum that turns a promising idea into a genuine standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  What MCP Actually Solves
&lt;/h2&gt;

&lt;p&gt;Before MCP, connecting an AI application to external tools meant building a custom integration for every single combination of model and tool. Ten AI applications and a hundred tools meant a potential one thousand separate integrations, each one bespoke, each one a maintenance burden of its own.&lt;/p&gt;

&lt;p&gt;MCP replaces that with one standardized interface. Think of it the way USB-C replaced a drawer full of proprietary charging cables. Any MCP-compatible client can talk to any MCP-compatible server through the same protocol, regardless of which model or which tool is on either end.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Core Pieces You Need to Understand
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MCP Host.&lt;/strong&gt; The AI application itself, the thing the end user actually interacts with&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Client.&lt;/strong&gt; Lives inside the host and manages the connection to one or more &lt;a href="https://zignuts.com/llm-genai-services/mcp-development/mcp-server-development-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;&lt;strong&gt;MCP servers&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Server.&lt;/strong&gt; Exposes specific tools, data sources, or capabilities in the standardized format the protocol expects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most developers building on top of MCP will spend their time on the server side, exposing their own systems and tools so any compatible AI application can use them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Your First MCP Server, Step by Step
&lt;/h2&gt;

&lt;p&gt;Let's build a simple MCP server that exposes a single tool, checking an order status, using the official &lt;a href="https://zignuts.com/python-development-company?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/a&gt; SDK.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step one: install the SDK&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step two: define the server and register a tool&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.server&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Server&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.types&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TextContent&lt;/span&gt;

&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order-status-server&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@server.list_tools&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_tools&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_order_status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Look up the current status of a customer order&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;inputSchema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;properties&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;string&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the discovery step. Any MCP client connecting to this server can now ask what tools are available and get back a structured description it can reason about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step three: implement what the tool actually does&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@server.call_tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_order_status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;order_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;lookup_order_in_database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;TextContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Order &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; status: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the actual execution layer. The AI model never touches your database directly, it calls the tool through the standardized protocol, and your server controls exactly what happens and what gets returned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step four: run the server with the appropriate transport&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.server.stdio&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;stdio_server&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;stdio_server&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nf"&gt;as &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;read_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;read_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;write_stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_initialization_options&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Local development typically uses stdio transport. Production deployments increasingly use Streamable HTTP, which lets the server run as a proper remote service rather than a local process, and it's the transport most enterprise MCP rollouts are standardizing around this year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step five: secure it before it goes anywhere near production&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;mcp.server.auth&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RequireAuth&lt;/span&gt;

&lt;span class="nd"&gt;@server.call_tool&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nd"&gt;@RequireAuth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scopes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orders:read&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# verified caller identity is available in context
&lt;/span&gt;    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every tool call should carry proper identity and scope verification. A recent industry analysis noted that in the MCP era, trust isn't established once at login, it's re-earned with every single tool call and data access an agent makes, which is a meaningfully different security posture than traditional API authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Changing Right Now, as of This Week
&lt;/h2&gt;

&lt;p&gt;This is genuinely current, not stale reporting. The next major MCP specification, dated 2026-07-28, has its release candidate locked and is shipping as the final spec this week. It introduces a stateless protocol core, an Extensions framework for adding capabilities without breaking existing implementations, a formal deprecation policy, and hardened authorization. If you're starting a new MCP implementation right now, building against this version rather than the November 2025 spec is the right call, since SDK maintainers are expected to support it within a defined validation window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes Teams Are Making With Early MCP Adoption
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tool overexposure.&lt;/strong&gt; Registering far more tools than a given workflow actually needs, which bloats the context an AI model has to reason over and increases the chance of it calling the wrong tool&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Treating authentication as an afterthought.&lt;/strong&gt; Standing up a functional MCP server quickly and only addressing proper scoped auth after it's already been connected to something sensitive&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring observability.&lt;/strong&gt; Deploying MCP servers into production workflows without tracking tool call success rates, latency, or error patterns, which makes debugging a failed agent workflow nearly impossible after the fact&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skipping the governance conversation.&lt;/strong&gt; Rolling out MCP servers across a team or organization without agreeing on security, compliance, and identity controls up front, then retrofitting governance after adoption has already sprawled&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Matters Beyond the Hype Cycle
&lt;/h2&gt;

&lt;p&gt;MCP exhibits genuine network effects. Every new MCP server makes every existing MCP client more capable, and every new client makes building an MCP server more worthwhile. That's a structurally different growth pattern than most developer tools, and it's part of why the ecosystem has grown as fast as it has.&lt;/p&gt;

&lt;p&gt;For teams evaluating whether to invest in this now, the practical answer is usually yes, but scoped carefully. Building custom MCP connectors and servers for your own internal tools and data sources, wired into &lt;strong&gt;&lt;a href="https://zignuts.com/blog/rag-vs-fine-tuning" rel="noopener noreferrer"&gt;RAG&lt;/a&gt;&lt;/strong&gt; development and existing LLM and GenAI workflows, is exactly the kind of foundational integration work that compounds in value as your AI features grow, rather than something that needs rebuilding from scratch every time a new tool gets added to the stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;The integration sprawl that used to make connecting AI to real business tools a slow, custom, one-off project each time is exactly what MCP was built to eliminate. With cross-vendor support, a maturing specification, and genuine network effects driving adoption, this has moved well past experimental territory into shared infrastructure that's shaping how serious AI applications get built this year.&lt;/p&gt;

&lt;p&gt;Has your team started building or adopting MCP servers yet, or are you still wiring up custom integrations one tool at a time? Curious how far along everyone actually is with this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; #ai #llm #genai #tutorial&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>tutorial</category>
      <category>genai</category>
    </item>
    <item>
      <title>Your AI Feature Isn't Slow. Your Architecture Is Making It Feel Slow.</title>
      <dc:creator>Emma Schmidt</dc:creator>
      <pubDate>Tue, 28 Jul 2026 10:30:54 +0000</pubDate>
      <link>https://dev.to/emma_schmidt_/your-ai-feature-isnt-slow-your-architecture-is-making-it-feel-slow-150p</link>
      <guid>https://dev.to/emma_schmidt_/your-ai-feature-isnt-slow-your-architecture-is-making-it-feel-slow-150p</guid>
      <description>&lt;p&gt;You've seen it a hundred times. A user types a question into an AI feature, hits submit, and then just stares at a blank screen for eight seconds before a wall of text dumps onto the page all at once. That gap between "I asked something" and "something happened" is exactly where users lose patience, and it's rarely the model's fault. It's almost always a streaming problem, not a speed problem. This is one of the core patterns behind modern &lt;a href="https://zignuts.com/ai-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;&lt;strong&gt;AI services&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://zignuts.com/ai-services/custom-ai-development/ai-web-application-development-services?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;&lt;strong&gt;AI web application development&lt;/strong&gt;&lt;/a&gt;, and getting it right in Next.js is simpler than most developers expect, especially now that the framework's App Router and Server Actions map almost perfectly onto how real-time AI responses actually need to flow.&lt;/p&gt;

&lt;p&gt;Here's how to build a genuinely responsive, streaming AI feature in &lt;strong&gt;&lt;a href="https://zignuts.com/hire-nextjs-developers?utm_source=seo&amp;amp;utm_medium=backlinks&amp;amp;utm_campaign=seo_referral&amp;amp;utm_id=7" rel="noopener noreferrer"&gt;Next.js &lt;/a&gt;&lt;/strong&gt;from the ground up, understanding what's actually happening under the hood instead of just wiring up a library and hoping.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Streaming Changed What "Fast" Means for AI Features
&lt;/h2&gt;

&lt;p&gt;A non-streaming AI feature waits for the entire response to generate before showing anything. For short answers that's tolerable. For anything longer, a paragraph, a summary, a generated document, it means staring at a static loading spinner for several seconds with zero feedback that anything is actually happening.&lt;/p&gt;

&lt;p&gt;Streaming flips this. Tokens appear as the model generates them, the same way ChatGPT-style interfaces work. The perceived speed difference is enormous even when the total generation time is identical, because the user sees progress immediately instead of waiting in silence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real-World Difference This Makes
&lt;/h2&gt;

&lt;p&gt;Picture a support tool generating a written summary of a long customer thread. The generation itself takes about six seconds either way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without streaming:&lt;/strong&gt; the user submits, sees a static spinner, and waits the full six seconds staring at nothing. To someone who isn't sure the request even registered, six seconds of silence feels much longer than it actually is, and a meaningful number of users will refresh or click again out of doubt, sometimes triggering a duplicate request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With streaming:&lt;/strong&gt; the user sees the first words appear within a few hundred milliseconds, and text keeps flowing steadily until the summary is complete. The total time is identical, but it reads as fast because there's constant, visible progress instead of dead air.&lt;/p&gt;

&lt;p&gt;Same backend, same model, same six seconds of actual compute. The only difference is architecture, and it's the difference between a feature that feels broken and one that feels instant.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing Your Transport Mechanism
&lt;/h2&gt;

&lt;p&gt;Before writing code, it's worth understanding the three real options for getting streaming data from server to client, since picking the wrong one for your use case creates real problems later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server-Sent Events (SSE)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One-directional, server to client only&lt;/li&gt;
&lt;li&gt;Works over standard HTTP, no special infrastructure required&lt;/li&gt;
&lt;li&gt;The natural fit for AI text generation, since the client only needs to receive tokens, not send data mid-stream&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;WebSockets&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bidirectional, full duplex communication&lt;/li&gt;
&lt;li&gt;Better suited for genuinely interactive real-time features like collaborative editing or live multiplayer state&lt;/li&gt;
&lt;li&gt;Overkill for most AI chat features, and adds real infrastructure complexity you don't need for one-way token streaming&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Web Streams API (ReadableStream)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The lowest-level option, giving direct control over how chunks are read and processed&lt;/li&gt;
&lt;li&gt;What the AI SDK and most Route Handler implementations are actually built on under the hood&lt;/li&gt;
&lt;li&gt;Best when you need fine-grained control over parsing structured data mid-stream, like tool calls or JSON fragments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the vast majority of AI chat and generation features, SSE built on top of the Web Streams API is the right choice. Reach for WebSockets only when you genuinely need bidirectional communication during generation, which is rarer than most implementations assume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step-by-Step: Building a Streaming AI Route Handler
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step one: set up the project&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest ai-streaming-app
&lt;span class="nb"&gt;cd &lt;/span&gt;ai-streaming-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Select the App Router when prompted. This pattern depends on Route Handlers, which live specifically in the App Router architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step two: create the streaming Route Handler&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/api/chat/route.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ReadableStream&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;callModelProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enqueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/event-stream&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key detail here: the API key and the call to the model provider stay entirely server-side. Nothing sensitive ever ships to the client bundle, which matters both for security and for keeping your provider costs from being exposed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step three: consume the stream on the client&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/components/ChatInput.tsx&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ChatInput&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setResponse&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;getReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextDecoder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;setResponse&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;decoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the piece that actually creates the typing effect. Each chunk arrives and appends to state as it comes in, instead of waiting for one giant response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step four: add proper error and cancellation handling&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AbortController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="c1"&gt;// stream reading logic here&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AbortError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Generation cancelled by user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Something went wrong, please try again&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleCancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A stop button that actually cancels an in-flight generation is a small detail users notice immediately when it's missing, and it costs very little to implement properly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step five: validate structured output when you need more than plain text&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;responseSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;confidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;number&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validateResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;responseSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of hoping a model returns well-formed JSON, defining a schema and validating against it catches malformed output before it ever reaches your UI, which matters a lot once an AI feature is doing more than just displaying conversational text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step six: add rate limiting before this ever reaches production&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/api/chat/route.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;requestCounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getUserIdFromSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;requestCounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentCount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rate limit exceeded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;429&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;requestCounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentCount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// proceed with streaming logic&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simplified example, a real implementation would use a proper store like Redis rather than an in-memory map, but the principle holds regardless of scale. Without rate limiting, a single user or a scripted abuse pattern can run your model provider costs up fast, and this is one of the most commonly skipped steps in early AI feature builds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step seven: track cost per feature, not just in aggregate&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;logUsage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;feature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tokenCount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;getCostPerToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;analytics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;track&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ai_usage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;feature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cost&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Breaking cost down by feature rather than watching one aggregate monthly number lets you catch a specific feature quietly ballooning in usage long before it shows up as a surprise on the bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes Worth Avoiding
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Forgetting to handle stream errors mid-response, leaving the UI stuck in a permanent loading state if the connection drops partway through&lt;/li&gt;
&lt;li&gt;Skipping the cancellation handling entirely, which leaves users stuck watching a response they no longer want finish generating&lt;/li&gt;
&lt;li&gt;Calling the model provider directly from client-side code, which exposes API keys and lets costs run up uncontrolled&lt;/li&gt;
&lt;li&gt;Not validating structured output, and discovering malformed data only when it breaks something downstream in production&lt;/li&gt;
&lt;li&gt;Shipping without rate limiting and finding out the hard way when a single user or bot script drives up provider costs overnight&lt;/li&gt;
&lt;li&gt;Choosing WebSockets by default out of habit when SSE would be simpler, cheaper to run, and perfectly sufficient for one-way token streaming&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Quick Self-Check Before You Ship
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Does your UI show visible progress within the first second, or does it sit on a static spinner while waiting for the full response?&lt;/li&gt;
&lt;li&gt;Can a user actually cancel a generation mid-stream, or does clicking away just leave the request running in the background?&lt;/li&gt;
&lt;li&gt;Is there a rate limit in place, or is the endpoint currently wide open to unlimited requests per user?&lt;/li&gt;
&lt;li&gt;Are you tracking cost per feature, or would a sudden spike in usage only show up once the monthly bill arrives?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why This Is Worth Building Properly, Not Just Quickly
&lt;/h2&gt;

&lt;p&gt;Getting a demo chat working in an afternoon is genuinely easy now. Getting it production-ready, proper error handling, rate limiting, cost monitoring, structured output validation, and a UI that gracefully degrades when something goes wrong, is where most teams underestimate the actual scope of the work. Custom AI development and API integration work focused specifically on shipping these features at production scale tends to close that gap far faster than assembling it piece by piece under a deadline, especially for teams integrating multiple providers or building on top of an existing enterprise codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;The gap between an AI feature that feels instant and one that feels sluggish usually isn't the model's raw speed, it's whether the response streams token by token or dumps all at once after a long, silent wait. Next.js's architecture, particularly Server Actions and Route Handlers, maps naturally onto this pattern, which is exactly why it's become the default framework for AI-powered web applications this year.&lt;/p&gt;

&lt;p&gt;Has your team already shipped a streaming AI feature in production, or are you still working through the plumbing on this one? Curious what's tripped people up most.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>ai</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
