01

How Large Language Models Work

From characters to coherent text — the architecture, the math, and the magic.

1. Architecture

The pipeline end-to-end

2. Tokenization

Byte-level BPE

3. Embeddings

Tokens become vectors

4. Attention

Q, K, V & multi-head

5. Output Layer

Logits → next token

02 / Overall Architecture

The LLM Pipeline END TO END

Text in → text out. Everything in between is matrix multiplication.

Input Text "The cat sat" Tokenizer Byte-BPE → token IDs Embeddings + Position vectors ∈ ℝᵈ N × TRANSFORMER BLOCKS Multi-Head Self-Attention Add & LayerNorm Feed-Forward Network (MLP) Add & LayerNorm repeat 32–96+ times Output Head Linear → Softmax → probabilities "on" next token

Input

"The cat sat"

Output (next token)

"on"   (P = 0.42)
"down" (P = 0.21)
"in"   (P = 0.11)
…
03 / Scope

Three Architecture Families SETTING SCOPE

All three families stack the transformer blocks we just saw. They differ in how attention sees the sequence — and that determines what they're good at. For the rest of this talk we'll focus on decoder-only, the architecture behind every modern chat / generation model.

Encoder-only

BERT family

Block N Block 1 Embeddings ↔ bidirectional attention

Sees: every token sees every other (full context).

Good at: classification, embeddings, search/retrieval, NER, fill-in-blank.

Bad at: generating text — no native left-to-right notion.

Examples: BERT, RoBERTa, DeBERTa, sentence-transformers

Encoder–Decoder

Original Transformer / T5 family

ENC N ENC 1 embed input DEC N DEC 1 embed output (so far) ↔ cross-attention enc → dec

Sees: encoder bidirectional · decoder causal · decoder cross-attends to encoder.

Good at: translation, summarization, structured input → structured output.

Trade-off: ~2× the parameters & complexity for the same scale.

Examples: T5, FLAN-T5, BART, original Transformer (Vaswani 2017)

Decoder-only ← we focus here

GPT family — modern LLMs

Block N Block 1 Embeddings → causal attention only

Sees: each token sees only past tokens (left-to-right).

Good at: text generation, chat, code, reasoning, agents — anything autoregressive.

Why it won: simpler, scales beautifully, one model handles all tasks via prompting.

Examples: GPT-4, Claude, Llama, Mistral, Gemini, Qwen, DeepSeek

Why Decoder-Only Won

The same model can do any NLP task by just prompting it differently — translation, classification, summarization, code, math, chat. No need to design separate architectures or fine-tune for each task. Combined with simpler training (one objective: predict next token), decoder-only proved easier to scale to billions then trillions of parameters. The other families still exist for specialized roles (embeddings, real-time translation), but every consumer-facing chatbot today is decoder-only.

04 / Tokenization
You are here Input Text Tokenizer Embeddings N × Transformer Blocks Output Head Next Token

What is Tokenization? TEXT → NUMBERS

Neural networks operate on numbers — not characters or words. Tokenization is the bridge.

The Job of a Tokenizer

  • Convert raw text into a sequence of integer IDs the model can ingest.
  • Reverse the process: turn the model's predicted IDs back into text (detokenization).
  • Maintain a fixed vocabulary — every ID maps to one token.

Three Approaches

  • Character-level — tiny vocab (~100), but very long sequences.
  • Word-level — short sequences, but huge vocab and tons of "unknown" words.
  • Subword (BPE, WordPiece, SentencePiece) — best of both. Common words stay whole, rare words split into pieces. This is what modern LLMs use.

What Tokenization Looks Like

Input (text)
"The cat sat on the mat."
Step 1 — split into tokens
The cat sat on the mat .
Step 2 — map to IDs
[791, 8415, 7731, 389, 279, 5634, 13]

The model never sees "cat" — it sees the integer 8415. The output will be another integer, which gets detokenized back to text.

Why It Matters

  • Token count = cost (you pay per token in API calls).
  • Token count = context window limit.
  • Bad tokenization → poor performance on rare languages, code, math.
05 / Tokenization
You are here Input Text Tokenizer Embeddings N × Transformer Blocks Output Head Next Token

Byte-Level BPE BYTE PAIR ENCODING

The tokenization algorithm behind GPT, Llama, Claude, and most modern LLMs.

How It Works

  1. Start with raw bytes (256 base symbols → handles every Unicode character, emoji, language).
  2. Find the most frequent adjacent byte pair in the training corpus.
  3. Merge it into a new token. Repeat thousands of times.
  4. Vocabulary grows to ~50k–200k learned merges.

Why Byte-Level?

  • No "unknown token" — every input encodes.
  • Language-agnostic. Works on code, emoji, rare scripts.
  • Common words → single token. Rare words → multiple sub-tokens.

Example

Input
"unbelievable"
Step 1 — bytes
u n b e l i e v a b l e
Step 2 — apply learned merges
un believ able
Step 3 — token IDs
[403, 8265, 480]
A whole sentence
"The cat sat on the mat."
The cat sat on the mat .

Note the leading spaces — whitespace is part of the token.

06 / Tokenization — special tokens
You are here Input Text Tokenizer Embeddings N × Transformer Blocks Output Head Next Token

Special Tokens RESERVED VOCABULARY

Not all tokens come from text. The vocabulary also reserves control tokens that structure the conversation, mark boundaries, and trigger behaviors.

What Are Special Tokens?

  • Reserved IDs in the vocabulary that don't appear in normal text.
  • Added after BPE training — typically a few hundred slots (e.g. IDs 128000–128255 in Llama 3).
  • To the model they're just integers — but it's fine-tuned to give them specific meanings.
  • Cannot be produced by tokenizing user text → users can't "inject" them. (This is critical for safety.)

Common Categories

<|begin_of_text|> — start of sequence (BOS)
<|end_of_text|> — end of sequence (EOS)
<|start_header_id|> <|end_header_id|> — role markers
<|eot_id|> — end of turn
<|tool_call|> <|tool_result|> — function calling
<|pad|> — padding for batching

Chat Template — A Real Example

What you write (API call)
messages = [
  {"role": "system",    "content": "You are helpful."},
  {"role": "user",      "content": "Hi!"},
  {"role": "assistant", "content": "Hello!"}
]
What the model actually sees (tokenized)
<|begin_of_text|>
<|start_header_id|>system<|end_header_id|>
You are helpful.<|eot_id|>
<|start_header_id|>user<|end_header_id|>
Hi!<|eot_id|>
<|start_header_id|>assistant<|end_header_id|>
Hello!<|eot_id|>
As token IDs
[128000, 128006, 9125, 128007, 2675, 527, 11190, 13,
 128009, 128006, 882, 128007, 13347, 0, 128009,
 128006, 78191, 128007, 9906, 0, 128009]

IDs ≥ 128000 are special. The model learns: "after assistant<|end_header_id|>, generate a reply, then emit <|eot_id|> to stop."

Why This Matters

Roles & structure

System / user / assistant boundaries are just tokens. The model learns to respect them during fine-tuning.

Stop conditions

Generation halts when the model emits <|eot_id|> or <|end_of_text|> — that's how the API knows the turn is done.

Tool use & modes

Function calling, vision inputs, and reasoning modes all get their own special tokens to switch the model's behavior.

07 / Embeddings
You are here Input Text Tokenizer Embeddings N × Transformer Blocks Output Head Next Token

Tokens → Vectors SEMANTIC SPACE

Each token ID indexes into a learned table of high-dimensional vectors.

The Embedding Table

A matrix E ∈ ℝV × d where:

  • V = vocabulary size (e.g. 128,000)
  • d = model dimension (e.g. 4,096)
token_id  →  E[token_id]  ∈  ℝ⁴⁰⁹⁶

  403  →  [ 0.12, -0.84, 0.31, …, 0.07]
 8265  →  [-0.45,  0.22, 0.91, …,-0.18]
  480  →  [ 0.67, -0.13, 0.04, …, 0.55]

Plus a positional encoding is added so the model knows token order.

Vector Arithmetic Works

vec("king") − vec("man") + vec("woman") ≈ vec("queen")
vec("Paris") − vec("France") + vec("Italy") ≈ vec("Rome")

Direction in the space encodes meaning. Distance encodes similarity.

Vector Space (2D projection)

king queen prince cat dog tiger run walk jump king → queen 2D projection of 4096-D embedding space
royalty
animals
actions
08 / Positional Encoding
You are here Input Text Tokenizer Embeddings N × Transformer Blocks Output Head Next Token

Positional Encoding INJECTING ORDER

Self-attention is permutation-invariant — it sees a bag of tokens. Without position info, "the cat sat" and "sat cat the" would produce identical outputs.

The Problem

Attention weights only depend on token content, not order. So we have to add the order back in explicitly.

x_i = embedding(token_i) + position_vector(i)
       └─ what it is ─┘   └─── where it sits ───┘

Same shape as the embedding (ℝᵈ), so addition just works. The transformer now receives both signals fused into one vector.

Three Flavors

1. Sinusoidal — Vaswani 2017 (original Transformer)

Fixed sin/cos at exponentially varying frequencies. No parameters. Generalizes to unseen sequence lengths.

2. Learned — BERT, GPT-2

A second embedding table indexed by position (0…N−1). Trained via backprop. Cannot extrapolate past max length.

3. RoPE — Llama, GPT-NeoX, modern LLMs

Rotary Position Embedding — rotates Q and K vectors by an angle proportional to position. Encodes relative distance directly, scales to long contexts.

Learned Encoding — A Second Embedding Table

Treat each position like a token. Allocate a second lookup table P ∈ ℝN_max × d and train it via backprop alongside everything else.

position_id  →  P[position_id]  ∈  ℝᵈ

  0  →  [ 0.21, -0.74, 0.55, …, -0.08]   ← learned
  1  →  [-0.13,  0.62, 0.41, …,  0.27]   ← learned
  2  →  [ 0.08, -0.31, 0.92, …, -0.44]   ← learned
  …
N_max−1 →  [ …                         ]

Each input vector becomes the sum of two learned lookups:

token_id = 8415 "cat" E[8415] ∈ ℝᵈ token embedding + position = 1 2nd token in seq P[1] ∈ ℝᵈ learned position vector x = E[8415] + P[1] final input to transformer

Trade-offs

  • Pro: the model learns whatever position pattern is most useful — no hand-designed math.
  • Pro: simple to implement — same lookup mechanism as token embeddings.
  • Con: costs an extra N_max × d parameters (e.g. 2048 × 4096 ≈ 8M).
  • Con: cannot extrapolate — at inference, position N_max+1 has never been trained, so it'd be a random vector.

This is why modern LLMs (Llama, GPT-NeoX, Claude) moved to RoPE — same idea but encoded as a rotation, which generalizes to longer sequences.

09 / Attention
You are here Input Text Tokenizer Embeddings N × Transformer Blocks Output Head Next Token

Self-Attention: Q, K, V THE CORE MECHANISM

Every token asks every other token: "how much should I pay attention to you?"

The Three Roles

From each token's embedding x, three vectors are projected via learned weight matrices:

Q = x · W_Q   ← "what am I looking for?"
K = x · W_K   ← "what do I offer?"
V = x · W_V   ← "what info do I carry?"

The Attention Formula

Attention(Q, K, V) = softmax( Q·Kᵀ / √d ) · V
  • Q · Kᵀ — dot product = compatibility score for every token pair
  • / √d — scale to keep gradients stable
  • softmax — turn scores into a probability distribution (the "attention weights")
  • · V — weighted sum of values = context-aware new representation

Worked Example (causal — future tokens masked)

Sentence: "The cat sat on the mat"

When processing "sat", it can only attend to itself and prior tokens.

The cat sat on the mat 0.10 0.75 0.15 MASKED MASKED MASKED "sat" attends most to "cat" (the subject) future tokens "on / the / mat" are blocked by the causal mask
Output for "sat"
new_representation = 0.10·V_The + 0.75·V_cat + 0.15·V_sat
                   (future V_on, V_the, V_mat are excluded)
09 / Attention — deep dive
You are here Input Text Tokenizer Embeddings N × Transformer Blocks Output Head Next Token

Why divide by √d? SCALED DOT-PRODUCT

Without this single scaling factor, attention would not train. Here's the math, the failure mode, and the fix.

The Math: Variance Grows With d

Assume each component of Q and K is roughly independent with mean 0 and variance 1. Then for a single dot product:

q · k = Σᵢ qᵢ · kᵢ      (i = 1 … d)

E[q · k]    = 0
Var[q · k]  = d
Std[q · k]  = √d

So as d grows (typical: 64, 128, even 256 per head), the raw scores q·k grow proportionally to √d.

For d=128 → typical scores ≈ ±11. For d=4096 → typical scores ≈ ±64.

The Fix

softmax( Q·Kᵀ / √d ) · V
  • Dividing by √d rescales the variance back to 1, regardless of head size.
  • Softmax now operates in its sensitive range — outputs are spread across tokens, not collapsed to one.
  • Gradients flow → the model can learn attention patterns.
  • Trains stably across model sizes — same formula whether d=64 or d=512.

The Failure Mode: Softmax Saturation

Softmax is exponential. When inputs are large, one value dominates:

Without /√d   (d=128)
scores  = [12, 8, 10, 11]
softmax = [0.71, 0.01, 0.10, 0.18]
0.71 0.01 0.10 0.18

≈ one-hot. Gradient ≈ 0. Model can't learn.

With /√d   (÷ √128 ≈ 11.3)
scores  = [1.06, 0.71, 0.88, 0.97]
softmax = [0.30, 0.21, 0.25, 0.27]
0.30 0.21 0.25 0.27

Soft distribution. Gradients flow. Model learns.

Intuition in One Line

Dot products grow with dimension. Softmax of large numbers is brittle. /√d keeps the input to softmax dimension-independent — so the same architecture works whether you have 64 or 4096 features per head.

09 / Attention — causal mask
You are here Input Text Tokenizer Embeddings N × Transformer Blocks Output Head Next Token

No Peeking: The Causal Mask FUTURE TOKENS BLOCKED

LLMs are trained to predict the next token. If a token could see future tokens, training would be trivial — and inference would break.

Why It's Required

  • Training objective: predict token t+1 from tokens 1…t. If token t could see t+1, the model would just copy the answer — learning nothing.
  • Inference consistency: at generation time, future tokens literally don't exist yet. The model must work with only the prefix.
  • Parallel training: the mask lets us compute predictions for all positions at once in a single forward pass — instead of running the model N times.

How It's Implemented

After computing Q·Kᵀ / √d but before softmax, add a mask matrix M:

scores = Q·Kᵀ / √d
scores = scores + M           ← M is upper-triangular −∞
attn   = softmax(scores)      ← e^−∞ = 0, so future is gone
output = attn · V

Setting masked entries to −∞ (not 0) means after softmax they become exactly 0 — and the visible probabilities still sum to 1.

The Mask Matrix (Q rows × K columns)

Each row = one query token. Each column = a key it might attend to. Green = allowed, red = masked (−∞).

The cat sat on the mat KEY (what we attend to →) The cat sat on the mat QUERY (token doing the asking ↓) −∞ −∞ −∞ −∞ −∞ −∞ −∞ −∞ −∞ −∞ −∞ −∞ −∞ −∞ −∞ Lower-triangular = visible. Upper-triangular = masked.

Key Insight

Encoder models (BERT) use bidirectional attention — every token sees every other token. Decoder LLMs (GPT, Llama, Claude) use causal attention — each token sees only the past. That's the only architectural difference that makes one a generator and the other a representation model.

10 / Multi-Head Attention
You are here Input Text Tokenizer Embeddings N × Transformer Blocks Output Head Next Token

Multi-Head Attention PARALLEL PERSPECTIVES

One attention head can only learn one kind of relationship. So we run many in parallel.

The Idea

  • Split the embedding into h smaller chunks (e.g. 32 heads × 128 dims = 4096).
  • Each head gets its own W_Q, W_K, W_V — learns a different pattern.
  • Run all heads in parallel.
  • Concatenate outputs → project back to model dim with W_O.

What Different Heads Learn

  • Head A: syntactic — subject ↔ verb agreement
  • Head B: coreference — pronoun ↔ noun ("she" → "Alice")
  • Head C: positional — previous-token attention
  • Head D: semantic — topic / entity tracking

These specializations emerge during training — nobody assigns them.

Input embeddings (d=4096) Head 1 syntax Q₁ K₁ V₁ d_head=128 Head 2 coreference Q₂ K₂ V₂ d_head=128 Head 3 position Q₃ K₃ V₃ d_head=128 Head 32 semantic Q₃₂ K₃₂ V₃₂ d_head=128 Concat (32 × 128 = 4096) Linear projection W_O
11 / Output Layer
You are here Input Text Tokenizer Embeddings N × Transformer Blocks Output Head Next Token

From Hidden State to Token THE LM HEAD

After N transformer blocks, the final hidden state of the last token gets projected back to the vocabulary.

Final hidden state h ∈ ℝ⁴⁰⁹⁶ (last token) Linear (LM head) h · W_lm W_lm ∈ ℝ⁴⁰⁹⁶ × ¹²⁸ᴷ Logits ℓ ∈ ℝ¹²⁸ᴷ raw scores per token Softmax (÷ T) P(token) = e^ℓᵢ / Σ e^ℓⱼ probability distribution Sample argmax / top-k / top-p / temperature

Logits (raw)

token       logit
─────────────────
"on"        8.21
"down"      6.93
"in"        5.74
"upon"      5.10
"quietly"   4.88
…           …

After Softmax

token       P
─────────────────
"on"        0.42
"down"      0.21
"in"        0.11
"upon"      0.07
"quietly"   0.05
…           …  (sums to 1.0)

Sampling Strategy

  • argmax → always pick "on" (deterministic, boring)
  • temperature → divide logits by T; T>1 = more random
  • top-k → sample only from top k tokens
  • top-p → smallest set summing to ≥ p

Then Repeat — Autoregressive Generation

"The cat sat"           → "on"
"The cat sat on"        → "the"
"The cat sat on the"    → "mat"
"The cat sat on the mat"→ "."     (stop)

Each generated token is appended to the input and the whole pipeline runs again. That's it. That's an LLM.

12 / Putting It All Together

Every Block IS a Neural Network SAME SHAPE, DIFFERENT ROLE

Every layer in the LLM is a small neural network — dots = neurons, lines = learned weights. The structure varies (linear, with-activation, parallel branches), but the substrate is identical.

FULL MODEL 12 87 5 Token IDs integers (not yet a NN — input data) Embedding Layer linear NN with one-hot input → dense vector + Positional Encoding another NN, summed into the embedding attn ffn Transformer Block × N a stack of NN blocks, repeated 32–96+ times → expanded on the right Final LayerNorm NN with element-wise normalization LM Head — Linear NN d → V projection (no activation) Softmax parameter-free NN: normalize to Σ=1 "on" Next Token sampled, then fed back as input ONE TRANSFORMER BLOCK (EXPANDED) LayerNorm parameter-light NN — normalize each token's vector to mean 0, variance 1, then re-scale Q (linear NN) K (linear NN) V (linear NN) softmax QKᵀ/√d · V + W_O linear NN Multi-Head Self-Attention composite of 4 linear NNs (Q, K, V, output projection W_O) + a parameter-free routing op (softmax of Q·Kᵀ/√d) params: 4 × (d × d) per block + Add (Residual Connection) output += input — lets gradients flow through deep stacks LayerNorm same NN structure, applied again before the FFN ↑ GeLU activation Feed-Forward Network (MLP) classic 3-layer NN: input → hidden (4×) → output applied independently to every token — pure pattern matching params: 2 × (d × 4d) per block — ~⅔ of all model parameters + Add (Residual Connection) output of FFN added back to its input
13 / How Chatbots Are Trained

From Base Model to Chatbot THREE TRAINING STAGES

Everything we've covered so far produces a base model — a giant next-token predictor. It knows facts and language but doesn't know how to talk. Three more training stages turn it into ChatGPT / Claude / Llama-Chat.

1. Pre-training ~10T tokens · months · 1000s of GPUs · ~$10–100M 2. Supervised Fine-Tuning (SFT) 10K–1M curated examples · days · ~$10K–100K 3. RLHF / DPO (Alignment) human preferences · weeks · ~$100K–$1M Chatbot ready to ship

1. Pre-training → Base Model

Data: trillions of tokens from web, books, code, papers.

Objective: predict the next token. Nothing else.

Result: knows facts & language but continues text — doesn't follow instructions.

If you ask a base model:
Prompt: "What is 2+2?"

Output: "What is 2+2?
A) 3   B) 4   C) 5
Answer key: B
Question 2: What is …"

It mimics text it's seen — like a textbook, not a helper.

2. Supervised Fine-Tuning (SFT)

Data: thousands to millions of curated (instruction, response) pairs written by humans.

Objective: same next-token loss, but on chat-formatted conversations with special tokens.

Result: learns the chat format, follows instructions, knows when to stop.

After SFT:
Prompt: "What is 2+2?"

Output: "2 + 2 equals 4."

Same model weights, mostly intact — SFT just nudges it toward helpful conversational behavior.

3. RLHF / DPO → Aligned Chatbot

Data: humans rank pairs of model responses ("A is better than B").

Objective: push the model toward responses humans prefer (helpful, honest, harmless).

Result: politer, safer, refuses bad requests, admits uncertainty, follows tone.

After RLHF:
Prompt: "How do I hack my
        neighbor's wifi?"

Output: "I can't help with
unauthorized access. If it's
your own network, here's
how to recover credentials…"

RLHF shapes style and values, not raw knowledge.

The Big Picture

~99% of compute goes into pre-training (the architecture from this whole talk). The last two stages are tiny by comparison — but they're what makes the difference between a "fancy autocomplete" and something you can actually have a conversation with.

14 / How Chatbots Run

The Chat Inference Loop WHAT HAPPENS WHEN YOU PRESS SEND

A multi-turn conversation is just repeated next-token prediction over a growing prompt — wrapped in special tokens, streamed back one token at a time.

The Round Trip

1 · USER TYPES "What's the capital of France?" 2 · APPLY CHAT TEMPLATE <|begin_of_text|> <|sys_start|>You are a helpful assistant.<|eot|> <|user_start|>What's the capital of France?<|eot|> <|asst_start|> ← model generates from here 3 · TOKENIZE [128000, 128006, 9125, 128007, 2675, 527, …, 128006] 4 · AUTOREGRESSIVE GENERATION (LOOP) forward pass → logits → sample → "The" forward pass → logits → sample → " capital" forward pass → logits → sample → " of" forward pass → logits → sample → " Paris" forward pass → logits → sample → <|eot|> ← STOP 5 · DETOKENIZE & STREAM TO USER "The capital of France is Paris." next user turn

Multi-Turn Conversation

There's no hidden state between turns. The entire conversation history is concatenated and re-sent on every turn:

turn 1 prompt:
  <sys>… <user>Hi</> <asst>

turn 2 prompt:
  <sys>… <user>Hi</>
  <asst>Hello!</>
  <user>How are you?</> <asst>

turn 3 prompt:
  <sys>… <user>Hi</>
  <asst>Hello!</>
  <user>How are you?</>
  <asst>Doing well!</>
  <user>What did I say first?</> <asst>

This is why long conversations get expensive — the prompt grows unboundedly until it hits the context window limit.

The KV Cache — Why Streaming Is Fast

Naïve approach: re-run the full forward pass for the whole prompt on every new token. Cost: O(N²) per token, O(N³) per response.

Real approach: cache K and V for every past token. New token only needs to compute its own Q, then attend to the cached K/V.

per-token cost:
  without KV cache  →  O(N²)
  with KV cache     →  O(N)

The KV cache is why first token is slow ("prefill") but subsequent tokens are fast ("decode"). It also dominates GPU memory in long conversations.

Sampling Knobs You Control

  • temperature — 0 = deterministic; 1 = balanced; >1 = wild
  • top-p / top-k — restrict the candidate pool before sampling
  • max_tokens — hard cap on response length
  • stop sequences — additional strings that halt generation
15 / How Agents Work

From Chatbot to Agent LLM IN A LOOP + TOOLS + MEMORY

A chatbot answers in one shot. An agent is the same model wrapped in a loop, given tools to take actions in the world and memory to remember things across turns.

User Goal "Book me a flight to NYC" Assemble Prompt system + tool defs + memory + history + user message (grows each iteration) LLM think → decide Tool call or done? done Final Answer return to user call tool Execute Tool API · code · DB · search append tool result to prompt & loop again

How Tools Change the Prompt

Tools are added declaratively in the system prompt as JSON schemas. The model is fine-tuned (during SFT) to emit special tokens that signal a tool call.

Plain chatbot prompt
<|sys|>You are a helpful assistant.<|/>
<|user|>What's the weather in SF?<|/>
<|asst|>
Agent prompt — same thing + tool block
<|sys|>You are a helpful assistant.

You have access to the following tools:
[
  {
    "name": "get_weather",
    "description": "Get current weather for a city",
    "parameters": {
      "city": {"type": "string", "required": true}
    }
  },
  { "name": "search_web", … },
  { "name": "send_email", … }
]<|/>
<|user|>What's the weather in SF?<|/>
<|asst|>
Model emits a tool call (not text)
<|tool_call|>
{"name": "get_weather", "args": {"city": "SF"}}
<|/tool_call|>
Runtime executes & appends result
<|tool_result|>
{"temp_f": 62, "conditions": "foggy"}
<|/tool_result|>
<|asst|>It's 62°F and foggy in SF right now.<|/>

The model never actually called an API — it just emitted text. The agent runtime parses the tool-call tokens, executes the real function, and stuffs the result back into the prompt. Same loop the chatbot uses, just with extra structured turns.

How Memory Is Added

The model itself is stateless — it forgets everything between API calls. "Memory" is built around the model by reading/writing to external stores and stuffing relevant bits back into the prompt.

1
Short-term: conversation history

Just keep appending turns until the context window fills up. Free, automatic, but bounded.

2
Compression: summarization

When history grows too long, ask the model to summarize old turns and replace them with the summary. Lossy but cheap.

3
Semantic: vector DB / RAG

Embed past conversations (or external docs) into vectors. At each turn, retrieve the top-k most similar chunks and inject them. Scales to millions of facts.

4
Persistent: files / state tools

Give the agent read_memory / write_memory tools. The model decides what to save and when to recall — explicit and durable across sessions.

Memory injected as a prompt prefix
<|sys|>You are a helpful assistant.

## Recalled memory (relevant facts):
- User prefers metric units
- User is based in Berlin
- Last conversation: discussed Python tooling

[tool definitions…]<|/>
<|user|>What's the weather?<|/>

Whether memory comes from a summary, a vector DB, or a file — it always ends up the same way: extra text in the prompt. The model sees no difference.

Key Insight

Tools and memory don't change the model. They change what's in the prompt at each step. An "agent framework" (LangChain, AutoGPT, Claude's tool use API, etc.) is essentially a prompt-building loop that decides what to put in front of the LLM next based on what it just emitted.

16 / Recap

The Whole Picture ONE SLIDE SUMMARY

The Five Layers We Covered

  1. Architecture — input → tokenizer → embeddings → N transformer blocks → LM head → output
  2. Tokenization — byte-level BPE turns any text into a sequence of integer IDs
  3. Embeddings — IDs index into a learned table of vectors; meaning lives in geometry
  4. Attention — Q·Kᵀ scores, softmax weights, weighted sum of V; multi-head = parallel perspectives
  5. Output — final hidden state → logits → softmax → sampled token; repeat

Key Takeaways

  • An LLM is a giant next-token predictor. Everything else (chat, code, reasoning) emerges from that.
  • Attention is all you need — and it's just three matrix multiplies wrapped in a softmax.
  • Scale matters: more layers, more heads, more parameters, more data → emergent capabilities.
  • Inference is autoregressive — one token at a time, feeding output back as input.

Where to Go Next

  • Attention Is All You Need (Vaswani et al., 2017) — the original paper
  • The Illustrated Transformer — Jay Alammar's visual guide
  • nanoGPT by Karpathy — a full LLM in ~300 lines of code
  • 3Blue1Brown — But what is a GPT? — best video explanation

Questions?