Every few weeks someone publishes a hot take about whether “prompt engineering” is a real skill. Half the replies say it’s the future of software. The other half say it’ll be automated away within a year.
Both camps are missing something.
The Thing Prompt Engineering Actually Is
Writing a good prompt is an act of specification. You have a system (the LLM) that will do exactly what you describe — no more, no less. If your description is ambiguous, you’ll get an ambiguous result. If you don’t specify the edge cases, they won’t be handled.
This is not a new problem.
It’s the same problem you have when you write a ticket for another developer. When you write a function signature that other engineers will implement. When you write a test that encodes expected behavior. When you write requirements that a system will be built against.
The discipline is the same: communicate intent precisely, anticipate misinterpretation, specify the constraints.
Where Prompt Engineers Are Failing
The engineers who complain that prompting is “not real engineering” usually mean: I’ve seen terrible prompts. And they’re right. Most prompts are vague, context-free, and optimistic about the model’s ability to read minds.
But the solution isn’t to dismiss prompting — it’s to apply the rigor that good engineering has always demanded.
A good prompt:
- States the goal, not the steps (unless the steps matter)
- Provides relevant context the model can’t infer
- Specifies the format and scope of the expected output
- Includes examples when the task is ambiguous
- Anticipates failure modes and constrains against them
This is exactly what a well-written test case looks like. Or a good API spec. Or a clear user story.
The Part That Is New
What is genuinely different about prompting LLMs vs. traditional specification:
The system is probabilistic. You can write a perfect prompt and still get variance. Traditional specs don’t have that property — a deterministic system either meets the spec or it doesn’t.
Iteration is cheap. The feedback loop is seconds, not days. This changes how you approach specification — you can explore and refine rather than front-loading all the precision.
The system has broad world knowledge. You don’t need to define terms that are common knowledge. But you do need to be precise about anything domain-specific or unusual.
Failure modes are different. Traditional systems fail loudly. LLMs fail confidently. A bad prompt doesn’t return an error — it returns a plausible-sounding wrong answer. The test passes. The PR description sounds correct. The generated spec covers the happy path and omits every edge case that matters. A quality engineer catches this because they’ve been trained to look for it. A developer who treats the output as correct and moves on doesn’t.
This is the specific advantage that QE thinking brings. Not just that you can spot a hallucinated result, but that you’re already suspicious of anything that looks too clean.
What This Means for Quality Engineers
If you work in quality engineering, you have a head start here. The skill of thinking adversarially about how something could go wrong, the habit of specifying behavior precisely, the instinct to ask “but what if…?” — these transfer directly.
Here’s what that looks like in practice. Compare these two prompts for the same task:
Vague:
“Write a test for the login endpoint.”
QE specification framing:
“Write tests for
POST /auth/login. Valid credentials return 200 with a JWT. Invalid password returns 401 with{ error: 'invalid_credentials' }. Locked account returns 403 with{ error: 'account_locked' }. Missing body returns 400. The token must expire after 24 hours — include an assertion for theexpclaim.”
The second prompt isn’t longer because you’re being thorough for its own sake. It’s longer because you’ve specified what the system needs to know to produce a useful result. Same discipline. Different syntax.
Quality engineers have been writing specifications under uncertainty since before LLMs existed. That’s not just a head start — it’s the job description, repackaged.