AI Prompt Engineering: A Comprehensive Guide to Building Effective Prompts for Language Models

May 06, 2023
Shrikar Archak

Natural language processing (NLP) is an area of computer science that focuses on enabling computers to understand and interact with human language. Large language models, such as GPT-3 and BERT, have revolutionized NLP by allowing machines to generate more human-like responses to natural language prompts. However, to get the most out of these models, it's essential to master the art of prompt engineering.

What is Prompt Engineering?

Prompt engineering involves designing prompts that are specific enough to guide the output of large language models, while still being broad enough to allow for creative and varied responses. In other words, prompt engineering is about creating prompts that can effectively "teach" a machine to generate the desired output.

Understanding Large Language Models

Large language models are machine learning algorithms that have been trained on massive amounts of text data. These models use a technique called unsupervised learning to generate predictions about what word or phrase is most likely to come next in a sentence.

For example, if a large language model is given the prompt "The cat sat on the", it might generate the response "mat". While this might seem like a simple task, large language models are capable of generating much more complex responses, such as writing an entire news article or composing a poem.

How Prompts Work in Large Language Models

Prompts are essential for large language models because they provide the necessary context for the machine to generate output that is relevant to the task at hand. Prompts also help guide the output of the machine, ensuring that it generates responses that are more likely to be accurate and useful.

In contrast to traditional machine learning models, which require the explicit specification of input features and output labels, large language models rely on prompts to guide their output. This makes large language models much more flexible and adaptable to different types of tasks, as prompts can be tailored to specific needs and contexts.

Steps for Prompt Engineering

To create effective prompts for large language models, there are several key steps that you should follow:

Creating Clear and Concise Prompts

One of the most important factors in prompt engineering is creating a clear and concise prompt. A clear prompt accurately conveys the task at hand to the machine learning model and allows it to generate the desired output. A concise prompt is brief and to-the-point, avoiding any unnecessary information that may confuse or distract the model. Here are some tips for creating clear and concise prompts:

1. Specify the task

Begin the prompt by clearly stating the task you want the model to perform. Be specific about what you want the model to do and what kind of output you expect. For example, if you want the model to perform sentiment analysis on a given sentence, the prompt could be: "Analyze the sentiment of the following sentence and provide a positive/negative/neutral score."

2. Provide context

Provide sufficient context so that the model can understand the task. This can include any relevant information about the data, the domain, or the task itself. For example, if the task is text classification, you could provide some context about the categories the text can be classified into, and how many categories there are.

3. Avoid ambiguity

Be clear and precise with your language to avoid any ambiguity. Avoid using words that have multiple meanings or phrases that can be interpreted in different ways. Also, be careful when using idiomatic expressions or slang as they may not be easily understood by the model.

4. Be concise

Keep the prompt as concise as possible, while still providing all the necessary information. Long prompts with irrelevant information can confuse the model and lead to inaccurate results. Use simple and direct language to convey the task and avoid unnecessary details.

5. Provide examples

Providing examples can help clarify the task and make it easier for the model to understand. Use clear and representative examples to demonstrate the kind of input and output the model should produce. This can help ensure that the model produces the desired output and help you evaluate its performance.

Example:

Let's say we want to create a prompt for a text classification task. We want the model to classify a given text into one of three categories: sports, politics, or entertainment. Here's an example of a clear and concise prompt:

    "Classify the following text into one of the following categories: sports, politics, or entertainment. Please provide the category label for the text."

In this prompt, we clearly specify the task, provide context about the categories, avoid ambiguity in language, keep the prompt concise, and provide an example to clarify the task.

By following these tips and examples, you can create clear and concise prompts for a variety of NLP tasks, which can help ensure the accuracy and effectiveness of your machine learning models.

Guidelines for Prompting

Here are a few examples and responses

import openai
import os

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())

openai.api_key  = os.getenv('OPENAI_API_KEY')

## Helper function for making OpenAI Calls

def get_completion(prompt, model="gpt-3.5-turbo"):
    messages = [{"role": "user", "content": prompt}]
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=0, # this is the degree of randomness of the model's output
    )
    return response.choices[0].message["content"]

Prompting Principles

  • Principle 1: Write clear and specific instructions
  • Principle 2: Give the model time to “think”

Tactics

Tactic 1: Use delimiters to clearly indicate distinct parts of the input Delimiters can be anything like: ```, """, < >, <tag> </tag>, :

text = f"""
You should express what you want a model to do by \ 
providing instructions that are as clear and \ 
specific as you can possibly make them. \ 
This will guide the model towards the desired output, \ 
and reduce the chances of receiving irrelevant \ 
or incorrect responses. Don't confuse writing a \ 
clear prompt with writing a short prompt. \ 
In many cases, longer prompts provide more clarity \ 
and context for the model, which can lead to \ 
more detailed and relevant outputs.
"""
prompt = f"""
Summarize the text delimited by triple backticks \ 
into a single sentence.
```{text}```
"""
response = get_completion(prompt)
print(response)

## Response
To guide a model towards the desired output and reduce the chances of irrelevant or incorrect responses, it is important to provide clear and specific instructions, which may require longer prompts for more clarity and context.

Tactic 2: Ask for a structured output¶ JSON, HTML

prompt = f"""
Generate a list of three made-up book titles along \ 
with their authors and genres. 
Provide them in JSON format with the following keys: 
book_id, title, author, genre.
"""
response = get_completion(prompt)
print(response)

---
## Response
prompt = f"""
Generate a list of three made-up book titles along \ 
with their authors and genres. 
Provide them in JSON format with the following keys: 
book_id, title, author, genre.
"""
response = get_completion(prompt)
print(response)
prompt = f"""
Generate a list of three made-up book titles along \ 
with their authors and genres. 
Provide them in JSON format with the following keys: 
book_id, title, author, genre.
"""
response = get_completion(prompt)
print(response)
[
  {
    "book_id": 1,
    "title": "The Lost City of Zorath",
    "author": "Aria Blackwood",
    "genre": "Fantasy"
  },
  {
    "book_id": 2,
    "title": "The Last Survivors",
    "author": "Ethan Stone",
    "genre": "Science Fiction"
  },
  {
    "book_id": 3,
    "title": "The Secret Life of Bees",
    "author": "Lila Rose",
    "genre": "Romance"
  }
]

Tactic 3: Ask the model to check whether conditions are satisfied

text_1 = f"""
Making a cup of tea is easy! First, you need to get some \ 
water boiling. While that's happening, \ 
grab a cup and put a tea bag in it. Once the water is \ 
hot enough, just pour it over the tea bag. \ 
Let it sit for a bit so the tea can steep. After a \ 
few minutes, take out the tea bag. If you \ 
like, you can add some sugar or milk to taste. \ 
And that's it! You've got yourself a delicious \ 
cup of tea to enjoy.
"""
prompt = f"""
You will be provided with text delimited by triple quotes. 
If it contains a sequence of instructions, \ 
re-write those instructions in the following format:

Step 1 - ...
Step 2 - …
…
Step N - …

If the text does not contain a sequence of instructions, \ 
then simply write \"No steps provided.\"

\"\"\"{text_1}\"\"\"
"""
response = get_completion(prompt)
print("Completion for Text 1:")
print(response)

--
Response
Completion for Text 1:
Step 1 - Get some water boiling.
Step 2 - Grab a cup and put a tea bag in it.
Step 3 - Once the water is hot enough, pour it over the tea bag.
Step 4 - Let it sit for a bit so the tea can steep.
Step 5 - After a few minutes, take out the tea bag.
Step 6 - Add some sugar or milk to taste.
Step 7 - Enjoy your delicious cup of tea!

Tactic 4: "Few-shot" prompting

prompt = f"""
Your task is to answer in a consistent style.

<child>: Teach me about patience.

<grandparent>: The river that carves the deepest \ 
valley flows from a modest spring; the \ 
grandest symphony originates from a single note; \ 
the most intricate tapestry begins with a solitary thread.

<child>: Teach me about resilience.
"""
response = get_completion(prompt)
print(response)
--
Response
<grandparent>: Resilience is like a tree that bends with the wind but never breaks. It is the ability to bounce back from adversity and keep moving forward, even when things get tough. Just like a tree that grows stronger with each storm it weathers, resilience is a quality that can be developed and strengthened over time.

Principle 2: Give the model time to “think”

Tactic 1: Specify the steps required to complete a task

text = f"""
In a charming village, siblings Jack and Jill set out on \ 
a quest to fetch water from a hilltop \ 
well. As they climbed, singing joyfully, misfortune \ 
struck—Jack tripped on a stone and tumbled \ 
down the hill, with Jill following suit. \ 
Though slightly battered, the pair returned home to \ 
comforting embraces. Despite the mishap, \ 
their adventurous spirits remained undimmed, and they \ 
continued exploring with delight.
"""
# example 1
prompt_1 = f"""
Perform the following actions: 
1 - Summarize the following text delimited by triple \
backticks with 1 sentence.
2 - Translate the summary into French.
3 - List each name in the French summary.
4 - Output a json object that contains the following \
keys: french_summary, num_names.

Separate your answers with line breaks.

Text:
```{text}```
"""
response = get_completion(prompt_1)
print("Completion for prompt 1:")
print(response)
--
Response

Completion for prompt 1:
Two siblings, Jack and Jill, go on a quest to fetch water from a well on a hilltop, but misfortune strikes and they both tumble down the hill, returning home slightly battered but with their adventurous spirits undimmed.

Deux frères et sœurs, Jack et Jill, partent en quête d'eau d'un puits sur une colline, mais un malheur frappe et ils tombent tous les deux de la colline, rentrant chez eux légèrement meurtris mais avec leurs esprits aventureux intacts. 
Noms: Jack, Jill. 

{
  "french_summary": "Deux frères et sœurs, Jack et Jill, partent en quête d'eau d'un puits sur une colline, mais un malheur frappe et ils tombent tous les deux de la colline, rentrant chez eux légèrement meurtris mais avec leurs esprits aventureux intacts.",
  "num_names": 2
}

Ask for output in a specified format

prompt_2 = f"""
Your task is to perform the following actions: 
1 - Summarize the following text delimited by 
  <> with 1 sentence.
2 - Translate the summary into French.
3 - List each name in the French summary.
4 - Output a json object that contains the 
  following keys: french_summary, num_names.

Use the following format:
Text: <text to summarize>
Summary: <summary>
Translation: <summary translation>
Names: <list of names in Italian summary>
Output JSON: <json with summary and num_names>

Text: <{text}>
"""
response = get_completion(prompt_2)
print("\nCompletion for prompt 2:")
print(response)
--
Response

Completion for prompt 2:
Summary: Jack and Jill go on a quest to fetch water, but misfortune strikes and they tumble down the hill, returning home slightly battered but with their adventurous spirits undimmed. 
Translation: Jack et Jill partent en quête d'eau, mais la malchance frappe et ils dégringolent la colline, rentrant chez eux légèrement meurtris mais avec leurs esprits aventureux intacts.
Names: Jack, Jill
Output JSON: {"french_summary": "Jack et Jill partent en quête d'eau, mais la malchance frappe et ils dégringolent la colline, rentrant chez eux légèrement meurtris mais avec leurs esprits aventureux intacts.", "num_names": 2}

All of the examples are taken from Prompt Engineer Course by Deeplearning.AI. I strongly suggest taking the course. In my next post I will be taking about how to write custom prompts for certain tasks

Subscribe to the newsletter

Get notified when new content or topic is released.

You won't receive any spam! ✌️