Week1
Week1
▪ What a parameter is
▪ The numbers have exploded
▪ Why models come in sizes (nano, mini, haiku, sonnet…)
▪ Inference, and two ways to make a model “smarter”
◦ Part 5 — LLMs Have No Memory (The Stateless Truth)
▪ What it is
1 / 52
▪ Sizes vary a lot
▪ Why it matters
◦ Part 7 — Talking to an LLM: Prompts and Messages
▪ 1. Base model
▪ 2. Chat (or “instruct”) model
▪ 3. Reasoning (or “thinking”) model
▪ 4. Hybrid model
▪ Which type should you use?
▪ A note on terminology
◦ Part 9 — The Chat Completions API and Endpoints
2 / 52
◦ Part 12 — Using Other Providers and Running Models Locally
▪ OpenAI-compatible endpoints
▪ Running models locally with Ollama
▪ Frontier vs. local: the trade-off
▪ Chatting with Ollama straight from the command line
◦ Part 13 — The Landscape of Models (Who Makes What)
▪ 1. Packaged products
▪ 2. Cloud APIs
▪ 3. Running a model yourself (locally)
◦ Part 15 — Your First Real Project: Summarize a Web Page
▪ One-shot prompting
▪ Asking for structured JSON
▪ One-shot vs. multi-shot prompting
▪ Why JSON works so well
▪ What response_format actually does
◦ Part 17 — Combining Multiple Calls: A Multi-Step Solution
3 / 52
▪ Keeping input to a reasonable size
◦ Part 18 — Streaming: The Typewriter Effect
◦ Part 19 — What Frontier Models Are Great and Bad At
▪ Strengths
▪ Weaknesses
▪ The takeaway: use them under supervision
◦ Part 20 — Understanding API Costs
▪ Prompt engineering
▪ Context engineering
▪ Tools
▪ Agentic AI
◦ Part 22 — Where This Is Useful (Business Applications)
◦ Quick Glossary
4 / 52
Part 1 — What Is a Large Language
Model?
That’s it. When you give an LLM some text, it looks at everything
so far and asks itself: “Given all of this, what is the most likely
next piece of text?” Then it adds that piece, looks again, and
predicts the next one, and so on. What feels like conversation,
reasoning, or writing is really this prediction happening over and
over, very fast.
5 / 52
Part 2 — The Transformer: How We Got
Here
You’ll hear the word transformer constantly. It’s worth knowing
where LLMs came from, because it explains a lot of the vocabulary
you’ll meet later.
6 / 52
“Attention Is All You Need”
In 2017, researchers at Google published a paper called Attention
Is All You Need. It introduced the transformer — a new way of
wiring up a neural network that is especially good at handling
sequences (like a sentence, where the order of words matters). Its
key ingredient is a step called self-attention: a layer that figures
out which earlier words in the input matter most when predicting
what comes next.
The word architecture just means “the way the pieces are
connected together.” The transformer is one architecture; there are
others (older ones like RNNs and LSTMs, and newer experimental
ones). None has yet clearly beaten the transformer, so it remains
the standard design for LLMs today.
7 / 52
answer-shaped text — it frequently produces the right answer. This
tendency for real capability to appear once a model is large
enough is called emergent intelligence, and it’s still not fully
understood.
8 / 52
import tiktoken
You can also go the other way and turn a token ID back into text:
9 / 52
The next attempt was word by word. But there are a huge
number of possible words (plus every name and place), so the list
exploded and rare words had to be dropped.
Code, maths, and scientific terms use up more tokens per word
(closer to one token per character), because they contain unusual
symbols and names.
10 / 52
Try it yourself
Besides tiktoken in code, OpenAI has a web page at
[Link]/tokenizer where you can paste text and
see it split into colored tokens. It’s a great way to build intuition.
What a parameter is
A parameter is a single adjustable number inside the model —
think of it as one tiny dial. Training the model means tuning all
these dials, by showing it example after example, until the whole
collection of dials produces good predictions. A model can have
millions, billions, or even trillions of these dials.
11 / 52
• The newest frontier models don’t publish their counts, but
they’re believed to be in the tens of trillions.
12 / 52
Inference, and two ways to make a model
“smarter”
Inference is simply the technical word for running a trained model
— feeding it an input and getting an output. (Training is building
the model; inference is using it.)
There are two different ways to get better results, and you can use
both:
13 / 52
Every request starts from zero
Each time you send a message to an LLM, it is a brand-new,
independent request. The model remembers nothing from your
previous messages. In technical terms, the LLM is stateless — it
holds no state, no memory, between calls.
The second request has no idea our name is Ed, because the first
request is gone.
14 / 52
# We include the earlier turns ourselves, so the model can "see"
them
messages = [
{"role": "system", "content": "You are a helpful assistant"},
{"role": "user", "content": "Hi! I'm Ed!"},
{"role": "assistant", "content": "Hi Ed! How can I assist you
today?"},
{"role": "user", "content": "What's my name?"}
]
# Now the model can predict "Ed" — because the answer is right
there in the text.
15 / 52
What it is
The context window is the maximum number of tokens a model
can look at in one go. It’s the model’s “working memory” for a
single request. Try to send more than fits, and the request simply
fails.
The model produces its answer one token at a time, feeding its
own growing output back in as it goes — so a long answer also
eats into the window.
16 / 52
Why it matters
The context window sets a hard ceiling on how much background
the model can consider at once. It becomes especially important
for techniques that deliberately fill the input with helpful material
— like multi-shot prompting (giving several worked examples)
and RAG (feeding in relevant documents). If you’ve ever used a
coding assistant and noticed it “forgetting” earlier details in a very
long session, that’s the context window filling up.
system_prompt = """
You are a snarky assistant that analyzes the contents of a website
and provides a short, humorous summary, ignoring navigation text.
Respond in markdown. Do not wrap the markdown in a code block.
"""
17 / 52
Simply changing the wording of the system prompt changes how
the model behaves — for example, adding “Respond in Spanish” or
“Be witty and humorous” instantly changes the output. This is one
of the easiest and most powerful ways to control an LLM.
messages = [
{"role": "system", "content": "system instructions go here"},
{"role": "user", "content": "the user's message goes here"}
]
18 / 52
def messages_for(website_text):
return [
{"role": "system", "content": system_prompt},
{"role": "user", "content": "Summarize this website:\n\n"
+ website_text}
]
1. Base model
A base model does one raw thing: given a sequence of text, it
predicts what comes next. Nothing more. It hasn’t been taught how
to “chat” or follow instructions — it just continues the text.
You already use a base model every day: the predictive text on
your phone keyboard. Type “See you” and it suggests “later” —
that’s next-token prediction with no notion of conversation. Early
models like GPT-3 were base models, and people had to trick them
into answering questions by writing prompts in a “Q: … A: …”
pattern.
Base models are mostly useful when you plan to train the model
further yourself to give it a new skill, because you want a blank-ish
slate rather than one already shaped for chatting.
19 / 52
2. Chat (or “instruct”) model
OpenAI’s breakthrough was to train a base model further so it
works as a back-and-forth assistant: a system message, then user/
assistant turns. The result is a chat model (also called an instruct
model) — the kind you actually talk to.
That inspired the next step: train a model to always write out its
reasoning before giving a final answer. The result is a reasoning
model (or thinking model). It first produces its thought process,
then its conclusion. (You may have seen a model show its
“thinking” in a different color before answering — that’s this.)
20 / 52
4. Hybrid model
A hybrid model decides for itself how much to reason based on
the question. A simple “hi there” gets almost no reasoning (fast,
like a chat model); a hard puzzle triggers lots of it. Most of the
newest flagship models (e.g. GPT-5, Gemini 2.5 Pro) are hybrids.
A note on terminology
You’ll also hear foundation model, used much like “frontier
model”: it means a large, general-purpose model that many other
products are built on top of. The terms are fuzzy and often used
interchangeably.
21 / 52
Part 9 — The Chat Completions API and
Endpoints
22 / 52
import requests
Notice how the reply is a nested structure — the useful text lives
inside choices[0]["message"]["content"] . Working with raw JSON like
this is fiddly, which is exactly why the client library (next) exists.
23 / 52
The same request, made simple
import os
from dotenv import load_dotenv
# A quick sanity check that the key was found and looks right
if not api_key:
print("No API key found — check your .env file.")
elif not api_key.startswith("sk-proj-"):
print("A key was found, but it doesn't look like an OpenAI
key.")
else:
print("API key found and looks good!")
24 / 52
OPENAI_API_KEY=sk-proj-//.your-key-here//.
To get a copy of an online project onto your machine, you clone it:
25 / 52
uv: managing Python and packages
Real projects depend on many Python packages (reusable code
libraries). Keeping the right versions of everything installed and
consistent is handled by an environment manager. uv is a fast,
popular one. A single command sets up everything a project needs:
uv sync
26 / 52
Getting an API key (and the cost side)
To call a paid service like OpenAI, you sign up on its platform (the
developer side, separate from the ChatGPT product) and create an
API key — a secret password linking your code to your account.
Paid APIs are usually pay-as-you-go: you add a small balance (e.g.
a $5 minimum) and draw it down as you use the service. Everyday
experimenting costs tiny fractions of a cent, and keeping “auto-
recharge” off means you stay in full control of spending. As
covered earlier, the key goes in a .env file, never directly in your
code.
OpenAI-compatible endpoints
Because the Chat Completions API became a de-facto standard,
other providers (like Google) built endpoints that behave
identically. These are called OpenAI-compatible endpoints.
The friendly result: you can reuse the very same openai client
library to talk to a different provider — you just point it at a
different URL and give it that provider’s key. Again, no OpenAI
model is involved; you’re only borrowing the lightweight library.
27 / 52
# Using Google Gemini through the OpenAI-compatible endpoint
gemini = OpenAI(
base_url="[Link]
openai/",
api_key=google_api_key # a Google key, starts with "AIz..."
)
response = [Link](
model="gemini-2.5-flash-lite",
messages=[{"role": "user", "content": "Tell me a fun fact"}]
)
print([Link][0].[Link])
Then you call it with the same familiar code, just pointed at your
local address:
28 / 52
# Point the OpenAI client at your local Ollama server
ollama = OpenAI(base_url="[Link] api_key="oll
ama")
response = [Link](
model="llama3.2",
messages=[{"role": "user", "content": "Tell me a fun fact"}]
)
print([Link][0].[Link])
29 / 52
ollama run gemma3:270m
# download (if needed) and start chatting with a tiny model
ollama run phi3 # a larger, more capable model (needs
more disk/RAM)
Type a message and the model replies right there. Press Ctrl-D to
end the chat. Bigger models give more capable conversations but
need more disk space and memory. Running a model like this —
feeding it input and getting output — is what’s technically called
inference.
30 / 52
The major closed-source models
• GPT — from OpenAI, the most famous lab. GPT-5 is a hybrid
chat-and-reasoning model; the earlier o-series (o1, o3, o4-mini)
were pure reasoning models, and GPT-4.1 is a fast pure chat
model many people still like. The chat product is ChatGPT.
• Claude — from Anthropic (founded by ex-OpenAI staff). Comes
in haiku / sonnet / opus sizes; sonnet is often the sweet spot.
It’s the model behind the Claude Code coding tool and is a
community favorite.
• Gemini — from Google. Started behind (remember “Bard”?) but
caught up fast; strong on multimodal and huge context
windows.
• Grok — from xAI (Elon Musk’s company). Spelled with a k.
(Don’t confuse it with Groq spelled with a q — that’s a different
company, mentioned below.)
• Others in the next tier include Mistral (French; has both closed
and open models), Cohere, and the model behind Perplexity
(known for real-time search).
31 / 52
• DeepSeek — from the Chinese lab DeepSeek AI; caused a stir
not for beating the top models but for reaching near-frontier
quality at a fraction of the training cost (reportedly a few million
dollars versus $100M+). Its full model is 671B parameters, too
big for a laptop.
• GPT-OSS — OpenAI’s own open-source model, released in 20B
and 120B sizes.
1. Packaged products
These are finished apps with a user interface, like ChatGPT,
Claude, or Gemini’s chat site. A key distinction: you’re using a
product, not a model directly. The product wraps a model with
extra features — a chat interface, memory, web search, file
uploads — that were built by engineers on top of the underlying
model. When ChatGPT searches the web, that search isn’t part of
the LLM; it’s added functionality glued around it.
32 / 52
2. Cloud APIs
Here your own code calls a model running on a server somewhere.
This is what most of this material focuses on. There are a few
varieties:
You can reach both closed and open models this way.
33 / 52
once running, gives you a local endpoint to call — like an API,
but pointed at your own computer.
website_text = fetch_website_contents("[Link]
34 / 52
Step 2 — Write the prompts
system_prompt = """
You are an assistant that summarizes the contents of a website.
Respond in markdown. Ignore navigation-related text.
"""
user_prompt_prefix = """
Here are the contents of a website. Provide a short summary.
If it includes news or announcements, summarize those too.
"""
openai = OpenAI()
def summarize(url):
website_text = fetch_website_contents(url)
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt_prefix + website_t
ext}
]
response = [Link](
model="gpt-4.1-mini",
messages=messages
)
return [Link][0].[Link]
def display_summary(url):
summary = summarize(url)
display(Markdown(summary)) # show it nicely formatted
display_summary("[Link]
35 / 52
A note on the limits of simple scraping
This basic approach reads the text that’s already in the page’s
HTML. It will not work on sites that build their content with
JavaScript after loading (many modern apps do this) — those pages
come back empty. Some sites also block automated requests and
return errors. Tools like Selenium or Playwright, which run a real
browser behind the scenes, can handle those harder cases.
One-shot prompting
One-shot prompting means giving the model one worked
example of what you want inside the prompt, so it copies the
pattern. (Zero-shot = no example; few-shot = several examples.)
Showing an example is one of the simplest ways to get reliable
results.
36 / 52
# System prompt includes ONE example of the exact JSON shape we
want
link_system_prompt = """
You are given a list of links from a webpage.
Decide which links are relevant for a company brochure
(such as About or Careers pages), and respond in JSON like this:
{
"links": [
{"type": "about page", "url": "[Link]
{"type": "careers page", "url": "[Link]
careers"}
]
}
"""
import json
def select_relevant_links(url):
response = [Link](
model="gpt-5-nano",
messages=[
{"role": "system", "content": link_system_prompt},
{"role": "user", "content": get_links_user_prompt(url)
}
],
response_format={"type": "json_object"} # force valid
JSON
)
result = [Link][0].[Link]
return [Link](result)
# turn the JSON text into a Python dictionary
37 / 52
• Multi-shot (or few-shot) prompting gives several examples.
Strictly, this means a series of example question-and-answer
pairs, so the model sees the pattern of good responses. Adding
more good examples — and even counter-examples (“don’t do it
like this”) — is one of the most reliable ways to improve output
quality. This is a practical use of the context window.
38 / 52
Part 17 — Combining Multiple Calls: A
Multi-Step Solution
Real business tools rarely rely on a single LLM call. Chaining
several calls together — where the output of one feeds the next —
is the first taste of Agentic AI (systems where LLMs work through
a task in multiple coordinated steps).
39 / 52
def fetch_page_and_all_relevant_links(url):
# Combine the landing page text with the text of each relevant
sub-page
contents = fetch_website_contents(url)
relevant = select_relevant_links(url) # LLM call #1
result = f"/# Landing Page:\n\n{contents}\n/# Relevant Links:\
n"
for link in relevant['links']:
result += f"\n\n//# {link['type']}\n"
result += fetch_website_contents(link["url"])
return result
brochure_system_prompt = """
You are an assistant that analyzes several pages from a company
website
and creates a short brochure for customers, investors, and
recruits.
Respond in markdown. Include company culture, customers, and
careers if available.
"""
Controlling tone
Notice that switching from a professional brochure to a humorous
one takes nothing more than rewording the system prompt (e.g.,
“create a witty, entertaining brochure”). Tone is controlled entirely
through the prompt — no code changes needed.
40 / 52
Keeping input to a reasonable size
The line combined_text[:5000] truncates the text to the first 5,000
characters. Because you pay per token and models have size limits,
trimming overly long input keeps calls cheap and reliable.
You turn it on with stream=True and loop over the incoming chunks:
response = ""
display_handle = display(Markdown(""), display_id=True)
for chunk in stream:
# Each chunk carries a little more text in .[Link]
response += [Link][0].[Link] or ''
update_display(Markdown(response), display_id=display_hand
le.display_id)
41 / 52
Streaming also reflects what’s really happening inside the model: it
generates the reply one token at a time, so it can hand each token
to you the moment it’s produced. Each small piece that arrives is
called a chunk, and the new bit of text in a chunk lives in
.[Link] (a “delta” is just “the extra bit since last time”).
Under the hood this uses a web technology called SSE (Server-Sent
Events) to push the pieces to you as they’re ready.
Strengths
• Synthesizing information — reading a lot of material and
producing a clear, well-structured, balanced summary or a pros-
and-cons analysis. This is one of their most reliable talents.
• Generating content — drafting emails, presentations, outlines,
and first versions of almost anything. They’re excellent for
fleshing out a rough idea into a starting skeleton.
• Coding — writing, explaining, and debugging code, often
iterating in a loop of write-test-fix. They’ve largely replaced
older resources like Stack Overflow as the first place engineers
turn for help.
Weaknesses
• Knowledge cutoff — a model only knows what existed up to
when it was trained. Ask about newer events and it simply
42 / 52
doesn’t know (unless the product adds web search on top). It
can even confidently insist a real, recent thing “doesn’t exist.”
• Knowledge gaps — expertise is uneven. A model may be
above PhD level in one area and shaky in another.
• Confident mistakes (hallucination) — because a model only
predicts plausible next tokens, it can produce something that
sounds authoritative but is wrong, stated with complete
confidence. (It’s arguably surprising they’re right as often as
they are.)
• Jumping to conclusions — especially in coding, a model tends
to slap a patch on the obvious symptom and push forward,
rather than stepping back to find the real root cause. A classic
trap: a beginner gets pages of increasingly elaborate AI-
generated code fixing the wrong problem, and doesn’t realize
they’ve been led astray.
43 / 52
Subscriptions vs. paying per use
There are two separate ways money changes hands, and they’re
unrelated:
• GPT-5: about $1.25 per million input tokens and $10 per
million output tokens.
44 / 52
• GPT-5 nano (the tiny version): about $0.05 per million input
and $0.40 per million output.
45 / 52
Prompt engineering
Prompt engineering is the craft of writing prompts that get good
results — being clear about the task, giving context, specifying the
style and format, and showing examples. It was briefly a
standalone, high-paying job title; now it’s just a basic skill everyone
working with LLMs picks up.
Context engineering
Context engineering is the newer, broader idea: thinking
carefully about all the information you place into the model’s input
to set it up for success. That includes the prompt, but also
business-specific data you stitch in, and tools the model can use
(see below). It sounds fancy, but at heart it’s simple — give the
model the right input so its predicted output matches your goal. If
you want it to quote correct ticket prices, those prices need to be
in the input.
Tools
A tool is a piece of functionality you give the model access to —
like searching the web, running code, or looking something up in a
database. Rather than answering only from memory, the model can
decide to use a tool and incorporate the result. Tools are a big part
of what makes modern assistants so capable.
Agentic AI
Agentic AI is currently the hottest topic in the field. Two common
definitions:
46 / 52
2. An LLM running in a loop with tools — it’s called repeatedly,
and on each pass it can take actions (use tools) and decide its
next step.
People often describe agents with the word autonomy: the model
appears to choose its own next moves. Under the hood it’s still just
predicting tokens — but when those predicted tokens describe
actions to take next, the system behaves autonomously. That
repeated call-act-decide cycle is an agent loop.
47 / 52
Part 22 — Where This Is Useful
(Business Applications)
The small projects above map directly onto real, valuable use
cases:
Quick Glossary
• LLM (Large Language Model): a program trained on huge
amounts of text that predicts the next chunk of text.
• Frontier model: one of the most powerful, state-of-the-art
LLMs (e.g., GPT, Gemini, Claude), usually accessed as a paid
online service.
• Token / token ID: the small pieces (and their numeric codes)
that text is broken into for the model.
• Stateless: having no memory between requests; each call
starts fresh.
48 / 52
• Prompt: the text you send the model. A system prompt sets
role and tone; a user prompt is the actual question.
• Message: a {"role": //., "content": //.} dictionary. Roles are
system , user , and assistant .
• API / endpoint: a way for your code to call a service, and the
specific URL it calls.
• Chat Completions API: the standard way to ask an LLM to
continue a conversation.
• Client library: a package (like openai ) that wraps the API in
convenient code; it does not contain the model.
• OpenAI-compatible endpoint: another provider’s endpoint
that works with the same code and format.
• Ollama: a free tool for running open-source LLMs locally on
your own machine.
• API key: a secret password identifying your account; kept out
of code in a .env file.
• Web scraping: programmatically fetching the text content of a
web page.
• One-shot prompting: including one example in the prompt so
the model copies the pattern.
• JSON: a structured text format for data that code can easily
read.
• Streaming: receiving the model’s reply piece by piece as it’s
generated (the typewriter effect).
• Agentic AI: systems that chain multiple LLM calls to work
through complex tasks.
• Transformer: the neural-network design (from the 2017 paper
Attention Is All You Need) behind modern LLMs; the “T” in GPT.
• GPT: Generative Pre-trained Transformer — generative
(produces text), pre-trained (trained in advance), transformer
(its design).
49 / 52
• Neural network / deep learning: a model built from many
connected “neurons”; “deep” means many stacked layers.
• Self-attention: the transformer step that decides which earlier
parts of the input matter most for predicting the next token.
• Emergent intelligence: the surprising way real capability
appears once a model is large enough.
• Parameter: one adjustable number (“dial”) inside a model;
models have millions to trillions of them.
• Inference: running a trained model to get an output (as
opposed to training it).
• Training-time vs. inference-time scaling: getting more out
of a model by making it bigger/training more vs. by using tricks
when you run it.
• Mixture of experts (MoE): a big model made of many
specialist sub-models, each used only when relevant.
• Small language model (SLM): a deliberately small LLM.
• Context window: the maximum number of tokens a model can
consider at once (history + input + generated reply).
• Base model: a raw next-token predictor, not trained to chat
(like phone predictive text).
• Chat / instruct model: a model trained (via RLHF) to work as
a back-and-forth assistant.
• RLHF (Reinforcement Learning from Human Feedback):
training that nudges a model toward responses people prefer;
turned GPT into ChatGPT.
• Chain-of-thought prompting: asking a model to “think step
by step” to improve hard answers.
• Reasoning / thinking model: a model trained to write out its
reasoning before answering.
• Hybrid model: a model that decides for itself how much to
reason.
50 / 52
• Reasoning budget / budget forcing: how much a reasoning
model thinks, and techniques to make it think longer.
• Foundation model: a large general-purpose model others build
on; used much like “frontier model.”
• Closed source vs. open source (open weight): models you
can only pay to call vs. models you can download and run
yourself.
• Frontier lab: a leading company that trains top-tier models
(OpenAI, Anthropic, Google, etc.).
• Distillation: training a small model to imitate a big one, often
using AI-generated (synthetic) data.
• Managed cloud service: a platform (Bedrock, Vertex AI, Azure
ML) that hosts and runs models you call.
• Groq (with a q): a service that runs open-source models very
fast on special hardware — not Grok (with a k), which is xAI’s
model.
• Hugging Face Transformers: a library for running open-source
model code directly on your machine.
• GGUF: the compressed file format Ollama uses to store a
model.
• Hallucination: a confident but incorrect answer from a model.
• Knowledge cutoff: the date beyond which a model has no
built-in training knowledge.
• Multi-shot / few-shot prompting: giving several examples in
the prompt (one example = one-shot).
• Structured outputs: forcing a model’s output to match an
exact data specification (schema).
• Prompt engineering: the craft of writing effective prompts.
• Context engineering: thoughtfully assembling all the input
(prompts, data, tools) that a model receives.
51 / 52
• Tool: functionality (web search, code execution, database
lookup) a model can choose to use.
• Agent loop / autonomy: an LLM called repeatedly with tools,
deciding its own next steps.
• RAG (Retrieval-Augmented Generation): feeding a model
relevant documents so it can answer about them.
• Fine-tuning: training an existing model further to specialize it
for a task.
• API costs: pay-per-use charges for API calls, based on input
and output tokens (usually priced per million).
• Chunk / delta: a small streamed piece of a reply, and the new
text it adds.
• Git / GitHub / repo: a change-tracking tool, the website that
hosts code, and a stored project.
• IDE (Cursor / VS Code): the editor you write and run code in.
• uv / virtual environment: a tool that installs a project’s exact
Python and packages into an isolated folder.
• Jupyter notebook / cell / kernel: an interactive code-and-text
document, its runnable blocks, and the Python process that runs
them.
52 / 52