# Stop Building AI Wrappers: The Hidden Cost of 'Thin' Applications

> Source: <https://dev.to/ntty/stop-building-ai-wrappers-the-hidden-cost-of-thin-applications-4hb6>
> Published: 2026-09-01 11:00:04+00:00

Last month, I spent three days building a feature for a client. The request was simple: analyze user support tickets and categorize them by urgency. I connected an LLM API, wrote a prompt that asked the model to return JSON, and the demo worked perfectly. I showed the client the results. They nodded, smiled, and said it looked great.

Then I tried to deploy it.

The first production error happened within an hour. A user submitted a ticket that contained a nested JSON string inside the text. The model got confused. It tried to parse the string as code and returned a malformed response. My backend crashed because it expected a strict schema.

I fixed the parser. Then the next issue appeared. The model started hallucinating categories that did not exist in our database. It invented a new priority level called "critical plus." I had to add logic to map unknown values to a default "low" category, but that was too aggressive. Some high-priority bugs got buried because the model was being creative.

This is the gap between a demo and a product. Most developers treat AI integration like they treat database integration. You query the database, you get data. You query the LLM, you get... vibes. The non-deterministic nature of large language models breaks standard software engineering assumptions. Here are three specific lessons I learned the hard way.

When you use a traditional API, you trust the schema. If I expect an integer, I get an integer. If I expect a string, I get a string. With LLMs, the output is probabilistic. It is natural language that *looks* like structured data.

I stopped trying to force the model to output specific JSON. Instead, I moved the validation logic to the application layer. I now use a two-step process. First, I ask the model for a simple, unstructured summary. Second, I use a deterministic script to extract keywords and map them to my internal categories. The model provides context; the code provides structure.

If you are building anything in production, assume the model will fail. Write defensive code that handles nulls, unexpected types, and garbage input. Do not trust the prompt. Trust your validation layer.

I initially tried to feed the entire conversation history to the model for every request. It worked in testing because the conversations were short. In production, users write long, rambling emails. The context window filled up faster than I expected.

Worse, the quality of the responses degraded as the context grew. The model started repeating itself. It lost the thread of the original question. I had to implement a sliding window approach. I kept only the last five messages in the context. I also added a summary step for older messages.

But summaries introduce drift. If you summarize a conversation about a bug, and then summarize the summary, you lose details. I now store the raw data in a vector database. I retrieve only the most relevant chunks based on the current query. This reduced my token costs by 60% and improved accuracy significantly.

The lesson here is that context management is an engineering problem, not a prompt engineering problem. You need storage, retrieval logic, and cleanup jobs. You need the same infrastructure you would build for a search engine.

How do you know if your AI feature is breaking? In traditional apps, you monitor error rates and latency. In AI apps, you also need to monitor quality. A request can return a 200 OK status, but the answer can be completely wrong.

I built a simple feedback loop. Users can rate the response with a thumbs up or thumbs down. I log these ratings alongside the prompt and the response. Weekly, I review the negative ratings. I look for patterns. Why did the model fail? Was the prompt ambiguous? Was the data noisy?

I also added a confidence score. I ask the model to estimate its own confidence. If the confidence is below a certain threshold, I route the request to a human agent instead of showing the AI response. This reduced our support tickets by 20%, but it also gave us a safety net.

Do not launch an AI feature without a way to measure quality. You will not know if it is working until it is broken.

AI is a powerful tool, but it is not a magic bullet. It does not replace your backend logic. It adds a new layer of complexity. You need robust error handling, careful context management, and rigorous monitoring.

If you are starting a new project, ask yourself: can I build this with traditional logic? If the answer is yes, do that. If the answer is no, then build the infrastructure to support the AI. Do not just wrap an API. Build a system.

The developers who succeed with AI are not the ones who write the best prompts. They are the ones who write the best code around the prompts.
