Books/Prompt Engineering Essentials/Prompt Patterns and Templates

    Prompt Patterns and Templates

    Prompt Patterns and Templates

    Once you understand prompting techniques, the next step is building a library of reusable patterns. Just like software design patterns, prompt patterns solve common problems in reliable, repeatable ways. This chapter gives you battle-tested templates you can copy, customize, and use immediately.

    The Four Core Prompt Patterns

    Most AI tasks fall into one of four categories:

    PatternWhat It DoesExample
    ExtractionPull structured data from unstructured textExtract names, dates, and amounts from emails
    ClassificationSort inputs into categoriesClassify support tickets by type
    GenerationCreate new content from requirementsWrite documentation, code, or marketing copy
    TransformationConvert one format to anotherRewrite code, translate languages, reformat data

    Let's build reusable templates for each.

    Pattern 1: Extraction

    Use extraction when you need to pull specific information out of unstructured text.

    Template

    Extract the following fields from the text below.
    Return the result as valid JSON.
    If a field is not found, use null.
    
    Fields to extract:
    - [field1]: [description and type]
    - [field2]: [description and type]
    - [field3]: [description and type]
    
    Text:
    """
    [paste text here]
    """
    

    Real Example: Invoice Extraction

    Extract the following fields from the invoice text below.
    Return the result as valid JSON.
    If a field is not found, use null.
    
    Fields to extract:
    - vendor_name: string, the company issuing the invoice
    - invoice_number: string, the invoice or reference number
    - date: string in YYYY-MM-DD format
    - total_amount: number, the total due amount
    - currency: string, 3-letter currency code
    - line_items: array of { description: string, quantity: number, unit_price: number }
    
    Text:
    """
    INVOICE #INV-2024-0892
    From: TechSupply Co.
    Date: March 15, 2024
    
    2x Wireless Mouse - $29.99 each
    1x USB-C Hub - $49.99
    5x HDMI Cable 6ft - $12.99 each
    
    Subtotal: $174.92
    Tax (8%): $13.99
    Total Due: $188.91 USD
    """
    

    In Code

    async function extractInvoiceData(invoiceText: string) {
      const response = await openai.chat.completions.create({
        model: "gpt-4o",
        messages: [
          {
            role: "system",
            content: "You extract structured data from invoices. Always return valid JSON. Use null for missing fields."
          },
          {
            role: "user",
            content: `Extract invoice data from this text:\n\n${invoiceText}`
          }
        ],
        response_format: { type: "json_object" }, // Forces valid JSON output
        temperature: 0, // Deterministic output for extraction
      });
    
      return JSON.parse(response.choices[0].message.content);
    }

    Pattern 2: Classification

    Use classification when you need to sort inputs into predefined categories.

    Template

    Classify the following [input type] into exactly one of these categories:
    [list of categories]
    
    Rules:
    - Choose the single best-fitting category
    - If uncertain, choose the closest match
    - Return only the category name, nothing else
    
    [Input type]: "[the input to classify]"
    Category:
    

    Real Example: Support Ticket Classification

    Classify the following support ticket into exactly one of these categories:
    - billing
    - technical-issue
    - feature-request
    - account-access
    - general-question
    
    Rules:
    - Choose the single best-fitting category
    - If the ticket spans multiple categories, choose the primary concern
    - Return only the category name, nothing else
    
    Ticket: "I was charged twice for my subscription this month. I need a refund for the duplicate charge."
    Category:
    

    In Code with Batch Processing

    type TicketCategory = "billing" | "technical-issue" | "feature-request" | "account-access" | "general-question";
    
    async function classifyTicket(ticketText: string): Promise<TicketCategory> {
      const response = await openai.chat.completions.create({
        model: "gpt-4o-mini", // Smaller model is fine for classification
        messages: [
          {
            role: "system",
            content: `You classify support tickets. Categories: billing, technical-issue, feature-request, account-access, general-question. Return only the category name.`
          },
          { role: "user", content: ticketText }
        ],
        temperature: 0,
        max_tokens: 20,
      });
    
      return response.choices[0].message.content.trim() as TicketCategory;
    }
    
    // Batch classify multiple tickets
    async function classifyTickets(tickets: string[]): Promise<TicketCategory[]> {
      const results = await Promise.all(tickets.map(classifyTicket));
      return results;
    }

    Pattern 3: Generation

    Use generation when you need to create new content based on specifications.

    Template

    Generate [what] based on the following specifications:
    
    Requirements:
    - [requirement 1]
    - [requirement 2]
    - [requirement 3]
    
    Tone: [professional/casual/technical/friendly]
    Length: [word count or size constraint]
    Audience: [who will read this]
    Format: [how it should be structured]
    
    Additional context:
    [any relevant background information]
    

    Real Example: API Documentation Generation

    Generate API documentation for the following endpoint:
    
    Endpoint: POST /api/v1/projects
    Purpose: Creates a new project within an organization
    
    Requirements:
    - Requires Bearer token authentication
    - Request body includes: name (required string), description (optional string),
      visibility (enum: "public" | "private", default "private")
    - Returns the created project object with id, createdAt, and owner fields
    - Returns 400 for missing name, 401 for invalid token, 409 for duplicate name
    
    Tone: Technical, concise
    Format: Use sections: Description, Authentication, Request, Response, Errors, Example
    Include: curl example and TypeScript fetch example
    

    Pattern 4: Transformation

    Use transformation when you need to convert content from one format or style to another.

    Template

    Transform the following [source format] into [target format].
    
    Rules:
    - [transformation rule 1]
    - [transformation rule 2]
    - [preservation rule — what to keep unchanged]
    
    Source:
    """
    [input content]
    """
    

    Real Example: SQL to Firestore

    Transform the following SQL query into a Firestore query using
    the Firebase Admin SDK (Node.js/TypeScript).
    
    Rules:
    - Use the firebase-admin/firestore import style
    - Handle the WHERE clauses with .where() chains
    - Convert ORDER BY to .orderBy()
    - Convert LIMIT to .limit()
    - Return the equivalent TypeScript code
    
    Source:
    """
    SELECT * FROM products
    WHERE category = 'electronics'
    AND price < 500
    AND inStock = true
    ORDER BY price ASC
    LIMIT 20
    """
    

    Building a Prompt Library

    Organize your prompts like you organize code — in a structured, reusable way:

    // src/prompts/index.ts
    
    export const PROMPTS = {
      extraction: {
        invoice: (text: string) => ({
          system: "You extract structured data from invoices. Return valid JSON.",
          user: `Extract from this invoice:\n\n${text}`,
        }),
        contactInfo: (text: string) => ({
          system: "You extract contact information. Return valid JSON with fields: name, email, phone, company.",
          user: `Extract contact info:\n\n${text}`,
        }),
      },
    
      classification: {
        sentiment: (text: string) => ({
          system: "Classify sentiment as: positive, negative, or neutral. Return only the label.",
          user: text,
        }),
        supportTicket: (text: string) => ({
          system: "Classify into: billing, technical-issue, feature-request, account-access. Return only the category.",
          user: text,
        }),
      },
    
      generation: {
        commitMessage: (diff: string) => ({
          system: "Write concise git commit messages in conventional commit format. One line, under 72 characters.",
          user: `Write a commit message for this diff:\n\n${diff}`,
        }),
        codeReview: (code: string) => ({
          system: "Review code for bugs, performance, and best practices. Format: Issues, Suggestions, Score (1-10).",
          user: `Review this code:\n\n${code}`,
        }),
      },
    
      transformation: {
        toTypeScript: (jsCode: string) => ({
          system: "Convert JavaScript to TypeScript. Add proper types, interfaces, and type annotations. Do not change logic.",
          user: `Convert to TypeScript:\n\n${jsCode}`,
        }),
        simplify: (text: string) => ({
          system: "Rewrite the text for a non-technical audience. Keep the meaning, remove jargon, use simple words.",
          user: `Simplify:\n\n${text}`,
        }),
      },
    };

    Using the Prompt Library

    import { PROMPTS } from "@/prompts";
    
    async function callAI(prompt: { system: string; user: string }) {
      const response = await openai.chat.completions.create({
        model: "gpt-4o",
        messages: [
          { role: "system", content: prompt.system },
          { role: "user", content: prompt.user },
        ],
      });
      return response.choices[0].message.content;
    }
    
    // Usage
    const review = await callAI(PROMPTS.generation.codeReview(myCode));
    const category = await callAI(PROMPTS.classification.supportTicket(ticketText));
    const tsCode = await callAI(PROMPTS.transformation.toTypeScript(jsCode));

    Prompt Chaining — Multi-Step Workflows

    Some tasks are too complex for a single prompt. Prompt chaining breaks them into steps, where each step's output becomes the next step's input.

    Example: Blog Post Pipeline

    // Step 1: Generate an outline
    const outline = await callAI({
      system: "You create blog post outlines. Return a structured outline with sections and key points.",
      user: "Create an outline for a blog post about 'Why TypeScript is worth learning in 2025'. Target audience: JavaScript developers.",
    });
    
    // Step 2: Write each section using the outline
    const draft = await callAI({
      system: "You write technical blog posts. Write in a conversational but authoritative tone. Use code examples.",
      user: `Write a complete blog post from this outline. 1500-2000 words.\n\nOutline:\n${outline}`,
    });
    
    // Step 3: Edit and polish
    const finalPost = await callAI({
      system: "You are a technical editor. Improve clarity, fix awkward phrasing, ensure code examples are correct, and add a compelling intro and conclusion.",
      user: `Edit and polish this blog post draft:\n\n${draft}`,
    });
    
    // Step 4: Generate metadata
    const metadata = await callAI({
      system: "Generate SEO metadata. Return JSON with: title (under 60 chars), description (under 160 chars), tags (array of 5-8 keywords).",
      user: `Generate metadata for this post:\n\n${finalPost}`,
    });

    Example: Code Generation Pipeline

    // Step 1: Design the data model
    const dataModel = await callAI({
      system: "Design TypeScript interfaces for a Firestore data model.",
      user: "Design data models for a project management app with: projects, tasks, users, and comments.",
    });
    
    // Step 2: Generate service code
    const serviceCode = await callAI({
      system: "Generate a Firestore service file with CRUD operations.",
      user: `Create a service file based on these data models:\n\n${dataModel}`,
    });
    
    // Step 3: Generate tests
    const tests = await callAI({
      system: "Write unit tests using Vitest for Firestore service functions.",
      user: `Write tests for this service file:\n\n${serviceCode}`,
    });

    When to Chain vs. Single Prompt

    Use Single PromptUse Chain
    Task has one clear outputTask has multiple distinct phases
    Output is under 500 wordsOutput would be 1000+ words
    Simple transformationRequires different "expertise" at each step
    Classification or extractionGenerate, then refine, then validate

    Key Takeaways

    1. Most AI tasks fit four patterns: extraction, classification, generation, transformation
    2. Build a prompt library so you don't rewrite prompts from scratch
    3. Chain prompts for complex workflows — each step focused on one task
    4. Test your templates with edge cases before relying on them in production
    5. Iterate and improve — track which prompts produce the best results and refine them over time

    Try it now: Identify three tasks you regularly do with AI. Write a reusable prompt template for each one, following the patterns in this chapter. Store them somewhere accessible so you can reuse and refine them.


    🌐 www.genai-mentor.ai