Module 8 · Expert Track15 min read · Prompt Engineering Mastery
Prompting for Code and Technical Tasks
Code generation is where prompt engineering meets the highest-stakes domain of AI-assisted work — bad outputs in a document are an inconvenience, but bad code can be a silent bug in production. The techniques in this module transform AI from an unreliable autocomplete into a disciplined technical collaborator.
The Anatomy of a Great Code Generation Prompt
Most people ask for code the same way they would ask a search engine: "Python function to parse CSV." This produces generic, untestable code that rarely fits the actual context. Expert code prompting provides the model with the complete specification a professional engineer would need before writing a single line.
A complete code generation prompt includes: the programming language and version, the runtime environment and constraints, the function signature or interface you need, edge cases that must be handled, what should happen on failure, and any existing code or APIs it must integrate with. Think of it as writing a ticket in a well-run engineering team.
Write a Python 3.11 function with this exact signature:
def parse_webhook_payload(
raw_body: bytes,
signature: str,
secret: str,
tolerance_seconds: int = 300
) -> dict:
Requirements:
- Verify the HMAC-SHA256 signature using the secret
- Reject payloads where the timestamp is older than
tolerance_seconds (use the 't' field in the payload)
- Parse and return the JSON body as a dict on success
- Raise ValueError with descriptive messages on:
* Invalid signature
* Expired timestamp
* Malformed JSON
* Missing required fields ('t', 'data')
Do NOT use any external libraries beyond hashlib and json.
Include type hints throughout.
After the function, write pytest unit tests covering:
- Happy path with valid signature and fresh timestamp
- Expired timestamp rejection
- Invalid signature rejection
- Missing 't' field rejection
Notice what this prompt does: it specifies the exact signature (no ambiguity about interface), the exact error conditions (no guessing about edge cases), the constraints (no external libraries), and it requests tests alongside the implementation. This prompt is closer to a specification document than a question.
Test-Driven Prompting
One of the most powerful code prompting techniques is to provide the tests first and ask the model to write code that passes them. This flips the typical AI coding workflow and has several profound advantages: you define the contract explicitly, the model has an objective success criterion to optimize against, and you immediately have a test suite regardless of how the implementation looks.
Write a Python function called `merge_sorted_arrays` that makes
all of the following tests pass. Do not modify the tests.
import pytest
def test_basic_merge():
assert merge_sorted_arrays([1,3,5], [2,4,6]) == [1,2,3,4,5,6]
def test_empty_arrays():
assert merge_sorted_arrays([], []) == []
assert merge_sorted_arrays([1,2,3], []) == [1,2,3]
assert merge_sorted_arrays([], [1,2,3]) == [1,2,3]
def test_duplicates():
assert merge_sorted_arrays([1,2,2,3], [2,3,4]) == [1,2,2,2,3,3,4]
def test_single_elements():
assert merge_sorted_arrays([5], [3]) == [3,5]
def test_already_sorted():
assert merge_sorted_arrays([1,2,3], [4,5,6]) == [1,2,3,4,5,6]
def test_large_arrays():
a = list(range(0, 1000, 2))
b = list(range(1, 1001, 2))
result = merge_sorted_arrays(a, b)
assert result == list(range(1000))
assert len(result) == 1000
Implement the most efficient algorithm and state its
time and space complexity after the code.
Why Test-Driven Prompting Works
When you provide tests, you eliminate an entire category of misunderstanding. The model cannot produce technically valid but semantically wrong code because the tests define semantics precisely. The model also cannot take shortcuts on edge cases — they are all enumerated in the test suite.
Debugging Prompts
Debugging is one of the highest-leverage uses of AI assistance, but generic "what's wrong with this code?" prompts waste the model's ability. Effective debugging prompts provide: the code, the exact error message or unexpected behavior, the expected behavior, what you have already tried, and the relevant environment information.
I have a bug I cannot figure out. Here is the context:
LANGUAGE: Python 3.10
ENVIRONMENT: FastAPI 0.104, running in Docker on Linux
THE CODE:
[paste the relevant function or module]
THE ERROR (exact output from terminal):
Traceback (most recent call last):
File "/app/api/routes.py", line 47, in process_request
result = await service.transform(data)
File "/app/services/transform.py", line 23, in transform
return {k: float(v) for k, v in data.items()}
ValueError: could not convert string to float: 'N/A'
EXPECTED BEHAVIOR:
The transform function should skip or substitute 0.0 for any
values that cannot be converted to float.
WHAT I HAVE TRIED:
- Checked that the data dict looks correct before the call
- Confirmed the error is always on 'N/A' strings from the
upstream API
Please: (1) explain the root cause, (2) provide a fix,
(3) suggest any defensive improvements to make this more
robust against other non-numeric strings in future.
Code Review Prompts
AI code review is most valuable when you structure it as a multi-dimensional analysis rather than a generic "review this code" request. Different review dimensions require different mental modes: security analysis requires adversarial thinking, performance requires measurement orientation, readability requires empathy for future maintainers. Combining them in one prompt produces shallow treatment of each.
Review the following Python function for SECURITY vulnerabilities
only. Do not comment on style, performance, or logic unless
the issue is security-relevant.
For each vulnerability found:
1. Name the vulnerability class (e.g., SQL injection, path
traversal, SSRF)
2. Quote the exact line(s) containing the vulnerability
3. Explain the exploit scenario in plain language
4. Provide a corrected version of those specific lines
If you find no security vulnerabilities, say so explicitly
and briefly explain why the main risk areas appear safe.
CODE TO REVIEW:
[paste code here]
Run separate review passes for security, performance, and readability. Each pass produces actionable, focused feedback rather than a diluted overview of everything.
Documentation Generation
Documentation generation is an underutilized application of prompt engineering. Models can produce docstrings, README sections, API reference documentation, and architectural explanations — but only if you specify the audience, format, and depth precisely.
Generate complete documentation for the following Python module.
TARGET AUDIENCE: Junior engineers who understand basic Python
but are new to this codebase.
REQUIRED SECTIONS:
1. Module Overview (2-3 sentences: what it does, when to use it)
2. Installation / Dependencies (list any non-stdlib dependencies)
3. Quick Start (a minimal working example in a code block)
4. Function Reference (for every public function: purpose,
parameters with types, return value, exceptions raised,
and one example call)
5. Common Gotchas (edge cases or non-obvious behaviors that
junior engineers frequently get wrong)
FORMAT: GitHub-flavored Markdown
MODULE CODE:
[paste module here]
Explaining Complex Codebases
When onboarding to an unfamiliar codebase or trying to understand inherited legacy code, prompt engineering turns what would take days of archaeology into hours of structured analysis. The key is to request a hierarchical explanation: architecture first, then modules, then specific functions — never the other way around.
I am a new engineer joining this project. Explain this codebase
to me at three levels:
LEVEL 1 — ARCHITECTURE (200 words)
What does this system do overall? What are its main components?
What is the data flow from input to output?
LEVEL 2 — KEY MODULES (bullet list)
For each major file or module in the code I've pasted:
- What is its single responsibility?
- What does it depend on?
- What depends on it?
LEVEL 3 — NON-OBVIOUS PATTERNS
What design patterns, conventions, or architectural decisions
would confuse a competent engineer who hasn't seen this specific
codebase before? What do I need to know to avoid breaking things?
CODEBASE:
[paste relevant files]
Domain-Specific Technical Prompting
Technical prompting extends beyond general-purpose code into domain-specific contexts: data engineering, ML pipelines, infrastructure-as-code, database query optimization, and more. Each domain has its own vocabulary, failure modes, and performance considerations that a well-crafted prompt can activate.
The principle is the same: give the model enough domain context to reason like a specialist, not just write syntactically valid code. For SQL optimization, include the execution plan. For ML prompts, include the dataset shape and target metric. For infrastructure code, include the cloud provider, region constraints, and cost sensitivity.
Optimize this PostgreSQL query for a table with 50 million rows.
The query currently takes 8-12 seconds. Target: under 500ms.
CURRENT QUERY:
SELECT u.email, COUNT(o.id) as order_count,
SUM(o.total_cents) as lifetime_value
FROM users u
LEFT JOIN orders o ON o.user_id = u.id
WHERE u.created_at > '2022-01-01'
AND o.status = 'completed'
GROUP BY u.id, u.email
ORDER BY lifetime_value DESC
LIMIT 100;
CURRENT INDEXES:
- users: primary key (id), index on created_at
- orders: primary key (id), index on user_id
EXPLAIN ANALYZE OUTPUT:
[paste output here]
Please:
1. Explain what is causing the slow performance
2. Suggest index changes with exact CREATE INDEX statements
3. Suggest query rewrites if applicable
4. Estimate the expected improvement for each suggestion
Summary
Code prompting rewards specificity above all else. Provide the language, version, constraints, signature, and edge cases upfront. Use test-driven prompting to define the contract precisely. Structure debugging prompts with the full error context. Run code reviews as focused single-dimension passes. For documentation and explanation tasks, specify audience, format, and depth explicitly. In domain-specific contexts, include the technical metadata (execution plans, dataset shapes, infrastructure constraints) that a specialist would need to reason correctly.