ARCHIVE_LOG // VCN_LATAM · 16 JUL 2026MIT LICENSE

Six scripts.
Zero API keys.

Runnable companions to Meta Prompting with Claude Code (Irina Vélez + Rayyan Zahid). Each script is one metaprompting technique from the talk, reduced to a single file you can read in five minutes. No frameworks, no dependencies, no API keys: every model call goes through the claude command-line tool that ships with Claude Code.

Before you start

  1. Install Claude Code. That gives you the claude command the scripts call under the hood. If you can type claude -p "hello" in a terminal and get an answer, you are ready.
  2. Have Python 3 installed (any recent version, nothing to pip-install).
  3. Download a script and run it:
$ curl -O https://vcn-latam-metaprompting.vercel.app/examples/01_self_refine.py
$ python 01_self_refine.py "a cold email inviting a CTO to a demo"

Every script prints what it is doing at each step, so you can watch the technique work. By default they use the fast Haiku model; set the environment variable METAPROMPT_MODEL=sonnet for higher quality, slower runs. To change the task, edit the small, clearly marked block at the top of each file.

0101_self_refine.py

Self-Refine · Madaan et al. 2023 · ~20% average gain in the paper

What it does

The simplest metaprompting loop there is. The model writes a first draft of whatever you ask for. Then the same model is asked to critique its own draft: what is weak, what to cut, what to sharpen. Then it rewrites the draft applying that feedback. It does this twice. You watch the draft get measurably sharper each round, with no human editing in between.

How to use it
$ python 01_self_refine.py "a two-sentence invite to our AI workshop"
== DRAFT 0 ==   (first attempt)
== FEEDBACK 1 == (the model attacks its own draft, 4 bullets)
== DRAFT 1 ==   (rewrite applying the feedback)
== FEEDBACK 2 == ...

Use it tonight on anything you write repeatedly: emails, product copy, bug reports. The argument is the task; the loop is the technique. Set ROUNDS=3 as an environment variable for a third pass.

0202_ape.py

APE, Automatic Prompt Engineer · Zhou et al. 2022 · human-level instructions on 24/24 tasks

What it does

You do not write the instruction at all. You show the model a few input-and-output examples of a job (the built-in demo: turning formal English into casual Spanish), and it reverse-engineers what the instruction must have been, producing four candidate instructions. Then each candidate is tested on held-out examples it has not seen, a judge scores how close the results are, and the best instruction wins. The prompt is found, not written.

How to use it
$ python 02_ape.py
== CANDIDATE INSTRUCTIONS ==  (4 guesses at the instruction)
== SCORING ON HELD-OUT PAIRS ==  (each scored 0-10)
== WINNER ==  (the instruction you should actually use)

To point it at your own job, edit the TRAIN and TEST pairs at the top of the file: 4 examples to learn from, 2 to score against. Any task you can show examples of works: reformatting, tone conversion, extraction, classification.

0303_opro.py

OPRO, Optimization by PROmpting · Yang et al. 2023 · how "Take a deep breath" beat the human prompt 80.2% to 71.8%

What it does

Treats prompt-writing as an optimization problem. It starts with a bare instruction ("Solve the problem.") and measures it against a small set of trick word-problems with known answers. Then, each round, the model is shown the full history of every instruction tried so far with its measured score, and asked to propose one it expects to score higher. The score history itself becomes the prompt. This is the exact mechanism that discovered "Take a deep breath and work on this problem step by step."

How to use it
$ python 03_opro.py
round 0 · 'Solve the problem.' -> 4/5
round 1 · 'Show all work step by step...' -> 3/5   (worse! the scorer caught it)
round 2 · ...
== BEST INSTRUCTION ==

Watch the trajectory, not just the winner: clever-sounding instructions often score worse, and catching a regression is the same muscle as finding a gain. To optimize for your own task, replace the PROBLEMS list with your own test cases and expected answers. The one thing you truly need is a scorer: a way to check answers automatically.

0404_conductor.py

Meta-Prompting (conductor + experts) · Suzgun & Kalai 2024 · the pattern behind Claude Code subagents

What it does

One model plays conductor. Given your question, it decides which two or three specialists to consult, and writes each one a self-contained instruction. Each specialist then runs as a completely fresh model call with zero shared context: it sees only the instruction the conductor wrote for it. Fresh eyes, no groupthink. Finally the conductor reads all the reports, synthesizes a recommendation, and flags any point where its experts contradict each other. This is exactly how Claude Code subagents work in production.

How to use it
$ python 04_conductor.py "should we charge for our workshop series?"
== CONDUCTOR'S PLAN ==       (experts chosen + their instructions)
== GROWTH STRATEGIST (fresh instance) == ...
== OPERATIONS LEAD (fresh instance) == ...
== CONDUCTOR'S SYNTHESIS ==  (one recommendation, contradictions flagged)

Use it for decisions where you would normally want three opinions: pricing, naming, build-vs-buy, architecture choices. The interesting part to study is the plan step: the conductor writing prompts for other instances of itself IS metaprompting.

0505_criterion.py

Versioned criterion · production pattern from Ray's automation repo (106 logged runs of the real thing)

What it does

Turns a judgment you keep making by hand into infrastructure. The judgment here: "does this inbox message need a reply, is it just waiting, or can I ignore it?" That criterion is written once, as a prompt, with a version number. Every message's verdict is cached under a key made of the message content plus the prompt version. Run the script twice: the first run calls the model five times, the second run costs zero calls because every verdict is cached. Edit one message and only that one recomputes. Bump PROMPT_VERSION and everything recomputes, because your criterion itself changed.

How to use it
$ python 05_criterion.py
[REPLY ] (model) Hey! Are we still on for the demo tomorrow...
[IGNORE] (model) Newsletter: 10 AI tools you missed...
5 model calls · 0 cache hits · criterion v1
$ python 05_criterion.py
[REPLY ] (cache) Hey! Are we still on for the demo tomorrow...
0 model calls · 5 cache hits · criterion v1

Swap the INBOX list and the CRITERION text for your own: lead triage, PR review labels, support-ticket routing. This is the pattern that scales a one-off prompt into a durable service.

0606_router.py

Template router · production pattern from Ray's repo, where 18 templates cover 56% of real asks by keyword alone · no model call at all

What it does

The prompts you keep retyping are templates waiting for a name. This script holds three named templates (fix a bug, reverse an API, build a deck), each with aliases, keyword signatures, and fill-in slots. Type a terse ask and it routes through the cheapest tier first: an exact alias match, then keyword signatures, and only in production a model call for the long tail. Then it expands the matched template into the full, detailed prompt you actually wanted to type. Pure Python, instant, free.

How to use it
$ python 06_router.py "reverse https://app.example.com/dashboard"
pattern: reverse-api  via keyword (2 hits)
== EXPANDED PROMPT ==
Reverse https://app.example.com/dashboard. I will help with login...
$ python 06_router.py deck
pattern: brand-deck  via alias

To make it yours, look at your own chat history, find the three requests you type most, and add them to the PATTERNS dictionary with the wording you wish you always used. Measure the router honestly: in our production version some patterns route 36/36 by keyword, one routes 0/8 and should always fall through to the model. Knowing which is which is the point.