The code-generation skeleton

Why "write me a function" fails

4 min read

Meet Karim. He's a mid-level backend engineer who started using AI coding assistants six months ago. He gets correct-looking code that breaks subtly in production. He wants to write prompts that produce code he'd actually accept in code review. By the end of this course, he'll ship a real 200-line GitHub PR using only prompts.

Same goal, two prompts — toggle to see what Karim should have written

Vague
Write a Python function to dedupe a list.

Karim's first instinct is the same as most engineers'. He types:

Write a Python function to dedupe a list.

Here is what Claude Sonnet 4.5 actually returned:

# Python function to dedupe a list

Here are several approaches to remove duplicates from a list:

## 1. Using set (simplest, but doesn't preserve order)
def dedupe_list(lst):
    """Remove duplicates from a list (order not preserved)"""
    return list(set(lst))

## 2. Using dict.fromkeys() (preserves order, Python 3.7+)
def dedupe_list(lst):
    """Remove duplicates while preserving order"""
    return list(dict.fromkeys(lst))

Captured from Claude Sonnet 4.5 (claude-sonnet-4-5) on 2026-04-27. Re-runs may differ slightly — see the model-lifecycle note in Module 1, lesson 1.

The model returned two functions with the same name. It guessed at the trade-off Karim cared about. It did not return tests. It did not commit to a signature. The output is a tutorial, not a unit of code Karim can paste into a file.

Why did this happen? The prompt left every important decision to the model:

  • Should order be preserved?
  • Are strings case-sensitive?
  • Is performance the goal, or readability?
  • What signature should def use?
  • Should the result include tests?

When you don't pin those down, the model picks a defensible default — and "defensible" usually means show the user multiple options and let them choose. That's helpful for a tutorial. It's terrible for a code change.

Code course knowledge map

This course gives you a four-block skeleton — INTENT, CONSTRAINTS, TESTS, FORMAT — that forces the model into one specific function with one specific shape. You'll see the same dedupe task done correctly in lesson 5.

The course flow at a glance:

Six modules, one PR at the end

M1 · The codegen skeleton

INTENT + CONSTRAINTS + TESTS + FORMAT — the shape every code prompt reuses

M2 · Debugging prompts

Localize before you fix. Traceback explainers, expected-vs-actual, regression tests

M3 · Refactor locks

Constraint-locked transformations so a refactor cannot quietly change behaviour

M4 · Review prompts

Three categories, a severity rubric, and a verdict you can act on

M5 · Tool envelopes

Cursor diffs, Aider SEARCH/REPLACE, Claude Code plans, Copilot context

M6 · Capstone

Karim ships a real ~200-line PR using only prompts from M1–M5

Vague vs skeleton-shaped prompts produce wildly different outputs:

Vague prompt vs skeleton-shaped prompt

Tutorial

Vague: "write me a function to dedupe a list"

Functions returned2 (same name)
Includes testsNo
Type hintsNo
Ships without editsNo
Cons
  • Model picks defaults you didn't pin
  • Output is a tutorial, not a unit of code
  • You burn time stripping prose and choosing
Pasteable

Skeleton: INTENT + CONSTRAINTS + TESTS + FORMAT

Functions returned1
Includes testsYes (4 asserts)
Type hintsYes
Ships without editsYes
Pros
  • Signature pinned by you, not the model
  • Asserts prove correctness before commit
  • Output drops straight into a .py file
Cons
  • Costs you the decisions up front — you must already know the signature
  • Over-constraining hides a better approach the model would have offered
  • Wrong constraint = confidently wrong code, with tests that agree with it

Read that right-hand cons column before you go on. The skeleton moves the decisions from the model to you; it does not remove them. Every lesson from here is about making those decisions cheap to state — and module 2 is about what to do when you state one wrong.

A note on the captures in this course

Every model output in this course is a real capture, run on Claude Sonnet 4.5 (claude-sonnet-4-5) on 2026-04-27, and printed unedited — including the ones that turn out to be wrong. Three things follow from that, and they matter more than the outputs themselves:

  • Re-runs will differ. These models are not deterministic, and the vendor is explicit that no parameter setting has ever guaranteed identical outputs. Treat each capture as one observation, not as the model's fixed behaviour.
  • Model IDs retire. claude-sonnet-4-5 has a published retirement date, and so does whatever replaces it. Before you pin a model in your own tooling, check the vendor's model deprecations page — that page is corrected when a date moves; this sentence is not.
  • A capture is evidence of behaviour, never a source of fact. If a model states something about the world — or about itself — that claim needs the same sourcing as any other. Several lessons here re-run the capture and find the model wrong. That is the point of showing them.

Next up: the four-block skeleton itself. :::

Quiz

Module 1: The Codegen Skeleton

Take Quiz
Was this lesson helpful?

Sign in to rate