Skip to main content
Lesson 5 of 16 · Prompt Engineering for Developers

Meta-prompting: Generate Optimal Prompts

Lesson 5 of 16 Updated November 3, 2026 Developer
On this page
  1. Meta-prompting: Generate Optimal Prompts
  2. The Principle
  3. Generate from Specifications
  4. Improve an Existing Prompt
  5. Generate Variants to Compare
  6. Assemble the Pipeline
  7. What Meta-prompting Won’t Do for You
  8. Key Takeaways

Lesson updated November 3, 2026 based on OpenAI documentation: temperature and top_p are only accepted with a reasoning effort of none, whereas GPT-5.6 models reason by default (medium). Calls that set these parameters must therefore specify reasoning={"effort": "none"} (Responses API) or reasoning_effort="none" (Chat Completions). Sources: Using GPT-6 · GPT-5.6 Terra.

Meta-prompting: Generate Optimal Prompts

Meta-prompting involves using an LLM to generate or improve prompts. Instead of manually writing every instruction, you describe the task and ask the model to produce the optimal prompt. The time savings are immediate, but the real benefit lies elsewhere: this technique surfaces phrasing you might never have considered, because developers always write prompts with the same reflexes and blind spots.

The Principle

A good prompt is a program written in natural language. As with any program, it is sometimes more efficient to generate it than to type it by hand—you don’t write your database migrations character by character either. Meta-prompting leverages the fact that during training, the model encountered a vast quantity of prompts and discussions about what makes them effective. The example below requests a system prompt for classifying support tickets. Two details deserve your attention: the specification is precise down to the category values, and the last line mandates a raw output with no accompanying commentary, ensuring the result is directly usable by code.

from openai import OpenAI

client = OpenAI()

meta_prompt = """You are an expert in prompt engineering.

Generate an optimized system prompt for the following task:
- Objective: Classify customer support tickets
- Categories: bug, feature_request, question, billing
- Output: JSON with "category", "priority" (1-5), "summary"
- Constraints: Response in French, max 100 tokens

The prompt must include:
1. A clear role
2. The categories with classification criteria
3. The exact output format with an example
4. Edge cases (ambiguous ticket, out-of-category)

Return ONLY the system prompt, with no explanation."""

response = client.responses.create(
    model="gpt-5.6-sol",
    reasoning={"effort": "none"},  # temperature requires effort none
    input=meta_prompt,
    temperature=0.7
)

generated_prompt = response.output_text
print(generated_prompt)

Generate from Specifications

The first pattern industrializes what you just did manually: you describe your requirements as functional constraints, and the model produces the corresponding prompt. By wrapping the meta-prompt in a function, you get a reusable generator for every task in your application. The side effect is significant: prompts written by five different developers stop having five different styles, which simplifies code review considerably.

def generate_prompt(objective: str, constraints: list[str],
                   output_format: str) -> str:
    """Generates a system prompt from specifications."""
    spec = f"""Generate a system prompt for this task:

Objective: {objective}

Constraints:
{chr(10).join(f'- {c}' for c in constraints)}

Expected output format:
{output_format}

Include a concrete input/output example.
Return only the prompt, with no commentary."""

    response = client.responses.create(
        model="gpt-5.6-sol",
        reasoning={"effort": "none"},  # temperature requires effort none
        input=spec,
        temperature=0.5
    )
    return response.output_text

Improve an Existing Prompt

The second pattern starts with a prompt already in production and an observed defect in the field. Instead of rewriting it entirely—which risks breaking what was working perfectly—you provide the current prompt along with a precise description of the problem: “it sometimes responds in English,” or “it invents order numbers when the reference is missing.” The instruction “keep what works” is the decisive part here. Without it, the model spontaneously refactors the whole thing and hands you a brand-new prompt you no longer understand.

def improve_prompt(current_prompt: str, problem: str) -> str:
    """Improves an existing prompt based on feedback."""
    meta = f"""Here is a system prompt that has a problem:

--- CURRENT PROMPT ---
{current_prompt}
--- END ---

Observed problem: {problem}

Rewrite this prompt to fix this problem.
Keep what works; modify only what is necessary.
Return only the improved prompt."""

    response = client.responses.create(
        model="gpt-5.6-sol",
        reasoning={"effort": "none"},  # temperature requires effort none
        input=meta,
        temperature=0.3
    )
    return response.output_text

Generate Variants to Compare

The third pattern generates multiple versions of the same prompt: constant objective, but divergent phrasing and structures. This is the raw material for the A/B testing we will cover in Lesson 15; without variants, you simply have nothing to compare. The high temperature here is not an oversight: it serves precisely to create diversity between versions, whereas a low temperature would give you three nearly identical rephrasings.

def generate_variants(base_prompt: str, n: int = 3) -> list[str]:
    """Generates n variants of a prompt."""
    meta = f"""Here is a system prompt:

{base_prompt}

Generate {n} variants of this prompt that:
- Keep the same objective
- Use different phrasing
- Vary the structure (lists vs. paragraphs, order of instructions)

Separate each variant with "---VARIANT---"."""

    response = client.responses.create(
        model="gpt-5.6-sol",
        reasoning={"effort": "none"},  # temperature requires effort none
        input=meta,
        temperature=0.9
    )
    return response.output_text.split("---VARIANT---")

Assemble the Pipeline

These three building blocks chain together naturally: generate a prompt from the objective, produce variants, then execute each variant on a representative test set to judge them on evidence rather than estimation.

def meta_prompt_pipeline(objective: str, tests: list[str]) -> str:
    """Complete meta-prompting pipeline."""

    # 1. Generate 3 variants
    variants = generate_variants(
        generate_prompt(objective, [], "free text"), n=3
    )

    # 2. Test each variant
    scores = []
    for i, prompt in enumerate(variants):
        results = []
        for test in tests:
            response = client.responses.create(
                model="gpt-5.6-terra",
                reasoning={"effort": "none"},  # temperature requires effort none
                instructions=prompt.strip(),
                input=test,
                temperature=0.2
            )
            results.append(response.output_text)
        scores.append((i, results))

    # 3. Evaluate (adapt to your criteria)
    print("Compare the results and select the best variant.")
    return variants, scores

What Meta-prompting Won’t Do for You

The model has a strong tendency toward over-optimization: the prompt it returns is often too verbose or too narrowly calibrated to the examples you provided, causing it to behave poorly on slightly different cases. Human review is therefore mandatory before any deployment, if only to verify that no business rules were invented along the way—a model completing an incomplete specification always does so in good faith, and sometimes incorrectly. Also watch the cost: every iteration consumes tokens, and an unbounded improvement loop can run for a long time without ever converging. Set the maximum number of iterations in your code, not in your personal discipline.

To master this technique, take a real task from your domain, write its complete specification (objective, constraints, format), generate three variants, test them on five cases from your production environment, and then refine the best one by hand. It is almost always this final manual touch that makes the difference between a decent prompt and one you are ready to put into production.

Key Takeaways

  • Meta-prompting uses the LLM as a prompt generator
  • Three patterns: generation, iterative improvement, variants
  • Always validate generated prompts with concrete tests
  • Combine automatic generation with manual adjustment
  • Set limits to avoid costly iteration loops