Weak prompt:
Write a function to process data
Result: Copilot has to guess about the data, behavior, and output.
Strong prompt:
Write a Python function called process_csv_row that takes
a dictionary representing a CSV row, validates that 'email'
and 'name' fields are present and non-empty, normalizes the
email to lowercase, and returns a cleaned dictionary.
Raise ValueError for invalid rows.
Result: The request gives Copilot behavior and failure rules to follow.
The prompt supplies the missing detail.
┌──────────────────────────────────────────────┐
│ A GOOD PROMPT │
│ │
│ 1. INTENT — What do you want? │
│ 2. CONTEXT — What should Copilot know? │
│ 3. CONSTRAINTS — What are the boundaries? │
│ 4. EXAMPLES — What does good look like? │
└──────────────────────────────────────────────┘
You don't need all four every time. But when a prompt isn't working, this tells you what's missing.
| Problem | ||
|---|---|---|
| "Help with this code" | Help how? | "Explain why this returns None for empty lists" |
| "Make it better" | Better how? | "Refactor to flatten nested if-else into early returns" |
| "Write a test" | For what? | "Write a pytest test verifying 20% discount for orders over $100" |
| "Fix the bug" | What bug? | "Fix the off-by-one error — returns 11 items when page_size is 10" |
Specify the what, the action, and the scope.
Context strategies (best to worst):
#file:services/user_service.pyBased on the patterns in #file:services/user_service.py,
create a new service method for order cancellation.
Show Copilot a relevant example and ask it to follow the pattern. That is usually more useful than describing the style.
| Category | Example |
|---|---|
| Dependencies | "Use only the standard library" |
| Performance | "Must handle 10,000 items/sec — use batch processing" |
| Compatibility | "Must work on Python 3.8+ (no walrus operator)" |
| Style | "Follow PEP 8, use type hints, functions under 20 lines" |
| Security | "Never log the API key. Use environment variables." |
| Output format | "Return JSON with keys 'status' and 'data'" |
Without constraints, Copilot makes its own choices about libraries, patterns, and style.
Write a function to format phone numbers.
Input examples:
"5551234567" → "(555) 123-4567"
"+15551234567" → "(555) 123-4567"
"555-123-4567" → "(555) 123-4567"
Examples are especially powerful for:
Copilot reads your open tabs to gather context — not just the current file.
How to use this:
The effect is real: Opening a related file can change Copilot's suggestions even if you don't reference it explicitly.
Open the files that show the pattern you want before you request a suggestion.
Write comments first — let Copilot implement:
# Validate email format using regex
# Return True for valid, False for invalid
# Handle edge cases: empty string, missing @, multiple @
def validate_email(email: str) -> bool:
Why it works:
Don't expect perfection on the first try. Build iteratively:
1. Write a user registration function
→ Too basic, no validation
2. Add email validation and password strength checks
→ Better, but no error messages
3. Return specific error messages for each validation failure
→ Good, but not using our error format
4. Use the AppError class from #file:errors.py
→
Matches project patterns
After each response, name the specific behavior that is still missing.
| Anti-Pattern | Problem | Fix |
|---|---|---|
| Vague prompt | "Make it work" | Specify what "working" looks like |
| Over-specified | 50-line prompt for a 5-line function | Match prompt length to task complexity |
| No context | Expects Copilot to know your project | Use #file, @workspace, or inline context |
| Copy-paste blindly | Accept without reading | Always review and test |
| One-and-done | Give up if first result is wrong | Iterate — refine the prompt |
Bad output? Check three things: unclear intent, missing context, or no constraints.
Create reusable prompt templates your team shares:
## Generate API Endpoint
Create a {METHOD} endpoint at {PATH} that:
- Accepts: {INPUT_SCHEMA}
- Validates: {VALIDATION_RULES}
- Returns: {OUTPUT_SCHEMA}
- Error handling: Use AppError from src/errors/
- Follow patterns in #file:src/routes/users.ts
Store these in .github/prompts/ (covered in Session 06).
Write a good template once, reuse it everywhere — just like a good function.
| Exercise | Topic | Duration |
|---|---|---|
| 1 | Prompt Challenge Rounds (5 timed challenges) | 40 min |
| 2 | Comment-Driven API Development | 40 min |
| 3 | Context Manipulation Experiments | 20 min |
| 4 | Prompt Cheat Sheet | 20 min |
Deliverable: A prompt engineering cheat sheet + a fully prompted REST API endpoint.
Take a moment to discuss with your trainer
Thank you!