left-icon

Prompt Engineering for Developers Succinctly®
by Ed Freitas

Previous
Chapter

of
A
A
A

CHAPTER 3

Advanced Prompting


Overview

Building upon the foundational principles of clarity, specificity, and context, this chapter introduces more advanced prompting techniques that can unlock even greater capabilities in your AI assistant. These methods are beneficial for completing complex tasks, improving accuracy, and integrating AI seamlessly into your development workflow.

Few-shot prompting

Few-shot prompting is a powerful technique where you provide the AI with a few examples of input-output pairs before asking it to complete a new task. The term one-shot prompting is sometimes used to indicate a single example.

This helps the model understand the desired pattern, format, or behavior without requiring extensive fine-tuning. It’s like showing a new intern a few completed tasks so they can replicate the style and quality.

How few-shot prompting works

By presenting a small number of examples, you implicitly teach the AI the nuances of the task. The model learns from these examples and applies that understanding to the new, unseen input. This is especially effective when the task is specific or requires a particular style that might not be obvious from a simple instruction.

Suppose you want the AI to generate PHP class structures for different entities in a consistent style. The prompt might be something like the following.

Code Listing 3-a: Few-Shot Prompting Example

Act as a senior PHP developer. I need you to generate PHP class definitions for various entities.

Follow the example provided for the types, the constructor, and the getter methods.

Example:

Input:

User with properties id (int), name (string), email (string)

Output:

Task:

Input: Document with properties id (int), expirationDate (string), notes (string, nullable)

Output:

After running this prompt, we get the following result from ChatGPT.

Code Listing 3-b: Few-Shot Prompting Result

<?php

class Document

{

    private int $id;

    private string $expirationDate;

    private ?string $notes;

    public function __construct(int $id, string $expirationDate,

        ?string $notes = null)

    {

        $this->id = $id;

        $this->expirationDate = $expirationDate;

        $this->notes = $notes;

    }

    public function getId(): int

    {

        return $this->id;

    }

    public function getExpirationDate(): string

    {

        return $this->expirationDate;

    }

    public function getNotes(): ?string

    {

        return $this->notes;

    }

}

Notice that this result includes:

·     Typed properties (int, string, ?string).

·     A default value of null for the optional notes field in the constructor.

·     A corresponding getter method for each property.

·     A clean, modern PHP 8+ syntax.

By using this simple approach, the AI learns what the user expects as output. Now, let’s explore another technique that takes this approach to the next level.

Chain-of-thought prompting

Chain-of-thought (CoT) prompting is a technique that encourages the AI to articulate its reasoning process step-by-step before arriving at a final answer. This approach is convenient for complex problems that require logical deduction, multistep reasoning, or breaking down an enormous task into smaller, manageable subtasks.

Why CoT prompting is effective

By forcing the AI to show its work, CoT prompting often leads to more accurate results and makes the AI’s decision-making process transparent. It helps identify potential errors in reasoning and makes debugging the AI’s output easier. It mimics how a human would approach a complex problem.

Suppose you have a PHP function that isn’t working as expected and want the AI to help debug it.

Code Listing 3-c: CoT Example

Act as an experienced PHP debugger.

I have a PHP function that is supposed to calculate the number of days until a document expires.

It’s not returning the correct value for some dates.

Please analyze the code step by step, identify the potential issue, explain your reasoning, and then provide the corrected code.

Think step-by-step.

 <?php

    function daysUntilExpiration(string $expirationDate): int

    {

        $today = new DateTime();

        $expiry = new DateTime($expirationDate);

        $interval = $today->diff($expiry);

        return $interval->days;

    }

 

    // Test cases

    echo daysUntilExpiration('2025-10-10'); // Should be 3

    echo daysUntilExpiration('2025-10-07'); // Should be 0

    echo daysUntilExpiration('2025-10-06'); // Should be -1

 ?>

1. Analyze `daysUntilExpiration` function:

It uses `DateTime` objects and `diff()` to get the interval.

2. Examine `diff()` behavior:

The `diff()` method returns a `DateInterval` object. The `days` property of `DateInterval` always returns the absolute number of days. It does not indicate if the date is in the past or future.

3. Identify the issue:

For past dates, `diff()->days` will still be a positive number, which is incorrect for calculating days until expiration. We need to check the `invert` property of the `DateInterval` object to determine if the expiration date is in the past.

4. Formulate correction:

If `interval->invert` is 1, the expiration date is in the past, so the result should be negative. Otherwise, it’s the positive number of days.

After running this prompt, we get back the following result from ChatGPT.

Code Listing 3-d: CoT Example Result

Good—let’s debug this step by step and fix it.

1) Step-by-step analysis

·     Your function builds two DateTime objects: $today = new DateTime(); and $expiry = new DateTime($expirationDate);.

·     You call $today->diff($expiry), which returns a DateInterval.

·     You return $interval->days.

Why this is wrong for "days until expiration":

·     DateInterval::$days is the total number of days between the two dates as an absolute value (it’s always non-negative). It will not tell you whether the expiry is in the past or the future.

·     DateInterval has an invert property: 0 means $expiry >= $today (future or same day), 1 means $expiry < $today (expiry in the past). You must use the inverse to sign the result.

·     Another subtle bug: using new DateTime() includes the current time (hours/minutes/seconds).

·     If $expiry is created as 2025-10-07 00:00:00 but $today is 2025-10-07 14:00:00, diff() may count days differently, producing unexpected off-by-one results. For "days until expiration," you usually want to compare dates only (normalize to midnight).

2) Fix strategy

  1. Normalize both dates to midnight so we compare date boundaries, not time of day.
  2. Use the days value and apply the sign using the invert flag.
  3. Return an int (positive for future, 0 for today, negative for past).

3) Corrected code

<?php

/**

 * Returns the number of days until $expirationDate.

 * Positive -> days in the future

 * 0        -> today

 * Negative -> days in the past

 *

 * @param string $expirationDate Date in 'YYYY-MM-DD'

 *(or any format accepted by DateTime)

 * @return int

 */

function daysUntilExpiration(string $expirationDate): int

{

    // Use DateTimeImmutable to avoid accidental mutation

    // (optional but good practice)

    $today = new DateTimeImmutable('today');

    // normalized to local timezone midnight

    try {

        $expiry = new DateTimeImmutable($expirationDate);

    } catch (Exception $e) {

        // If parse fails, log or rethrow — here we return 0 to indicate        

        // "invalid" in a simple way.

        error_log("Invalid expiration date provided: {$expirationDate}");

        return 0;

    }

    // Normalize expiry to midnight too (in case time part was provided)

    $expiry = $expiry->setTime(0, 0, 0);

    $interval = $today->diff($expiry);

    $days = (int)$interval->days;

    // If invert == 1, expiry is in the past, so return negative days

    return $interval->invert ? -$days : $days;

}

// Example test (assuming "today" is 2025-10-07 for these expectations):

echo daysUntilExpiration('2025-10-10') . PHP_EOL; // => 3

echo daysUntilExpiration('2025-10-07') . PHP_EOL; // => 0

echo daysUntilExpiration('2025-10-06') . PHP_EOL; // => -1

4) Notes & recommendations

·     If you need to force a specific timezone, construct DateTimeImmutable with a DateTimeZone object:
new DateTimeImmutable('today', new DateTimeZone('Europe/Madrid')).

·     If you want stricter handling of invalid input, throw an exception instead of returning 0.

·     Using DateTimeImmutable avoids accidental side-effects; you can switch to DateTime if you prefer.

That fixes both the sign problem (use invert) and the possible time-of-day off-by-one (normalize to midnight).

By explicitly asking the AI to "think step-by-step," you guide it to perform a more thorough analysis, which is invaluable for debugging and understanding complex logic.

Self-correction and debugging with AI

AI models can be powerful allies in the debugging process, not just by identifying errors but also by suggesting self-correction mechanisms. This involves using the AI to analyze its own previous outputs or to review code for potential issues and then propose fixes. This technique leverages the iterative nature of prompt engineering to improve the quality of AI-generated code.

Instead of just asking for code, you can ask the AI to act as a code reviewer, identifying common pitfalls, suggesting improvements, or even fixing bugs in code you provide (whether AI-generated or human-written). Let’s look at an example.

Code Listing 3-e: Self-Correction/Code Review Example

Act as a meticulous PHP code reviewer. I have the following PHP function that handles user input.

Please review it for potential security vulnerabilities (e.g., SQL injection and XSS), common coding errors, and adherence to best practices.

If you find any issues, explain them and provide a corrected version of the function.

<?php

 function processUserInput($input)

 {

    $name = $_POST["name"];

    $email = $_POST["email"];

    $age = $_POST["age"];

    // Assume $db is a global SQLite PDO connection.

    global $db;

    $stmt = $db->prepare("INSERT INTO users (name, email, age) VALUES

    (".$name.", ".$email.", ".$age.")");

    $stmt->execute();

    echo "User added successfully!";

}

The AI should identify the direct concatenation of user input into the SQL query as a severe SQL injection vulnerability. It would then explain the risk and provide a corrected version using prepared statements with parameter binding.

Now, after executing this prompt, we get the following result from ChatGPT.

Code Listing 3-f: Self-Correction/Code Review Example Result

1. SQL Injection vulnerability

The following line is dangerous:

$stmt = $db->prepare("INSERT INTO users (name, email, age) VALUES (".$name.", ".$email.", ".$age.")");

·     The user-provided variables $name, $email, and $age are concatenated directly into the SQL query string.

·     This completely bypasses PDO’s protection, making the query vulnerable to SQL injection and allowing attackers to manipulate the Database (e.g., deleting tables or extracting data).

Fix: Always use parameterized queries with placeholders and bind values safely.

2. Cross-Site Scripting (XSS)

The line:

echo "User added successfully!";

It is not itself dangerous, but if you ever echo user-supplied input back to the browser (like $name or $email), it should be escaped with htmlspecialchars() to prevent XSS.

Fix: Use htmlspecialchars() when outputting user data in HTML.

3. Input validation

There’s no validation or sanitization of the incoming data:

$name = $_POST["name"];

$email = $_POST["email"];

$age = $_POST["age"];

·     $age should be numeric.

·     $email should be validated with filter_var($email, FILTER_VALIDATE_EMAIL).

·     $name should be trimmed and restricted to a reasonable length/characters.

Fix: Validate and sanitize each field before inserting.

4. Error handling

No error handling is present. If the query fails, the user still sees "User added successfully!", which is misleading.

Fix: Wrap the database call in a try/catch block and provide a safe fallback message.

5. Global variable use

Using global $db; is not ideal—it makes the function harder to test and maintain.

Fix: Pass the database connection as a parameter.

Corrected version

Here’s a secure, maintainable rewrite:

<?php

function processUserInput(PDO $db): void

{

    // Validate and sanitize input

    $name  = trim($_POST['name'] ?? '');

    $email = trim($_POST['email'] ?? '');

    $age   = $_POST['age'] ?? null;

    if (empty($name) || !filter_var($email, FILTER_VALIDATE_EMAIL) ||

        !is_numeric($age)) {

        echo "Invalid input. Please check your data.";

        return;

    }

    try {

        $stmt = $db->prepare("

            INSERT INTO users (name, email, age)

            VALUES (:name, :email, :age)

        ");

        $stmt->bindParam(':name', $name, PDO::PARAM_STR);

        $stmt->bindParam(':email', $email, PDO::PARAM_STR);

        $stmt->bindParam(':age', $age, PDO::PARAM_INT);

        $stmt->execute();

        echo "User added successfully!";

    } catch (PDOException $e) {

        // Log error to file, not shown to user

        error_log("Database error in processUserInput: " .

          $e->getMessage());

        echo "An error occurred while adding the user.";

    }

}

This demonstrates how AI can act as a proactive security and quality-assurance assistant, catching errors that might otherwise go unnoticed.

Integrating AI into your workflow

The ultimate goal of mastering advanced prompting techniques is to integrate AI seamlessly into your daily development workflow, making it an extension of your own capabilities.

This isn’t about replacing human developers but about augmenting them, enabling greater efficiency, creativity, and focus on higher-level problems.

Practical integration strategies

·     IDE extensions: Many AI assistants offer IDE integrations (such as GitHub Copilot for VS Code) that provide real-time code suggestions, autocompletion, and even the generation of entire functions as you type. This is the most direct form of integration.

·     Dedicated AI chat interfaces: Use web-based or desktop AI chat applications for more complex tasks that require multiturn conversations, detailed explanations, or brainstorming sessions. Copying and pasting code snippets and prompts is common here.

·     Command-line tools and APIs: For automated tasks or integrating AI into scripts, leverage AI APIs. You can write scripts that send prompts to an LLM and process its responses, automating tasks such as documentation generation, code analysis, and even test-case creation.

·     Version control integration: Integrate AI into your Git workflow. For example, an AI could generate commit messages based on code changes or review pull requests for potential issues.

Best practices for workflow integration

·     Start small: Begin by integrating AI for simple, repetitive tasks. As you gain confidence, gradually expand its role to more complex problems.

·     Verify everything: Always review AI-generated code and suggestions. Treat AI output as a starting point, not a final solution. Human oversight is critical.

·     Maintain context: When switching between tasks or tools, ensure the AI has the necessary context to provide relevant responses. This might involve copying previous conversation turns or relevant code snippets.

·     Learn from AI: Pay attention to the patterns and solutions the AI provides. This can help you learn new techniques, discover alternative approaches, and improve your own coding skills.

·     Document your prompts: For complex or frequently used tasks, document the effective prompts you’ve developed. This creates a reusable knowledge base and ensures consistency.

By strategically integrating AI into your development workflow and continuously refining your prompting skills, you can significantly boost your productivity and focus on the more challenging and creative aspects of software development.

The next part of the book will put these principles into practice as we begin building our document-expiration-tracking solution.

Scroll To Top
Disclaimer

DISCLAIMER: Web reader is currently in beta. Please report any issues through our support system. PDF and Kindle format files are also available for download.

Previous

Next



You are one step away from downloading ebooks from the Succinctly® series premier collection!
A confirmation has been sent to your email address. Please check and confirm your email subscription to complete the download.