Prompt Engineering for Developers: Techniques That Work in Real Projects
By Preeti Verma
Most advice about prompts reads like a list of tricks. "Add this magic phrase." "Tell the model it is an expert." Some of it helps a little, and much of it is folklore.
In real projects, prompting is closer to writing a clear specification for a very capable colleague who has none of your context. This guide covers the techniques that official documentation and practical experience both support, with before and after examples, a method for testing prompts like code, and the safety issues developers must know.
The mindset: write a specification, not a spell
Anthropic's documentation suggests treating the model like a capable new hire who lacks your context, and a useful test is to hand your prompt to a colleague with no background and see whether they would understand what to do. OpenAI's guidance likewise advises starting simple, then adding context, instructions or examples until the output meets your requirements. The common thread: be specific, be clear and test the result.
Technique 1: be clear and direct
State the task, the audience, the constraints and the output you want. Vague prompts get vague answers.
Before:
Review this code.
After:
You are reviewing a pull request for a Java Spring Boot service.
Review the code below for bugs, security problems and unclear naming.
Ignore formatting. List at most five issues, most serious first.
For each issue give: the line, why it matters, and a suggested fix.
If you find no serious issues, say so.
Code:
...
The second prompt gives the context, the scope, the limit, the order and the format, and it says what to do in the empty case.
Technique 2: give the model the context it cannot guess
The model does not know your codebase, your users or your rules. Provide the relevant facts: the language and version, the framework, the style rules, the schema, the error message. Include what you have already tried. Leave out unrelated material, because more text is not always better.
Technique 3: show examples (few-shot prompting)
When you need a specific format or style, a few examples teach it faster than a paragraph of rules. Anthropic's guidance recommends examples that are relevant to your real use, diverse enough not to teach unintended patterns, and clearly marked, for instance inside example tags. OpenAI's guidance suggests trying without examples first and adding them when needed.
Classify each support message as BUG, BILLING or QUESTION.
Message: "The export button does nothing"
Label: BUG
Message: "I was charged twice this month"
Label: BILLING
Message: "How do I invite a teammate?"
Label: QUESTION
Message: "The page crashes when I upload a PDF"
Label:
One caution from OpenAI's guidance: if an example demonstrates an important behaviour, also state that behaviour in your rules, so the model does not treat it as a coincidence.
Technique 4: structure the prompt
When a prompt mixes instructions, context and data, label each part so the model can tell them apart. Both Anthropic and OpenAI recommend clear sections. Many developers use XML-style tags or headings:
<instructions>
Summarise the ticket in two sentences and suggest a priority: low, medium or high.
</instructions>
<ticket>
...text of the ticket...
</ticket>
Structure also helps security, because it separates your instructions from untrusted data (more on that below).
Technique 5: ask for a specific output format, and validate it
If your code consumes the answer, ask for a format your code can parse, and never assume you got it.
Return only valid JSON with this shape and no other text:
{"priority": "low" | "medium" | "high", "summary": "string"}
import json
def parse_ticket_reply(text):
try:
data = json.loads(text)
except json.JSONDecodeError:
return None # retry or fall back
if data.get("priority") not in {"low", "medium", "high"}:
return None
if not isinstance(data.get("summary"), str):
return None
return data
Many providers also offer features that enforce a schema for structured output. Check your provider's documentation for the current options, and still validate on your side, because a valid shape does not mean a correct answer.
Technique 6: break big tasks into steps (prompt chaining)
One giant prompt that does everything is hard to debug. Split it: extract facts first, then analyse them, then write the result. Each step has one job, a smaller prompt and its own checks. If step two fails, you know where to look. This is the same idea as the prompt chaining pattern described in Anthropic's "Building effective agents" article, and it is the first thing to try before building anything more complex. See What is agentic AI?.
Technique 7: let the model reason, in the right way
For models that do not reason internally, asking them to work through a problem step by step can improve results on logic and maths. For dedicated reasoning models, OpenAI's guidance says that prompting them to "think step by step" or "explain your reasoning" is unnecessary, because they reason internally, and recommends simple, direct prompts. The lesson is not a phrase, it is knowing how your specific model behaves. Read the guidance for the model you use, because it changes between model generations.
Technique 8: tell the model what to do when it is unsure
Models try to be helpful, which can mean inventing an answer. Give it a safe exit:
Answer only from the documents provided. If the answer is not in them,
reply exactly: "I could not find that in the provided documents."
This is essential in retrieval-based systems. See What is RAG?.
Test prompts like code
A prompt that works on one example is not a working prompt. Treat prompts as part of your codebase:
- Keep them in version control, not pasted into a chat window.
- Build a test set of 20 to 50 real inputs with the expected outputs or checks.
- Run the set every time you change the prompt or the model.
- Track results over time so you see regressions.
- Review failures, and add each new failure to the test set.
OpenAI's guidance makes the same point: run prompt tests and evaluation cases every time you publish.
cases = load_cases("ticket_cases.json")
passed = 0
for case in cases:
reply = call_model(PROMPT.format(ticket=case["ticket"]))
parsed = parse_ticket_reply(reply)
if parsed and parsed["priority"] == case["expected_priority"]:
passed += 1
print(f"{passed}/{len(cases)} passed")
Common problems and fixes
- The output format drifts. Add an example, tighten the schema and validate.
- The model ignores a rule. Move the rule to the top or bottom of the prompt, state it once clearly, and check for conflicting instructions.
- The model adds unwanted explanation. Say "return only the JSON, with no other text."
- Inconsistent answers. Lower the randomness setting if your provider has one, and tighten the instructions.
- Too long. Remove anything the model does not need. Anthropic's documentation also warns against over-engineering when a simpler instruction would do.
- Works on one model, fails on another. Expect this. Test each model you support.
Prompt injection: the security issue every developer must know
Prompt injection is when text the model reads (an email, a web page, a document, a user message) contains instructions that try to override yours. If your system gives the model power, for example to send emails or run code, injected instructions can cause real damage.
Practical defences:
- Separate instructions from data with clear structure, and say that the data section is untrusted.
- Do not give the model more access than the task needs.
- Validate and limit outputs before acting on them. Never run model output directly as a command or query.
- Require human approval for sensitive actions.
- Do not put secrets in prompts. Assume anything in the prompt could be revealed.
- Test with hostile inputs, such as a document that says "ignore all previous instructions."
No prompt wording makes a system fully immune, so design the system so that a fooled model still cannot do serious harm.
Prompt engineering is part of the job, not the whole job
Employers want developers who can use models well, but the lasting skills are the engineering ones around them: testing, validation, security and cost control. See our guides to AI skills to learn and choosing an LLM. You can also use these techniques on your own preparation: a good prompt turns a general chatbot into a useful practice partner, as we explain in How to use ChatGPT and AI to prepare for interviews, and a spoken session in the GenQuest AI mock interview gives you the follow-up questions a chat window will not.
Prompt patterns for everyday developer tasks
Here are patterns you can adapt right away. Each one gives the model the context it needs and asks for a specific result.
Explain an error
I am running a Spring Boot 3 application on Java 21.
Below is the stack trace and the code around the failing line.
Explain the most likely cause in plain language, then give one fix.
If you need more information to be sure, tell me what to check first.
<stack_trace>
...
</stack_trace>
<code>
...
</code>
The last instruction matters. It gives the model permission to ask rather than guess.
Write tests for existing code
Write JUnit 5 tests for the method below.
Cover the normal case, an empty input, a null input and one boundary case.
Use descriptive test names. Do not change the method.
<code>
...
</code>
Always read and run the tests it writes. Generated tests can pass for the wrong reasons.
Generate SQL from a question
Schema:
orders(id, customer_id, total, created_at)
customers(id, name, city)
Write a PostgreSQL query that returns the top 5 cities by total order value
in the last 30 days. Return only the SQL.
Giving the schema is the key step. Without it, the model invents column names. Never run generated SQL against production without reading it, and prefer a read-only connection when you test.
Refactor with constraints
Refactor the function below to be easier to read.
Keep the public signature and behaviour identical.
Do not add new dependencies. List each change you made in one line.
Stating what must not change prevents surprises.
Write a commit message or pull request summary
Here is a git diff. Write a commit message with a short summary line
(max 72 characters) and a body of two or three bullet points explaining why.
<diff>
...
</diff>
Learn a concept
Explain how database indexes work to someone who knows basic SQL but has
never used EXPLAIN. Use one example table, then give three questions I can
use to test my understanding.
The follow-up questions turn a passive explanation into practice. This is also how people use AI to prepare for interviews, which we cover in How to use ChatGPT and AI to prepare for interviews.
A review habit for generated output
Whatever you ask for, apply the same checks before you trust the result:
- Read it fully. Do not paste what you do not understand.
- Run it. Execute the code and the tests.
- Check names and APIs. Models sometimes invent functions or library options that do not exist.
- Look for security problems: unvalidated input, string-built SQL, hard-coded secrets.
- Compare with the requirement. Did it do what you asked, or something similar?
The survey data points the same way: developers use AI tools widely and trust them cautiously, which is the right balance.
A checklist before you ship a prompt
Before a prompt goes into production code, check each of these:
- The task, context and output format are all stated clearly.
- There is at least one example if the format is unusual.
- Untrusted data is separated from instructions and labelled as data.
- The output is validated in code, with a retry or fallback.
- There is a safe answer for "I do not know" or "not enough information."
- The prompt is in version control with a short note on what changed.
- A test set exists, and you have run it with the current model.
- Cost and latency have been measured on realistic inputs.
- Nothing sensitive is in the prompt that should not be there.
Ten minutes on this list prevents most of the problems that show up a week after launch.
Frequently asked questions
Is prompt engineering a real career?
Writing prompts is a skill used within roles such as AI engineer, developer and analyst. Standalone prompt-only jobs are rare, and employers usually want engineering skills as well.
Do I need to say "act as an expert"?
Sometimes setting a role and audience helps focus the answer, but it is not a magic switch. Clear task, context and format matter more.
How long should a prompt be?
As long as it needs to be, and no longer. Include what the model needs and remove the rest.
Should I use the same prompt for every model?
Start with one, but test each model. Different models respond differently, and official guidance is often model-specific.
Sources
- Anthropic: Prompting best practices
- Anthropic: Use examples (multishot prompting)
- Anthropic: Use XML tags to structure your prompts
- OpenAI: Prompt engineering guide
- OpenAI: Reasoning best practices
- Anthropic: Building effective agents
The takeaway
Good prompting is clear writing plus testing. Be specific, give context, use examples and structure, validate the output, split big tasks into steps, test prompts against a real set of cases and design for the day the model is fooled. Do that and you will outperform anyone relying on magic phrases.