On the wallpaper app I run, I let Gemini sort incoming images into categories like "night view," "minimal," and "animals." My first prompt was a single line: "What category does this image belong to?" The answers came back inconsistent — sometimes "night view," sometimes "nighttime cityscape" — for the very same image. I couldn't drop that straight into a database.
The same Gemini model can be far more or far less stable depending on how you phrase the instruction. Prompt engineering is the craft of shaping that phrasing so you can reliably pull out the exact form of answer you want. It isn't flashy, but when you're a solo developer wiring AI into real work, I find it's the highest-return investment you can make.
Here I'll walk through the three techniques I keep coming back to — System Instructions, Few-shot prompting, and Chain-of-Thought — with working code and the spots where I stumbled along the way.
Using System Instructions
System Instructions control Gemini's behavior across an entire conversation. You can set them in Google AI Studio or via the API, and they apply consistently to every response.
Setting Up in Google AI Studio
In Google AI Studio, enter your instructions in the "System Instructions" panel on the left. Specify the model's role, output format, and any constraints.
Setting Up via API
# system_instructions_example.py
# Configure System Instructions with the Gemini API
import google.generativeai as genai
genai.configure(api_key="YOUR_API_KEY")
model = genai.GenerativeModel(
model_name="gemini-2.0-flash",
system_instruction="""You are a Python programming expert.
Follow these rules:
- Always include type hints in code examples
- Add clear comments explaining each step
- Mention security considerations when relevant
- Keep responses concise, under 300 words"""
)
response = model.generate_content("How do I safely read a file in Python?")
print(response.text)
# Expected output:
# Use the `with` statement for safe file handling:
# ```python
# from pathlib import Path
#
# def read_file_safely(file_path: str) -> str | None:
# """Safely read a file and return its contents."""
# path = Path(file_path)
# if not path.exists():
# return None
# # Security: resolve() prevents path traversal attacks
# resolved = path.resolve()
# return resolved.read_text(encoding="utf-8")
# ```Effective System Instructions include three key elements: role definition ("You are a ... expert"), output format specification ("in bullet points", "as JSON"), and constraint setting ("under 300 words", "in English"). For the wallpaper classifier, I added one more line here — "always pick exactly one category from the following 12 words" — pinning down the vocabulary itself. That single sentence in the System Instructions stopped most of the wording drift on its own.
Few-shot Prompting
Few-shot prompting provides 2–5 examples of desired output to guide the model's response pattern. It's especially effective for teaching the model new task formats.
# few_shot_example.py
# Few-shot prompting for sentiment analysis
import google.generativeai as genai
genai.configure(api_key="YOUR_API_KEY")
model = genai.GenerativeModel("gemini-2.0-flash")
prompt = """Analyze the sentiment of each review in this format:
## Example 1
Review: This product exceeded my expectations. Fast shipping and careful packaging.
Sentiment: Positive
Score: 0.92
Keywords: exceeded expectations, quality, fast shipping, careful
## Example 2
Review: The item looks nothing like the photos. Support is unreachable.
Sentiment: Negative
Score: 0.15
Keywords: nothing like photos, support unreachable
## Example 3
Review: It works fine but nothing special. You get what you pay for.
Sentiment: Neutral
Score: 0.50
Keywords: works fine, nothing special, price matches
## Analyze This
Review: The design is beautiful, but it broke after just one week. Very disappointing.
"""
response = model.generate_content(prompt)
print(response.text)
# Expected output:
# Sentiment: Negative
# Score: 0.25
# Keywords: beautiful design, broke after one week, disappointingThe key to effective few-shot prompting is example diversity. Include examples covering all expected output patterns (positive, negative, neutral) to prevent biased responses.
A Pitfall I Hit With Few-shot — Example Order and Edge Cases
Few-shot is powerful, but the order of your examples skews the results. The first set of examples I prepared for the wallpaper classifier happened to be all clean, easy-to-classify images. Gemini then started confidently labeling even genuinely ambiguous images — it carries the tone and length of the last example into the next output, the well-known recency bias.
The fix was simple: don't over-fix the order, and always slip in one borderline or ambiguous case. For instance, I include "a shot that could read as either a night view or a cityscape," and there I have it emit category: night view, confidence: low. The official docs just say "include diverse examples," but in practice I had to guarantee diversity across two axes — the range of categories and the degree of uncertainty. Once I added this step, both the wording drift and the over-confident labels dropped noticeably.
If the model returns confidence: low when it's unsure, the downstream automation can route that image into a "needs human review" queue automatically. When you design a prompt with the next step in mind rather than just standalone accuracy, small output fields like this start to pay off.
Chain-of-Thought (CoT) Reasoning
Chain-of-Thought prompting asks the model to show its step-by-step reasoning process, which significantly improves accuracy on complex problems.
# chain_of_thought_example.py
# Using Chain-of-Thought for step-by-step reasoning
import google.generativeai as genai
genai.configure(api_key="YOUR_API_KEY")
model = genai.GenerativeModel("gemini-2.0-flash")
# Without CoT (error-prone)
simple_prompt = "A store has 120 apples. They sold 30%, then gave 1/4 of the remainder to employees. How many are left?"
# With CoT (step-by-step reasoning)
cot_prompt = """A store has 120 apples. They sold 30%, then gave 1/4 of the remainder to employees. How many are left?
Please solve this step by step, showing the intermediate result at each step."""
response = model.generate_content(cot_prompt)
print(response.text)
# Expected output:
# Step 1: Starting apples = 120
# Step 2: Apples sold = 120 × 0.30 = 36
# Step 3: Remaining after sales = 120 - 36 = 84
# Step 4: Given to employees = 84 × 1/4 = 21
# Step 5: Final remaining = 84 - 21 = 63
#
# Answer: 63 applesCoT is particularly powerful for mathematical calculations, logical reasoning, and multi-step decision tasks. Simply adding "think step by step" to your prompt can improve accuracy noticeably. That said, when all you actually want is the final number, ask the model to reason first and then "write only the answer on the last line in the form answer:" — that keeps your downstream parsing stable.
Combining All Three Techniques
In real applications, combining these techniques produces the best results.
# combined_techniques.py
# System Instructions + Few-shot + CoT combined
import google.generativeai as genai
genai.configure(api_key="YOUR_API_KEY")
model = genai.GenerativeModel(
model_name="gemini-2.0-flash",
system_instruction="""You are a data analysis expert.
For each dataset provided:
1. Summarize the data overview
2. Analyze step by step (Chain-of-Thought)
3. Conclude with recommendations
Always show calculations with supporting evidence."""
)
prompt = """Analyze the following monthly sales data.
## Analysis Example
Data: Jan: $100K, Feb: $120K, Mar: $90K
Overview: 3 months of sales data with a February peak.
Analysis:
- Average: ($100K + $120K + $90K) / 3 = $103.3K
- Growth: Jan→Feb +20%, Feb→Mar -25%
- Trend: Declining after February peak
Conclusion: Investigate Feb success factors and Mar decline causes.
## Analyze This
Data: Apr: $150K, May: $180K, Jun: $210K, Jul: $195K"""
response = model.generate_content(prompt)
print(response.text)Role (System Instructions), format (Few-shot), and reasoning (CoT) each solve a different problem. I think of them as "persona, shape, and train of thought," and I add or drop them depending on where a task is unstable. If the vocabulary drifts, reach for System Instructions; if the structure drifts, Few-shot; if the conclusions are sloppy, CoT.
Testing Prompts in Google AI Studio
Google AI Studio is the ideal tool for iterating on prompts. Set System Instructions in the left panel, then test prompts in chat mode. The Temperature slider controls output randomness — closer to 0 produces consistent output, closer to 1 produces creative output.
For analysis and classification tasks, use Temperature 0.1–0.3. For creative writing, use 0.7–0.9. For work I don't want to wobble — like classification — I push it down to 0.1 and test roughly 20 images in AI Studio before wiring anything into the API. Nailing the examples and prompt there means fewer re-tries in production, which keeps the API bill down too.
Classify the Variance Before You Add Another Technique
Prompt techniques do not compound the way people expect. Stack System Instructions, few-shot examples, and Chain-of-Thought all at once and your input tokens balloon while you lose any sense of which piece is actually carrying the result.
The routine I use in my own work is to run the same prompt five times and classify what is drifting. Once the drift has a name, the technique to add narrows to exactly one.
| What drifts | What fixes it | What not to add |
|---|---|---|
| Tone, register, level of jargon | System Instructions | Chain-of-Thought |
| Output structure (item count, ordering, JSON shape) | Few-shot (one or two examples) | More System Instructions |
| Shallow conclusions, skipped reasoning | Chain-of-Thought | Few-shot |
The most common mistake I see is answering structural drift with ever-longer System Instructions. Rather than piling on "always exactly three items" and "order by importance," show one example of the shape you want. It lands faster and costs fewer tokens.
The inverse is equally wasteful: adding few-shot examples to fix tone. Each example lengthens the input, and what the model absorbs is the phrasing of that example rather than your underlying intent.
For the API side — particularly how system instructions interact with temperature — see "Gemini API System Instructions and Prompt Design", and if you want to stop resending a long system instruction on every call, "Operational Notes on Gemini API Caching Strategy" covers that.
Your Next Step
Gemini prompt engineering rests on three pillars: System Instructions (defining role and constraints), Few-shot (providing output examples), and Chain-of-Thought (encouraging step-by-step reasoning). Start by setting just the System Instructions in AI Studio and watching what drifts in the output — the vocabulary, the structure, or the conclusion. Once you can name the kind of drift, the technique to add chooses itself.
It took me a lot of quietly reordering examples and re-testing to get from that one-line prompt to here. If this shortens that first round of trial and error for someone else wiring AI into their own work, I'll be glad. When you're ready to move to the API, see the Gemini API Quickstart.