You wrote the spec with ChatGPT — 2,000 words, 30 bullet points, four tables, three “important notes,” acceptance criteria in Gherkin. It reads like a perfect brief. You paste it into your coding agent. The status line flips to “Thinking…” and stays there.
Five minutes pass. Ten. No file is read. No tool is called. No code is written. Just the spinner, burning tokens. You cancel and rewrite the prompt shorter — and the agent finishes the whole task in ninety seconds.
This is not bad luck, and it is not a broken agent. It is the single most common way to stall an agentic coding workflow, and it is almost always self-inflicted. The detailed prompt that looks most helpful to you is read by the model as: deliberate extensively before acting.
Your agent isn’t stuck — it was told to think
Reasoning-enabled models do not think a fixed amount. They allocate thinking roughly proportional to how complex the task appears — a learned policy, reinforced during training, that rewards longer deliberation when ambiguity and constraint density are high. That policy is the mechanism, and your workflow is feeding it everything it is trained to over-respond to.
Here is the causal chain in one paragraph. When you ask an LLM to “write a good prompt for a coding agent,” it optimizes for comprehensiveness — because that is what looks like quality to you. So you get a spec document: full architecture requirements, edge-case checklists, “must handle X, Y, Z” constraints, performance and security mentions, file-structure demands. Every constraint you list is a variable the reasoning model tries to satisfy and verify before it feels cleared to write code. And constraint interactions grow super-linearly: fifteen constraints means the model effectively checks on the order of a hundred pairwise interactions in its thinking phase. A human prompt has implicit prioritization — what you mention first matters most. An LLM-generated prompt is a flat list where everything is flagged as important, so nothing can be triaged.
The short version: you have built a pipeline that maximizes the one signal that makes reasoning models think longest — perceived task complexity — and you are wondering why the agent is doing architecture review before writing code.
Inside the five minutes
The stall is not empty time. Something specific is happening in there, and it follows a predictable sequence:
- Requirement extraction. The model parses your thirty bullets, four tables, and three “important notes” into a constraint graph.
- Conflict detection. It finds the places where those bullets contradict each other — or contradict the agent’s own system prompt (“always explore the codebase first” vs. “build X using Y architecture”).
- Planning explosion. It tries to produce a perfect step-by-step plan that satisfies all of it before touching a single file.
- Grounding failure. It has no real environment feedback yet — no file read, no test run — so its simulation drifts into re-checking its own logic against imagined states of a repository it has never inspected.
What you see as “thinking” is the model oscillating between two bosses: your prompt, which demands a flawless plan up front, and the agent harness, which demands it gather evidence first. It cannot resolve the conflict, so it stays in the scratchpad. If you let it run, models with a large reasoning budget will happily burn ten to twenty thousand hidden tokens over five-plus minutes and never emit a first tool call. The <think> block runs to the budget ceiling. It does not recover on its own.
Why LLM-generated prompts are poison for agents
ChatGPT is optimized to sound complete. A coding agent is optimized to act. Those are opposite goals, and a typical LLM-authored prompt performs seven moves that each trigger analysis paralysis on its own:
1. Constraint overload. Fifteen to twenty “requirements” reads as thorough to you. To a reasoning model it is a constraint-satisfaction problem — it must solve all of them simultaneously before its first tool call. Ambiguity about how they interrelate is not something it can resolve by asking; most agents are configured to just proceed, so it resolves it by thinking.
2. False precision. “Use clean architecture with a service layer, repository pattern, and DTOs.” The generating model invented this architecture because it cannot see your repository. The coding agent now has to reason about whether that architecture fits a codebase it has not read yet.
3. No grounding. “Create a file at src/components/Auth.tsx.” The agent has no idea whether that path exists or what the surrounding module conventions are. It spends thinking budget deciding whether to obey you or explore first.
4. Negative instructions. “Don’t use X. Don’t do Y. Avoid Z.” Reasoning models fixate on negatives — they spend reasoning budget proving they are not violating them. Every “don’t” is a constraint to verify.
5. Identity conflict. “You are an expert senior engineer…” — layered on top of the agent’s own system prompt that already defines who it is and how it operates. Two identity frames means the model spends tokens reconciling which one governs.
6. Format worship. Tables, JSON schemas, Gherkin acceptance criteria. The generating model adds them to look professional. For the consuming model they are just more tokens to reconcile, more structure whose internal consistency must be checked before action.
7. No exit condition. A good agent prompt is goal + context + two constraints. An LLM-generated prompt is an essay with no definition of done — so the planner never feels safe stopping planning and starting to code.
Notice the pattern: most of these are instructions the agent would have followed anyway, or constraints it could only resolve by looking at the actual code. The prompt pre-commits the agent to solving problems that only exist because the prompt was written blind.
Why reasoning models make it ten times worse
On a plain chat model, a heavy system prompt tends to suppress some deliberation — the model just gets on with it. Reasoning-enabled coding models invert that:
- Thinking is on by default. Several current coding-oriented reasoning models ship with no way to disable extended thinking — only an effort dial. GLM-5.x exposes
low/high/maxreasoning effort and, left unset by the integration, defaults to the top setting; the o-series models behave equivalently. The dial’s default is the most expensive search over solutions the model offers. - They are trained to deliberate. The ARC generation of models — agentic, reasoning, coding — was reinforcement-trained to think harder before acting. That is a feature for hard debugging. It is a tax for “rename this variable.”
- The harness raises the floor. Coding agents ship with heavy system prompts of their own — explore first, use tools, follow conventions, run tests. Stack your ChatGPT essay on top and the model is processing multiple layers of “think before acting,” each of which justifies more scratchpad.
- Meta-instructions are literal triggers. Go re-read your generated prompt. It almost certainly contains at least one of: “before writing any code, think through the architecture carefully,” “create a detailed plan first,” “consider edge cases and error handling,” “ensure the solution is production-ready.” These are not harmless filler — they are direct commands to extend reasoning. The model is dutifully following instructions you did not realize you were giving.
There is also a genuinely pathological variant worth knowing about: on certain serving stacks, the combination of a complex system prompt, many available tools, and automatic tool selection has been reported to push reasoning models into a degenerate loop — thousands of repeated characters or endlessly re-derived plans, with no tool call ever emitted, regardless of effort setting. Simple prompts with few tools do not trigger it. If you see this, it is a serving-side defect, not a prompt problem — but the practical response is the same: cancel, shorten, retry, or change the endpoint.
The fix: one goal, context, three constraints
The discipline that prevents all of this is a single rule that fits in one line:
Goal: one sentence. Context: which files to look at. Constraints: three bullets, maximum.
Here is the shape of a bad prompt — the kind ChatGPT produces when asked to “write a detailed prompt”:
You are an expert full-stack engineer. Build a modern, scalable, production-ready authentication system using Next.js 14 App Router, TypeScript, Prisma, and Tailwind. Before implementing, thoroughly analyze the existing codebase and consider all edge cases. Requirements: (1) must be secure against OWASP Top 10… (20) must include comprehensive tests with 90% coverage… [1,500 more words]
And here is the same intent as a prompt that an agent can execute:
Goal: Add email + password login to the existing app. Context: @src/app/layout.tsx @prisma/schema.prisma — currently no auth. Constraints: use next-auth; keep the existing UI; do not touch billing code.
The second version works because there is nothing to decompose. Every item maps directly to files the agent can inspect and decisions it can make without resolving a contradiction. The solution space is small, so the model reaches “enough understanding to act” in one pass and calls its first tool.
If you still want an LLM in the loop, invert its role: use it to compress your intent, not to author the brief. Give the generator a hard format constraint:
Take my idea below and compress it into an agent prompt. Max 500 tokens. Format: Goal — one sentence. Context — which files to look at. Constraints — max three bullets. No architecture. No “you are an expert.” No tables. No “don’t do” list unless critical. My idea: [paste]
The generating model’s talent for comprehensiveness becomes useless when you cap the output; its summarization skill is what you actually wanted.
The rest of the discipline
Compression is necessary but not sufficient. Four more rules close the remaining gaps:
Delete meta-instructions. Strip every “think carefully,” “plan first,” “consider edge cases,” “ensure production-ready” line from anything you hand an agent. The reasoning model will plan anyway if the task warrants it — let it decide. You are not making the agent dumber by removing them; you are removing explicit commands to deliberate.
Force tool-first behavior. Add a direct instruction that makes the first action cheap and concrete: “Start by inspecting the target directory and running the existing tests before planning. Do not plan the entire implementation in one step.” This changes the loop from reason → reason → reason → inspect to inspect → reason → act. Evidence acquired early collapses most of the speculative thinking, because the answers to the model’s open questions are now in the tool results instead of in its imagination.
Give a concrete execution boundary, not a state description. Compare “implement a robust, scalable caching layer with TTL, eviction, and thread-safe operations as described in this five-page spec” with “draft the interface for the cache in src/cache.ts and stop so I can review it.” The second form is one decision, one file, one review checkpoint. Breaking the initial handshake into a small, concrete boundary is the single most reliable way to prevent an upfront mental simulation of the entire feature.
Add an exit condition and a size guard. Two sentences that do disproportionate work: “Prefer the smallest coherent change that satisfies the requirements. Do not redesign existing architecture unless the task requires it.” — and for anything ambiguous, “If you cannot decide, choose the simplest option and proceed.” Reasoning models stop thinking when they judge the plan complete, and there is no timer; an explicit definition of done and permission to be imperfect are what let them converge.
Match reasoning effort to the task
The effort dial exists precisely because one setting does not fit all work. Treat it as a budget, not a quality slider:
| Task type | Reasoning effort |
|---|---|
| Rename, one-file edit, CSS change | Low |
| Add a CRUD field or simple endpoint | Low |
| Small feature, single module | Low / Medium |
| Cross-file feature work | Medium |
| Debugging a failing integration | High |
| Database migration, security-sensitive change | High |
| Architecture change, large refactor | Max |
The mistake is assuming max equals best. Max is the most expensive search over possible solutions — exactly what you want for an auth redesign and a waste for scaffolding. The better principle: enough reasoning to reach the next useful action. If your agent integration pins effort to high or max globally, override it per-session: low for the first file of a new feature, high only when the debugger is on.
And when it still happens — it will — treat the stall as a signal, not a mystery. If you see thinking run past sixty seconds with no tool call, cancel. The plan has diverged; it is not going to recover on its own. Cut the prompt by about seventy percent and retry. To attribute the cause, run the cheap experiment: give the agent a trivial task (“add a comment above foo()”) and then the real one. If the trivial task stalls too, the problem is configuration or the model endpoint, not your prompt. If only the real task stalls, it is task complexity and prompt structure — which is the part you control.
Instrument what matters: time to first tool
The reason this failure mode hides is that teams measure the wrong thing. Nobody should care how long the agent “thought” — wall-clock thinking time conflates model inference, provider queueing, context processing, and genuine deliberation. What you can act on is:
- Time to first tool call — the gap between prompt submission and the agent touching the environment. This is where the five-minute loop lives.
- Time to first edit — how long before the agent modifies a file.
A “slow” agent with a four-minute time-to-first-tool and a fast one with a seven-second time-to-first-tool are not differently smart. One is badly calibrated — pointed at an impossible planning problem before it was allowed to look at the code. If you run agents at any scale, surface both metrics per session and alert when time-to-first-tool blows past a threshold with zero tool calls. A watchdog rule — “no tool call, no repository evidence, N minutes elapsed → intervene” — turns the five-minute stall from an annoyance into a caught condition.
The bottom line
None of this is a model-quality problem. A reasoning model given a clean, grounded, bounded task is fast and excellent. A reasoning model given a 2,000-word spec it must reconcile with a repository it has never seen is a maximum-thinker pointed at a maximally ambiguous problem — and five minutes of silence is the expected output.
So stop optimizing agents for how much they can think. Optimize them for how quickly they acquire the information needed to make the next correct action. The agent loop you want is not think → think → think → act. It is enough reasoning → get evidence → act → observe → verify, repeated. Everything else — the compression rule, the tool-first instruction, the effort budget, the watchdog — exists to keep the model in that loop.
Write the goal yourself. Point the agent at the files. Give it three constraints and a definition of done. Then get out of its way — it will start coding in the time it used to spend planning to start coding.
Research note: [[Preventing Coding Agent Thinking loop]]
Saram Consulting