← Back to Blog

Coding with AI brings worries that standard tools don't solve

Illustration contrasting chaotic AI code changes with AITM's structured approach

Today's AI can write a function, a component, or an entire endpoint in a few seconds. The problem doesn't show up where people expect it — in syntax or speed. It shows up the moment AI has to touch an existing system: dozens of files, a history of decisions, business rules that are written down nowhere except "in the heads" of the developers. How to systematically prevent this problem is the subject of this whole series — and the tool we'll gradually get to is called AITM.

Before we get there, it's worth asking a question that every team working with AI agents answers sooner or later — either the easy way or the expensive way: how do you actually know that the result an agent handed back as "done" is really correct, and not just that it looks that way? We'll get to the answer at the end of this post — but first, let's see why this isn't such an obvious question in the first place.

What this looks like in practice

A typical scenario: you ask an AI agent to modify one function. The agent fixes it — but forgets that this function is called from three other places with different expectations. Or it "improves" the structure of the code because that seemed logical to it, and in doing so breaks downstream logic it never even saw.

These aren't isolated bugs — they're a systemic problem: the AI agent doesn't have the context of the whole system, only what fits into the prompt and what it manages to read via full-text search. It decides based on words, not business logic. If documentation is available, it often loads the entire content — including the part that has nothing to do with the given prompt. And this holds true even for the strongest available models (Opus, Fable, Astra, and similar): it's not that the model isn't smart enough, it's that it has nowhere to systematically store this knowledge between individual interventions.

As the number of lines of source code grows, as business logic gets more complex, and as individual modules and classes become more interconnected, this search gets worse. Data that has nothing to do with the fix ends up going into the AI — and the result is code that's technically written correctly but follows the wrong business logic. The resulting functionality is broken, or a piece of code gets "fixed" that nobody wanted touched in the first place.

Where exactly it gets stuck

The fundamental stumbling block is hallucination — and it's very hard to eliminate. The second problem is prompt quality, which we as users can already partially influence. But looming over both is a harder constraint: context limitation. Even with the largest available models, we're talking roughly a million tokens — for environments that have hundreds of thousands of lines of code.

From experience, the practical threshold where basics like a skill or a hint in an md file stop being enough is roughly around 150,000 lines of code. Around 300,000 lines, the environment becomes genuinely complex — the day-to-day state starts falling apart and things break on their own. We're talking about software built on OOP, with complicated logical conditions and parts connected through message/event mechanisms and similar techniques. In code like that, the reference between a call and its handling isn't always obvious, and AI struggles considerably with this part — it will quite likely fail to discover all the code tied to a given method.

On top of that comes another layer: the AI agent itself, based on the prompt, often spawns its own subagents — and the creation of those subagents is itself under the AI's control, which introduces yet another source of error. If the AI assigns a higher weight to a word you only included in a sentence for grammatical flow (not as an instruction), it may spawn a subagent based on that word which processes something you never wanted at all. And a subagent can pass its own errors further down the line to other agents — so individual hallucinations can propagate and compound through the chain.

It would seem a checking agent, whose job is to verify everything was done according to spec, should solve this. But what does "verify" actually mean? If another AI evaluates the task the same way it was processed, you only get confirmation of the same judgment, not an independent check. Only when you use a different and better LLM for the check does the chance of catching the error actually rise — but that's a choice someone has to make deliberately, not an automatic outcome of "a check happened."

There's one more path left: run the application or an existing test, read the error from the log, and fix it so the test passes. Even here, though, the question remains what was actually fixed — is it really a bug, or is it an error caused by a change in business logic that an earlier step made unintentionally? The fix itself is usually clear-cut and the error disappears, but it often breaks some other part of the code in the process. A lot depends on how complex the code is and what dependencies it has.

For simpler things — say, a web form with editing, validation after filling it in, and saving data through business logic — this usually isn't demanding, and the probability of success is close to 99%. For more complex structures, you can genuinely end up in a state where the code's structure starts falling apart and bug follows bug. Running tests and e2e tests repeatedly can gradually fix this, but on a truly complex system it can take many attempts — and each one costs something.

The answer we promised at the start

Back to the opening question: how do you know a result is actually correct, and not just that it looks finished? From the prompt and the follow-up check alone, you can't reliably tell. We've seen why: limited context, hallucinations propagating between subagents, a check that in the worst case only confirms the same error, and a log-driven fix that can't distinguish a real bug from a side effect.

These are the methods programmers commonly use today, and for simpler changes they hold up fine. The next level is orchestration using AI — you prepare certain data about the system and keep it up to date, so you can hand the AI better information and thereby shrink the room it has to do something other than what you asked for. This is exactly the purpose AITM — AI Task Manager was built for: before the agent that writes the code ever gets to the request, the system pulls in contracts (documented behavior), a DOM map, and the business logic for the given area — and only then, with that knowledge, assembles the task. It doesn't rely on a single agent directly, but on a whole pipeline and other methods that AITM uses to achieve better results.

The following days will show exactly what this looks like in AITM in concrete prompts, agents, and pipeline steps — and why this is a different way of working with AI than what programmers are used to from a plain console.