The hard part of a multi-tool AI product is never any individual tool. It is that the thirty-third one has to cost almost nothing to add.
A single AI tool is a weekend. A prompt, a text box, a streaming response, deploy. Most of the work is the part you would have to do for any web app, and the model does the interesting bit.
Montlify has thirty-three of them behind one account — writing, research, summarisation, citation, chat. And thirty-three is not thirty-three weekends. Somewhere around the fourth tool, the problem stops being “build a tool” and becomes “build the thing tools live in”, and if you do not notice the change you end up maintaining thirty-three small applications that happen to share a domain name.
Here is what that shell has to own.
Everything shared has to be inherited, not copied
Each tool needs the same things: an authenticated user, a quota check before the expensive call, a record of what was run, a consistent layout, a streaming response, and sane behaviour when the model is slow or fails. Implement those per tool and you have not built a platform, you have built a template — and templates drift. Tool 6 gets a bug fix that tools 1 through 5 never receive, and nobody notices until a user reports that the same failure behaves three different ways.
The test we used: adding a tool should be a configuration change, not a release. A new tool declares what it needs — its inputs, its prompt strategy, its output shape, its cost class — and inherits everything else. If adding one requires touching auth, billing or layout, the shell is not finished.
This is worth over-investing in early, and it is very hard to retrofit. The cost of extracting a shared shell out of twelve existing tools is far more than the cost of building it before the third.
Model choice belongs behind the interface
A grammar checker and an essay writer have wildly different economics. A short, high-volume, low-stakes call should not run on the same model as a long generation a user waits on, and the right answer changes every few months as prices and capabilities move.
So the tool does not know which model it uses. It declares intent — roughly, how much capability this task needs and how latency-sensitive it is — and routing resolves that to a provider and model at call time. Changing the model behind a tool is then a config change with no frontend involvement.
That indirection buys three things:
- You can move a tool to a cheaper model and watch the numbers, rather than committing in a deploy.
- When a provider has an incident, failover is a routing decision, not a thirty-three-file change.
- Prompt strategy lives next to the routing rule, so the pair that has to change together is stored together.
Metering has to exist before pricing does
This is the one most teams get wrong, and we would have got it wrong too if we had not been burnt by it before.
You cannot price a product whose unit costs you do not know. Not approximately — per user, per tool, per call. Without that, a subscription tier is a guess, and the specific way it goes wrong is silent: a small number of heavy users on your most expensive tool quietly invert the margin on a whole tier, and the aggregate bill looks fine until it suddenly does not.
So metering came before billing. Every call records who made it, which tool, which model, and what it cost. Quota enforcement then sits on real numbers rather than a guess about what a fair limit might be, and a pricing change is an informed decision.
# Recorded per call, before the tier structure existed
usage = {
user_id, tool_id, model_id,
input_tokens, output_tokens,
cost_estimate, latency_ms, status,
}The schema is unremarkable. The decision that mattered was writing it on day one rather than after the first surprising invoice.
Cost is an architectural concern, not an optimisation pass
In a conventional web app you can defer cost. Compute is cheap enough that architecture and spend are separate conversations, and you optimise when something hurts.
In an AI product they are the same conversation. The cost line moves with usage, roughly linearly, and the levers are architectural: caching repeated work, cascading a small model in front of a large one, trimming context that is not earning its place, batching where latency allows. Each of those is a design decision, and each is far cheaper to make at the start than to retrofit across thirty-three surfaces.
A useful habit: put cost per call next to latency in whatever dashboard the team already looks at. A number nobody sees is a number nobody manages.
The unglamorous half is the product
None of the above is about prompting, and that is the point. The difference between a demo with one impressive tool and a product with thirty-three is almost entirely in the boring layer: accounts, quotas, metering, routing, consistent failure behaviour, deployment.
It is also the layer that decides whether the thirty-fourth tool takes an afternoon or a sprint — which, over a year, is the whole difference between a product that compounds and one that ossifies.
Montlify is live at montlify.com. If you are building something with more than a couple of AI surfaces and want a second opinion on the shell underneath them, we are happy to talk it through — no charge and no obligation.