# Context Basics

Course: [Context Engineering](https://www.devtutorials.ai/learn/context-engineering) · Section: Foundations
Source: https://www.devtutorials.ai/learn/context-engineering/foundations/context-basics

> What context is, why a model only knows what is in its context window, how context engineering differs from prompt engineering, the 14 parts a context can hold, and why good context gives better answers.

Imagine you call a help desk. The person is smart and polite. But they can only see papers on their desk. They can't see your account, your last email, or the error on your screen. So they guess.

Now imagine the same person with your account, the error message, and the right help page on the desk. They give you the right answer on the first try.

The person didn't get smarter. The desk got better. For an AI model, that desk is called the **context**. Choosing what goes on it is called **context engineering**.

**The main idea:** a model can only use what is in its context. Good context gets good answers.

## A Real-World Example

Think about an open-book exam.

- You bring notes, but only one page.
- If you bring the wrong page, you can't answer the question, even if you are smart.
- If you fill the page with everything you know, you can't find what you need.

The best page has the facts the exam needs in clear order. Nothing else is there.

A model works the same way. Its context is the one page. Context engineering is picking what goes on that page and in what order.

**In simple words:** context engineering means giving the model the right information in the right shape at the right time.

## What You Will Learn

In this lesson, you will learn:

1. What context is.
2. Why a model has no memory between requests.
3. How context engineering is different from prompt engineering.
4. The 14 parts a context can contain.
5. Why good context gives better, safer, cheaper answers.

This course has a **Context sandbox** at the bottom of every page. It runs a real AI model in your browser. Nothing you type leaves your computer. The "Try it" cards send a context to it. The code boxes use plain JavaScript and run without a model.

## AI Context

### Context Definition

**Context** is everything the model reads before it writes its reply.

That includes your message. It also includes:

- The instructions the app gives the model.
- Earlier messages in the chat.
- Documents, records, and files the app added.
- Results from tools, like a search or a database lookup.

The model doesn't know where each piece came from. It just reads all of it as one long text. Then it writes a reply based on that text.

So if a fact is not in the context, the model can't use it. It will either say "I don't know" or make up something that sounds right.

### Working Memory Model

Think of context like **working memory**. Working memory is the small space you hold things in right now. Like a phone number you are about to dial.

A model's working memory is its **context window**. The context window is the most text the model can read in one request. It is measured in **tokens**, which are small pieces of words. You learned about tokens in the Large Language Models course.

Two facts make this important:

- **The space is limited.** You can't put everything on the desk. You must choose.
- **The desk is cleared after every reply.** The model doesn't remember the last request. If a chat app seems to remember, the app is sending the earlier messages again inside the new context.

The next box shows this. It checks if a request contains the name "Asha". It is a simple word check, not AI. It just shows the idea.

```js runnable title="Each request starts with an empty desk"
function sees(request, word) {
  return request.messages.some((m) => m.content.includes(word));
}

const first = { messages: [{ role: "user", content: "Hi, my name is Asha." }] };

const secondAlone = { messages: [{ role: "user", content: "What is my name?" }] };

const secondWithHistory = {
  messages: [
    { role: "user", content: "Hi, my name is Asha." },
    { role: "assistant", content: "Nice to meet you, Asha." },
    { role: "user", content: "What is my name?" },
  ],
};

console.log("Request 1 has the name:", sees(first, "Asha"));
console.log("Request 2 alone has the name:", sees(secondAlone, "Asha"));
console.log("Request 2 with history has the name:", sees(secondWithHistory, "Asha"));
```

Expected output:

```text
Request 1 has the name: true
Request 2 alone has the name: false
Request 2 with history has the name: true
```

Request 2 on its own doesn't have the name. A model that only gets that request can't know it. The name is there only when the app sends the earlier messages again.

**In simple words:** the model remembers nothing. Everything it needs must be in the context every time.

### Prompt vs Context Engineering

You already know **prompt engineering**. It is the skill of writing one clear message. You write the task, the audience, the length, and the format.

**Context engineering** is bigger. It decides everything that goes into the context window. The prompt is just one part.

| | Prompt engineering | Context engineering |
|---|---|---|
| Works on | The words of one message | Everything the model reads |
| Main question | How should I ask? | What should the model see? |
| Typical fix | Add the audience, the length, or the format | Add the missing record, remove an old document, label a source |
| Who usually does it | Anyone who types into an AI tool | People who build AI apps and assistants |

The two skills work together. A perfect prompt still fails if the model is missing a fact. Perfect facts still fail if the question is unclear.

The next box compares the size of a prompt with the size of the whole context for the same question.

```js runnable title="The prompt is a small part of the context"
const prompt = "Why did my export fail, and what can I do?";

const context = [
  "System: You are the support assistant for Brightgrid.",
  "Rules: Never share other customers' details.",
  "Record: Customer Asha Rao. Plan: Free.",
  "Article: Free plan exports up to 5,000 rows.",
  "File: ERROR 413. Rows requested: 80,000.",
  "Question: " + prompt,
];

const words = (text) => text.split(" ").length;

console.log("Prompt words:", words(prompt));
console.log("Context words:", words(context.join(" ")));
console.log("Parts in the context:", context.length);
```

Expected output:

```text
Prompt words: 10
Context words: 45
Parts in the context: 6
```

The customer typed 10 words. The model read 45. The app chose the other 35 words and they decide if the answer is right.

**Easy Way to Remember:** prompt engineering asks "**how do I say it?**" Context engineering asks "**what does the model need to see?**"

## Context Structure

A context can be built from many kinds of parts. This course uses 14 of them. You will not use all 14 in every request. But you should know each one.

All the examples below come from one product called **Brightgrid**, a data grid for web apps. A customer named Asha asks: "Why did my export fail, and what can I do?"

### System Instructions

**System instructions** tell the model who it is and what job it does. They are sent before everything else.

Example: "You are the support assistant for Brightgrid. Help the customer with their question."

Without them, the model doesn't know it is a support assistant. It may answer like a general chatbot.

### User Requests

The **user request** is the message the person typed. It is the prompt from the Prompt Engineering course.

Example: "Why did my export fail, and what can I do?"

It is the only part the user controls. The app chooses every other part.

### Conversation History

**Conversation history** is the list of earlier messages in the chat. The app sends them again with every new message.

Example: "User: Hi, I need help with exporting. Assistant: Sure. What would you like to export?"

Without it, the model can't follow a chat. With too much of it, old messages crowd out the facts that matter.

### Uploaded Files

**Uploaded files** are documents the user attaches. This could be a PDF, spreadsheet, or log file. The app reads the file and puts its text into the context.

Example: an `export-error.txt` file that says "ERROR 413: Export limit reached. Rows requested: 80,000."

Without it, the model can only guess what went wrong.

### Database Records

**Database records** are rows the app looks up. This could be a customer's account or an order.

Example: "Customer: Asha Rao. Plan: Free. Seats: 3."

These facts are private. The model never learned them in training. They reach the model only through the context.

### Examples

**Examples** show the model one or more sample questions with good answers. The model copies their style and shape.

Example: a sample answer with a one-line answer, two numbered steps, and a source line.

You learned this as few-shot prompting in the Prompt Engineering course. Here, examples are one part you can choose to include or leave out.

### Retrieved Content

**Retrieved content** is text the app finds by searching. Usually in help articles or other documents.

Example: "Free plan: export up to 5,000 rows. Pro plan: export up to 1,000,000 rows."

This is how an assistant answers questions about things the model never saw in training. How that search works is covered in the RAG course.

### Tool Definitions

**Tool definitions** describe tools the model can ask the app to use. Each one has a name, a purpose, and the inputs it needs.

Example: "upgrade_plan(customer_id, plan): moves a customer to a new plan. Only use it after the customer says yes."

The model can't run a tool itself. It can only ask and the app decides. Tools are covered in depth in the MCP course.

### Tool Outputs

**Tool outputs** are the results a tool sends back. The app adds them to the context so the model can read them.

Example: "Tool: export_status. Status: failed. Rows requested: 80,000."

A tool output is fresh evidence. It shows what is true right now. Not what was true when the model was trained.

### Short-Term Memory

**Short-term memory** is a short note about the current task. It keeps the important points of this chat without sending every message again.

Example: "Current task: the customer wants to export 80,000 rows to Excel."

It is like a sticky note on the desk that says what you are working on.

### Long-Term Memory

**Long-term memory** is a fact saved from earlier chats. So the assistant can use it next week too.

Example: "Saved preference: Asha likes short answers with clear steps."

Long-term memory must be handled with care. It can hold personal details and it can go out of date.

### Metadata Headers

**Metadata** is information about information. A **metadata header** is a short label on top of a document. It says where the text came from, how new it is, and how much to trust it.

Example: "[source: docs/export-limits.md · updated: 2026-05-01 · trust: official]"

Without labels, the model can't tell an official help page from an old forum post. Both look like plain text.

### Safety Rules

**Safety rules** tell the model what it must never do and what to do when it is unsure.

Example: "Never share details about other customers. If the context does not contain the answer, say you are not sure."

Without them, the model fills gaps with guesses that sound confident.

### Output Schemas

An **output schema** describes the exact shape the reply must have. A program can then read the reply and check it.

Example: "Reply in this format. Answer: one sentence. Steps: at most 3. Source: the document you used."

Without a schema, every reply comes back in a different shape. Code that reads the replies then breaks.

### Putting the Parts Together

Now see how an app joins some of these parts into the messages a model gets. The stable parts go into the system message. The parts for this question go into the user message. Each one is under a heading.

```js runnable title="Five parts become two messages"
const parts = {
  system: "You are the support assistant for Brightgrid.",
  safety: "Never share other customers' details.",
  record: "Customer: Asha Rao. Plan: Free.",
  retrieved: "Free plan: export up to 5,000 rows.",
  question: "Why did my export fail?",
};

const messages = [
  { role: "system", content: parts.system + "\n" + parts.safety },
  {
    role: "user",
    content:
      "### Customer record\n" + parts.record +
      "\n\n### Help article\n" + parts.retrieved +
      "\n\n### Question\n" + parts.question,
  },
];

for (const m of messages) {
  console.log(m.role + ": " + m.content.split("\n").length + " lines");
}
console.log(messages[1].content);
```

Expected output:

```text
system: 2 lines
user: 8 lines
### Customer record
Customer: Asha Rao. Plan: Free.

### Help article
Free plan: export up to 5,000 rows.

### Question
Why did my export fail?
```

The headings tell the model what each part is. Lesson 4, Context Formatting, covers headings, tags, and order in detail.

Now try it with the real model. The card below switches on seven of the 14 parts. In the Builder, switch parts on and off and watch the token bar and the exact context change.

## Context Benefits

Why put in this effort? Because the context decides how good, how safe, and how costly every answer is. Here are the eight main benefits.

### Response Quality

The model answers from what it sees. Give it the customer's plan and the error. It can explain the real cause. Leave them out and it can only give general advice.

Try it. Context A has only the question. Context B has the record, the article, and the error file. The question is the same.

Look at the two replies:

- Context A gets a general answer. It may list many possible causes or invent one.
- Context B can point to the real cause: 80,000 rows were asked for. The Free plan allows 5,000.

### Grounding

**Grounding** means the answer is based on facts in the context. Not on the model's guesses. A grounded answer can be checked against its source.

The next box checks if every number in an answer appears in the context.

```js runnable title="Is every number in the answer in the context?"
const context = "Free plan: export up to 5,000 rows. Pro plan: up to 1,000,000 rows.";

function grounded(answer) {
  const numbers = answer.match(/\d[\d,]*/g) ?? [];
  const unsupported = numbers.filter((n) => !context.includes(n));
  return unsupported.length === 0 ? "grounded" : "not in context: " + unsupported.join(", ");
}

console.log(grounded("The Free plan exports up to 5,000 rows."));
console.log(grounded("The Free plan exports up to 10,000 rows."));
```

Expected output:

```text
grounded
not in context: 10,000
```

The second answer sounds just as sure. But 10,000 is nowhere in the context. So the model made it up. A check like this is only possible when the facts are in the context.

### Hallucination Reduction

A **hallucination** is an answer that sounds right but is false. Models hallucinate most when the facts they need are missing.

Good context reduces this in two ways:

- It gives the model the real facts. So it has less to guess.
- Its safety rules tell the model to say "I'm not sure" when the facts are missing.

Context does not remove hallucinations completely. It makes them much less likely.

### Security

Context engineering decides what the model is allowed to see. If a document is not in the context, the model can't leak it.

For example, the app puts only Asha's record in the context. Not the whole customer table. Even if someone tricks the model, it has no other customer's data to share. Lesson 13 covers this in depth.

### Latency Control

**Latency** is how long you wait for the reply. The model must read every token in the context before it writes. More context means a longer wait.

Keeping the context small and relevant makes replies start faster.

### Token Optimization

Most AI services charge by the token on every request. A part you send by habit is a part you pay for again and again.

The next box compares sending everything with sending only the parts this question needs.

```js runnable title="Fewer tokens for the same answer"
const tokens = (text) => Math.ceil(text.length / 4);

const everything = [
  "You are the support assistant for Brightgrid, a data grid component for web apps.",
  "Never share details about other customers.",
  "Customer: Asha Rao. Plan: Free. Seats: 3.",
  "Free plan: export up to 5,000 rows. Pro plan: up to 1,000,000 rows.",
  "ERROR 413: Export limit reached. Rows requested: 80,000.",
  "Theme guide: open Grid settings, then choose Theme.",
  "Keyboard guide: press Ctrl+F to search the grid.",
  "Release notes: version 30 adds dark mode and faster sorting.",
  "Old chat: the customer asked about invoices in March.",
];

const justRight = everything.slice(0, 5);

const total = (list) => list.reduce((sum, text) => sum + tokens(text), 0);

console.log("Everything:", total(everything), "tokens");
console.log("Just right:", total(justRight), "tokens");
console.log("Saved:", total(everything) - total(justRight), "tokens on every request");
```

Expected output:

```text
Everything: 128 tokens
Just right: 74 tokens
Saved: 54 tokens on every request
```

The last four parts have nothing to do with exports. Leaving them out cuts the context by 54 tokens. That is about 42%. Over thousands of requests, that is real money. The token count here is a rough guess of 4 letters per token. Lesson 2 shows real token counts.

### Workflow Stability

A **workflow** is a series of steps an app runs. Often with several model calls. If each step gets a different, messy context, the results change from run to run.

When every step gets a clear, planned context, the same input gives the same kind of result. That makes the whole app reliable.

### Failure Analysis

When an answer is wrong, the first question is: "What did the model see?" If you can list the parts that were sent, you can often find the cause in seconds.

```js runnable title="Find the missing part"
const needed = ["system", "record", "retrieved", "file"];

const sent = ["system", "safety", "retrieved"];

const missing = needed.filter((part) => !sent.includes(part));

console.log("Needed:", needed.join(", "));
console.log("Sent:", sent.join(", "));
console.log("Missing:", missing.join(", "));
```

Expected output:

```text
Needed: system, record, retrieved, file
Sent: system, safety, retrieved
Missing: record, file
```

The model never saw the customer's plan or the error file. So it could not explain the failure. The fix is in the context, not in the model. Lesson 14 turns this into a full checklist.

Good context makes good answers much more likely. It does not make the model always right. For facts, prices, and actions, still check the answer.

## Common mistakes

| Mistake | Wrong idea | Correct idea | What goes wrong |
|---|---|---|---|
| Expecting memory | "I told the model my plan earlier, so it knows." | The model sees only this request. The app must send the facts again. | The model forgets and guesses. |
| Fixing only the prompt | "If I word the question better, it will know the answer." | A missing fact can't be fixed with better wording. Add it to the context. | Hours spent rewording a question the model can't answer. |
| Sending everything | "More context is always better." | Send the smallest set of parts that is enough. | Higher cost, slower replies, and the key fact gets lost. |
| No labels | "The model will work out which text is the rule and which is the document." | Use headings and metadata headers to label each part. | The model follows text in a document as if it were a rule. |
| No safety rules | "The model will say when it does not know." | Tell it what to do when the facts are missing. | Confident answers made up from nothing. |
| Blaming the model first | "The model is bad at this question." | First check what was in the context. | The real cause, a missing record, is never fixed. |

## Exercises

Each exercise ends with a value on the last line. Press **Check** to compare it with the expected answer.

## What to Remember

- A model can only use what is in its context.
- The model remembers nothing. Everything it needs must be in the context every time.
- The context has 14 possible parts in six groups.
- Good context gives better, safer, cheaper answers.
- Ask "what does the model need to see?" not "how should I ask?"

Next: **Context Windows**, how text becomes tokens and how the model uses a limited space.
