# Prompt Structure

Course: [Prompt Engineering](https://www.devtutorials.ai/learn/prompt-engineering) · Section: Foundations
Source: https://www.devtutorials.ai/learn/prompt-engineering/foundations/prompt-structure

> The six parts of a prompt (role, instruction, context, examples, input, output format), labelling them with headings or tags, a good order, templates, and checking the output format.

A prompt written as one long sentence is hard to read, both for you and for the model. Important details get lost in the middle, and it's hard to tell which part is the task and which part is the data.

Good prompts have a **structure**. Each part has one job, and each part has its own place. This lesson shows you the six parts of a prompt and how to put them together.

**The main idea:** split your prompt into clear parts, give each part a label, and keep the parts in the same order every time.

## A Real-World Example

Think about a recipe card. It always has the same sections:

- The **name of the dish**: what you are making.
- The **ingredients**: what you work with.
- The **steps**: what to do.
- The **serving note**: how the dish should look at the end.

You never have to search for the ingredients, because they are always in the same place. A structured prompt works the same way. The model can find the task, the facts, and the data without guessing.

## What You Will Learn

In this lesson, you will learn:

1. The six parts of a prompt (role, instruction, context, examples, input, and output format).
2. Which parts you always need, and which ones you can leave out.
3. How to label the parts with headings or tags.
4. A good order for the parts.
5. How to turn a structure into a template you can use again.
6. How to check that a reply follows the output format.

The Prompt sandbox has a **Builder** tab. You fill in the six parts, and you see the exact prompt they make. The "Try it" cards below open it for you.

## The Six Parts of a Prompt

| Part | What it does | Example | Do you need it? |
|---|---|---|---|
| Role | Says who the model should act as | You are a support agent for a software company. | You can leave it out |
| Instruction | Gives the task as a clear action | Reply to the customer message below. | Always |
| Context | Gives the facts and background the model needs | Exports over 50,000 rows need the Pro plan. | Often |
| Examples | Shows sample inputs with the outputs you want | Message: ... Reply: ... | You can leave it out |
| Input | The data the model should work on | The customer's message. | When there is data |
| Output format | Says the length, shape, and style of the reply | Two short sentences. No greeting. | Almost always |

Only the **instruction** is always needed. But most weak prompts fail because the **context** or the **output format** is missing.

**In simple words:** the role says who, the instruction says what to do, the context says what to know, the examples show how, the input is the thing to work on, and the format says what the answer should look like.

## The GCCF Formula

Another popular way to remember the parts is **GCCF: Goal + Context + Constraints + Format**. It is not the only way, but it is a good place to start for any task. Two more parts make it even stronger: the **source material** and the **quality bar**.

| GCCF part | The question it answers | Where it fits in the six parts |
|---|---|---|
| **Goal** | What exactly should the model do? | Instruction |
| **Context** | Who is it for, and what background information matters? | Role and context |
| **Constraints** | What limits must it follow, like length, tone, or things to avoid? | Instruction or output format |
| **Format** | Should it be bullets, a table, JSON, an email, or steps? | Output format |
| Source material | Which text, file, or code should it use? | Input (inside tags) |
| Quality bar | What does "good" mean here? For example: easy for beginners, ready for a busy manager, or technically exact. | Output format |

People forget the **quality bar** more than any other part. "Write a summary" and "Write a summary a busy executive can read in 20 seconds" ask for different things.

Here is a weak prompt, and a GCCF version of the same request:

The difference is not the length. The GCCF version removes the guessing. The model knows who the reader is, what to cover, what the limits are, and what the finished reply should look like.

## Build a Prompt From Parts

The next box builds a prompt from parts. Each part gets a heading, and any empty parts are skipped.

```js runnable title="Join the parts with headings"
const parts = {
  instruction: "Reply to the customer message below.",
  context: "Exports over 50,000 rows need the Pro plan.",
  examples: "",
  input: "Can I export 80,000 rows on the free plan?",
  format: "Two short sentences. No greeting.",
};

const labels = { instruction: "Instruction", context: "Context", examples: "Examples", input: "Input", format: "Output format" };

const blocks = [];
for (const key in labels) {
  if (parts[key]) blocks.push("### " + labels[key] + "\n" + parts[key]);
}

console.log(blocks.join("\n\n"));
```

Expected output:

```text
### Instruction
Reply to the customer message below.

### Context
Exports over 50,000 rows need the Pro plan.

### Input
Can I export 80,000 rows on the free plan?

### Output format
Two short sentences. No greeting.
```

The `examples` part was empty, so the code left it out. The model sees four clear sections.

Now try it with the model. Change any part in the card, and then run it.

Then clear the **Context** part, and run it again. Without the facts, the model has to guess where the button is and what the limit is.

## Headings or Tags

There are two common ways to label the parts. Both work. Choose one, and use it every time.

- **Markdown headings**, like `### Context`. These are easy for people to read.
- **Tags**, like `<context>` and `</context>`. These show very clearly where each part starts and ends, which helps with long data.

```js runnable title="The same part as a heading and as tags"
function asHeading(label, text) {
  return "### " + label + "\n" + text;
}

function asTags(label, text) {
  const tag = label.toLowerCase().replace(/ /g, "_");
  return "<" + tag + ">\n" + text + "\n</" + tag + ">";
}

console.log(asHeading("Output format", "One word."));
console.log("---");
console.log(asTags("Output format", "One word."));
```

Expected output:

```text
### Output format
One word.
---
<output_format>
One word.
</output_format>
```

In the Builder tab, switch between **### headings** and **&lt;tags&gt;** to see the whole prompt both ways.

**Easy Way to Remember:** use **tags** when a part holds long or messy data, like an email, a document, or code. Use **headings** when every part is short.

## A Good Order for the Parts

Models pay the most attention to the start and the end of a prompt. In a long prompt, they miss details in the middle more easily. So this is a good order:

1. Put the **role** in the system message.
2. Put the **instruction** first, so the model knows the task before it reads anything else.
3. Put the **context** and **examples** next.
4. Put the **input** after that, inside clear markers.
5. Put the **output format** last, just before the model starts writing.

When the input is very long, like a whole document, repeat the main instruction at the end as well. Otherwise, the model may forget the task by the time it reaches the end.

The next box checks a prompt for missing parts and gives advice. It is a simple helper you could use before you run any prompt.

```js runnable title="Check a prompt for missing parts"
function reviewParts(parts) {
  const notes = [];
  if (!parts.instruction) notes.push("Add an instruction: the task as an action.");
  if (!parts.format) notes.push("Add an output format: length and shape.");
  if (parts.input && parts.input.length > 500) notes.push("Long input: repeat the instruction at the end.");
  if (!parts.context) notes.push("No context: the model will use only what it learned in training.");
  return notes.length ? notes : ["Looks complete."];
}

const draft = { instruction: "Summarise the report.", input: "x".repeat(800) };
reviewParts(draft).forEach((n) => console.log("-", n));
```

Expected output:

```text
- Add an output format: length and shape.
- Long input: repeat the instruction at the end.
- No context: the model will use only what it learned in training.
```

## Structure Makes a Template

Once a prompt has a structure, you can use it again. Keep the fixed parts the same, and change only the input. This is called a **prompt template**.

```js runnable title="One template, many inputs"
function supportPrompt(message) {
  return [
    "### Instruction",
    "Classify the customer message.",
    "### Input",
    message,
    "### Output format",
    "One word: bug, question, or praise.",
  ].join("\n");
}

const inbox = ["The export button crashes.", "Where is the export button?", "I love the new grid!"];

inbox.forEach((m, i) => {
  const prompt = supportPrompt(m);
  console.log("Prompt " + (i + 1) + ": " + prompt.split("\n").length + " lines, input = " + m);
});
```

Expected output:

```text
Prompt 1: 6 lines, input = The export button crashes.
Prompt 2: 6 lines, input = Where is the export button?
Prompt 3: 6 lines, input = I love the new grid!
```

Every prompt has the same shape, and only the input changes. This makes the results easy to compare. It is also how apps send prompts in real code.

In the sandbox, the **Test** tab uses templates too. Write `{{input}}` where each test input should go.

## Check the Output Format

An output format is only useful if you check it. When you ask for "one word: bug, question, or praise", test that the reply is exactly one of those words.

```js runnable title="Check that a reply follows the format"
const allowed = ["bug", "question", "praise"];

function followsFormat(reply) {
  const word = reply.trim().toLowerCase().replace(/\.$/, "");
  return allowed.includes(word);
}

const replies = ["Bug", "question.", "This is a bug report.", "feature"];
replies.forEach((r) => console.log(JSON.stringify(r), "->", followsFormat(r)));
```

Expected output:

```text
"Bug" -> true
"question." -> true
"This is a bug report." -> false
"feature" -> false
```

- `Bug` and `question.` pass. The code cleans up small differences first, like a capital letter or a full stop at the end.
- `This is a bug report.` fails. It has the right meaning, but the wrong shape. Code that expects one word would break.
- `feature` fails. It is one word, but it is not one of the allowed labels.

Now test it on the real model. The Test tab runs the template on each input and checks every reply.

Small models break format rules more often than big ones. If a check fails, make the format clearer, add an example, or repeat the format at the end. Never assume the model followed the format without checking.

## Common mistakes

| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
| One long sentence | "Everything is in there somewhere." | Split the prompt into parts with labels. | The model misses details in the middle. |
| No output format | "The model will choose a good format." | Always say the length and shape you want. | Replies are too long, or in a shape your code can't read. |
| Instruction hidden in the middle | "The order doesn't matter." | Put the instruction first and the format last. | The model works on the wrong task, or ignores the format. |
| Data without markers | "The model knows which part is the email." | Put long data inside tags. | The model follows text in the data as if it were an instruction. |
| Mixed label styles | "Headings here and tags there is fine." | Choose one style and use it for the whole prompt. | The parts blur together, and the model may skip one. |
| Not checking the format | "I asked for one word, so it will be one word." | Check every reply with code. | A full sentence breaks the code that reads the reply. |

## Exercises

In each exercise, the last line should give back a value. Press **Check** to compare your value with the expected answer.

## What to Remember

- A prompt has six parts: **role**, **instruction**, **context**, **examples**, **input**, and **output format**.
- You always need the **instruction**. Adding **context** and an **output format** fixes most weak prompts.
- **GCCF** (Goal, Context, Constraints, Format) is a quick check. Add the **source material** and a **quality bar** too.
- Label the parts with **headings** or **tags**, and use only one style in each prompt.
- Put the **instruction first** and the **output format last**.
- A fixed structure with an input that changes is called a **prompt template**.
- Always **check** that the reply follows the format.

Next: **Context and Grounding**, where you learn how to give the model the facts it needs, and stop it from making things up.
