Prompt Engineering Techniques for Developers

Prompt Engineering Techniques for Developers

A few years into my development career, AI tools have essentially reshaped how I work. But honestly, the way a lot of people use AI to write code is pretty wasteful -- either treating it as a magic wish-granting machine that should understand everything from vague descriptions, or blindly copy-pasting whatever it spits out without review, ending up with buggy code in production.

The problem isn't the AI. It's how you talk to it.

This article isn't going to cover fancy theory or academic concepts. Just real lessons from my own mistakes and experience -- practical stuff that actually works when you're trying to get things done.

First, Understand What AI Is Good At

When I first started using ChatGPT to write code, I did something pretty dumb: I told it "help me build an e-commerce website." What I looked like it could work at first glance but had no real architecture, missed critical features like authentication, and used outdated libraries.

Eventually I figured out that AI works best when you give it small, well-defined tasks that you've already thought through. Things like "write a validated login form in React," "convert this function to async," or "write unit tests for this code" -- that's where AI shines. The more specific and bounded the task, the better the output.

What about big projects? You build the skeleton, let AI fill in the meat. You define the architecture, the technology stack, and the key design decisions. Then you ask AI to implement individual components, one at a time.

Another trap I fell into was pasting AI-generated code directly into my project without reviewing it. The first time I did this, I introduced an XSS vulnerability -- the AI's code concatenated user input directly into the DOM with no escaping whatsoever. Since then, I review every single line AI writes. It's not that AI is bad -- it just doesn't understand your specific context, your security requirements, or your business constraints.

Role Setting Actually Works

At first I didn't believe in prompts like "you are a senior engineer" -- it felt silly. But after actually trying it consistently, I noticed a real and measurable difference.

Without role setting, the AI's code style is all over the place -- sometimes concise, sometimes verbose, error handling inconsistent. But when you tell it "you are a backend engineer with 10 years of experience who values error handling and code readability," the output quality becomes noticeably more stable.

The role setting I typically use looks something like this:

You are a senior full-stack developer. Your code style is clean and clear,
with a focus on error handling and edge cases.
Your code must have comprehensive error handling, clear comments on complex logic,
and be easy to maintain by other developers.

I don't write something this long every time, but for complex requirements, spending 30 seconds on role setting saves a lot of back-and-forth later.

You can also specify the tech stack directly to avoid mixed coding styles:

You are a React + TypeScript frontend developer, strictly using functional components
and hooks, with complete type definitions and no 'any' types.
Follow React best practices and include proper accessibility attributes.

This genuinely helps. Without specifying the tech stack, the AI sometimes gives you class components when you want functional ones, or mixes various coding styles in the same file.

Describing Requirements Is Everything

"Help me write a login feature" -- I've seen prompts like this way too often, and they basically only get you the most bare-bones demo-level code.

Think of it like ordering at a restaurant. If you just say "bring me food," you get whatever the chef feels like making. You need to say how many people, what flavors, any dietary restrictions, what's the budget. Same with code.

My habit now is to describe what I need, what tech stack to use, and what the specific requirements are. For example:

Help me write a user login form. React 18 + TypeScript + Tailwind CSS.

Specific requirements:
1. Email and password input fields with validation (email format, password at least 6 characters)
2. "Remember me" checkbox that persists login state
3. Login button with loading state and disabled during submission
4. Show error messages below the corresponding field on input error
5. Redirect to home page on successful login using react-router
6. Use axios for API requests with proper error handling
7. Include "Forgot password" link

Use functional components + hooks, complete type definitions, comments on key logic.

It's a long prompt, but what AI gives you is basically usable the first time. Compared to going back and forth seven or eight rounds -- which is really more efficient?

One tip: use numbered lists for requirements, not a big paragraph. AI handles structured information much better, and numbering helps it not miss things. I've noticed that with paragraph-form requirements, AI sometimes skips details or merges separate points together.

How to Ask About Bugs

When you hit a bug, just pasting the error message into AI doesn't work that well. I've settled on a format that works much better because it gives the AI all the relevant context:

This code has a bug: (paste code)

The error message is: (paste exact error message)

I've already tried: (e.g., checked the types, confirmed data isn't null,
verified the API endpoint is correct, but the issue persists)

My environment: (relevant details like Node version, library versions, browser)

Please help me:
1. Pinpoint where the problem is and explain the root cause
2. Provide the fix
3. Explain why this issue occurs
4. How to write a test that would catch this bug in the future

The most important part is telling the AI what you've already tried. Otherwise its suggestions will probably be directions you've already ruled out, and you'll just go in circles.

For intermittent bugs that you can't reliably reproduce, I also ask AI to "list all possible causes sorted by likelihood." The debugging directions it gives are usually much more efficient than guessing on your own.

Using AI for Code Review

I've developed a habit over the past few years: after writing a complex piece of logic, I have AI look it over before I commit. Not as a replacement for human review, but a lot of basic issues -- like forgetting to handle null, making duplicate requests inside a loop, or inconsistent variable naming -- it catches immediately.

My prompt usually goes:

Review this code from these angles:
1. Any potential bugs or edge cases I'm missing
2. Any performance issues or inefficiencies
3. Any security concerns (especially injection, XSS, auth bypass)
4. Code style consistency and readability
5. What could be improved for maintainability

Give specific suggestions for each issue you find, with example code where applicable.
Rate the overall code quality from 1-10 and explain why.

Sometimes AI points out things I missed, like "this function does two things, better split it" or "there might be a race condition here." Not everything it says is right, but it does help you see blind spots in your own logic.

Learning New Things

When encountering a technology I haven't learned before, the old approach was reading docs, watching tutorials, finding examples. Now there's another path -- having AI explain it to me in a structured way.

But the key is to ask it to use plain language. Tell it "explain in the simplest terms, no jargon."

For example:

I want to learn Docker, but I've never worked with containers.
In the plainest language possible:
- What problem does Docker actually solve (vs. just using the host system)
- What are the core concepts I need to understand (images, containers, volumes, networks)
- What are the most common pitfalls beginners encounter
- Give me the simplest possible example that demonstrates a real use case

No jargon -- explain it like I'm a complete beginner who only knows basic command line usage.

Learning new concepts this way is way faster than reading official docs. Official docs are written for people with a baseline. AI can adjust the explanation to your level and answer follow-up questions on the spot.

Generating Test Code

Writing unit tests is, honestly, always been a bit tedious. So now I have AI generate the test case framework first, then I fill in the business-specific logic.

Write unit tests for this function using Jest, covering:
- Normal cases with typical input values
- Edge cases (empty arrays, null/undefined inputs, very large numbers, boundary values)
- Error cases (invalid input types, network failure simulation, timeout scenarios)
- Each test case should have a clear description of what it's testing

The test cases it generates usually cover most scenarios, and I just add a few business-specific cases. Saves a lot of time compared to writing from scratch. I've found that AI-generated tests catch edge cases I wouldn't have thought of -- particularly around input validation and error handling.

A Few Words on Security

Finally, some security reminders -- all from real mistakes I've made or heard about:

  • Don't paste company code directly into AI. This should go without saying -- many companies have explicit policies, and most AI tools use conversation data for training unless you opt out.
  • Keys and passwords need special care -- never include them in code you send to AI, and use placeholder values like process.env.API_KEY instead.
  • AI-written encryption and security-related code needs extra scrutiny. It tends to mess this up -- using weak algorithms, forgetting to salt passwords, recommending deprecated libraries. Always verify security code against current best practices.
  • For logic involving permission control and input validation, spend extra time checking yourself. AI sometimes misses authorization checks or recommends approaches that are vulnerable to injection attacks.

Wrapping Up

Using AI to write code comes down to one thing: you need to be its project manager. Describe requirements clearly like you're writing a spec. Review the output like you're reviewing a pull request. Iterate on problems like you're mentoring a junior developer.

Treat it as a capable-but-inexperienced colleague, not a magic lamp. It knows a lot, but it needs clear direction, specific requirements, and occasional course corrections.

As for how much efficiency improves -- it varies for everyone, and I don't want to make up some "3x efficiency boost" statistic. But honestly -- the gap between developers who use AI well and those who don't is widening. It's not necessarily about coding speed; it's more about how you approach problems.

The best way to start: next time you write code, spend 30 seconds writing a clear prompt first, and see how the results differ from your usual approach. Once you experience the difference, you won't go back.