Ideas Engineered for Tomorrow
We Engineer Services & Solutions for Your Business Needs
Consulting Services Hire Book Consulting

Generative AI Development Services in India

We build generative AI features that survive contact with real users: model selection and routing, prompt engineering held in version control, fine-tuning where it genuinely pays, evaluation harnesses that catch regressions, and cost per task you can forecast. Built by senior engineers in India for product teams in the US, UK, Canada, Australia and New Zealand.

The Demo Worked. Production Did Not.

Almost every company that comes to us for generative AI development services in India has already built something. Usually one engineer, usually over a weekend, usually impressive. It summarised the contract, drafted the reply, generated the product description, and everyone in the room agreed it was the future. Then it met a thousand real users and the story changed.

The complaints are consistent enough that we can almost predict them before the first call. Output quality swings without anyone changing anything. A prompt tweak that fixed one customer's complaint quietly broke three other cases, and nobody noticed for two weeks because there was no way to notice. The monthly provider bill went from a rounding error to a line item that finance now asks about, and nobody can explain which feature is spending the money. Someone pasted the output into a legal document without checking it. Support has a folder of screenshots titled "AI said what".

None of that is a model problem. Those are engineering problems that happen to involve a model. A prototype is a single happy path through a system that answers differently every time you ask it. A product is that same system with a defined quality bar, a measured failure rate, a cost ceiling, a rollback path and someone who gets paged. The distance between the two is where most of the work lives, and it is almost entirely software engineering rather than machine learning.

The cost of staying in prototype territory is easy to underestimate. You cannot promise anything to a customer because you cannot state a quality number. You cannot price the feature because you cannot forecast the spend. You cannot change providers because you have no way of knowing whether the new one is better or worse. And you cannot let the feature touch anything that matters, which usually means the AI work sits next to the product rather than inside it, generating enthusiasm and no revenue.

What a Generative AI Build Actually Includes

This is application engineering on top of foundation models. We are not training a model from scratch, and you almost certainly should not be either. The scope below is what we deliver on a typical build, and the definition of done for each item is written into the statement of work before anyone opens an editor.

Task definition and the quality bar

Before any code, we write down what a good output looks like in a form that can be checked. "Better summaries" is not a specification. "A summary of at most 120 words that names every party, states the renewal date if one exists, and never invents a monetary figure" is one, because each clause maps to a test. This document is short, it is argued over, and it saves more time than anything else in the engagement. Teams that skip it spend the next three months relitigating what the feature is supposed to do, one Slack thread at a time.

Prompt engineering as versioned code

Prompts live in the repository with the rest of the application, not in a vendor console where an unlogged edit can change production behaviour at four in the afternoon. Each prompt has a version, a changelog entry, an owner and a set of eval results attached to the commit that changed it. When output quality moves, the first question anyone asks is which prompt version was live, and that question should have a one-second answer.

The techniques matter less than the discipline, but they still matter. Few-shot examples pulled from your real data outperform invented ones. Explicit output contracts beat polite requests. Chain-of-thought helps on reasoning tasks and wastes tokens on extraction. Where the task is genuinely hard to specify by hand, we use DSPy to compile prompts against the eval set rather than guessing our way through fifteen manual revisions.

Model selection, routing and the abstraction layer

One internal interface sits between your application and every provider, so the model behind a feature is configuration rather than architecture. That layer carries the retry policy, the timeout, the fallback provider, the token accounting and the trace ID. It takes a day or two to build and it is the reason a model deprecation notice becomes a ticket instead of a quarter.

Evaluation harness and regression gates

A golden set of real inputs with expected properties, a scoring pipeline, and a threshold that blocks a merge. This is the single artefact that separates teams shipping confidently from teams shipping nervously, and it is the thing most in-house prototypes lack entirely. It gets its own section below because it deserves one.

Structured output, validation and tool use

Almost every useful generative feature has to hand its result to something that is not a human: a database write, a UI component, an approval workflow. That means JSON that validates against a schema every single time, not most of the time, and a defined behaviour for the times it does not.

Guardrails, moderation and refusal behaviour

Input filtering, output checks, a policy for what the feature must refuse, and logging of every refusal so you can see what people are actually trying. The interesting cases are rarely the obvious abuse. They are the customer who asks your product-description generator for medical advice because it is the only text box on the page.

Observability, tracing and cost accounting

Every call traced with its prompt version, model, token counts, latency, cost and outcome, tagged by tenant and feature. Langfuse or the OpenTelemetry GenAI conventions both work; what matters is that when someone asks why the bill doubled, the answer takes ten minutes rather than a week of guessing.

Deployment, rollout and the kill switch

Feature flags per tenant, staged rollout, a shadow mode where the new version runs alongside the old without users seeing it, and a switch that turns the feature off without a deploy. Generative features fail in ways that batch jobs do not, and the ability to stop one in thirty seconds is worth more than any amount of pre-launch testing.

Documentation and handover

Model and routing decisions with the eval numbers that justified them, the prompt history, the eval sets with their labels, the cost model, the red-team findings and the runbook for each alert. Written for the engineer on your side who inherits this in eight months, not for the person who commissioned it.

When Does Fine-Tuning Beat Prompting?

This question comes up on nearly every scoping call, usually framed as "should we fine-tune our own model", and the honest answer is that most teams asking it should not, yet. But the cases where fine-tuning is clearly right are specific enough to describe precisely, so here is where we draw the line.

Start with prompting, always

A careful prompt against a capable model is the fastest way to find out whether the task is even solvable. It costs a day. It requires no data pipeline, no GPU, no training run, no versioning of weights. If a strong model with a well-built prompt and a handful of real examples cannot do the job at all, fine-tuning a smaller model usually will not rescue it, because you are asking the training run to supply capability rather than style. Establish the ceiling first.

If the problem is missing knowledge, it is not a fine-tuning problem

This is the most expensive misunderstanding in the field. Fine-tuning teaches a model how to behave, not what is true this morning. If your feature gets facts wrong about your own products, your policies or your customers, training on those documents is a slow and unreliable way to fix it, and the model will still not tell you where an answer came from. Retrieval is the right tool for that job and it is a different discipline with its own engineering, which is why we treat retrieval-augmented generation as separate work rather than folding it in here.

Where fine-tuning genuinely wins

Four conditions, and you want at least three of them before it is worth the effort. The task is narrow and stable, so the definition will not shift next quarter. The output has a house style or a rigid format that takes a long prompt to describe and still comes out inconsistent. Volume is high enough that prompt tokens are a real cost, because a fine-tuned model needs a fraction of the instruction. And you have somewhere between two and ten thousand reviewed examples of the task done correctly, which usually means you have been running the prompted version long enough to harvest them.

When those hold, the economics change sharply. A small open-weights model with a LoRA adapter, trained on your own accepted outputs, can match a much larger model on that one task while running on hardware you control at a fraction of the per-call cost and a fraction of the latency. That is the trade we look for: a narrow task, moved off a frontier model, with quality held constant and measured.

The techniques, and what each is for

Supervised fine-tuning on input and output pairs is the workhorse and covers most cases. LoRA and QLoRA train a small adapter rather than the whole network, which is why fine-tuning a seven or eight billion parameter model no longer needs a cluster; QLoRA quantises the base model so the run fits on a single high-memory GPU. Adapters also mean you can hold several task-specific variants of one base model without storing several copies of the weights.

Preference tuning with DPO comes later and needs a different kind of data: pairs where a human preferred one output over another. It is the right tool when the problem is taste rather than correctness, when reviewers keep saying "technically right, wrong tone". Distillation is the third pattern, where a large model generates training data for a small one; check the provider terms before you do it, because several explicitly prohibit training competing models on their output.

Tooling is unglamorous and stable. Hugging Face PEFT and TRL for the training loop, Axolotl or Unsloth when we want configuration over code, and either a managed fine-tuning API or a rented GPU depending on where the data is allowed to live. The training run is rarely the hard part. Building a clean dataset with consistent labels, and holding out a test split that the training never sees, is where the time goes.

What fine-tuning costs you afterwards

The part people forget. A fine-tuned model is a versioned asset you now own and must maintain. When the task drifts, you retrain. When the base model has a better successor, you decide whether to redo the run. You need the eval harness anyway to know whether the fine-tune actually beat the prompt, and you need somewhere to serve it. We will tell you when a longer prompt on a hosted model is the cheaper answer, because a fine-tune that saves inference cost and adds a monthly maintenance burden is not always a win.

Choosing Models Without Painting Yourself Into a Corner

Model choice is a per-task decision, not a company-wide religion. The same product will sensibly run a frontier model on the hard reasoning step, a mid-tier model on the bulk generation, and a small open-weights model on classification that happens ten thousand times a day. Standardising on one provider for everything is tidy and usually wasteful.

Hosted frontier models

Best capability, no infrastructure, and a dependency you do not control. You accept the provider's deprecation calendar, their rate limits, their availability, and their pricing changes. For most application features that trade is correct, and pretending otherwise costs more than it saves. What you must not accept is the coupling: if your application code calls the provider SDK directly from fifteen places, you have made a business decision look like a refactor.

Open-weights models you host

Llama, Mistral, Qwen and Gemma families cover most application tasks well once the task is narrow. Served with vLLM for throughput, or llama.cpp where the deployment is small or on-premise, with AWQ or GPTQ quantisation when memory is the constraint. You take on GPU capacity planning, batching, and an on-call rotation that now includes inference. The reasons to do it are real: data that cannot leave your estate, per-call cost at high volume, latency you control, and the ability to keep a model version alive after the vendor world has moved on.

Cloud-mediated access

AWS Bedrock, Google Vertex AI and Azure OpenAI sit in the middle and are frequently the right answer for a regulated buyer. You get several model families under one contract, the data stays inside your existing cloud agreement and region, and procurement has already approved the vendor. Model availability lags the direct APIs by weeks or months, which is a real cost only if you need the newest thing.

Routing and cascades

Once the abstraction layer exists, routing becomes cheap to add and often halves the bill. The pattern that works most reliably is a cascade: attempt the task with a small fast model, score the result with deterministic checks, and escalate to a stronger model only when the check fails or confidence is low. On classification and extraction work the small model handles the large majority of traffic, and users never see the difference because the escalation happens inside a single request.

Two warnings from experience. Route on task type and measured difficulty, not on a guess about which prompt looks hard; the guess is usually wrong. And make the fallback path a first-class citizen with its own eval run, because a fallback nobody has tested is just an outage with extra steps.

Planning for deprecation

Every hosted model you build on will be retired. Treat that as a maintenance schedule rather than an emergency: the eval set replays against the candidate model in an afternoon, you compare quality and cost, you run shadow traffic for a few days to catch what the eval set missed, and you cut over behind a flag. Teams with evals do this in a sprint. Teams without them rebuild by feel, ship a regression, and find out from a customer.

How Do You Test Output That Is Different Every Time?

This is the question that separates a generative AI team from a team that has read about generative AI, and it is the first thing we build on any engagement. Conventional testing assumes the same input produces the same output. Here it does not, and at temperature zero it still will not across model versions. So you stop asserting equality and start asserting properties, and you accept a score rather than a pass.

The golden set

Between 100 and 500 real inputs, drawn from your actual traffic or your actual documents, chosen to cover the boring middle and the awkward edges. Short inputs and enormous ones. The customer with an apostrophe in their name. The contract with no renewal clause. The support ticket written in three languages. Every production bug becomes a new case in the set, which is how the set earns its keep over time. Invented test data is worse than useless here because it lacks exactly the mess that breaks things.

Cheap deterministic checks first

Most quality failures are catchable without any model in the loop, and these checks are fast enough to run on every commit. Does the JSON validate against the schema. Is every required field populated. Is the word count inside the range. Do all cited figures appear verbatim in the source text. Are there no placeholder strings, no truncated final sentence, no instruction text echoed back. In practice this layer catches a surprising share of regressions and costs nothing to run.

Judge models, used carefully

For the subjective remainder, tone, helpfulness, whether the answer addresses the question asked, a stronger model scores the output against a rubric. This works, and it fails in specific ways you need to design around. Judges favour longer answers. They favour output from their own family. They drift when the judge model is upgraded underneath you. So we calibrate: a few hundred human-labelled examples, agreement measured between judge and human, the rubric rewritten until agreement is acceptable, and the judge model pinned to a version. An uncalibrated judge is a number that feels like evidence and is not.

Regression gating in CI

Any change to a prompt, a model, a routing rule or the retrieval layer triggers the harness. The merge is blocked on two conditions: the aggregate score must not drop below the threshold, and no case that previously passed may now fail. That second condition matters more than the first, because an average can hide a category getting quietly worse. Results are posted to the pull request so a reviewer sees the effect of a prompt edit before approving it, in the same place they see the test suite.

Watching production, not just CI

Offline evals tell you about the inputs you thought of. Production tells you the rest. We sample live traffic, run the same automated checks on it, track the refusal rate, the schema failure rate, the escalation rate and the latency distribution, and alert when any of them move. A weekly human review of a small random sample catches the slow drift that no automated metric notices, and it is the most consistently useful hour in the sprint.

A/B testing where the money is

For features tied to a business outcome, the eval score is a proxy and the outcome is the truth. Acceptance rate on a generated draft, edit distance between what the model wrote and what the human sent, deflection rate, conversion. We instrument those from the start, because "the score went up" and "the feature got better for users" are related but not the same claim, and only one of them is worth reporting to your board.

Token Cost Modelling and Unit Economics

Cost is a design constraint on generative features in a way it is not for ordinary web work, because the marginal cost of a request is high enough to change the shape of the product. We model it in the first week, not after the first invoice.

Model the task, not the token

Provider pricing is per million tokens. Your business runs on cost per completed job: per summary, per draft, per document processed, per active tenant per month. Getting from one to the other means measuring the real distribution of prompt and completion length across your actual data, including retries and escalations, and including the calls that fail and get repeated. That number is what tells you whether the feature can be included in a plan tier or has to be metered, and it is a product decision disguised as an engineering one.

Work it out before you build, not after the first invoice.

Attack the input side first

In most applications the prompt dwarfs the answer. A 4,000 token instruction with examples and context, producing 200 tokens of output, means roughly ninety-five percent of what you are paying for is input. Trimming the context to what the task actually needs usually beats any provider negotiation. Prompt caching, where the provider supports it, cuts the cost of the stable prefix substantially and is close to free to adopt if you order the prompt so the fixed part comes first. That single ordering decision is worth doing on day one.

Batch what nobody is waiting for

Overnight enrichment, back-catalogue processing, bulk classification and re-scoring do not need an interactive response. Batch endpoints from the major providers trade latency for a materially lower rate, and self-hosted inference with vLLM gets far better throughput on batched work than on one request at a time. Splitting your workload into interactive and background is one of the highest-value architectural decisions available, and most prototypes treat everything as interactive by default.

Guard against the runaway

Per-tenant and per-feature budgets enforced in the gateway layer, hard caps on retries, a maximum output length on every call, and alerting on cost per hour rather than cost per month. The classic incident is a retry loop against a provider returning errors, discovered on the invoice. A cap in the code costs nothing and prevents the conversation where you explain to your CFO what happened over a weekend.

Streaming, Latency and the Feel of the Thing

A generative feature is slow by the standards of every other part of your interface. A page renders in 200 milliseconds; a decent completion takes several seconds. How you handle that gap decides whether users describe the feature as thoughtful or broken, and it is mostly a front-end problem.

Time to first token is the metric that matters

Total generation time matters less than how long the user stares at nothing. Streaming tokens over server-sent events as they arrive turns a six-second wait into an immediate response that finishes six seconds later, and users rate the second one far higher even though the work took the same time. We instrument time to first token and inter-token latency separately from total duration, because they have different causes and different fixes.

Streaming is easy until you need structure

Streaming plain prose is straightforward. Streaming into a structured UI is where it gets interesting, because half-formed JSON is not parseable and users should not watch braces appear. The workable patterns are streaming the prose sections while buffering the structured fields, using a partial-parse library that tolerates incomplete JSON, or splitting into two calls so the structure arrives fast and the long text streams after. Which one is right depends on your interface, and it is worth deciding before the component is built rather than retrofitting.

The interruption and the reconnection

Users close tabs mid-generation. Mobile connections drop at the worst moment. Someone hits stop after two sentences. Each of those needs a defined behaviour: cancel the upstream request so you stop paying for tokens nobody will read, persist the partial output if it has value, and make regeneration cheap. Long-running generation belongs behind a job queue with a status endpoint rather than an open HTTP connection you are hoping stays alive.

Latency budgets across the chain

Once a feature makes more than one model call the delays compound, and a chain of three sequential calls at three seconds each produces a user experience nobody signed off on. We set a budget per stage, parallelise anything independent, and treat a chain of more than two sequential calls in an interactive path as a design smell to be justified rather than assumed.

Structured Output and Tool Use That Fits Your System

The moment a generative feature stops producing text for a human to read and starts producing data for a system to consume, the tolerance for looseness drops to zero. A summary that is slightly off is a minor annoyance. A malformed JSON field that reaches your database is an incident.

Schemas enforced, not requested

Asking politely for JSON in the prompt is not a contract. Constrained decoding, where the provider or the serving stack restricts token selection to what the grammar allows, makes schema conformance a property of generation rather than a hope. The major providers now support a schema parameter directly; on self-hosted models, Outlines or similar grammar-constrained decoding does the same job. Where neither is available, Instructor with Pydantic validation and a bounded repair loop is the fallback, and the repair attempts are capped and logged rather than retried forever.

Schema conformance is not correctness. A response can validate perfectly and be wrong, so field-level validation runs afterwards: dates parse and fall in a plausible range, enumerated values are actually in the enum, referenced identifiers exist in your database, totals add up. We have seen a well-formed extraction confidently assign an invoice to a customer who left in 2019, and no schema in the world catches that.

Tool calling with an adult's caution

Letting a model call your functions is powerful and it is the point where a generative feature acquires the ability to do damage. Our rules are boring and non-negotiable. Read operations can be automatic; anything that writes, sends, charges or deletes needs either an explicit user confirmation or a policy check that a human wrote. Every tool call is authorised against the end user's own permissions rather than a service account, because otherwise the model becomes a privilege escalation path. Arguments are validated exactly like untrusted user input, because that is precisely what they are.

Long autonomous chains of tool calls are a different discipline with different failure modes, and we treat that as agentic AI work rather than folding it into a generative feature build. Here we are talking about a bounded set of calls in service of one task, with the loop capped and every step traced.

Failing in a way the product can absorb

Design the failure path with the same care as the happy path. When validation fails after the repair budget is spent, the feature should degrade to something useful: return the raw text for a human to handle, drop into a manual form with whatever fields were extracted successfully, or queue for review. Silently returning an empty object because the parse failed is how bad data enters a system that everyone downstream trusts.

Generation Beyond Text

Plenty of the generative work we ship is not chat-shaped at all. Image pipelines and code generation have their own engineering problems, and they rarely get the same attention as text.

Image and creative pipelines

Product photography variants, marketing creative at scale, listing imagery, background replacement and localisation of the same asset across markets. The stack is usually a diffusion model such as SDXL or Flux, ControlNet for composition and pose constraints, inpainting for targeted edits, and a LoRA trained on your own brand assets so output looks like your catalogue rather than a stock library. This is one of the clearest fine-tuning wins available, because visual style is exactly what a small adapter learns well.

The production problems are different from text. GPU scheduling and queueing dominate, because generation takes seconds to minutes rather than milliseconds. Assets need provenance metadata and, increasingly, C2PA content credentials. Brand safety review has to sit in the pipeline rather than after publication. And the human review step is not optional at any volume worth doing, so the interface for approving or rejecting a batch quickly is a real part of the build.

Code and configuration generation

Generating code inside a product, migration scripts, SQL from a natural-language question, configuration from a description, has a property that makes it more tractable than most generative tasks: you can execute the output. That means the eval harness can run the generated code in a sandbox and check the result, which is a far stronger signal than any judge model. It also means the sandbox has to be genuinely isolated, with no network, no credentials and a hard timeout, and that generated SQL is parameterised and permission-scoped rather than executed as written.

Safety, Red-Teaming and What Goes Wrong in Public

The public failures of generative features are rarely exotic. A model is talked into saying something the brand cannot defend, or it invents a policy that does not exist, or it repeats content from one customer's data to another. All three are preventable, and none are prevented by asking the model nicely in the system prompt.

Prompt injection is an architecture problem

If your feature reads any content it did not author, a web page, an uploaded document, an inbound email, a support ticket, then that content can contain instructions, and the model has no reliable way to tell instructions from data. There is no prompt that fixes this. The mitigations are structural: untrusted content is clearly delimited and labelled as data, the model's tools are scoped so that following a malicious instruction cannot cause real harm, anything consequential requires human confirmation, and outbound content is checked before it is rendered or sent. The OWASP Top 10 for LLM Applications is the checklist we work through, and prompt injection sits at the top of it for good reason.

Red-teaming before launch and on a schedule

A structured adversarial pass against the specific feature, not a generic jailbreak list. We attack the things that would actually hurt: making the feature produce advice it is not licensed to give, extracting the system prompt, getting it to reveal another tenant's data through a crafted input, driving it into a loop that costs money, and finding the phrasing that produces the most embarrassing plausible output. Findings become permanent cases in the eval set, so a future prompt change cannot quietly reopen a hole that was closed. Automated adversarial suites run in CI; the interesting findings still come from a person with bad intentions and an afternoon.

Guardrails that are actually enforced

Classifier-based filtering on input and output, either a hosted moderation endpoint or an open model such as Llama Guard where data must stay inside your estate. Topic boundaries defined as policy and checked in code, not merely described in the prompt. PII detection before text is sent to a third-party provider, with redaction where the task does not need the identifier. Every block logged with the input, so you can distinguish genuine abuse from a filter that is too aggressive and is quietly frustrating real customers.

Disclosure, review and the governance paperwork

Users should know when they are reading generated content, and the interface should make correction easy and capture it, because corrections are the cheapest training data you will ever get. Where the output touches a regulated decision, a documented human review step is not optional. We map builds against the NIST AI Risk Management Framework where a US buyer needs a governance story, and against the EU AI Act's transparency obligations where a UK or European deployment brings them into scope. For buyers who need a certifiable position, ISO/IEC 42001 is the standard their auditor will ask about.

Data Residency, IP and Compliance When Your Team Is in India

This is the section that decides most deals, and vagueness here is a red flag from any vendor. Engineers being in India does not mean your data is in India. Those are separate decisions and we keep them separate on purpose.

Where the data lives

Production data stays in your cloud account, in the region you choose. If you run in eu-west-2 or us-east-1, inference runs there too, through Bedrock, Vertex AI or Azure OpenAI in that region, or through a self-hosted model on your own instances. Our engineers access your systems the way any remote employee would: your identity provider, your VPN or zero-trust proxy, your access policies, your audit log. Nothing is copied to a laptop in Mumbai. Development runs against synthetic or de-identified data, which is better practice regardless of geography.

Provider data handling

Before a single record leaves your estate we go through the provider terms with you: whether inputs are used for training and how to opt out, retention windows and the process for zero-retention where a provider offers it, sub-processor lists, and which certifications actually cover the endpoint you are calling rather than the company in general. For a healthcare buyer we check whether a BAA is available on the specific service. For a European deployment we check the sub-processor chain, because that is what a DPIA will ask about.

The contractual position

An NDA before scoping. An MSA agreed with you up front, covering assignment of work product: code, prompts, eval sets, training data derived from your data, and any fine-tuned adapter weights. Data processing terms with standard contractual clauses where GDPR applies, and India's DPDP Act 2023 addressed on our side as the processor. Background-checked staff, company-managed devices with disk encryption and MDM, access revoked the day someone leaves the project rather than the month.

Model licensing, which people forget

Open-weights models carry licences with real terms. Llama's community licence has conditions above a user threshold. Some models are research-only and cannot be used commercially at all. Some provider terms prohibit using outputs to train a competing model, which directly affects the distillation approach described earlier. We record the licence for every model in the build alongside its eval results, so your legal team has one document to review rather than a scavenger hunt.

Three Situations We See Repeatedly

The SaaS feature that shipped and then embarrassed everyone

A property management platform added a one-click listing description generator. It launched to applause and started producing descriptions that mentioned amenities the property did not have, because the prompt included the whole property record and the model filled gaps with plausible detail. Support was fielding complaints from agents whose listings claimed a pool.

The fix was not a better prompt. We built an eval set from 240 real properties, including the sparse records that caused the problem, and added a deterministic check that every noun phrase describing a feature must map to a populated field in the source record. Anything unsupported was stripped before the draft reached the agent. The prompt was rewritten to describe absence explicitly rather than leaving the field out, because an empty field invites invention. Escalation to a stronger model happens only when the record is unusually sparse, which is around one listing in twelve, so the cost per description fell while the failure that mattered went to zero on the eval set and stayed there through four subsequent prompt changes.

The document pipeline where a frontier model was overkill

A logistics company was extracting structured fields from shipping documents at high volume using a frontier model, one call per document, with a long prompt describing every field and every edge case. It worked well and the monthly bill had become a boardroom topic.

Nine months of operation had produced a large corpus of human-reviewed extractions, which is exactly the asset fine-tuning needs. We built the eval set from held-out documents first, then trained a LoRA adapter on an open-weights model of around eight billion parameters using the reviewed pairs, and served it with vLLM in their own cloud account. It matched the frontier model on the eval set for their document types, ran considerably faster because the prompt shrank from thousands of tokens to a short instruction, and the frontier model stayed in place as an escalation path for document types the adapter had not seen. This is the textbook case: narrow task, rigid output, high volume, and training data that already existed as a by-product of the previous approach.

The estate of fourteen prompts and no owner

A mid-sized fintech had generative features built by three different squads over eighteen months, using two providers, with prompts living variously in code, in a vendor playground and in a Notion page. Nobody could say what the total spend was per feature. Then a provider announced a model retirement and the team discovered they had no way to tell whether the replacement was better or worse than what they had.

We consolidated onto a single internal gateway with per-feature routing, tracing and budgets, moved every prompt into the repository with version history, and built one eval set per feature from production traffic. The migration itself was then unremarkable: replay, compare, shadow, flip the flag. The lasting value was not the migration. It was that the next model change, and there is always a next one, became a scheduled task instead of a fire drill, and that finance could finally see which feature was spending what.

How the Engagement Runs

Week 0: scoping

A two-hour call and a written brief. What the feature does, who uses it, what a good output looks like, what data it touches, where it must run, and what happens when it is wrong. We come back with a scope, a plan and a fixed price against it. If the honest answer is that you do not need a generative feature for this, we say so on that call.

Weeks 1 to 2: the quality bar and the harness

The specification of a good output, the golden set assembled from your real data, the deterministic checks, and a first prompted baseline measured against it. You get a number for current quality before anyone optimises anything. That baseline is what every later claim of improvement is measured against.

Weeks 3 to 5: build

The gateway and model abstraction, prompts in version control, structured output with validation, streaming interface, tracing and cost accounting. Everything lands in your repository behind a feature flag. Demos are against real inputs from the golden set, never a curated example.

Week 6: adversarial pass

Red-teaming against this specific feature, guardrail tuning, refusal behaviour, and cost testing at projected volume rather than at demo volume. Findings become permanent eval cases. This week reliably surfaces at least one thing nobody had considered.

Weeks 7 to 8: staged rollout

Internal users, then a small tenant cohort, then wider, with production sampling and the same automated checks running against live traffic. The kill switch is tested before the first external user sees the feature, not after.

After launch: iterate or hand over

Either we continue on a retainer, adding cases to the eval set, tuning cost and evaluating new models as they land, or we hand over to your team with the documentation, the eval sets and two weeks of paired work. Both are normal and we do not make the second one difficult.

Eight weeks is a typical single-feature build. A programme covering several features, a shared gateway and a fine-tuning track runs longer, and the honest estimate comes after week two rather than before week one, because the baseline measurement is what tells us how far the gap actually is.

How We Run Delivery From India

India has a deep pool of engineers who have shipped production machine learning and a much shallower pool who have shipped production generative AI, because the field is young everywhere. We hire for software engineering judgement first and treat model familiarity as trainable, which is the right way round: the failure modes on these projects are architectural, and someone who has run a system with an on-call rotation is better equipped than someone who has read every paper.

The overlap window, stated honestly

A standard day here is 09:30 to 18:30 IST. Against London that gives four hours in winter and five during British Summer Time, which is enough for a real working relationship. Against Sydney it gives about two hours at the end of their day, and we move the India start earlier to make it four. Against US Eastern it gives essentially nothing, so we do not pretend: the India day shifts to roughly 13:30 to 22:30 IST, which buys three to four hours from mid morning Eastern. US Pacific is the genuinely hard one. Without a night shift the realistic overlap is one to two hours, and anyone promising you a comfortable working day across that gap is either not planning to honour it or planning to burn out their team.

What makes a small window work is written-first discipline rather than heroics. Decisions live in the pull request or the design document, not in a call. The window is used for the things that genuinely need synchronous discussion: demos against real inputs, disagreements, and anything with a trade-off in it. Everything else is asynchronous with a defined response expectation.

Handover, standups and reporting

A written end-of-day handover from India lands in your morning, covering what shipped, how the evals moved and what is still open. Anything blocking is flagged as a question with options and a recommendation, so you can unblock it in two minutes rather than scheduling a call. Sprints are two weeks with a demo at the end, run against golden-set inputs so you are watching the same cases every time and can see movement.

Code review and the definition of done

Every change is reviewed by a second engineer before merge. Your team has review rights on everything and we expect you to use them, especially early, because that is how the standard gets set. Done for a generative feature means the eval harness passes with no previously passing case regressing, tracing is in place, the cost per task is measured and inside budget, the failure path is implemented and tested, and the documentation is updated in the same pull request rather than promised for later.

The vetting, since you will ask

Candidates work through a real task from a past project rather than an algorithm puzzle: given a prompted feature and a set of failing cases, diagnose and fix. It is a good filter because it cannot be pattern-matched. Written English is assessed from the written artefacts they produce during that exercise, not from the interview, since written communication is what you will actually rely on across a five-hour gap. You interview any engineer proposed for your team and you can decline without a reason.

Risks, and What We Do About Them

The task turns out not to be solvable at the quality you need

It happens. Some tasks require judgement that current models do not have, and the baseline measurement in week two is designed to surface that early and cheaply rather than in month four. When it happens we tell you, we show you the numbers, and we discuss narrowing the scope to the part that does work, usually with a human in the loop for the rest. A generative feature that handles seventy percent of cases and routes the rest to a person is often the right product; discovering that in week two is much better than discovering it after launch.

Quality drifts after launch and nobody notices

Providers update models under stable names, your traffic changes shape, and a feature that was fine in March is subtly worse in June. Production sampling against the same automated checks, alerting on the metrics that move first, and a weekly human review of a random sample are the defence. This is exactly the failure that offline testing alone will miss.

Cost grows faster than usage

Usually because the context grew: someone added a few more examples, then a longer instruction, then more history, and each addition was individually reasonable. Cost per task is tracked as a first-class metric with an alert threshold, and prompt size is reviewed in code review like any other resource.

The timezone gap slows decisions

The real risk on offshore work is not code quality, it is a question sitting unanswered for eighteen hours. We manage it by making every blocker a question with options and a recommendation attached, so the answer is a reply rather than a meeting, and by naming a single decision-maker on your side. If that person is unavailable for a week, tell us who deputises before the sprint starts.

An engineer leaves mid-project

Every project runs with a second engineer who has context and reviews the code, no component has a single owner, and we work to overlap a replacement with the person leaving. How the ramp-up on a replacement is treated is part of what your agreement should set out, so it is worth settling before you sign rather than after.

It does not work out

Notice and exit terms are agreed when the retainer starts, and the code is in your repositories throughout, so there is nothing to hand back. The last two weeks are spent on knowledge transfer to named people on your side, and we will tell you honestly at any point if we think you would be better served by hiring in-house for this.

Engagement Models

Fixed-scope build

One feature, a written specification, a defined quality bar and a fixed price. Best when you know what you want and want it delivered. Typically six to ten weeks including the adversarial pass and staged rollout. Changes to scope are quoted rather than absorbed silently.

Dedicated team

Two to six engineers working only on your product, in your tools, in your process, attending your standups. Best when generative AI is part of a roadmap rather than a single feature. Billing and notice terms are agreed with you upfront, and you interview everyone before they join.

Retainer for an existing build

You have shipped something and need it maintained properly: evals extended, models evaluated as they launch, cost tuned, incidents handled. A defined number of days per month against an agreed backlog, with the same reporting cadence as a full build.

All three start with the same scoping call and the same written brief. We do not quote a build before we understand what a good output looks like, because a price given before that is a guess dressed up as a number.

Where This Sits Next to Our Other Work

This page is about building generative features into a product. Several neighbouring problems have their own pages because they are genuinely different builds. If the feature needs to know things about your own documents, policies or products, that is retrieval-augmented generation. If it needs to plan and act over many steps with tools, that is agentic AI. If what you actually want is a conversational interface for customers or staff, start with chatbot development, and if that conversation happens over the phone, AI voice agents carry a different set of latency and telephony problems.

If you are unsure which of your ideas is worth building at all, an AI strategy engagement produces the shortlist, the sequence and an honest assessment before anyone writes a prompt. Where the generative layer sits on top of models you are training or serving yourself, our AI and machine learning services cover the modelling side. On the staffing side, most generative AI work in production is Python plus a typed front end, so teams are usually built from Python developers in India with TypeScript developers on the interface.

Frequently Asked Questions

When does fine-tuning actually beat prompting?

Fine-tuning wins on narrow, high-volume, format-heavy tasks where you already have a few thousand reviewed examples and where prompt length is the thing costing you money. It teaches format, tone and task shape. It does not teach facts, so it will not fix an out-of-date answer. Our rule is simple: prompt first, measure, and only fine-tune when a small model plus training data beats a large model plus a long prompt on the same eval set.

How do you test a feature when the model gives a different answer every time?

You stop testing for string equality and start testing for properties. A golden set of real inputs runs on every change, each output is checked by cheap deterministic assertions first, and only the subjective part goes to a judge model calibrated against human labels. The gate is a score threshold and a check on the worst cases, not a diff. Every prompt and model change ships through that harness.

Which model should we build on, and what happens when it is deprecated?

Pick per task rather than per company, and keep the choice behind one internal interface so swapping is a config change. Deprecation is a scheduling problem, not a crisis, when you have an eval set: replay it against the candidate model, compare scores and cost, shadow real traffic for a few days, then cut over. Teams without evals rebuild by feel and ship regressions.

How do you control token cost once the feature is live?

By modelling cost per completed task rather than per token, then attacking the input side first, because in most products the prompt is far larger than the answer. Prompt caching, trimming the context to what the task needs, routing easy work to a small model, and batching anything that is not user-facing usually do more than switching providers. Per-tenant budgets and alerts stop a loop from spending your month in a night.

Can our data stay outside India, and who owns the model and prompts?

Yes. Engineers in India work against systems hosted in your region, so production data stays in your AWS, Azure or GCP account and inference runs in a region you choose. You own the code, the prompts, the eval sets, the training data and any adapter weights, assigned to you under the MSA. Confidentiality, data processing terms and standard contractual clauses where GDPR applies are agreed with you before work starts.

How much overlap will we get with a team in India?

On a standard 09:30 to 18:30 IST day, London gets four to five hours and Sydney gets about two. US Eastern gets close to none, so we shift the India day later and get three to four hours from mid morning Eastern. US Pacific is the hard one and honestly caps at about two hours without a night shift. We publish the window in the contract rather than promising round-the-clock cover.

What do you hand over, and what happens if we stop the engagement?

Everything runs in your repositories and your cloud accounts from week one, so there is nothing to extract at the end. Handover is the eval sets with their labels, the prompt history, the model and routing decisions with the numbers behind them, the cost dashboard, the red-team findings and the runbooks. Notice and handover terms are agreed with you when the retainer is set up, and the closing stretch of the engagement is spent on knowledge transfer to named people on your side.

Tell Us What the Feature Is Supposed to Do

Describe the task, who uses the output, and where it currently falls over. We will come back with a quality bar you can measure, a model and routing plan, an eight-week shape and a fixed price against it.

Start the Conversation