AIMarch 08, 20264 min read

Prompt Engineering for Developers (With Python Examples)

Practical prompt engineering for developers — system prompts, few-shot examples, structured JSON output, and temperature, with working Python code.

Galvan

Galvan

Founder & Creator

Introduction

The same AI model can produce a brilliant answer or garbage — and the difference is usually the prompt. Prompt engineering isn't magic words; it's a *developer skill*: giving a model the context, format, and constraints it needs to do your job.

This guide covers the six techniques that matter in real applications, each with working Python code using the Mistral API from the chatbot tutorial (the same patterns work with local Ollama models).

Setup (used by every example)

code
import requests

def ask(messages, temperature=0.7):
    response = requests.post(
        "https://api.mistral.ai/v1/chat/completions",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={"model": "mistral-small-latest",
              "messages": messages,
              "temperature": temperature},
        timeout=60,
    )
    return response.json()["choices"][0]["message"]["content"]

Every technique below is just a smarter messages list.

Technique 1: System prompts — set the role

The system message is the model's job description. Vague role, vague output:

code
# weak
messages = [{"role": "user", "content": "Explain recursion"}]

# strong — audience, style, and length are specified
messages = [
    {"role": "system", "content":
     "You are a Python tutor for teenage beginners. "
     "Explain concepts using simple analogies and one short code example. "
     "Never exceed 150 words."},
    {"role": "user", "content": "Explain recursion"},
]

Same model, completely different usefulness. Audience, format, and length — the three things a system prompt should almost always pin down.

Technique 2: Specify the output format explicitly

If your code needs to parse the answer, tell the model the exact shape:

code
prompt = """Analyze this review and respond with ONLY a JSON object:
{"sentiment": "positive" or "negative" or "neutral", "score": 0-10}

Review: """ + review

Without that instruction, you get chatty prose like "Sure! This review seems..." — unparseable. With it, json.loads() works. This single technique is what makes the AI flashcard generator possible.

Always pair format requests with a fallback — models occasionally wrap JSON in prose, so extract with a regex before parsing (the flashcard tutorial shows the pattern).

Technique 3: Few-shot examples — show, don't tell

One example of the input-output you want teaches the model more than a paragraph of rules:

code
prompt = """Extract the city from each message.

Message: "I'm moving to Chennai next week"
City: Chennai

Message: "Is the Bangalore office open?"
City: Bangalore

Message: "What's the weather in Jaipur like?"
City:"""

The model completes the pattern. Two or three examples ("few-shot") turn a vague task into a fill-in-the-blank exercise — the most reliable trick for extraction and classification tasks.

Technique 4: Give context — the model can't read minds

code
# the model doesn't know your app exists
messages = [{"role": "user", "content": "Why did it crash?"}]

# feed the actual error and code
messages = [
    {"role": "system", "content": "You are a Python debugging assistant."},
    {"role": "user", "content":
     f"This code crashes:\n{code}\n\nError:\n{error_message}\n"
     "Explain the cause in one paragraph, then the fix."},
]

The model has no memory of your project, your data, or yesterday's conversation — every request must carry the context it needs. In chat apps, that means sending the message history (the chatbot tutorial's core pattern). In tools like the PDF chat, it means retrieving relevant chunks first.

Technique 5: Chain of thought — ask it to think in steps

For anything involving reasoning or math, jumping straight to the answer invites errors. Ask for the steps:

code
prompt = """A store applies a 20% discount, then 18% tax on the discounted price.
The original price is 2000 rupees. What is the final price?
Think step by step, then give the final answer on a new line as: FINAL: amount"""

The model works through discount, then tax, then total — landing on the right answer far more reliably than with a one-line prompt. The FINAL: marker also makes the answer extractable for your code while keeping the reasoning visible.

Technique 6: Temperature — the creativity dial

Temperature (0 to 1) controls randomness:

TaskTemperatureWhy
JSON output, classification, flashcards0.0–0.3Consistency beats creativity
General chat, explanations0.5–0.7Balanced
Brainstorming, names, stories0.8–1.0Variety wanted

The flashcard generator uses 0.3; a story-writing app would use 0.9. Match the dial to the task.

Common Mistakes (and their fixes)

  • Vague asks — "make it better" gives random edits. Specify what better means.
  • Trusting JSON blindly — always extract-and-fallback; models drift from format.
  • Overloading one prompt — five tasks in one prompt degrade all of them. Chain smaller calls instead.
  • Forgetting history — follow-up questions fail because the context wasn't resent. Every request is stateless.
  • No length limit — add "in under 100 words" or the model rambles.
  • Key Concepts

  • System prompt = job description — audience, style, constraints
  • Few-shot examples — patterns beat paragraphs
  • Output contracts — exact formats + regex fallbacks
  • Context is fuel — the model knows only what you send
  • Temperature matches the task — low for facts, high for ideas
  • What to Try Next

  • Upgrade the Mistral chatbot with a tuned system prompt and temperature 0.4 — feel the difference.
  • Build a review classifier with few-shot prompting and JSON output, then compare it against the lexicon-based sentiment app.
  • Apply structured output to the flashcard generator to add difficulty ratings.
  • Test all six techniques against local Ollama models — free experimentation, unlimited retries.
  • FAQ

    Is prompt engineering a real skill or hype?

    A real, learnable developer skill — the difference between a demo and a product is almost always prompt + output handling. That said, it's a skill *on top of* coding, not a replacement for it.

    Do these techniques work on local Ollama models?

    Yes — system prompts, few-shot, and format specification all apply. Small models need *tighter* formats and lower temperatures to stay reliable.

    Why did the model ignore my format instruction?

    Models drift, especially on long prompts. The professional pattern is always: specify the format and code a tolerant extractor (regex for the JSON block, fallback on failure). Never parse raw chat text and hope.