Effective prompt engineering for AI newbies
Here’s a little guide on how I speak to my LLMs. I’m a very heavy Claude user, but I’m entirely sure these same tactics work across all models because they’re fundamental to the way LLMs work.
As a disclaimer, I don’t think anything in here is particularly groundbreaking or novel; I’m just sharing my thinking and why I frame things the way I do when using these tools.
The basics⌗
First up - the basics. It’s a machine.
Don’t speak to it like a person. Filler words are not neutrally unhelpful, they’re actively negative - they pollute the context window and waste tokens.
You don’t need to say please, you don’t need to ask it to do something, you don’t need to apologize or hedge. Use very clear, direct language, and don’t waste precious tokens on filler!
Secondly, frontload your context. Include the most important information up front - give it what you want, any contraints, examples if possible, and what format you need for it to be acceptable.
Finally, be specific. I use the term unreasonable specificity. Given that you should be as direct and clear as possible, you should dictate exactly what you want. This is easier when you’re an expert in the domain you’re working in - I can be exceedingly clear when I want something written in PHP for example, and less so if I’m writing in Swift - but even if you’re not an expert you’re still the one driving. Instead of being specific about the implementation, be specific about the results you want instead.
Your job is to remove as much doubt and ambiguity as possible, threading the needle between verbosity and conciseness.
Prompt structure⌗
I typically structure my prompts like this:
- Task statement - What I want done
- Context/Requirements - Key details, format, constraints
- Examples (if appropriate) - Show, don’t tell
- Success criteria - What does a good output look like?
This is how I structure any writing, even for other humans!
Examples⌗
Example 1: Remove unnecessary politeness⌗
Hi there! Could you please help me to write some JavaScript. I'm trying to write a function that adds two numbers together. Please write this for me.
Write a JavaScript function that [adds two numbers and returns the result](## "Clear, specific task").
The bad version wastes tokens on pleasantries. The good version gets straight to the point and is far more specific about the return behavior.
Example 2: Frontload your context⌗
Can you help me write some code? I'm working on a project and I need a function. It should take a string as input. The function needs to return something. Actually, I want it to return the string but reversed. Oh, and make sure it handles edge cases like empty strings.
Write a Python function that [reverses a string, handling empty strings gracefully](## "Context first, clear requirements"). [Return just the function with a docstring](## "Specific output format").
The bad version makes the LLM parse through scattered requirements. The good version states everything upfront and specifies the exact output format needed.
Example 3: Be specific about format⌗
I need help with my resume. Can you make it better? Here's what I have so far: [resume content]. Improve it so it reads better.
[Rewrite this resume to be more concise and highlight technical achievements](## "Specific improvements requested"). [Keep it to one page, use bullet points, focus on quantifiable results](## "Clear constraints"). [Return only the revised resume text, no commentary](## "Exact output specification").
[resume content]
'Make it read better' is so ambiguous, and whilst most models will do a decent job at this, but we can do better than leaving it to chance! The good version specifies exactly what improvements to make, the constraints to follow, and the output format.
Example 4: Use examples instead of lengthy explanations⌗
I need you to extract data in a very specific way. What I want is to find all the email addresses, but only the ones from companies, not personal emails. Company emails usually have domains like company names, not gmail or yahoo or hotmail. Personal emails are like [email protected] but company emails are like [email protected]. So basically I want corporate email addresses extracted from text. Here's the list:
[list of emails]
Extract corporate email addresses from this list. Exclude gmail, yahoo, hotmail, outlook, etc.
[Examples of what to extract:
- [email protected] ✓
- [email protected] ✓
- [email protected] ✗](## "Examples show exactly what you want")
[list of emails]
I see this all the time! Instead of a 50+ word explanation, three examples instantly communicate the exact requirement. Much clearer and uses fewer tokens.
Example 5: Specific trigger words⌗
Change the "I" image type so that it works like the other examples in the page.
Simplify the current code that handles my "I" image type. [Refactor](## "Specific meaning") it so that it uses the same `<template>` mechanism that's used by the "F" type. It's important to [retain all of the specific functionality, layout etc](## "Clear example of success") that is currently in my "I" type.
'Simplify' and 'refactor' are much more specific than 'change'. Success criteria is provided by telling it to retain functionality but change only the implementation/structure.