A crash course in the ideas behind the AI engineering guide: what a large language model is, how the Claude API works, what embeddings and vector databases do, and how RAG, tools, agents and MCP fit together. Mostly concepts and diagrams; code only appears where it makes an idea concrete, and in the setup at the end.
How LLMs work
What a large language model actually does, why it behaves the way it does, and what that means for the software you build around it.
What an LLM is
A large language model (LLM) is a neural network trained to do one thing: given some text, predict what comes next. It scores every possible next piece of text, one is chosen, appended, and the model predicts again. Answering questions, summarizing, translating and writing code all come out of this single repeated step.
Illustrative numbers. This step repeats once per token until the model emits a stop signal or reaches your output limit.
It generates, it doesn't look up. There is no table of facts inside the model. What it "knows" is spread across billions of learned numbers (weights), which is why an answer can be fluent and wrong at the same time.
How a model gets trained
Pretraining runs the model over a huge amount of text so it learns language, facts, reasoning patterns and code. The result predicts text well but isn't yet a helpful assistant. Post-training then tunes it, using example conversations and human and AI feedback, to follow instructions, use tools and decline harmful requests.
Three consequences shape everything you build:
Knowledge cutoff: the model knows nothing that happened after its training data was collected.
No private knowledge: it has never seen your company's documents, database or tickets.
No learning while you use it: the weights are fixed. Anything it needs for a task has to be in the request itself.
Getting the right information into the request is most of AI engineering, and it's what retrieval (RAG) and tools are for.
Tokens and the context window
Models don't read characters or words; they read tokens, which are word fragments. Limits and prices are all measured in tokens. The context window is the maximum number of tokens one request can hold, and everything counts toward it: your instructions, the conversation so far, tool definitions, any documents you include, and the answer being generated.
Each model family splits text differently, and context window sizes vary by model. The API can count tokens for you before you send a request.
Two practical effects: long conversations and big documents cost more on every request, because the whole context is sent each time; and anything that doesn't fit simply isn't seen by the model.
Strengths and failure modes
LLMs are strong at language: explaining, summarizing, rewriting, extracting structure from messy text, writing code and reasoning over material you provide. Their typical failures are just as predictable:
Failure
What it looks like
How engineering handles it
Hallucination
Confident, specific and wrong: invented function names, numbers or sources
Give it sources (RAG), ask for citations, verify in code, measure with evals
Non-determinism
The same request can produce different answers
Structured outputs, tests over many examples instead of one
Instructions hidden in documents or tool results get followed
Treat inputs as data, limit tool permissions, require approval for actions
Prompts
A request has a system prompt (who the model is, rules, output format) and a list of messages alternating between the user and the assistant. Good prompts read like a brief to a smart colleague who has no context: say what you want, give the material, say what to do when unsure.
System: You are a support assistant for the FastAPI documentation.
Answer only from the provided documentation and cite the page.
If the answer isn't in it, say you don't know.
User:
<docs>
...passages found by search...
</docs>
<question>How do I run code after the response is sent?</question>
Tags like <docs> have no special meaning to the API; they just make it unambiguous where material starts and ends. Examples of good answers, included in the prompt, are one of the most effective ways to steer output.
Claude and the API
Which model you'll use, what a request and response look like, and how accounts, keys and billing work.
Claude and Anthropic
Claude is a family of LLMs built by Anthropic. People use it through apps (claude.ai on web, desktop and mobile), through coding tools like Claude Code, and through the Claude API, which is how your own software talks to it. The AI engineering guide uses the API.
Models come in tiers that trade capability against speed and cost: Haiku is the fastest and cheapest, Sonnet balances capability and cost, and Opus is the most capable of the three. Anthropic's newer Mythos tier sits above Opus. Model names and versions change regularly, so treat the models overview in the Claude docs as the source of truth, and keep model ids in configuration rather than code.
Choosing a model: start with a mid-tier model, then move individual jobs down to a cheaper one (or up) when your evals show it makes no difference (or a real one).
Anatomy of an API call
Every interaction is one HTTPS request to the Messages API with your API key. You send the model id, an output limit, an optional system prompt and the messages; you get back content blocks, a stop reason and token usage. The official SDKs (Python, TypeScript and others) wrap this in function calls.
The response content is a list because a reply can mix text with other blocks, such as a request to call one of your tools.
Accounts, keys and cost
API keys live in the Claude Console at platform.claude.com, under Settings → API keys. A key starts with sk-ant- and is shown only once, when you create it.
API billing is separate from a claude.ai subscription. A Pro or Max plan doesn't include API usage; the API is paid per token from its own balance.
Keys are secrets. Keep them in a .env file that's in .gitignore. A key pushed to a public repository gets found and abused quickly; if that happens, delete it in the Console and create a new one.
Set limits. Keys belong to a workspace, and workspaces can have their own limits. Use a small budget while learning.
Embeddings need a second account. Anthropic doesn't offer an embedding model; the guide uses Voyage AI, which has its own key and a free allowance (check its pricing page).
Other providers
OpenAI, Google (Gemini) and others offer similar APIs, and open-weight models can run on your own hardware with tools like Ollama. The concepts in this crash course apply to all of them; request formats and feature names differ in the details. Frameworks such as LangChain hide some of those differences behind one interface, which is one of their main selling points.
Structured output and tools
How a text generator becomes something your code can rely on, and how it can act on the world through your functions.
Structured output
Models produce text, but programs need data. With structured outputs you supply a JSON schema, usually generated from a Pydantic model, and generation is constrained so the reply always matches it. Instead of parsing prose, you get a validated object: a page summary with title, summary and topics, or a verdict with grounded: true.
This is the bridge between a language model and ordinary code: once output has a type, you can store it, test it and branch on it.
Tool use
A model can't do anything by itself: it can't search your database, call an API or read a file. Tool use lets you describe functions (a name, what it does, what arguments it takes). When the model decides it needs one, it replies with a request to call it. Your code runs the function and sends back the result, and the model continues with that information.
Steps 2 to 5 can repeat several times before the final answer. Repeating this loop, with the model choosing the steps, is what an agent is.
The model never executes anything. It only asks. Your code decides whether to run the call and with what permissions, which is exactly where safety checks belong.
Embeddings and vector search
How software finds text by meaning instead of by exact words, and what a vector database is for.
Embeddings
An embedding model turns a piece of text into a fixed-length list of numbers, a vector (for example 1024 numbers). It's trained so that texts with similar meaning get vectors that point in similar directions, even when they share no words: "How do I test my API?" lands near a passage about TestClient.
A two-dimensional sketch. Real embeddings have hundreds or thousands of dimensions, but the idea holds: closeness means similar meaning.
Embedding models are separate from chat models: smaller, cheaper, and they only produce vectors. The same model must embed both your documents and the incoming questions, or the vectors aren't comparable.
Measuring similarity
The usual measure is cosine similarity: it compares the direction two vectors point in. 1 means the same direction (very similar), around 0 means unrelated. Distance is the flip side: smaller distance, more similar.
import math
def cosine(a: list[float], b: list[float]) -> float:
dot = sum(x * y for x, y in zip(a, b))
return dot / (math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b)))
cosine([0.9, 0.1, 0.0], [0.8, 0.2, 0.1]) # 0.98: very similar
cosine([0.9, 0.1, 0.0], [0.0, 0.2, 0.9]) # 0.02: unrelated
Real vectors have about a thousand dimensions instead of three, but the arithmetic is the same.
Vector databases
A vector database stores vectors next to their source text and metadata, and answers one question fast: which stored vectors are closest to this one? Comparing against every vector works for thousands of items but is too slow for millions, so vector databases build approximate nearest neighbour indexes (HNSW is the common one) that skip most comparisons in exchange for occasionally missing a close match.
Option
What it is
Typical use
pgvector
An extension that adds vector columns and indexes to Postgres
Vectors next to your app data; the guide's default
Qdrant
Open-source dedicated vector database; self-hosted or cloud
Larger scale, heavy filtering; covered as the alternative
Pinecone
Fully managed vector database service
Teams that want no infrastructure to run
Chroma
Lightweight open-source vector store
Prototypes and notebooks
Keyword search still matters
Vector search finds meaning but can miss exact strings: a class name like BackgroundTasks, an error code, a version number. Classic full-text search is the opposite. Production systems usually run both and merge the results, which is called hybrid search. Postgres has full-text search built in, so pgvector plus Postgres covers both.
Retrieval-augmented generation
The most common pattern in AI engineering: find the relevant material first, then have the model answer from it.
Why RAG exists
Your model doesn't know your documents, its knowledge has a cutoff, and it fills gaps with plausible guesses. There are three ways to give it your knowledge:
Approach
Trade-off
Put everything in the prompt
Simple, but limited by the context window, and you pay for every token on every request
Fine-tune a model on your data
Expensive, slow to update, and poor at recalling exact facts
Retrieve the relevant passages per question (RAG)
Cheap to update (re-index), answers can cite sources; quality depends on retrieval
The two pipelines
RAG is two separate flows. Ingestion runs ahead of time: split documents into chunks, embed each chunk, store the vectors. Answering runs per question: embed the question, find the nearest chunks, and give them to the model with instructions to answer only from them and cite them.
Both pipelines must use the same embedding model. Real systems add hybrid search and a reranking step between search and the model.
Where RAG goes wrong
Bad chunks: pieces too small to make sense alone, or too big to be specific.
Wrong passages retrieved: the answer exists but search didn't find it. No prompt can fix this.
Right passages, wrong answer: the model ignores them or adds claims they don't support.
Stale index: documents changed but weren't re-ingested.
Each failure has a different fix, so you need to measure retrieval and answers separately. That measurement is what evals are, covered next.
Agents, MCP and evals
The vocabulary for systems that take multiple steps, connect to other tools, and need testing that works when outputs vary.
Workflows and agents
Anthropic draws a useful line between two kinds of systems. In a workflow, your code decides the steps and the model fills them in. In an agent, the model decides the steps itself, calling tools in a loop until it judges the task done.
Workflows are predictable, cheaper and easier to test. Agents handle open-ended tasks at the cost of latency, tokens and predictability.
Anthropic's guidance is to start with the simplest thing that works, often a single well-prompted call, and add steps or autonomy only when it measurably helps.
MCP: a standard plug for tools
Without a standard, every AI app needs custom code for every tool it connects to. The Model Context Protocol is an open standard that fixes this: write a tool integration once as an MCP server, and any compatible host can use it. The official docs compare it to USB-C: one connector for many devices.
Each client holds one connection to one server. stdio is for servers the host launches locally; Streamable HTTP is for servers running elsewhere.
A server can offer tools (actions the model calls), resources (data the app can read) and prompts (templates the user picks). If you know REST APIs, think of an MCP server as an API designed to be discovered and called by AI applications.
Evals: testing when outputs vary
A unit test expects one exact output. LLM systems give varied outputs, so testing them means running a fixed set of realistic questions, the golden dataset, and scoring the results:
Deterministic checks where possible: did the right page come back, does the answer mention the required term, are citations valid.
LLM-as-judge for what rules can't check, such as "is every claim supported by the sources?". A second model grades the answer against a rubric.
Scores over time: the point isn't pass or fail on one run, it's seeing whether a change to the prompt, model or chunking made things better or worse.
Frameworks
Everything above can be built with a provider SDK and ordinary code, and the AI engineering guide does that first so you see the mechanics. Frameworks package common patterns:
Framework
What it gives you
LangChain
A common interface across model providers, prebuilt agents, many integrations
LangGraph
Workflows as graphs with shared state, pauses for human approval, resumable runs
LlamaIndex
Data-focused tooling for loading, indexing and querying documents
The trade-off is always the same: less code to write, but another layer between you and the model to understand and debug.
Your toolbox and setup
Every tool the AI engineering guide uses, where it fits, and what to install before you start.
The stack at a glance
Filled chips are the main path; outlined chips are alternatives or later additions covered in the guide.
Tool
What it is
Used for
Anthropic Python SDK
Official client for the Claude API
Every model call: messages, streaming, structured output, tools
Voyage AI
Embedding and reranking models (Anthropic's recommended embeddings provider)
Turning chunks and questions into vectors; reordering search results
pgvector
Postgres extension for vector columns and indexes
Storing and searching embeddings next to your data
Qdrant
Dedicated vector database
The comparison stop: when a separate vector store is worth it
Redis
In-memory store
Caching answers, rate limits and budgets
MCP Python SDK
Official library for MCP servers and clients
Exposing the assistant to any MCP host
LangChain, LangGraph
Agent and workflow frameworks
Rebuilding the hand-written agent to compare approaches
pytest, Ragas, DeepEval
Test runner and eval libraries
Measuring retrieval and answer quality
Langfuse
Open-source tracing and eval platform
Seeing every step and cost of a request in production
Before you start
Python 3.12 or newer and uv, plus the FastAPI, Postgres and pytest basics from the first guide.
Docker, to run Postgres (with pgvector) and Redis locally.
A Claude API key from the Claude Console, a small prepaid balance, and a spending limit.
A Voyage AI API key.
A corpus to work with. FastAPI's documentation is Markdown in its GitHub repository: git clone https://github.com/fastapi/fastapi, then look in docs/en/docs.
Then check your key works with one call (put ANTHROPIC_API_KEY in your environment or .env first):
# hello_claude.py run with: uv run --with anthropic python hello_claude.py
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=100,
messages=[{"role": "user", "content": "Say hello in five words."}],
)
print(next(block.text for block in response.content if block.type == "text"))
print(response.usage)
If it prints a greeting and a token count, you're ready for the AI engineering guide.
Glossary
Term
Meaning
Token
A word fragment; the unit models read, write and bill by
Context window
The most tokens one request can hold, input and output together
System prompt
Instructions that set the model's role, rules and output format
Hallucination
A fluent answer that isn't supported by facts or sources
Structured output
Generation constrained to a JSON schema, so replies parse into typed objects
Tool use
The model requests a call to one of your functions; your code runs it
Embedding
A vector representing a text's meaning
Cosine similarity
How closely two vectors point in the same direction; 1 is identical
ANN index, HNSW
Approximate nearest-neighbour index: fast similarity search that may miss a few matches
Chunk
A passage of a document, the unit that gets embedded and retrieved
RAG
Retrieval-augmented generation: retrieve relevant passages, then answer from them
Hybrid search
Vector search and keyword search combined
Reranker
A model that reorders search results by relevance to the question
Workflow, agent
Code-directed steps versus model-directed steps
MCP host, client, server
The AI app, its connection, and the program exposing tools and data
Eval, golden dataset
A scored test run over a fixed set of realistic cases
LLM-as-judge
Using a model to grade another model's output against a rubric
Prompt injection
Instructions hidden in input data that the model might follow
Prompt caching
Reusing an already-processed prompt prefix to cut cost and latency