All posts
AI LLMs Claude Gemini System Design Architecture Prompt Engineering Context Engineering Software Engineering Production AI TypeScript Node.js

How We Integrated AI Into an Existing SaaS Platform Without Rewriting the Entire System

Most AI projects begin from scratch. Mine didn't. I joined an existing production SaaS to design and integrate an AI infrastructure that could support intelligent assistants, Copilot-style workflows, and future AI capabilities without disrupting the application's existing architecture. This wasn't about calling an LLM API. It required designing a scalable AI layer with model routing, context engineering, memory management, usage limits, caching, security, and observability. This article shares the engineering decisions, trade-offs, and lessons I learned while bringing production AI into an already mature software platform.

12-15 min read

Production AI isn’t another feature. It’s another distributed system that happens to use language models.

Over the last few months, one of the most interesting engineering problems I’ve worked on wasn’t building a chatbot.

The application already existed. It already had customers, years of business logic, authentication, authorization, billing, permissions, dashboards, APIs, frontend applications, and production databases. Everything was already running.

My responsibility wasn’t to build the application. It was to design and integrate an AI infrastructure that could power intelligent assistants, Copilot experiences, and future AI features — while fitting naturally into an already mature production system.

That distinction completely changes how you approach AI engineering.

AI Is Infrastructure, Not a Feature

One mistake I see quite often is treating AI like another API integration: add an endpoint, send a prompt, receive a response, ship it. That approach works for demos. It rarely works for production software.

AI introduces entirely new concerns that traditional CRUD applications don’t have — questions like:

These aren’t prompt engineering problems. They’re architecture problems.

Defining the AI Layer

One of the first architectural decisions was keeping AI completely isolated from the existing business logic. Instead of allowing controllers or services to communicate directly with language models, every request flows through a dedicated AI layer.

AI infrastructure request flow: Frontend to Backend API to AI Orchestrator to Context Builder to Model Router to Claude or Gemini to Response Pipeline to Application

This abstraction gave us several important benefits. The rest of the application never needed to know which provider generated a response. Business logic remained unchanged. Changing providers became an internal implementation detail instead of a full application refactor.

Model Selection Isn’t One Size Fits All

A common misconception is that the most capable model should answer every request. That sounds reasonable until you look at latency and cost. Different requests require different levels of reasoning — simple classification tasks don’t need advanced reasoning, and summarization doesn’t require the same model as complex content generation.

After experimenting with multiple providers, I designed a routing strategy where each model had a clear responsibility.

Claude Haiku

Used for lightweight operations:

The priority here was speed and low cost.

Claude Sonnet

Reserved for more demanding workloads:

These requests benefited from higher reasoning capabilities, making the additional cost worthwhile.

Gemini as a Fallback

Production systems should never depend on a single provider. Providers experience outages, rate limits change, and latency fluctuates. To improve resilience, the AI layer was designed with fallback support — if a request couldn’t be completed by the primary provider under predefined conditions, it was automatically routed to Gemini without requiring changes elsewhere in the application. Users continued working without being aware that the provider had changed.

Context Engineering Matters More Than Prompt Engineering

Prompt engineering receives a lot of attention. In practice, context engineering had a much greater impact.

A language model can only reason over the information it receives. Giving it too little context produces generic answers. Giving it too much context increases cost, latency, and often reduces quality.

Instead of forwarding entire conversations or large datasets, every request builds a focused context package containing only the information relevant to the current task. Typical context included:

The goal wasn’t to give the model more information. The goal was to give it the right information.

Memory Should Be Intentional

One of the biggest challenges with conversational AI is memory. Keeping every previous message quickly becomes expensive and inefficient.

Instead, memory should evolve over time. Important facts are retained, temporary details are discarded, and older conversations are summarized into structured knowledge rather than replayed indefinitely. This allows conversations to remain coherent without continuously increasing token usage.

Good memory isn’t about storing everything. It’s about remembering what matters.

Designing a Prompt Pipeline

Another lesson was avoiding massive prompts. Instead, prompts were assembled from smaller components, each with a clear responsibility.

Prompt pipeline layers: System Instructions, Platform Policies, Business Rules, Context, Memory, Current User Request

This modular approach made prompts easier to maintain, review, and improve without affecting unrelated behaviour.

Usage Limits and Cost Control

Unlike traditional APIs, every AI request has a direct operational cost — unlimited usage isn’t sustainable. Part of the architecture involved designing an AI usage management layer. Instead of exposing unrestricted access, requests are evaluated against configurable usage policies, such as:

This makes the system predictable from both a financial and operational perspective. The goal wasn’t simply to reduce cost — it was to build a platform where AI usage could scale responsibly as adoption grows.

Caching Responses

Not every response needs to be generated again. Some requests are deterministic, and others produce identical outputs for the same inputs. For those scenarios, introducing intelligent caching significantly reduced latency and token consumption.

However, caching wasn’t applied universally. Personalized responses, live application data, or context-sensitive interactions bypassed the cache entirely. Choosing what not to cache was just as important as deciding what to cache.

Security Cannot Be an Afterthought

Adding AI creates new attack surfaces: prompt injection, prompt leakage, jailbreak attempts, and unauthorized tool access. The safest approach is to assume the model will eventually receive malicious input.

Every request is validated before reaching the model. Internal instructions remain isolated. Sensitive application data is never exposed unless explicitly authorized. Model outputs can also be validated before reaching users.

Security shouldn’t rely on the model making the correct decision. It should be enforced by the surrounding architecture.

Observability Is Essential

AI systems should never be treated as black boxes. For every request, we should be able to answer questions like:

Without this visibility, optimization becomes guesswork. Observability is what transforms AI from an experiment into production infrastructure.

What This Project Changed for Me

This project fundamentally changed how I think about AI. The most valuable engineering work wasn’t writing prompts — it was designing the systems around the models: clear abstractions, context management, model orchestration, memory, security, usage governance, caching, and observability.

The language model is only one component. Everything around it determines whether users experience AI as a reliable product or an unreliable demo.

Final Thoughts

The future of AI engineering isn’t about who writes the best prompts. It’s about who designs the best systems.

As models continue to improve, competitive advantage will come less from the models themselves and more from the engineering decisions surrounding them. The engineers who will build the next generation of AI products won’t simply know how to call an API — they’ll know how to design infrastructure that allows AI to operate reliably, securely, economically, and at scale.

That’s the lesson this project taught me, and it’s one I’ll carry into every AI system I build in the future.

Back to writing