Skip to content

Week 3 — Prompt engineering & LLM fundamentals

~20 min read · Examinable: 🔥🔥 (structured outputs, system prompts — asked + growing) · GA3 · ET-1 session

The week on making LLMs do what you want reliably. The exam cares about three things from here: prompt anatomy, system vs user prompts, and structured outputs. Everything else (embeddings, similarity search, prompt caching) feeds Week 4's RAG.

Course files: prompt engineering (3 parts) · AI coding assistants · context engineering · LangSmith/LiteLLM · LLM architecture survey · LLM CLI tools · multimodal inputs · prompt caching · similarity search · structured output · vector embeddings.


Prompt anatomy — the structure the exam tests

A good prompt answers the model's hidden questions before it asks them:

Bad prompt  = vague wish
Good prompt = task + context + constraints + output format + examples when needed
The model's hidden question What you provide
What is the task? Explain, summarize, classify, extract, rewrite
Who is the audience? Beginner, developer, manager, examiner
What context matters? Source text, data, scenario, goal
What should output look like? Markdown, table, JSON, bullets, code
What should be avoided? Hallucination, extra prose, unsupported claims
How will quality be judged? Rubric, examples, acceptance criteria

The exam connection

T3-AN Q29 asks exactly this: which prompt structure is most effective for sentiment classification? The answer is the one with clear instructions + specified output format + separated input data — the anatomy above.


System vs user prompts — the hierarchy

LLMs take input in two roles:

System prompt (developer) User prompt
Carries Core operational rules, safety constraints, identity The transient question or task
Set by The developer The end user
Weight Higher — the model obeys it more diligently Lower — subordinate to system rules

Must remember — why the hierarchy exists

LLMs are mathematically tuned to assign significantly higher attention weights to system prompts. This ensures the model adheres to its core operational rules even if a user tries to override them — which is the structural defense against prompt injection.

A user typing "ignore previous instructions" in the user prompt cannot easily override rules set in the system prompt — the model weighs the system prompt more heavily by design.

Trap — what role separation does NOT do

It doesn't block users from typing forbidden words (that's input filtering), and it doesn't make the model incapable of error. It makes the model more resistant to override attempts — a defense layer, not a wall.


Structured Outputs — guaranteed JSON from an LLM

The problem: LLMs return free-form text. Your application needs typed, validated data — a JSON object with specific fields, or your parser crashes.

The wrong fix: regex parsing, string splitting, "hoping the model formats it correctly." Brittle — breaks on every model update.

The right fix: Structured Outputs (via Instructor + Pydantic, or the API's native constraint parameter). You define a schema; the LLM fills it:

class Movie(BaseModel):
    title: str
    year: int
    rating: float

# The LLM returns a typed Movie object — not a string to parse
movie = client.messages.create(
    ...,
    response_model=Movie,
)
print(movie.year)  # 2014 (int, not string!)

What Structured Outputs guarantees — and what it doesn't

Guaranteed: the output is valid against your schema. The model's token generation is constrained at the sampling level — it cannot produce JSON that violates the schema.

NOT guaranteed: factual accuracy. The model can still be wrong about the content — it's just grammatically correct. A hallucinated movie title in valid JSON is still a hallucination.

→ T1-AN Q20

Structured Outputs vs Python validation — the exam's sharpest distinction

The one-sentence difference

Structured Outputs constrains token generation (invalid JSON cannot be produced). Python validation detects errors after generation (the model produced bad JSON, your code catches it). Prevention vs detection — different layers, both belong in a real system.

→ T1-FN Q22

The enforcement chain (worth memorizing)

1. Pin the format in the prompt     → "Respond with exactly one word: positive, negative, or neutral"
2. Validate the response             → try: parse JSON, check fields
3. Escalate to Structured Outputs    → when it must never break

T3-AN Q31 tests step 1; T1-AN Q20 tests step 3.


LLM API calls — the production questions

The HTTP verb: POST, not GET

LLM inference processes submitted data — that's POST by REST semantics. The payload (review text, question, document) goes in the request body, not the URL. GET is for retrieval without side effects.

→ T3-AN Q28 — asked as a one-mark MCQ here, and as a 2-mark short answer in T1-FN Q25

Cost and scale awareness

500 reviews at $0.002 each = $1.00 and ~17 minutes sequential. The professional approach:

  • Batch — respect rate limits, group efficiently
  • Track costs — it's real money; monitor spend per run
  • Handle errors — retries with backoff, fallbacks
  • Cache results — identical input → stored output, never pay twice

→ T3-AN Q30

The division of labour

The LLM judges each item; your code does the math. Asking the LLM to count or calculate re-introduces hallucination into a step that should be exact. The model returns verdicts; pandas sums them.

→ T3-AN Q32


Reliability discipline for LLM systems

On the official topic list: Reliable AI/LLM Systems.

The official topic names four disciplines. The first two have their full treatment here; the last two link out.

1. Verifying AI-generated output before trusting it. LLM output is evidence, not truth — it needs the same skepticism as a stranger's claim. The verification ladder, cheapest first:

  • Schema validation — the output parses and has the required fields (structured outputs guarantee this by construction)
  • Constraint checks in code — values in range, dates in order, IDs that exist in your data. Your code checks; the LLM never self-certifies
  • Grounding check — every factual claim traceable to a retrieved source (the RAG discipline)
  • Second-pass review — a separate model call (or a human) checks the output against the task before it acts or ships

The design principle: verification runs before the output is used, not after problems appear. An LLM that drafts an email → schema check → policy check → human approve → send. Skip a gate and the failure surfaces on the customer.

2. Authorization in code, not in prompts. "Never reveal internal documents" written in a system prompt is a request; enforced document permissions in your retrieval code is a control. The distinction:

Defense What it is Can it fail?
Prompt instruction ("don't show salary bands") asking the model nicely yes — paraphrased injection slips past
Retrieval scoping (docs not in the corpus) the model cannot access them no — nothing to leak
Permission checks in code user → allowed documents, enforced before generation no — code is deterministic

The rule the exam tests: sensitive-data boundaries live in architecture (what can be retrieved, what the code checks), never in the prompt (what the model is asked not to do). A prompt is not a security boundary — it's the same reasoning as prompt injection turned inside out.

3. Enforcing structured output — full treatment: Structured Outputs above. The exam phrase to remember: valid by construction, not by asking.

4. Grounding answers in current sources — full treatment: RAG staleness and versioning (expire old chunks; effective-date filtering; no document, no answer).

→ Short-note version: LLMs & prompting — reliability discipline


Vector embeddings — the foundation for RAG

What an embedding is: a fixed-length list of numbers (a vector) that represents the meaning of a text. Texts with similar meanings have vectors that are close together in high-dimensional space.

"King" − "Man" + "Woman" ≈ "Queen"

This isn't magic — the embedding model places semantically related concepts in similar geometric regions.

response = client.embeddings.create(
    model="text-embedding-3-small",
    input="The cat sat on the mat.",
)
embedding = response.data[0].embedding  # 1536 dimensions

Why it matters: embeddings power semantic search, RAG (Week 4), and recommendation systems. When the exam asks about "converting a query to an embedding and searching for similar chunks" — that's this.

→ The RAG questions in T3-AN Q33–37 all build on this concept.


Similarity search — finding the nearest neighbours

Once texts are embeddings, "find similar" becomes a geometry problem: which vectors are closest? Common distance measures:

Measure Best for
Cosine similarity Text semantics — measures angle, not magnitude
Euclidean distance Straight-line distance in vector space
Dot product Fast, used when vectors are normalized

The exam's cosine-similarity question (GA3: cosine-similarity-server) tests whether you know that semantic similarity = geometric proximity.


Context engineering — managing the window

LLMs have a context window — a maximum number of tokens they can process at once. Context engineering is the discipline of fitting the most useful information into that window:

  • What to include: the task, the critical context, recent conversation
  • What to leave out: irrelevant history, redundant examples, padding
  • The "lost in the middle" problem: models attend most to the beginning and end of the context — information buried in the middle gets less attention

This connects directly to RAG (Week 4): chunking strategies exist partly to manage context windows, and the context-assembly question in GA4 tests it.


Prompt caching — saving money on repeated prefixes

When you send the same system prompt (or prefix) repeatedly, the provider can cache the processed tokens. Subsequent requests with the same prefix are cheaper and faster — you pay for the cached input at a reduced rate.

The exam angle: this pairs with the caching family from Week 2 — same concept (cache what doesn't change), applied to LLM tokens instead of HTTP responses.


Self-check — can you answer these without looking?

1. Why do developers put core rules in the System prompt instead of the User prompt?

LLMs assign higher attention weights to system prompts — the model obeys them more diligently, making it harder for users to override the rules through their input.

2. What does Structured Outputs guarantee — and what does it NOT?

Guaranteed: valid JSON against your schema (token generation is constrained). NOT guaranteed: factual accuracy — the model can still be wrong, just grammatically correct.

3. What's the difference between Structured Outputs and Python validation?

Structured Outputs constrains generation (prevention — bad JSON can't be produced). Python validation detects errors after (the model already produced bad JSON, your code catches it).

4. An LLM returns 'negative', 'Negative', and 'neg' inconsistently. What do you do?

Pin the format in the prompt: "Respond with exactly one word: positive, negative, or neutral in lowercase." If it must never break, escalate to Structured Outputs.

5. Should an LLM inference endpoint use GET or POST? Why?

POST — the review text is a payload submitted for processing (REST semantics), it exceeds URL length limits (payload limits), and GET responses may be cached by proxies (leaking one user's result to another).

6. What is an embedding?

A fixed-length vector of numbers that represents the meaning of a text. Similar meanings → nearby vectors. This is the foundation of semantic search and RAG.