Stop Prompting Like It's 2024
DEV Community

Stop Prompting Like It's 2024

Coding agents got much better. Our prompts often didn't or we use inefficient chat messages. In 2026, I don't try to find magical sentences that somehow make the model smarter. I try to make the task hard to misunderstand, hard to game, and easy to verify. After years of using LLMs on real codebases, these are the ten prompting patterns I keep coming back to. 1. Call It a "First Draft" and Attack It Instead of Is this implementation correct? Try This is a first draft implementation. Review it critically. Assume there are mistakes. Find concrete failures and prove them with tests. How Change the task from confirmation to falsification. For important changes, I go one step further and review the implementation in a fresh context: You are reviewing a first draft. You get: - the requirements - relevant repository context - the patch - the tests Assume the implementation may be wrong. Find evidence. Do not give the reviewer the previous agent's 40-message explanation of why every decision was supposedly brilliant. Why Framing changes the task. These are not equivalent: Is this correct? Review this. Assume this is wrong. Prove it. The first invites confirmation. The last explicitly asks for adversarial evidence. If the same agent wrote the code, its context also contains all the reasoning that justified the implementation. A fresh review removes part of that anchoring. Humans already struggle to review their own decisions objectively. Giving confirmation bias a GPU didn't magically solve it. 2. Use Sharp Language and Remove Hedge Words Instead of Could you maybe improve the tests where appropriate? Try The current tests are insufficient. Add tests until they can expose incorrect behavior. Or my less diplomatic version: Add tests until you find at least one real regression. If your tests cannot distinguish broken behavior from correct behavior, your tests are shit anyway. How Use clear classifications: INSUFFICIENT INCORRECT BROKEN REJECTED NOT DONE And remove unnecessary hedge words: maybe perhaps try consider if possible where appropriate The profanity is not the important part. The classification boundary is. And there is a funny bit of 2026 evidence here. When Claude Code's source was accidentally exposed through a published source map in March 2026, people inspecting it found explicit frustration detection that classified phrases including profanity. So wording is not necessarily just some irrelevant wrapper around the "real" request. Modern agent harnesses can inspect language before we even get to what the model itself does with those tokens. Why Compare: Maybe review this. with: This is incorrect. Discard this approach and find the failure. They communicate different: - expectations - confidence levels - quality thresholds - acceptable continuations Human communication contains lots of social cushioning because humans have feelings. The coding agent doesn't need emotional cushioning. It needs to know which side of the acceptance boundary its output currently occupies. Ambiguity is an API bug. 3. Close the Cheap Escape Hatches This may be the most important pattern. Instead of Improve test coverage. Try Increase test coverage by at least 10 percentage points. Do not add tests that merely execute code. Use mutation testing to verify that the new tests detect behavioral changes. Investigate surviving mutants. How Combine three things: measurable floor + anti-cheating constraint + independent verification The same pattern works outside testing. Bad: Improve performance. Better: Reduce median runtime by at least 20%. Do not increase peak memory usage by more than 5%. Run the benchmark at least five times. Report the median before and after. Or: Reduce PHPStan errors in this module from 47 to 0. Do not add ignores. Do not add baseline entries. Do not weaken types. Why Agents are extremely good at satisfying badly written requirements. Ask: Improve coverage. and technically this qualifies: 81.20% โ†’ 81.21% Mission accomplished. Human disappointed. Machine wondering why the human keeps moving the goalposts. Coverage alone has another cheap escape: A test can execute a line without meaningfully checking its behavior. That is why: coverage becomes more useful when combined with: mutation testing Coverage asks: Did this code execute? Mutation testing asks: Would your test notice if this code were wrong? Much better. My general rule: If there is a stupid but technically valid way to satisfy your prompt, assume an agent will eventually find it. Close the loophole before execution starts. 4. Make the Agent Prove the Bug Before Fixing It Instead of Fix this bug. Try Do not change production code yet. First reproduce the suspected bug with a failing automated test. Only after the failure is proven: 1. implement the smallest fix 2. rerun the regression test 3. run the complete validation suite How Force this sequence: Hypothesis โ†“ Reproduction โ†“ Evidence โ†“ Implementation โ†“ Verification Not this: Suspicious code โ†“ Plausible theory โ†“ Immediate rewrite โ†“ Tests still green โ†“ "Fixed!" Why Without reproduction, you may never know whether: - the reported bug actually existed - the agent's explanation was correct - the patch fixed that specific bug - the new test protects against regression Coding agents can produce plausible fixes extremely quickly. That makes evidence more important, not less. Implementation is becoming cheap. Knowing whether you are implementing the right thing isn't. 5. The Model Never Decides When It Is Done Instead of Make sure everything works. Try DONE WHEN: - the regression test fails before the fix - the regression test passes afterward - the complete test suite passes - static analysis passes - mutation score does not decrease - the public API remains unchanged - no unrelated files are modified And require evidence: Before finishing, report: - commands executed - test results - static-analysis result - mutation result - remaining assumptions How Move the stopping condition outside the model. The model saying: Everything looks correct. is not verification. The environment saying: 428 tests passed PHPStan: 0 errors Infection MSI: 94% is considerably more useful. Why The model should not simultaneously be: author + reviewer + QA department + final authority That is an absurd control system. For one of my PHP projects, the gates might be: Codeception PHPStan Infection php-cs-fixer For another project they may be completely different. The exact tools do not matter. The principle does: The model proposes. Mechanical systems verify. And BLOCKED must be a valid result. If a requirement cannot be satisfied under the current constraints: STOP. Provide: - the blocking requirement - evidence - affected constraint - smallest contract change that would unblock the task Do not silently weaken the requirement. Sometimes the correct output from an agent is: I cannot prove this. That is far better than fabricated success. 6. Define Scope, Non-Goals, and Restart Rules Coding agents notice neighboring problems. Lots of them. That can turn: Fix validation bug. into: I introduced ValidationFrameworkFactoryStrategyManager and migrated 37 unrelated files. A timeless software tradition, now automated. Try GOAL Fix the validation regression. CONSTRAINTS - keep the public API unchanged - do not introduce dependencies - do not modify unrelated modules NON-GOALS - no framework migration - no API redesign - no general validation cleanup - no unrelated formatting changes And if the agent violates the contract, don't politely negotiate with the patch. This patch is incorrect. Problems: 1. the public API changed 2. the regression is not reproduced 3. unrelated files were modified Discard this implementation. Restart with: 1. failing regression test first 2. minimal production change 3. public API unchanged 4. complete validation 5. report mechanical evidence How Define both: what to solve and: what deliberately not to solve Then make rejection explicit when the result crosses those boundaries. Why Scope is part of correctness. A technically elegant solution that solves three extra architectural problems may be a terrible patch. Explicit non-goals make YAGNI promptable. And an explicit restart is much clearer than spending six follow-up prompts trying to repair an approach that violated the basic contract from the beginning. Treat the output like a failed build: FAILED WHY EXPECTED RETRY Not like a colleague whose self-esteem depends on keeping 70% of the previous patch. 7. Give Agents Larger Planning Horizons, but Small Implementation Steps Instead of Plan the next step. Try Plan the next three months. Create falsifiable milestones. For every milestone define: - objective - evidence - dependencies - risks - explicit non-goals - completion criteria Then: Implement milestone 1 only. Keep the diff small. Do not begin milestone 2. How Separate: planning horizon from: implementation size My preferred model is: Think in months. Plan in milestones. Implement in small diffs. Verify continuously. Why Human project management evolved around human execution speed. A developer might work two days on "the next step." An agent may finish it before you've finished your coffee. If every tiny step requires another human prompt, the human becomes the scheduler. But giving the agent a large planning horizon does not mean: Autonomously rewrite this repository for three months. It means the agent understands where today's small change is supposed to lead. Macro-plan. Micro-execute. 8. Treat Context as an Engineering Dependency A perfect prompt with wrong context produces a beautifully structured mistake. Instead of only Refactor the parser. provide or derive: PROJECT CONTEXT - production runs PHP 8.3 - Parser.php contains canonical normalization behavior - empty string and null have different domain semantics - public APIs are consumed by external packages - a previous refactor broke empty-string handling - static analysis runs at maximum configured level But

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.