In Part 1, I talked about the Bangla vs English question and came to a simple conclusion:
The language matters less than the clarity of the prompt.
Now let's get into the more practical part.
When a prompt doesn't give me the result I want, I usually don't immediately blame the model.
First, I look at the prompt and ask:
"Did I actually explain what I need?"
Because a lot of the time, the problem isn't the LLM.
The problem is that I gave it a very open-ended instruction.
Start With the Problem, Not the Prompt
One thing that helped me a lot is stopping myself from writing the prompt too quickly.
Before asking the model anything, I try to understand the actual problem first.
For example, instead of thinking:
"I need a better navbar prompt."
I think:
"My navbar works, but the mobile menu feels too large and the spacing is inconsistent."
Now the problem is clear.
So the prompt becomes much easier to write:
I have an existing responsive navbar. The functionality is working, but the mobile menu feels too large and the spacing is inconsistent. Keep the existing navigation logic and color palette. Improve the mobile layout, reduce unnecessary spacing, and keep the component accessible.
That is a much stronger request.
The main difference is simple:
I am not asking the AI to "make it better." I am telling it what is actually wrong.
The Prompt Structure I Usually Follow
There are many prompt frameworks online, but I don't think you need to memorize a complicated one.
For most development tasks, I can get pretty far with this:
Context → Goal → Requirements → Constraints → Output
Let's break that down.
1. Context
First, explain what you are working with.
For example:
I am building a personal portfolio using Next.js, TypeScript, and Tailwind CSS.
That's enough to give the model some direction.
Without context, the model may choose a completely different stack or approach.
2. Goal
Next, explain what you actually want to achieve.
For example:
I want to improve the projects section so it feels more professional and easier to scan.
Now the model understands the purpose.
3. Requirements
Then explain what the result should contain.
For example:
Each project card should include the project image, title, short description, tech stack, GitHub link, and live demo link.
Now the model has something concrete to work with.
4. Constraints
This part is easy to forget, but it can make a huge difference.
For example:
Do not introduce a new UI library. Keep the current typography and color palette. Make sure the layout still works on mobile.
Now the model knows its boundaries.
This is especially useful when you are working inside an existing project.
You usually don't want the AI to redesign everything just because you asked it to change one section.
5. Output
Finally, tell it what kind of response you want.
For example:
First explain the layout approach in a few sentences, then provide the updated component.
This is useful because otherwise the model might give you a giant explanation, a lot of code, or both.
A Small Example
Let's take a bad prompt:
Make my portfolio better.
There is almost nothing to work with.
Now let's improve it:
I have a developer portfolio built with Next.js and Tailwind CSS. The site looks clean, but the projects section feels generic. I want the project cards to feel more polished and easier to scan. Keep the existing color palette and typography. Add better hierarchy, spacing, and hover interaction without making the design flashy. First suggest the layout improvements, then provide the code.
Now the model has:
Context: existing portfolio
Goal: improve project section
Requirements: hierarchy, spacing, hover interaction
Constraints: don't change colors, don't make it flashy
Output: explain first, code second
That's a much better conversation to have with an LLM.
Don't Ask for Everything at Once
This is another thing I had to learn.
When I started using AI for development, it was tempting to write one giant prompt like:
Build the full website, create the components, add animations, connect the API, add authentication, make it responsive, write tests, and fix all errors.
Sometimes the result looks impressive.
But once you start reviewing the code, problems appear.
Some components don't match.
Some assumptions are wrong.
Some parts are over-engineered.
And fixing one thing can break another.
So now I prefer smaller steps.
For example:
First, define the page structure.
Then:
Now create the hero section.
Then:
Build the projects section using the same design system.
Then:
Add responsive behavior.
Then:
Review the whole page and identify accessibility issues.
The AI becomes much easier to control.
And more importantly, I can review the result after every step.
Think in Iterations
I think this is where prompt engineering becomes genuinely useful.
Imagine the AI gives you a component.
It's not terrible.
But it's not right either.
Instead of saying:
This is bad. Try again.
Give precise feedback.
For example:
The layout is fine, but the section feels visually heavy. Reduce the card padding, shorten the descriptions, and make the project title more prominent. Keep the existing structure and do not change the color palette.
That's useful feedback.
You can keep going:
Better. Now make the cards equal height and keep the buttons aligned at the bottom.
Then:
Good. Add a subtle hover interaction, but keep the animation under 200ms.
Each prompt is now building on the previous result.
That's much closer to real development.
Don't Just Ask for Code
One of my favorite ways to use LLMs is asking them to explain their thinking before writing the implementation.
For example:
Before writing the code, explain how you would structure this component and why.
This can be useful when the problem is architectural rather than purely syntactical.
For example, you might learn that the feature should be split into:
- a parent section
- reusable card component
- data object
- utility function
You may still disagree with the suggestion.
That's fine.
The point is that you're getting an additional perspective before committing to code.
Ask the Model to Review Its Own Work
Another useful pattern is to separate generation from review.
Instead of:
Build this component.
Try:
Build this component first. Then review the implementation for accessibility, responsiveness, unnecessary complexity, and potential bugs. List the issues you find and fix them.
This doesn't guarantee perfect code.
But it gives the model a second pass.
And in practice, that second pass can catch things that were missed during the first one.
Give It Your Existing Code
This becomes even more important when working on a real project.
Suppose you already have a component:
<Button variant="primary">
View Project
</Button>And you want to add a loading state.
Instead of:
Create a loading button in React.
Give the existing context:
Here is my current Button component:
[existing code]
I want to add a loading state while keeping the current API and existing variants. Do not break the current usage. Show me the smallest clean change needed.
Now the model isn't inventing a completely new solution.
It's working inside your existing system.
That usually produces much more useful code.
Tell It What Must Not Change
This is one of the simplest improvements you can make to a prompt.
Let's say you like your current UI and only want to improve one section.
You can say:
Keep the existing typography, colors, spacing system, component API, and responsive behavior. Only improve the visual hierarchy of the projects section.
This reduces unwanted changes.
I've found that telling the model what not to touch can be just as important as telling it what to change.
Use Examples When You Care About Style
Sometimes words aren't enough.
Suppose you want project descriptions to have a certain style.
Instead of:
Write a professional project description.
Give an example:
Keep project descriptions similar to this:
"Built a real-time analytics dashboard that helps teams monitor user activity and conversion trends."
Keep future descriptions around the same length, tone, and level of technical detail.
This gives the model a reference point.
And I find examples especially useful for:
- UI copy
- project descriptions
- landing page text
- headings
- error messages
- documentation
- commit messages
When you want consistency, examples are often better than vague instructions.
A Mistake I See a Lot: Too Much Prompt, Too Little Direction
There is another trap.
People sometimes think:
Long prompt = good prompt
Not really.
A long prompt can still be confusing.
For example, you can write 500 words describing a website, but if the actual goal is hidden somewhere in the middle, the prompt isn't necessarily useful.
I prefer prompts where each piece of information has a reason to exist.
The question I ask is:
"Does this information help the model make a better decision?"
If not, it probably doesn't need to be there.
Prompting for Debugging
Prompt engineering is not only for generating code.
It can also be useful for debugging.
Instead of:
My code isn't working. Fix it.
Give the model the actual problem.
For example:
I have a Next.js application using the App Router. This component throws a hydration mismatch warning on the client. Here is the component and the relevant error message.
[code]
[error]
First explain the likely cause. Then show the smallest change that would fix it. Do not rewrite the entire component.
This is much better.
Because now the model understands:
- the framework
- the problem
- the evidence
- the desired scope of the fix
Ask for the Smallest Change
This is especially useful when you're working on an existing codebase.
For example:
Fix the issue with the smallest possible change. Do not refactor unrelated code.
That sentence can save you from getting a completely rewritten file.
Because sometimes an LLM sees an opportunity to "improve" five other things while fixing one bug.
You probably don't want that.
Don't Trust the First Answer
This might be the most important part.
LLMs can confidently give you something that looks correct but isn't.
So when the task matters, I usually ask follow-up questions.
For example:
Why did you choose this approach?
or:
What are the trade-offs of this implementation?
or:
Are there any edge cases I should test?
or:
Could this cause a performance issue?
These questions often reveal important details.
And sometimes they reveal that the first answer wasn't actually the best solution.
The Developer Still Has to Think
This is something I think is easy to forget when using AI.
An LLM can write code very quickly.
But speed doesn't automatically mean correctness.
You still need to understand what you're accepting.
When I use AI-generated code, I want to know:
Why does this work?
What assumptions is it making?
What happens in an edge case?
Will this scale?
Is there a simpler solution?
Does this actually fit my project?
That's why I see prompting as a productivity skill rather than a replacement for engineering judgment.
A Prompt I Would Actually Use
Here is a practical example that combines everything above:
Act as a senior frontend developer.
I am working on a personal developer portfolio built with Next.js, TypeScript, and Tailwind CSS.
The current projects section works, but visually it feels too generic. I want to improve the hierarchy and make the cards easier to scan.
Each card should contain:
• Project image
• Project title
• Short description
• Tech stack
• GitHub link
• Live demo link
Keep the existing color palette, typography, and overall design language. Do not add a new UI library or redesign unrelated sections.
Make the cards responsive and keep the hover interaction subtle.
First explain the recommended layout changes. Then provide the updated component. Finally, review the code for accessibility and unnecessary complexity.
That is the kind of prompt I find much more useful than simply asking:
"Make my project section better."
The Bigger Lesson
The more I use LLMs, the more I realize that prompt engineering is really a communication skill.
The model doesn't know what is in your head.
It only knows what you give it.
So the better you can communicate:
what you have,
what you want,
what should stay,
what should change,
and what the final result should look like,
the more useful the output becomes.
And this is why I don't think the main goal should be finding some "secret prompt."
The better goal is learning how to describe a problem clearly.
What's Next?
So far, we've talked about the thinking behind better prompts.
But the most interesting part is what happens when you actually use this approach on a real project.
In Part 3, I'll take a website as an example and go through the prompting process step by step—from the first idea, to structure, UI, code generation, refinement, and final improvements.
That's where the theory becomes much more practical.